From 48c65ac7599cfa8d722788dd75e3911fc4cb974e Mon Sep 17 00:00:00 2001 From: srushti-patl Date: Tue, 5 Nov 2024 15:01:25 -0800 Subject: [PATCH] feat: Updating Service Token Resource for Aside Port Service Token --- docs/resources/fabric_service_token.md | 94 +++++++++++++------ .../aside_colo_service_token.tf | 25 +++++ .../zside_vd_service_token.tf | 5 + .../resources/fabric/service_token/models.go | 79 +++++++++++++++- .../fabric/service_token/resource_schema.go | 13 +-- .../fabric/service_token/resource_test.go | 87 ++++++++++++++++- .../resources/fabric_service_token.md.tmpl | 3 + 7 files changed, 261 insertions(+), 45 deletions(-) create mode 100644 examples/resources/equinix_fabric_service_token/aside_colo_service_token.tf diff --git a/docs/resources/fabric_service_token.md b/docs/resources/fabric_service_token.md index 687368767..d3c7caf46 100644 --- a/docs/resources/fabric_service_token.md +++ b/docs/resources/fabric_service_token.md @@ -12,10 +12,40 @@ Additional documentation: ## Example Usage +Aside Port Service Token +```terraform +resource "equinix_fabric_service_token" "test" { + type = "VC_TOKEN" + description = "Aside COLO Service Token" + expiration_date_time = "2025-01-18T06:43:49.981Z" + service_token_connection { + type = "EVPL_VC" + bandwidth_limit = 1000 + a_side { + access_point_selectors{ + type = "COLO" + port { + uuid = "" + } + link_protocol { + type = "DOT1Q" + vlan_tag = "2987" + } + } + } + } + notifications { + type = "ALL" + emails = ["example@equinix.com", "test1@equinix.com"] + } +} +``` + Zside Virtual Device Service Token ```terraform resource "equinix_fabric_service_token" "test" { type = "VC_TOKEN" + description = "Zside VD Service Token" expiration_date_time = "2025-01-18T06:43:49.986Z" service_token_connection { type = "EVPL_VC" @@ -33,6 +63,10 @@ resource "equinix_fabric_service_token" "test" { } } } + notifications { + type = "ALL" + emails = ["example@equinix.com"] + } } ``` @@ -82,7 +116,6 @@ Optional: Required: -- `supported_bandwidths` (List of Number) List of permitted bandwidths'; For Port-based Service Tokens, the maximum allowable bandwidth is 50 Gbps, while for Virtual Device-based Service Tokens, it is limited to 10 Gbps - `type` (String) Type of Connection supported by Service Token you will create; EVPL_VC, EVPLAN_VC, EPLAN_VC, IPWAN_VC Optional: @@ -91,6 +124,7 @@ Optional: - `allow_custom_bandwidth` (Boolean) Allow custom bandwidth value - `allow_remote_connection` (Boolean) Authorization to connect remotely - `bandwidth_limit` (Number) Connection bandwidth limit in Mbps +- `supported_bandwidths` (List of Number) List of permitted bandwidths'; For Port-based Service Tokens, the maximum allowable bandwidth is 50 Gbps, while for Virtual Device-based Service Tokens, it is limited to 10 Gbps - `z_side` (Block Set) Z-Side Connection link protocol,virtual device or network configuration (see [below for nested schema](#nestedblock--service_token_connection--z_side)) Read-Only: @@ -170,31 +204,34 @@ Optional: ### Nested Schema for `service_token_connection.a_side.access_point_selectors.port` +Required: + +- `uuid` (String) Equinix-assigned Port identifier + Optional: +- `type` (String) Type of Port + +Read-Only: + - `account_name` (String) Account Name - `bandwidth` (Number) Port Bandwidth - `cvp_id` (Number) Customer virtual port Id - `encapsulation_protocol_type` (String) Port Encapsulation -- `location` (Block Set) Port Location (see [below for nested schema](#nestedblock--service_token_connection--a_side--access_point_selectors--port--location)) +- `href` (String) Unique Resource Identifier +- `location` (Set of Object) Port Location (see [below for nested schema](#nestedatt--service_token_connection--a_side--access_point_selectors--port--location)) - `port_name` (String) Port Name - `priority` (String) Port Priority -- `type` (String) Type of Port -- `uuid` (String) Equinix-assigned Port identifier -Read-Only: - -- `href` (String) Unique Resource Identifier - - + ### Nested Schema for `service_token_connection.a_side.access_point_selectors.port.location` -Optional: +Read-Only: -- `ibx` (String) IBX Code -- `metro_code` (String) Access point metro code -- `metro_name` (String) Access point metro name -- `region` (String) Access point region +- `ibx` (String) +- `metro_code` (String) +- `metro_name` (String) +- `region` (String) @@ -291,31 +328,34 @@ Optional: ### Nested Schema for `service_token_connection.z_side.access_point_selectors.port` +Required: + +- `uuid` (String) Equinix-assigned Port identifier + Optional: +- `type` (String) Type of Port + +Read-Only: + - `account_name` (String) Account Name - `bandwidth` (Number) Port Bandwidth - `cvp_id` (Number) Customer virtual port Id - `encapsulation_protocol_type` (String) Port Encapsulation -- `location` (Block Set) Port Location (see [below for nested schema](#nestedblock--service_token_connection--z_side--access_point_selectors--port--location)) +- `href` (String) Unique Resource Identifier +- `location` (Set of Object) Port Location (see [below for nested schema](#nestedatt--service_token_connection--z_side--access_point_selectors--port--location)) - `port_name` (String) Port Name - `priority` (String) Port Priority -- `type` (String) Type of Port -- `uuid` (String) Equinix-assigned Port identifier - -Read-Only: - -- `href` (String) Unique Resource Identifier - + ### Nested Schema for `service_token_connection.z_side.access_point_selectors.port.location` -Optional: +Read-Only: -- `ibx` (String) IBX Code -- `metro_code` (String) Access point metro code -- `metro_name` (String) Access point metro name -- `region` (String) Access point region +- `ibx` (String) +- `metro_code` (String) +- `metro_name` (String) +- `region` (String) diff --git a/examples/resources/equinix_fabric_service_token/aside_colo_service_token.tf b/examples/resources/equinix_fabric_service_token/aside_colo_service_token.tf new file mode 100644 index 000000000..b65b98be7 --- /dev/null +++ b/examples/resources/equinix_fabric_service_token/aside_colo_service_token.tf @@ -0,0 +1,25 @@ +resource "equinix_fabric_service_token" "test" { + type = "VC_TOKEN" + description = "Aside COLO Service Token" + expiration_date_time = "2025-01-18T06:43:49.981Z" + service_token_connection { + type = "EVPL_VC" + bandwidth_limit = 1000 + a_side { + access_point_selectors{ + type = "COLO" + port { + uuid = "" + } + link_protocol { + type = "DOT1Q" + vlan_tag = "2987" + } + } + } + } + notifications { + type = "ALL" + emails = ["example@equinix.com", "test1@equinix.com"] + } +} diff --git a/examples/resources/equinix_fabric_service_token/zside_vd_service_token.tf b/examples/resources/equinix_fabric_service_token/zside_vd_service_token.tf index 15eaf72d6..f3f0b8b36 100644 --- a/examples/resources/equinix_fabric_service_token/zside_vd_service_token.tf +++ b/examples/resources/equinix_fabric_service_token/zside_vd_service_token.tf @@ -1,5 +1,6 @@ resource "equinix_fabric_service_token" "test" { type = "VC_TOKEN" + description = "Zside VD Service Token" expiration_date_time = "2025-01-18T06:43:49.986Z" service_token_connection { type = "EVPL_VC" @@ -17,4 +18,8 @@ resource "equinix_fabric_service_token" "test" { } } } + notifications { + type = "ALL" + emails = ["example@equinix.com"] + } } diff --git a/internal/resources/fabric/service_token/models.go b/internal/resources/fabric/service_token/models.go index 0a3a58c24..2e37c57b5 100644 --- a/internal/resources/fabric/service_token/models.go +++ b/internal/resources/fabric/service_token/models.go @@ -393,7 +393,47 @@ func portTerraformToGo(portList []interface{}) fabricv4.SimplifiedMetadataEntity var port fabricv4.SimplifiedMetadataEntity portListMap := portList[0].(map[string]interface{}) uuid := portListMap["uuid"].(string) - port.SetUuid(uuid) + href := portListMap["href"].(string) + type_ := portListMap["type"].(string) + cvpId := portListMap["cvp_id"].(int) + bandwidth := portListMap["bandwidth"].(int) + portName := portListMap["port_name"].(string) + encapsulationProtocolType := portListMap["encapsulation_protocol_type"].(string) + accountName := portListMap["account_name"].(string) + priority := portListMap["priority"].(string) + locationList := portListMap["location"].(*schema.Set).List() + + if uuid != "" { + port.SetUuid(uuid) + } + if href != "" { + port.SetHref(href) + } + if type_ != "" { + port.SetType(type_) + } + if cvpId != 0 { + port.SetCvpId(int32(cvpId)) + } + if bandwidth != 0 { + port.SetBandwidth(float32(bandwidth)) + } + if portName != "" { + port.SetPortName(portName) + } + if encapsulationProtocolType != "" { + port.SetEncapsulationProtocolType(encapsulationProtocolType) + } + if accountName != "" { + port.SetAccountName(accountName) + } + if priority != "" { + port.SetPriority(priority) + } + if len(locationList) != 0 { + location := equinix_fabric_schema.LocationTerraformToGo(locationList) + port.SetLocation(location) + } return port } @@ -601,10 +641,41 @@ func accessPointSelectorsGoToTerraform(apSelectors []fabricv4.AccessPointSelecto } func portGoToTerraform(port *fabricv4.SimplifiedMetadataEntity) *schema.Set { + if port == nil { + return nil + } mappedPort := make(map[string]interface{}) - mappedPort["href"] = port.GetHref() - mappedPort["type"] = port.GetType() - mappedPort["uuid"] = port.GetUuid() + if href := port.GetHref(); href != "" { + mappedPort["href"] = href + } + if uuid := port.GetUuid(); uuid != "" { + mappedPort["uuid"] = uuid + } + if port.GetType() != "" { + mappedPort["type"] = port.GetType() + } + if cvpId := port.GetCvpId(); cvpId != 0 { + mappedPort["cvp_id"] = port.GetCvpId() + } + if bandwidth := port.GetBandwidth(); bandwidth != 0 { + mappedPort["bandwidth"] = port.GetBandwidth() + } + if portName := port.GetPortName(); portName != "" { + mappedPort["port_name"] = port.GetPortName() + } + if encapsulationProtocolType := port.GetEncapsulationProtocolType(); encapsulationProtocolType != "" { + mappedPort["encapsulation_protocol_type"] = port.GetEncapsulationProtocolType() + } + if accountName := port.GetAccountName(); accountName != "" { + mappedPort["account_name"] = port.GetAccountName() + } + if priority := port.GetPriority(); priority != "" { + mappedPort["priority"] = port.GetPriority() + } + if port.Location != nil { + location := port.GetLocation() + mappedPort["location"] = equinix_fabric_schema.LocationGoToTerraform(&location) + } portSet := schema.NewSet( schema.HashResource(portSch()), diff --git a/internal/resources/fabric/service_token/resource_schema.go b/internal/resources/fabric/service_token/resource_schema.go index ab2a363a5..fe4bf0b02 100644 --- a/internal/resources/fabric/service_token/resource_schema.go +++ b/internal/resources/fabric/service_token/resource_schema.go @@ -129,7 +129,8 @@ func serviceTokenConnectionSch() *schema.Resource { }, "supported_bandwidths": { Type: schema.TypeList, - Required: true, + Optional: true, + Computed: true, Description: "List of permitted bandwidths'; For Port-based Service Tokens, the maximum allowable bandwidth is 50 Gbps, while for Virtual Device-based Service Tokens, it is limited to 10 Gbps", Elem: &schema.Schema{ Type: schema.TypeInt, @@ -230,8 +231,7 @@ func portSch() *schema.Resource { }, "uuid": { Type: schema.TypeString, - Optional: true, - Computed: true, + Required: true, Description: "Equinix-assigned Port identifier", }, "type": { @@ -243,43 +243,36 @@ func portSch() *schema.Resource { "cvp_id": { Type: schema.TypeInt, Computed: true, - Optional: true, Description: "Customer virtual port Id", }, "bandwidth": { Type: schema.TypeInt, Computed: true, - Optional: true, Description: "Port Bandwidth", }, "port_name": { Type: schema.TypeString, Computed: true, - Optional: true, Description: "Port Name", }, "encapsulation_protocol_type": { Type: schema.TypeString, Computed: true, - Optional: true, Description: "Port Encapsulation", }, "account_name": { Type: schema.TypeString, Computed: true, - Optional: true, Description: "Account Name", }, "priority": { Type: schema.TypeString, Computed: true, - Optional: true, Description: "Port Priority", }, "location": { Type: schema.TypeSet, Computed: true, - Optional: true, Description: "Port Location", Elem: &schema.Resource{ Schema: equinix_fabric_schema.LocationSch(), diff --git a/internal/resources/fabric/service_token/resource_test.go b/internal/resources/fabric/service_token/resource_test.go index 9790d8ba7..077f1cba8 100644 --- a/internal/resources/fabric/service_token/resource_test.go +++ b/internal/resources/fabric/service_token/resource_test.go @@ -14,7 +14,7 @@ import ( "github.com/hashicorp/terraform-plugin-testing/terraform" ) -func TestAccFabricServiceToken_PNFV(t *testing.T) { +func TestAccFabricZsideVirtualDeviceServiceToken_PNFV(t *testing.T) { connectionTestData := testing_helpers.GetFabricEnvConnectionTestData(t) var virtualDevice string if len(connectionTestData) > 0 { @@ -28,7 +28,7 @@ func TestAccFabricServiceToken_PNFV(t *testing.T) { CheckDestroy: CheckServiceTokenDelete, Steps: []resource.TestStep{ { - Config: testAccFabricServiceTokenConfig(serviceTokenName, serviceTokenDescription, virtualDevice), + Config: testAccFabricZsideVirtualDeviceServiceTokenConfig(serviceTokenName, serviceTokenDescription, virtualDevice), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet("equinix_fabric_service_token.test", "uuid"), resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "name", serviceTokenName), @@ -44,7 +44,7 @@ func TestAccFabricServiceToken_PNFV(t *testing.T) { ExpectNonEmptyPlan: false, }, { - Config: testAccFabricServiceTokenConfig(serviceTokenUpdatedName, serviceTokenUpdatedDescription, virtualDevice), + Config: testAccFabricZsideVirtualDeviceServiceTokenConfig(serviceTokenUpdatedName, serviceTokenUpdatedDescription, virtualDevice), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet("equinix_fabric_service_token.test", "uuid"), resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "name", serviceTokenUpdatedName), @@ -63,7 +63,54 @@ func TestAccFabricServiceToken_PNFV(t *testing.T) { }) } -func testAccFabricServiceTokenConfig(serviceTokenName string, serviceTokenDescription string, virtualDeviceUuid string) string { +func TestAccFabricAsidePortServiceToken_PNFV(t *testing.T) { + ports := testing_helpers.GetFabricEnvPorts(t) + var portUuid string + if len(ports) > 0 { + portUuid = ports["ppds"]["dot1q"][0].GetUuid() + } + serviceTokenName, serviceTokenUpdatedName := "token_port_PNFV", "UP_Token_port_PNFV" + serviceTokenDescription, serviceTokenUpdatedDescription := "aside port token", "Updated aside port token" + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.TestAccPreCheck(t) }, + Providers: acceptance.TestAccProviders, + CheckDestroy: CheckServiceTokenDelete, + Steps: []resource.TestStep{ + { + Config: testAccFabricAsidePortServiceTokenConfig(serviceTokenName, serviceTokenDescription, portUuid), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("equinix_fabric_service_token.test", "uuid"), + resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "name", serviceTokenName), + resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "type", "VC_TOKEN"), + resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "description", serviceTokenDescription), + resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "expiration_date_time", "2025-01-18T06:43:49.981Z"), + resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "service_token_connection.0.bandwidth_limit", "1000"), + resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "service_token_connection.0.a_side.0.access_point_selectors.0.port.0.uuid", portUuid), + resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "service_token_connection.0.a_side.0.access_point_selectors.0.link_protocol.0.type", "DOT1Q"), + resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "service_token_connection.0.a_side.0.access_point_selectors.0.link_protocol.0.vlan_tag", "2987"), + ), + ExpectNonEmptyPlan: false, + }, + { + Config: testAccFabricAsidePortServiceTokenConfig(serviceTokenUpdatedName, serviceTokenUpdatedDescription, portUuid), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("equinix_fabric_service_token.test", "uuid"), + resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "name", serviceTokenUpdatedName), + resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "type", "VC_TOKEN"), + resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "description", serviceTokenUpdatedDescription), + resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "expiration_date_time", "2025-01-18T06:43:49.981Z"), + resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "service_token_connection.0.bandwidth_limit", "1000"), + resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "service_token_connection.0.a_side.0.access_point_selectors.0.port.0.uuid", portUuid), + resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "service_token_connection.0.a_side.0.access_point_selectors.0.link_protocol.0.type", "DOT1Q"), + resource.TestCheckResourceAttr("equinix_fabric_service_token.test", "service_token_connection.0.a_side.0.access_point_selectors.0.link_protocol.0.vlan_tag", "2987"), + ), + ExpectNonEmptyPlan: false, + }, + }, + }) +} + +func testAccFabricZsideVirtualDeviceServiceTokenConfig(serviceTokenName string, serviceTokenDescription string, virtualDeviceUuid string) string { return fmt.Sprintf( `resource "equinix_fabric_service_token" "test"{ type = "VC_TOKEN" @@ -95,6 +142,38 @@ func testAccFabricServiceTokenConfig(serviceTokenName string, serviceTokenDescri `, serviceTokenName, serviceTokenDescription, virtualDeviceUuid) } +func testAccFabricAsidePortServiceTokenConfig(serviceTokenName string, serviceTokenDescription string, portUuid string) string { + return fmt.Sprintf( + `resource "equinix_fabric_service_token" "test"{ + type = "VC_TOKEN" + name = "%s" + description = "%s" + expiration_date_time = "2025-01-18T06:43:49.981Z" + service_token_connection { + type = "EVPL_VC" + bandwidth_limit = 1000 + a_side { + access_point_selectors{ + type = "COLO" + port { + uuid = "%s" + } + link_protocol { + type = "DOT1Q" + vlan_tag = "2987" + } + } + } + } + notifications { + type = "ALL" + emails = ["example@equinix.com", "test1@equinix.com"] + } + + } + `, serviceTokenName, serviceTokenDescription, portUuid) +} + func CheckServiceTokenDelete(s *terraform.State) error { ctx := context.Background() for _, rs := range s.RootModule().Resources { diff --git a/templates/resources/fabric_service_token.md.tmpl b/templates/resources/fabric_service_token.md.tmpl index 4d8d656f7..937d6ae6f 100644 --- a/templates/resources/fabric_service_token.md.tmpl +++ b/templates/resources/fabric_service_token.md.tmpl @@ -16,6 +16,9 @@ Additional documentation: ## Example Usage +Aside Port Service Token +{{tffile "examples/resources/equinix_fabric_service_token/aside_colo_service_token.tf"}} + Zside Virtual Device Service Token {{tffile "examples/resources/equinix_fabric_service_token/zside_vd_service_token.tf"}}