Skip to content

Commit

Permalink
NSOF-5917 metaport_mapped_elements_attachment: introduce resource
Browse files Browse the repository at this point in the history
  • Loading branch information
hod-alpert committed Jan 23, 2022
1 parent 35e2c9d commit 0d7dc22
Show file tree
Hide file tree
Showing 11 changed files with 319 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/resources/metaport.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ description: |-

MetaPort is a lightweight virtual appliance that enables the secure authenticated interface interact between existing servers and the Proofpoint NaaS cloud. Once configured, metaports enable users to access your applications via the Proofpoint cloud.

~> **NOTE:** When using the `mapped_elements` argument of this resource, the resource will take over the management of the MetaPort's mapped elements.
This argument is incompatible with other methods of managing MetaPort's mapped elements, such as `metaport_mapped_elements_attachment`.
Any attempt to manage MetaPort's mapped elements using different methods, will result in resource cycling and/or errors.

## Example Usage

```terraform
Expand Down
46 changes: 46 additions & 0 deletions docs/resources/metaport_mapped_elements_attachment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "pfptmeta_metaport_mapped_elements_attachment Resource - terraform-provider-pfptmeta"
subcategory: "Network"
description: |-
Attaches mapped elements to metaport.
---

# pfptmeta_metaport_mapped_elements_attachment (Resource)

Attaches mapped elements to metaport.

~> **NOTE:** Having multiple **metaport_mapped_elements_attachment** resources in conjunction with the same MetaPort and mapped elements will result in erratic behavior!
~> **NOTE:** For any given MetaPort, this resource is incompatible with the `pfptmeta_metaport`
[resource](https://registry.terraform.io/providers/nsofnetworks/pfptmeta/latest/docs/resources/metaport) `mapped_elements` argument.
When using this argument and resource simulteneously, both of them will attempt to manage the MetaPort's mapped elements. As a result, Terraform will display a permanent difference.

## Example Usage

```terraform
resource "pfptmeta_network_element" "mapped-subnet" {
name = "mapped subnet name"
mapped_subnets = ["0.0.0.0/0"]
}
resource "pfptmeta_metaport" "metaport" {
name = "metaport name"
}
resource "pfptmeta_metaport_mapped_elements_attachment" "attachment" {
metaport_id = pfptmeta_metaport.metaport.id
mapped_elements = [pfptmeta_network_element.mapped-subnet.id]
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- **mapped_elements** (Set of String) Mapped element IDs to be attached to the metaport (Mapped Subnet, Mapped Service or Enterprise DNS)
- **metaport_id** (String)

### Read-Only

- **id** (String) The ID of this resource.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
resource "pfptmeta_network_element" "mapped-subnet" {
name = "mapped subnet name"
mapped_subnets = ["0.0.0.0/0"]
}

resource "pfptmeta_metaport" "metaport" {
name = "metaport name"
}

resource "pfptmeta_metaport_mapped_elements_attachment" "attachment" {
metaport_id = pfptmeta_metaport.metaport.id
mapped_elements = [pfptmeta_network_element.mapped-subnet.id]
}
30 changes: 30 additions & 0 deletions internal/client/metaport.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,33 @@ func DeleteMetaport(ctx context.Context, c *Client, mID string) (*Metaport, erro
}
return parseMetaport(resp)
}

func AddMappedElementsToMetaport(ctx context.Context, c *Client, mID string, meIDs []string) (*Metaport, error) {
url := fmt.Sprintf("%s/%s/%s/add_mapped_elements", c.BaseURL, metaportEndpoint, mID)
body := make(map[string][]string)
body["mapped_elements"] = meIDs
jsonBody, err := json.Marshal(body)
if err != nil {
return nil, fmt.Errorf("could not convert mapped elements to json: %v", err)
}
resp, err := c.Post(ctx, url, bytes.NewReader(jsonBody))
if err != nil {
return nil, err
}
return parseMetaport(resp)
}

func RemoveMappedElementsFromMetaport(ctx context.Context, c *Client, mID string, meIDs []string) (*Metaport, error) {
url := fmt.Sprintf("%s/%s/%s/remove_mapped_elements", c.BaseURL, metaportEndpoint, mID)
body := make(map[string][]string)
body["mapped_elements"] = meIDs
jsonBody, err := json.Marshal(body)
if err != nil {
return nil, fmt.Errorf("could not convert mapped elements to json: %v", err)
}
resp, err := c.Post(ctx, url, bytes.NewReader(jsonBody))
if err != nil {
return nil, err
}
return parseMetaport(resp)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package acc_tests

import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"regexp"
"testing"
)

