diff --git a/Makefile b/Makefile index 4e321a7..76eb80b 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ HOSTNAME=registry.terraform.io NAMESPACE=megaport NAME=megaport BINARY=terraform-provider-${NAME} -VERSION=0.2.9 +VERSION=0.2.10-stateless-4 OS_ARCH=$$(go version | cut -d" " -f4 | sed 's/\//_/g') ZIP_FILE=terraform-provider-${NAME}_${VERSION}_${OS_ARCH}.zip diff --git a/build.sh b/build.sh index bfffc08..6dc0ddd 100755 --- a/build.sh +++ b/build.sh @@ -13,9 +13,9 @@ # limitations under the License. provider_directory="$(pwd)" -GO111MODULE=on GOSUMDB=off go get -d github.com/megaport/megaportgo +GOSUMDB=off go mod download rm -f bin/* -version="$(git describe --tags)" +version="v0.2.10-stateless-4" provider_filename="$(pwd)/bin/terraform-provider-megaport_$version" provider_filename_no_version="$(pwd)/bin/terraform-provider-megaport" go build -o $provider_filename @@ -26,10 +26,10 @@ cd ~ arch=$(go version | cut -d" " -f4 | sed 's/\//_/g') plugin_directory="$(pwd)/.terraform.d/plugins/${arch}/" mkdir -p $plugin_directory -ln -s $provider_filename_no_version $plugin_directory +ln -s --force $provider_filename_no_version $plugin_directory echo "Symbolic link created from build directory to terraform.d. < 0.13" plugin_directory="$(pwd)/.terraform.d/plugins/megaport.com/megaport/megaport/${version:1}/${arch}/" mkdir -p $plugin_directory -ln -s $provider_filename_no_version $plugin_directory +ln -s --force $provider_filename_no_version $plugin_directory echo "Symbolic link created from build directory to terraform.d. >= 0.13" cd $provider_directory diff --git a/data_megaport/data_megaport_aws_connection.go b/data_megaport/data_megaport_aws_connection.go index 4d85f3f..52d815d 100644 --- a/data_megaport/data_megaport_aws_connection.go +++ b/data_megaport/data_megaport_aws_connection.go @@ -15,7 +15,7 @@ package data_megaport import ( - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/megaport/terraform-provider-megaport/schema_megaport" ) diff --git a/data_megaport/data_megaport_azure_connection.go b/data_megaport/data_megaport_azure_connection.go index afe9713..98e7876 100644 --- a/data_megaport/data_megaport_azure_connection.go +++ b/data_megaport/data_megaport_azure_connection.go @@ -15,7 +15,7 @@ package data_megaport import ( - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/megaport/terraform-provider-megaport/schema_megaport" ) diff --git a/data_megaport/data_megaport_gcp_connection.go b/data_megaport/data_megaport_gcp_connection.go index c5147f7..9e0d784 100644 --- a/data_megaport/data_megaport_gcp_connection.go +++ b/data_megaport/data_megaport_gcp_connection.go @@ -15,7 +15,7 @@ package data_megaport import ( - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/megaport/terraform-provider-megaport/schema_megaport" ) diff --git a/data_megaport/data_megaport_location.go b/data_megaport/data_megaport_location.go index eb3afa2..7e1ad43 100644 --- a/data_megaport/data_megaport_location.go +++ b/data_megaport/data_megaport_location.go @@ -18,7 +18,7 @@ import ( "errors" "strconv" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/megaport/megaportgo/types" "github.com/megaport/terraform-provider-megaport/schema_megaport" "github.com/megaport/terraform-provider-megaport/terraform_utility" diff --git a/data_megaport/data_megaport_locations.go b/data_megaport/data_megaport_locations.go new file mode 100644 index 0000000..818a486 --- /dev/null +++ b/data_megaport/data_megaport_locations.go @@ -0,0 +1,81 @@ +// Copyright 2020 Megaport Pty Ltd +// +// Licensed under the Mozilla Public License, Version 2.0 (the +// "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// https://mozilla.org/MPL/2.0/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package data_megaport + +import ( + "context" + "github.com/hashicorp/go-cty/cty" + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/megaport/terraform-provider-megaport/schema_megaport" + "github.com/megaport/terraform-provider-megaport/terraform_utility" +) + +func MegaportLocations() *schema.Resource { + return &schema.Resource{ + ReadContext: dataMegaportLocationsRead, + Schema: schema_megaport.DataLocationsSchema(), + } +} + +func dataMegaportLocationsRead(c context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + errors := make([]diag.Diagnostic, 0) + location := m.(*terraform_utility.MegaportClient).Location + locationsResponse, err := location.GetAllLocations() + if err != nil { + errors = append(errors, diag.Diagnostic{ + Severity: diag.Error, + Summary: "Failed to get megaport locations list", + Detail: err.Error(), + AttributePath: make([]cty.PathStep, 0), + }) + return errors + } + + locations := make([]map[string]interface{}, len(locationsResponse)) + + for i, loc := range locationsResponse { + location := make(map[string]interface{}) + location["address"] = loc.Address + location["country"] = loc.Country + location["has_mcr"] = loc.VRouterAvailable + location["id"] = loc.ID + location["latitude"] = loc.Latitude + location["live_date"] = loc.LiveDate + location["longitude"] = loc.Longitude + location["market"] = loc.Market + location["metro"] = loc.Metro + location["name"] = loc.Name + location["site_code"] = loc.SiteCode + location["status"] = loc.Status + locations[i] = location + } + + id, err := uuid.GenerateUUID() + + if err != nil { + errors = append(errors, diag.Diagnostic{ + Severity: diag.Error, + Summary: err.Error(), + Detail: "Failed to generate UUID as Id", + AttributePath: make([]cty.PathStep, 0), + }) + return errors + } + d.Set("locations", &locations) + d.SetId(id) + return errors +} diff --git a/data_megaport/data_megaport_mcr.go b/data_megaport/data_megaport_mcr.go index 792679c..8cbcb37 100644 --- a/data_megaport/data_megaport_mcr.go +++ b/data_megaport/data_megaport_mcr.go @@ -15,7 +15,7 @@ package data_megaport import ( - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/megaport/terraform-provider-megaport/schema_megaport" "github.com/megaport/terraform-provider-megaport/terraform_utility" ) diff --git a/data_megaport/data_megaport_partner_port.go b/data_megaport/data_megaport_partner_port.go index 38fdbb7..8107259 100644 --- a/data_megaport/data_megaport_partner_port.go +++ b/data_megaport/data_megaport_partner_port.go @@ -17,7 +17,7 @@ package data_megaport import ( "errors" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/megaport/terraform-provider-megaport/schema_megaport" "github.com/megaport/terraform-provider-megaport/terraform_utility" ) diff --git a/data_megaport/data_megaport_port.go b/data_megaport/data_megaport_port.go index bb337af..416ced3 100644 --- a/data_megaport/data_megaport_port.go +++ b/data_megaport/data_megaport_port.go @@ -15,7 +15,7 @@ package data_megaport import ( - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/megaport/terraform-provider-megaport/schema_megaport" "github.com/megaport/terraform-provider-megaport/terraform_utility" ) @@ -23,7 +23,7 @@ import ( func MegaportPort() *schema.Resource { return &schema.Resource{ Read: dataMegaportPortRead, - Schema: schema_megaport.DataPortSchema(), + Schema: schema_megaport.ResourcePortSchema(), } } diff --git a/data_megaport/data_megaport_ports.go b/data_megaport/data_megaport_ports.go new file mode 100644 index 0000000..3486a61 --- /dev/null +++ b/data_megaport/data_megaport_ports.go @@ -0,0 +1,78 @@ +// Copyright 2020 Megaport Pty Ltd +// +// Licensed under the Mozilla Public License, Version 2.0 (the +// "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// https://mozilla.org/MPL/2.0/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package data_megaport + +import ( + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/megaport/megaportgo/types" + "github.com/megaport/terraform-provider-megaport/schema_megaport" + "github.com/megaport/terraform-provider-megaport/terraform_utility" +) + +func MegaportPorts() *schema.Resource { + return &schema.Resource{ + Read: dataMegaportPortsRead, + Schema: schema_megaport.DataPortsSchema(), + } +} + +func dataMegaportPortsRead(d *schema.ResourceData, m interface{}) error { + port := m.(*terraform_utility.MegaportClient).Port + + id, err := uuid.GenerateUUID() + + if err != nil { + return err + } + + ports, retrievalErr := port.GetPorts() + + if retrievalErr != nil { + return retrievalErr + } + + converted := make([]map[string]interface{}, len(ports)) + + for i, port := range ports { + converted[i] = tfizePort(port) + } + + d.SetId(id) + + return d.Set("ports", &converted) +} + +func tfizePort(port types.Port) map[string]interface{} { + tf := make(map[string]interface{}) + tf["admin_locked"] = port.AdminLocked + tf["company_name"] = port.CompanyName + tf["create_date"] = port.CreateDate + tf["created_by"] = port.CreatedBy + tf["lag_id"] = port.LAGID + tf["lag_primary"] = port.LAGPrimary + tf["live_date"] = port.LiveDate + tf["location_id"] = port.LocationID + tf["locked"] = port.Locked + tf["market_code"] = port.Market + tf["marketplace_visibility"] = port.MarketplaceVisibility + tf["port_name"] = port.Name + tf["port_speed"] = port.PortSpeed + tf["provisioning_status"] = port.ProvisioningStatus + tf["term"] = port.ContractTermMonths + tf["type"] = port.Type + tf["uid"] = port.UID + return tf +} diff --git a/data_megaport/data_megaport_vxc.go b/data_megaport/data_megaport_vxc.go index 4374263..cb7ae59 100644 --- a/data_megaport/data_megaport_vxc.go +++ b/data_megaport/data_megaport_vxc.go @@ -15,7 +15,7 @@ package data_megaport import ( - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/megaport/terraform-provider-megaport/schema_megaport" "github.com/megaport/terraform-provider-megaport/terraform_utility" ) diff --git a/go.mod b/go.mod index 6561fa0..2cb3692 100644 --- a/go.mod +++ b/go.mod @@ -2,11 +2,57 @@ module github.com/megaport/terraform-provider-megaport // For local development //replace github.com/megaport/megaportgo => +// azure-single-peering +replace github.com/megaport/megaportgo => github.com/bestateless/megaportgo v0.1.11-stateless.0.20230522231232-6a2eaee5047e -go 1.13 +go 1.20 require ( - github.com/aws/aws-sdk-go v1.25.3 - github.com/hashicorp/terraform-plugin-sdk v1.9.1 + github.com/aws/aws-sdk-go v1.44.267 + github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 + github.com/hashicorp/go-uuid v1.0.3 + github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1 github.com/megaport/megaportgo v0.1.15-beta ) + +require ( + github.com/agext/levenshtein v1.2.3 // indirect + github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect + github.com/fatih/color v1.15.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-plugin v1.4.9 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/hcl/v2 v2.16.2 // indirect + github.com/hashicorp/logutils v1.0.0 // indirect + github.com/hashicorp/terraform-plugin-go v0.15.0 // indirect + github.com/hashicorp/terraform-plugin-log v0.8.0 // indirect + github.com/hashicorp/terraform-registry-address v0.2.0 // indirect + github.com/hashicorp/terraform-svchost v0.1.0 // indirect + github.com/hashicorp/yamux v0.1.1 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/lithammer/fuzzysearch v1.1.8 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/oklog/run v1.1.0 // indirect + github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect + github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + github.com/xlzd/gotp v0.1.0 // indirect + github.com/zclconf/go-cty v1.13.2 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect + google.golang.org/grpc v1.55.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect +) diff --git a/main.go b/main.go index 37602eb..0005df5 100644 --- a/main.go +++ b/main.go @@ -15,14 +15,15 @@ package main import ( - "github.com/hashicorp/terraform-plugin-sdk/plugin" - "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/plugin" + "github.com/megaport/terraform-provider-megaport/provider" ) +import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" func main() { plugin.Serve(&plugin.ServeOpts{ - ProviderFunc: func() terraform.ResourceProvider { - return Provider() + ProviderFunc: func() *schema.Provider { + return provider.Provider() }, }) } diff --git a/provider.go b/provider/provider.go similarity index 94% rename from provider.go rename to provider/provider.go index 3d30c88..d7e481e 100644 --- a/provider.go +++ b/provider/provider.go @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -package main +package provider import ( "errors" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/megaport/terraform-provider-megaport/data_megaport" "github.com/megaport/terraform-provider-megaport/resource_megaport" "github.com/megaport/terraform-provider-megaport/terraform_utility" @@ -47,11 +47,13 @@ func Provider() *schema.Provider { Type: schema.TypeString, Required: true, DefaultFunc: schema.EnvDefaultFunc("MEGAPORT_PASSWORD", nil), + Sensitive: true, }, "mfa_otp_key": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("MEGAPORT_MFA_OTP_KEY", nil), + Sensitive: true, }, "delete_ports": { Type: schema.TypeBool, @@ -70,7 +72,9 @@ func Provider() *schema.Provider { ConfigureFunc: providerConfigure, DataSourcesMap: map[string]*schema.Resource{ "megaport_port": data_megaport.MegaportPort(), + "megaport_ports": data_megaport.MegaportPorts(), "megaport_location": data_megaport.MegaportLocation(), + "megaport_locations": data_megaport.MegaportLocations(), "megaport_vxc": data_megaport.MegaportVXC(), "megaport_partner_port": data_megaport.MegaportPartnerPort(), "megaport_aws_connection": data_megaport.MegaportAWSConnection(), diff --git a/resource_megaport/resource_megaport_aws_connection.go b/resource_megaport/resource_megaport_aws_connection.go index 2f42b32..d6f11f9 100644 --- a/resource_megaport/resource_megaport_aws_connection.go +++ b/resource_megaport/resource_megaport_aws_connection.go @@ -15,13 +15,16 @@ package resource_megaport import ( + "context" "errors" + "fmt" "log" + "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/directconnect" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/megaport/megaportgo/types" "github.com/megaport/terraform-provider-megaport/schema_megaport" "github.com/megaport/terraform-provider-megaport/terraform_utility" @@ -100,15 +103,83 @@ func resourceMegaportAWSConnectionRead(d *schema.ResourceData, m interface{}) er return retrievalErr } - d.Set("vxc_internal_type", "aws") + err := d.Set("vxc_internal_type", "aws") + if err != nil { + return err + } - // Aws read - if vifId := vxc.ExtractAwsId(vxcDetails); vifId != "" { - d.Set("aws_id", vifId) + cspSettings := d.Get("csp_settings").(*schema.Set).List()[0].(map[string]interface{}) + connectType := types.CONNECT_TYPE_AWS_VIF + hostedConnection := cspSettings["hosted_connection"].(bool) + if hostedConnection { + connectType = types.CONNECT_TYPE_AWS_HOSTED_CONNECTION } - if connectionId := vxc.ExtractConnectionId(vxcDetails); connectionId != "" { - d.Set("connection_id", connectionId) + switch connectType { + case types.CONNECT_TYPE_AWS_VIF: + { + _, awsIdErr := doWaitFor(context.Background(), 5*time.Minute, func(ctx context.Context) (bool, error) { + ticker := time.NewTicker(30 * time.Second) + defer ticker.Stop() + for range ticker.C { + if vifId := vxc.ExtractAwsId(vxcDetails); vifId != "" { + err := d.Set("aws_id", vifId) + if err != nil { + return false, err + } + err = d.Set("connection_id", "") + if err != nil { + return false, err + } + break + } + select { + case <-ctx.Done(): + return false, ctx.Err() + default: + continue + } + } + return true, nil + }) + + if awsIdErr != nil { + return awsIdErr + } + } + case types.CONNECT_TYPE_AWS_HOSTED_CONNECTION: + { + _, connectionIderr := doWaitFor(context.Background(), 5*time.Minute, func(ctx context.Context) (bool, error) { + ticker := time.NewTicker(30 * time.Second) + defer ticker.Stop() + for range ticker.C { + if connectionId := vxc.ExtractConnectionId(vxcDetails); connectionId != "" { + err := d.Set("connection_id", connectionId) + if err != nil { + return false, err + } + err = d.Set("aws_id", "") + if err != nil { + return false, err + } + break + } + select { + case <-ctx.Done(): + return false, ctx.Err() + default: + continue + } + } + return true, nil + }) + + if connectionIderr != nil { + return connectionIderr + } + } + default: + return fmt.Errorf("unknown connection type: %s", connectType) } // AWS CSP read diff --git a/resource_megaport/resource_megaport_azure_connection.go b/resource_megaport/resource_megaport_azure_connection.go index 7cdfaf5..518694fa 100644 --- a/resource_megaport/resource_megaport_azure_connection.go +++ b/resource_megaport/resource_megaport_azure_connection.go @@ -15,11 +15,16 @@ package resource_megaport import ( + "context" + "errors" "time" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/megaport/megaportgo/mega_err" vxc_service "github.com/megaport/megaportgo/service/vxc" "github.com/megaport/megaportgo/types" + "github.com/megaport/terraform-provider-megaport/schema_megaport" "github.com/megaport/terraform-provider-megaport/terraform_utility" ) @@ -44,6 +49,7 @@ func resourceMegaportAzureConnectionCreate(d *schema.ResourceData, m interface{} cspSettings := d.Get("csp_settings").(*schema.Set).List()[0].(map[string]interface{}) rateLimit := d.Get("rate_limit").(int) serviceKey := cspSettings["service_key"].(string) + var innerVlan *int = nil // peerings var peerings []types.PartnerOrderAzurePeeringConfig @@ -57,6 +63,7 @@ func resourceMegaportAzureConnectionCreate(d *schema.ResourceData, m interface{} SharedKey: private_peering["shared_key"].(string), VLAN: private_peering["requested_vlan"].(int), } + innerVlan = &new_private_peering.VLAN peerings = append(peerings, new_private_peering) } else if cspSettings["auto_create_private_peering"].(bool) { new_private_peering := types.PartnerOrderAzurePeeringConfig{ @@ -83,6 +90,28 @@ func resourceMegaportAzureConnectionCreate(d *schema.ResourceData, m interface{} peerings = append(peerings, new_microsoft_peering) } + // Azure seems to be eventually consistent. Thus we wait for megaport to see the service key before we move on + _, serviceKeyErr := doWaitFor(context.Background(), 5*time.Minute, func(ctx context.Context) (bool, error) { + ticker := time.NewTicker(30 * time.Second) + defer ticker.Stop() + for range ticker.C { + if _, serviceKeyLookupErr := vxc.LookupAzureServiceKey(serviceKey); serviceKeyLookupErr != nil { + select { + case <-ctx.Done(): + return false, ctx.Err() + default: + continue + } + } + break + } + return true, nil + }) + + if serviceKeyErr != nil { + return serviceKeyErr + } + // get partner port partnerPortId, partnerLookupErr := vxc.LookupPartnerPorts(serviceKey, rateLimit, vxc_service.PARTNER_AZURE, "") if partnerLookupErr != nil { @@ -99,6 +128,7 @@ func resourceMegaportAzureConnectionCreate(d *schema.ResourceData, m interface{} bEndConfiguration := types.PartnerOrderBEndConfiguration{ PartnerPortID: partnerPortId, PartnerConfig: partnerConfig, + InnerVLAN: innerVlan, } vxcId, buyErr := vxc.BuyPartnerVXC( @@ -114,15 +144,71 @@ func resourceMegaportAzureConnectionCreate(d *schema.ResourceData, m interface{} } d.SetId(vxcId) - vxc.WaitForVXCProvisioning(vxcId) - time.Sleep(60 * time.Second) // wait so that the vLANs will be available. + + // default waits up to 15 minutes for it to report that the VXC is LIVE, + // checking every 30 seconds and logging every 2 minutes 30 seconds. + // _, err := vxc.WaitForVXCProvisioning(vxcId) + // we are going to set an initial timeout of 15 minutes. If it expires, we'll + // subtract 5 minutes and try again for up to a total of 30 minutes. + timeout := 15 * time.Minute + pollFrequency := 30 * time.Second + for { + if timeout <= 0 { + return errors.New(mega_err.ERR_VXC_PROVISION_TIMEOUT_EXCEED) + } + + _, err := doWaitFor( + context.Background(), timeout, func(ctx context.Context) (bool, error) { + return vxc.WaitForVXCProvisioningCtx(ctx, pollFrequency, vxcId) + }, + ) + if err == nil { + break + } + + if err.Error() == mega_err.ERR_VXC_PROVISION_TIMEOUT_EXCEED || + err.Error() == mega_err.ERR_VXC_NOT_LIVE { + timeout = timeout - (5 * time.Minute) + } + } return resourceMegaportAzureConnectionRead(d, m) } +func doWaitFor(parentCtx context.Context, timeout time.Duration, f func(ctx context.Context) (bool, error)) ( + bool, + error, +) { + ctx, cancelFunc := context.WithTimeout(parentCtx, timeout) + defer cancelFunc() + return f(ctx) +} + func resourceMegaportAzureConnectionRead(d *schema.ResourceData, m interface{}) error { return ResourceMegaportVXCRead(d, m) } +func checkedCast[T interface{}](input *interface{}) *T { + if input == nil { + return nil + } + cast, check := (*input).(T) + if !check { + return nil + } + return &cast +} + +func digOutTfConfig[T interface{}](d *schema.ResourceData, key string) *T { + if d == nil { + return nil + } + keyLookup, found := (*d).GetOk(key) + if !found { + return nil + } + return checkedCast[T](&keyLookup) +} + func resourceMegaportAzureConnectionUpdate(d *schema.ResourceData, m interface{}) error { vxc := m.(*terraform_utility.MegaportClient).Vxc aVlan := 0 @@ -133,20 +219,59 @@ func resourceMegaportAzureConnectionUpdate(d *schema.ResourceData, m interface{} } } - if d.HasChange("vxc_name") || d.HasChange("rate_limit") || d.HasChange("a_end") { - _, updateErr := vxc.UpdateVXC(d.Id(), d.Get("vxc_name").(string), + if d.HasChange("vxc_name") || d.HasChange("rate_limit") || d.HasChange("a_end") || d.HasChange("csp_settings") { + var requestedVlan *int = nil + cspSettings := digOutTfConfig[map[string]interface{}](d, "csp_settings") + if cspSettings != nil { + privatePeeringTf, privatePeeringFound := (*cspSettings)["private_peering"] + if privatePeeringFound { + privatePeering := checkedCast[map[string]interface{}](&privatePeeringTf) + if privatePeering != nil { + vlanLookup := (*privatePeering)["requested_vlan"] + requestedVlan = checkedCast[int](&vlanLookup) + } + } + } + + _, updateErr := vxc.UpdateVXCWithInnerVlan(d.Id(), d.Get("vxc_name").(string), d.Get("rate_limit").(int), aVlan, - 0) + 0, + requestedVlan) if updateErr != nil { return updateErr } - vxc.WaitForVXCUpdated(d.Id(), d.Get("vxc_name").(string), - d.Get("rate_limit").(int), - aVlan, - 0) + timeout := 15 * time.Minute + pollFrequency := 30 * time.Second + for { + if timeout <= 0 { + return errors.New(mega_err.ERR_VXC_UPDATE_TIMEOUT_EXCEED) + } + + _, err := doWaitFor( + context.Background(), timeout, func(ctx context.Context) (bool, error) { + return vxc.WaitForVXCUpdatedCtx( + ctx, + pollFrequency, + d.Id(), + d.Get("vxc_name").(string), + d.Get("rate_limit").(int), + aVlan, + 0, + ) + }, + ) + if err == nil { + break + } + + if err.Error() == mega_err.ERR_VXC_UPDATE_TIMEOUT_EXCEED || + err.Error() == mega_err.ERR_VXC_NOT_LIVE { + timeout = timeout - (5 * time.Minute) + } + } } return resourceMegaportAzureConnectionRead(d, m) diff --git a/resource_megaport/resource_megaport_gcp_connection.go b/resource_megaport/resource_megaport_gcp_connection.go index c0d310e..4bd61ac 100644 --- a/resource_megaport/resource_megaport_gcp_connection.go +++ b/resource_megaport/resource_megaport_gcp_connection.go @@ -17,7 +17,7 @@ package resource_megaport import ( "time" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" vxc_service "github.com/megaport/megaportgo/service/vxc" "github.com/megaport/megaportgo/types" "github.com/megaport/terraform-provider-megaport/schema_megaport" diff --git a/resource_megaport/resource_megaport_mcr.go b/resource_megaport/resource_megaport_mcr.go index 97bc59b..63097b7 100644 --- a/resource_megaport/resource_megaport_mcr.go +++ b/resource_megaport/resource_megaport_mcr.go @@ -18,7 +18,7 @@ import ( "errors" "fmt" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/megaport/megaportgo/types" "github.com/megaport/terraform-provider-megaport/schema_megaport" "github.com/megaport/terraform-provider-megaport/terraform_utility" diff --git a/resource_megaport/resource_megaport_port.go b/resource_megaport/resource_megaport_port.go index 2d276b6..8e65f5b 100644 --- a/resource_megaport/resource_megaport_port.go +++ b/resource_megaport/resource_megaport_port.go @@ -18,7 +18,7 @@ import ( "errors" "fmt" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/megaport/terraform-provider-megaport/schema_megaport" "github.com/megaport/terraform-provider-megaport/terraform_utility" ) diff --git a/resource_megaport/resource_megaport_vxc.go b/resource_megaport/resource_megaport_vxc.go index f726d68..6ca3ffc 100644 --- a/resource_megaport/resource_megaport_vxc.go +++ b/resource_megaport/resource_megaport_vxc.go @@ -21,7 +21,7 @@ import ( "reflect" "time" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/megaport/megaportgo/types" "github.com/megaport/terraform-provider-megaport/schema_megaport" "github.com/megaport/terraform-provider-megaport/terraform_utility" diff --git a/schema_megaport/megaport_aws_connection.go b/schema_megaport/megaport_aws_connection.go index 534a164..91bb59b 100644 --- a/schema_megaport/megaport_aws_connection.go +++ b/schema_megaport/megaport_aws_connection.go @@ -15,7 +15,7 @@ package schema_megaport import ( - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func ResourceAWSConnectionVXCSchema() map[string]*schema.Schema { diff --git a/schema_megaport/megaport_azure_connection.go b/schema_megaport/megaport_azure_connection.go index 0137595..4d62779 100644 --- a/schema_megaport/megaport_azure_connection.go +++ b/schema_megaport/megaport_azure_connection.go @@ -15,7 +15,7 @@ package schema_megaport import ( - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func ResourceAzureConnectionVXCSchema() map[string]*schema.Schema { diff --git a/schema_megaport/megaport_gcp_connection.go b/schema_megaport/megaport_gcp_connection.go index 179ca3a..db191f5 100644 --- a/schema_megaport/megaport_gcp_connection.go +++ b/schema_megaport/megaport_gcp_connection.go @@ -15,7 +15,7 @@ package schema_megaport import ( - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func ResourceGcpConnectionVXCSchema() map[string]*schema.Schema { diff --git a/schema_megaport/megaport_location.go b/schema_megaport/megaport_location.go index f86c3a8..681cb65 100644 --- a/schema_megaport/megaport_location.go +++ b/schema_megaport/megaport_location.go @@ -14,7 +14,7 @@ package schema_megaport -import "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" // DataLocationSchema is the data schema of a Megaport Location func DataLocationSchema() map[string]*schema.Schema { diff --git a/schema_megaport/megaport_locations.go b/schema_megaport/megaport_locations.go new file mode 100644 index 0000000..91fbd18 --- /dev/null +++ b/schema_megaport/megaport_locations.go @@ -0,0 +1,31 @@ +// Copyright 2020 Megaport Pty Ltd +// +// Licensed under the Mozilla Public License, Version 2.0 (the +// "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// https://mozilla.org/MPL/2.0/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package schema_megaport + +import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + +// DataLocationsSchema is the data schema of a Megaport Locations query + +func DataLocationsSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "locations": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: DataLocationSchema(), + }, + }, + } +} diff --git a/schema_megaport/megaport_mcr.go b/schema_megaport/megaport_mcr.go index 3221d2a..7b44742 100644 --- a/schema_megaport/megaport_mcr.go +++ b/schema_megaport/megaport_mcr.go @@ -15,7 +15,7 @@ package schema_megaport import ( - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func ResourceMegaportMCRSchema() map[string]*schema.Schema { diff --git a/schema_megaport/megaport_partner_port.go b/schema_megaport/megaport_partner_port.go index 31f1fa8..6a330c7 100644 --- a/schema_megaport/megaport_partner_port.go +++ b/schema_megaport/megaport_partner_port.go @@ -15,7 +15,7 @@ package schema_megaport import ( - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func DataPartnerPortSchema() map[string]*schema.Schema { diff --git a/schema_megaport/megaport_port.go b/schema_megaport/megaport_port.go index fd4ed8c..2c3eff0 100644 --- a/schema_megaport/megaport_port.go +++ b/schema_megaport/megaport_port.go @@ -14,10 +14,14 @@ package schema_megaport -import "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" func ResourcePortSchema() map[string]*schema.Schema { return map[string]*schema.Schema{ + "uid": { + Type: schema.TypeString, + Computed: true, + }, "port_name": { Type: schema.TypeString, Required: true, @@ -100,92 +104,9 @@ func ResourcePortSchema() map[string]*schema.Schema { Default: 0, ForceNew: true, }, - } -} - -func DataPortSchema() map[string]*schema.Schema { - return map[string]*schema.Schema{ - "port_name": { - Type: schema.TypeString, - Computed: true, - }, - "type": { - Type: schema.TypeString, - Computed: true, - }, - "provisioning_status": { - Type: schema.TypeString, - Computed: true, - }, - "create_date": { + "product_id": { Type: schema.TypeInt, Computed: true, }, - "created_by": { - Type: schema.TypeString, - Computed: true, - }, - "port_speed": { - Type: schema.TypeInt, - Computed: true, - }, - "live_date": { - Type: schema.TypeInt, - Computed: true, - }, - "market_code": { - Type: schema.TypeString, - Computed: true, - }, - "location_id": { - Type: schema.TypeInt, - Computed: true, - }, - "marketplace_visibility": { - Type: schema.TypeBool, - Computed: true, - }, - "company_name": { - Type: schema.TypeString, - Computed: true, - }, - "term": { - Type: schema.TypeInt, - Computed: true, - }, - "port_id": { - Type: schema.TypeString, - Optional: true, - }, - "lag_primary": { - Type: schema.TypeBool, - Computed: true, - Optional: true, - }, - "lag_id": { - Type: schema.TypeInt, - Computed: true, - Optional: true, - }, - "locked": { - Type: schema.TypeBool, - Computed: true, - }, - "admin_locked": { - Type: schema.TypeBool, - Computed: true, - }, - "lag": { - Type: schema.TypeBool, - Optional: true, - Default: false, - ForceNew: true, - }, - "lag_port_count": { - Type: schema.TypeInt, - Optional: true, - Default: 0, - ForceNew: true, - }, } } diff --git a/schema_megaport/megaport_ports.go b/schema_megaport/megaport_ports.go new file mode 100644 index 0000000..a214e1c --- /dev/null +++ b/schema_megaport/megaport_ports.go @@ -0,0 +1,31 @@ +// Copyright 2020 Megaport Pty Ltd +// +// Licensed under the Mozilla Public License, Version 2.0 (the +// "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// https://mozilla.org/MPL/2.0/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package schema_megaport + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func DataPortsSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "ports": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: ResourcePortSchema(), + }, + }, + } +} diff --git a/schema_megaport/megaport_vxc.go b/schema_megaport/megaport_vxc.go index 6a46620..20ec601 100644 --- a/schema_megaport/megaport_vxc.go +++ b/schema_megaport/megaport_vxc.go @@ -15,7 +15,7 @@ package schema_megaport import ( - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func ResourceVXCSchema() map[string]*schema.Schema {