const (
metaportAttachmentDependencies = `
resource "pfptmeta_network_element" "mapped-service" {
name = "mapped service"
mapped_service = "mapped.service.com"
}
resource "pfptmeta_network_element" "mapped-service2" {
name = "mapped service"
mapped_service = "mapped.service2.com"
}
resource "pfptmeta_metaport" "metaport" {
name = "metaport name1"
}
`
metaportAttachment1 = `
resource "pfptmeta_metaport_mapped_elements_attachment" "attachment" {
metaport_id = pfptmeta_metaport.metaport.id
mapped_elements = [pfptmeta_network_element.mapped-service.id]
}
`
metaportAttachment2 = `
resource "pfptmeta_metaport_mapped_elements_attachment" "attachment2" {
metaport_id = pfptmeta_metaport.metaport.id
mapped_elements = [pfptmeta_network_element.mapped-service2.id]
}
`
metaportDataSource = `
data "pfptmeta_metaport" "metaport" {
id = pfptmeta_metaport.metaport.id
}
`
)

func TestAccMetaportAttachment(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
CheckDestroy: validateResourceDestroyed("metaport", "v1/metaports"),
Steps: []resource.TestStep{
{
Config: metaportAttachmentDependencies + metaportAttachment1 + metaportAttachment2,
Check: resource.ComposeTestCheckFunc(
resource.TestMatchResourceAttr(
"pfptmeta_metaport_mapped_elements_attachment.attachment", "metaport_id", regexp.MustCompile("^mp-.+$"),
),
resource.TestCheckResourceAttrPair(
"pfptmeta_network_element.mapped-service", "id",
"pfptmeta_metaport_mapped_elements_attachment.attachment", "mapped_elements.0"),
resource.TestCheckResourceAttrPair(
"pfptmeta_network_element.mapped-service2", "id",
"pfptmeta_metaport_mapped_elements_attachment.attachment2", "mapped_elements.0"),
),
},
{
Config: metaportAttachmentDependencies + metaportAttachment2,
},
{
Config: metaportAttachmentDependencies + metaportAttachment2 + metaportDataSource,
Check: resource.ComposeTestCheckFunc(
resource.TestMatchResourceAttr(
"data.pfptmeta_metaport.metaport", "id", regexp.MustCompile("^mp-.+$"),
),
resource.TestCheckResourceAttrPair(
"pfptmeta_network_element.mapped-service2", "id",
"data.pfptmeta_metaport.metaport", "mapped_elements.0"),
),
},
},
})
}
1 change: 1 addition & 0 deletions internal/provider/metaport/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func Resource() *schema.Resource {
Description: mappedElementsDesc,
Type: schema.TypeSet,
Optional: true,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateDiagFunc: common.ValidateID(true, "ed", "ne")},
Expand Down
79 changes: 79 additions & 0 deletions internal/provider/metaport_mapped_elements_attachment/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package metaport_mapped_elements_attachment

import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/nsofnetworks/terraform-provider-pfptmeta/internal/client"
"net/http"
)

func generateID(mID string, meIDs []string) string {
hash := 0
for _, meID := range meIDs {
hash += schema.HashString(meID)
}
return fmt.Sprintf("%s-%d", mID, hash)
}

func attachmentToResource(d *schema.ResourceData, m *client.Metaport) (diags diag.Diagnostics) {
err := d.Set("metaport_id", m.ID)
if err != nil {
return diag.FromErr(err)
}
mMes := &schema.Set{F: schema.HashString}
for _, i := range m.MappedElements {
mMes.Add(i)
}
schemaMes := d.Get("mapped_elements").(*schema.Set)
schemaMesSet := schema.NewSet(schema.HashString, schemaMes.List())
intersection := mMes.Intersection(schemaMesSet)
mes := client.ResourceTypeSetToStringSlice(intersection)
err = d.Set("mapped_elements", mes)
if err != nil {
return diag.FromErr(err)
}
d.SetId(generateID(m.ID, mes))
return
}

func readResource(ctx context.Context, d *schema.ResourceData, meta interface{}) (diags diag.Diagnostics) {
c := meta.(*client.Client)

mID := d.Get("metaport_id").(string)
rg, err := client.GetMetaport(ctx, c, mID)
if err != nil {
errResponse, ok := err.(*client.ErrorResponse)
if ok && errResponse.Status == http.StatusNotFound {
d.SetId("")
}
return diag.FromErr(err)
}
return attachmentToResource(d, rg)
}
func createResource(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
c := meta.(*client.Client)

mID := d.Get("metaport_id").(string)
mes := client.ResourceTypeSetToStringSlice(d.Get("mapped_elements").(*schema.Set))
m, err := client.AddMappedElementsToMetaport(ctx, c, mID, mes)
if err != nil {
return diag.FromErr(err)
}
return attachmentToResource(d, m)
}

func deleteResource(ctx context.Context, d *schema.ResourceData, meta interface{}) (diags diag.Diagnostics) {
c := meta.(*client.Client)

mID := d.Get("metaport_id").(string)
mes := d.Get("mapped_elements").(*schema.Set)
_, err := client.RemoveMappedElementsFromMetaport(ctx, c, mID, client.ResourceTypeSetToStringSlice(mes))
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
d.SetId("")
return
}
38 changes: 38 additions & 0 deletions internal/provider/metaport_mapped_elements_attachment/resource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package metaport_mapped_elements_attachment

import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/nsofnetworks/terraform-provider-pfptmeta/internal/provider/common"
)

func Resource() *schema.Resource {
return &schema.Resource{
Description: "Attaches mapped elements to metaport.",
ReadContext: readResource,
CreateContext: createResource,
DeleteContext: deleteResource,
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
},
"metaport_id": {
Type: schema.TypeString,
Required: true,
ValidateDiagFunc: common.ValidateID(false, "mp"),
ForceNew: true,
},
"mapped_elements": {
Description: "Mapped element IDs to be attached to the metaport (Mapped Subnet, Mapped Service or Enterprise DNS)",
Required: true,
Type: schema.TypeSet,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateDiagFunc: common.ValidateID(true, "ne", "ed"),
},
MinItems: 1,
ForceNew: true,
},
},
}
}
2 changes: 2 additions & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/nsofnetworks/terraform-provider-pfptmeta/internal/provider/metaport"
"github.com/nsofnetworks/terraform-provider-pfptmeta/internal/provider/metaport_cluster"
"github.com/nsofnetworks/terraform-provider-pfptmeta/internal/provider/metaport_failover"
"github.com/nsofnetworks/terraform-provider-pfptmeta/internal/provider/metaport_mapped_elements_attachment"
"github.com/nsofnetworks/terraform-provider-pfptmeta/internal/provider/network_element"
"github.com/nsofnetworks/terraform-provider-pfptmeta/internal/provider/network_element_alias"
"github.com/nsofnetworks/terraform-provider-pfptmeta/internal/provider/notification_channel"
Expand Down Expand Up @@ -89,6 +90,7 @@ func New(version string) func() *schema.Provider {
"pfptmeta_mapped_domain": mapped_domain.Resource(),
"pfptmeta_mapped_host": mapped_host.Resource(),
"pfptmeta_metaport": metaport.Resource(),
"pfptmeta_metaport_mapped_elements_attachment": metaport_mapped_elements_attachment.Resource(),
"pfptmeta_metaport_cluster": metaport_cluster.Resource(),
"pfptmeta_metaport_failover": metaport_failover.Resource(),
"pfptmeta_enterprise_dns": enterprise_dns.Resource(),
Expand Down
4 changes: 4 additions & 0 deletions templates/resources/metaport.md.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ description: |-

{{ .Description | trimspace }}

~> **NOTE:** When using the `mapped_elements` argument of this resource, the resource will take over the management of the MetaPort's mapped elements.
This argument is incompatible with other methods of managing MetaPort's mapped elements, such as `metaport_mapped_elements_attachment`.
Any attempt to manage MetaPort's mapped elements using different methods, will result in resource cycling and/or errors.

## Example Usage

{{tffile "examples/resources/pfptmeta_metaport/resource.tf"}}
Expand Down
22 changes: 22 additions & 0 deletions templates/resources/metaport_mapped_elements_attachment.md.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "{{.Type}} {{.Name}} - {{.ProviderName}}"
subcategory: "Network"
description: |-
{{ .Description | plainmarkdown | trimspace | prefixlines " " }}
---

# {{.Type}} ({{.Name}})

{{ .Description | trimspace }}

~> **NOTE:** Having multiple **metaport_mapped_elements_attachment** resources in conjunction with the same MetaPort and mapped elements will result in erratic behavior!
~> **NOTE:** For any given MetaPort, this resource is incompatible with the `pfptmeta_metaport`
[resource](https://registry.terraform.io/providers/nsofnetworks/pfptmeta/latest/docs/resources/metaport) `mapped_elements` argument.
When using this argument and resource simulteneously, both of them will attempt to manage the MetaPort's mapped elements. As a result, Terraform will display a permanent difference.

## Example Usage

{{tffile "/examples/resources/pfptmeta_metaport_mapped_elements_attachment/resource.tf"}}

{{ .SchemaMarkdown | trimspace }}

0 comments on commit 0d7dc22

Please sign in to comment.