Skip to content
This repository has been archived by the owner on Jan 17, 2025. It is now read-only.

Commit

Permalink
Merge branch 'partner_ports'
Browse files Browse the repository at this point in the history
  • Loading branch information
alkar committed Feb 6, 2020
2 parents a2c106c + 9272e67 commit 8d306d6
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 31 deletions.
6 changes: 4 additions & 2 deletions examples/megaport_aws_vxc_basic/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ data "megaport_location" "aws" {

data "megaport_partner_port" "aws" {
name_regex = "eu-west-1"
connect_type = "AWS"
location_id = data.megaport_location.aws.id

aws {
location_id = data.megaport_location.aws.id
}
}

data "megaport_location" "foo" {
Expand Down
6 changes: 4 additions & 2 deletions examples/megaport_aws_vxc_basic_update/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ data "megaport_location" "aws" {

data "megaport_partner_port" "aws" {
name_regex = "eu-west-1"
connect_type = "AWS"
location_id = data.megaport_location.aws.id

aws {
location_id = data.megaport_location.aws.id
}
}

data "megaport_location" "foo" {
Expand Down
16 changes: 16 additions & 0 deletions megaport/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,22 @@ func (c *Client) GetMegaports() ([]*Megaport, error) {
return data, nil
}

func (c *Client) GetMegaportsForGcpPairingKey(pairingKey string) ([]*MegaportCloud, []uint64, error) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/v2/secure/google/%s", c.BaseURL, pairingKey), nil)
if err != nil {
return nil, nil, err
}
data := struct {
Bandwidths []uint64
Megaports []*MegaportCloud
ResourceType string `json:"resource_type"`
}{}
if err := c.do(req, &data); err != nil {
return nil, nil, err
}
return data.Megaports, data.Bandwidths, nil
}

func (c *Client) GetInternetExchanges(locationId uint64) ([]*InternetExchange, error) {
v := url.Values{}
v.Set("locationId", strconv.FormatUint(locationId, 10))
Expand Down
18 changes: 18 additions & 0 deletions megaport/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,24 @@ type Megaport struct {
VxcPermitted bool
}

type MegaportCloud struct {
CompanyName string
CompanyId uint64
CompanyUid string
Country string
Description string
LocationId uint64
Name string
NServiceId uint64
Port uint64
PortSpeed uint64
ProductId uint64
ProductUid string
State string // This refers to the geographical location
Type string // Potentially only used for Oracle ports
Vxc interface{} // TODO: what is the appropriate type?
}

type InternetExchange struct {
ASN uint64
Description string
Expand Down
2 changes: 1 addition & 1 deletion megaport/api/vxc.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ func (v *PartnerConfigGcp) connectType() string {
func (v *PartnerConfigGcp) toPayload() interface{} {
return &vxcCreatePayloadPartnerConfigGcp{
ConnectType: String(v.connectType()),
PairingKey: String(v.PairingKey),
PairingKey: v.PairingKey,
}
}

Expand Down
151 changes: 125 additions & 26 deletions megaport/data_source_megaport_partner_port.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,64 @@ func dataSourceMegaportPartnerPort() *schema.Resource {
ForceNew: true,
ValidateFunc: validation.StringIsValidRegExp,
},
"connect_type": {
Type: schema.TypeString,
"aws": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{"AWS", "GOOGLE"}, false),
ExactlyOneOf: []string{"aws", "gcp", "marketplace"},
Elem: dataSourceMegaportPartnerPortMarketplace(),
},
"gcp": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
ExactlyOneOf: []string{"aws", "gcp", "marketplace"},
Elem: dataSourceMegaportPartnerPortGcp(),
},
"marketplace": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
ConflictsWith: []string{"aws", "marketplace"},
Elem: dataSourceMegaportPartnerPortMarketplace(),
},
"bandwidths": {
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
Computed: true,
},
},
}
}

func dataSourceMegaportPartnerPortMarketplace() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
"location_id": {
Type: schema.TypeInt,
Optional: true,
Required: true,
ForceNew: true,
},
"vxc_permitted": {
Type: schema.TypeBool,
Optional: true,
Default: true,
ForceNew: true,
},
},
}
}

func dataSourceMegaportPartnerPortGcp() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
"pairing_key": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[[:xdigit:]]{8}-([[:xdigit:]]{4}-){3}[[:xdigit:]]{12}\/[\w]+-[\w]+\d\/\d$`), "Invalid GCP pairing key format"),
},
},
}
Expand All @@ -62,51 +105,107 @@ func dataSourceUpdatePartnerPorts(c *api.Client) error {

func dataSourceMegaportPartnerPortRead(d *schema.ResourceData, m interface{}) error {
cfg := m.(*Config)
if err := dataSourceUpdatePartnerPorts(cfg.Client); err != nil {
return err
nameRegex := d.Get("name_regex").(string)
if v, ok := d.GetOk("aws"); ok {
if err := dataSourceUpdatePartnerPorts(cfg.Client); err != nil {
return err
}
p, err := filterPartnerPorts(megaportPartnerPorts, "AWS", nameRegex, expandFilters(v))
if err != nil {
return err
}
d.SetId(p.ProductUid)
d.Set("bandwidths", []int{})
return nil
}
if v, ok := d.GetOk("marketplace"); ok {
if err := dataSourceUpdatePartnerPorts(cfg.Client); err != nil {
return err
}
p, err := filterPartnerPorts(megaportPartnerPorts, "DEFAULT", nameRegex, expandFilters(v))
if err != nil {
return err
}
d.SetId(p.ProductUid)
d.Set("bandwidths", []int{})
return nil
}
if v, ok := d.GetOk("gcp"); ok {
ports, bandwidths, err := cfg.Client.GetMegaportsForGcpPairingKey(expandFilters(v)["pairing_key"].(string))
if err != nil {
return err
}
p, err := filterCloudPartnerPorts(ports, nameRegex)
if err != nil {
return err
}
d.SetId(p.ProductUid)
d.Set("bandwidths", bandwidths) // apparently it's fine to use []uint64 here
return nil
}
unfiltered := megaportPartnerPorts
return nil
}

func expandFilters(v interface{}) map[string]interface{} {
return v.([]interface{})[0].(map[string]interface{})
}

func filterPartnerPorts(ports []*api.Megaport, connectType, nameRegex string, d map[string]interface{}) (*api.Megaport, error) {
unfiltered := ports
filtered := []*api.Megaport{}
vp := d.Get("vxc_permitted")
for _, port := range unfiltered {
if port.VxcPermitted == vp.(bool) {
if port.ConnectType == connectType {
filtered = append(filtered, port)
}
}
if nameRegex, ok := d.GetOk("name_regex"); ok {
unfiltered = filtered
filtered = []*api.Megaport{}
nr := regexp.MustCompile(nameRegex.(string))
for _, port := range unfiltered {
if nr.MatchString(port.Title) {
filtered = append(filtered, port)
}
unfiltered = filtered
filtered = []*api.Megaport{}
nr := regexp.MustCompile(nameRegex)
for _, port := range unfiltered {
if nr.MatchString(port.Title) {
filtered = append(filtered, port)
}
}
if ct, ok := d.GetOk("connect_type"); ok {
if lid, ok := d["location_id"]; ok {
unfiltered = filtered
filtered = []*api.Megaport{}
for _, port := range unfiltered {
if port.ConnectType == ct.(string) {
if port.LocationId == uint64(lid.(int)) {
filtered = append(filtered, port)
}
}
}
if lid, ok := d.GetOk("location_id"); ok {
if vp, ok := d["vxc_permitted"]; ok {
unfiltered = filtered
filtered = []*api.Megaport{}
for _, port := range unfiltered {
if port.LocationId == uint64(lid.(int)) {
if port.VxcPermitted == vp.(bool) {
filtered = append(filtered, port)
}
}
}
if len(filtered) < 1 {
return fmt.Errorf("No partner ports were found.")
return nil, fmt.Errorf("No ports were found. You might want to use a less specific query.")
}
if len(filtered) > 1 {
return fmt.Errorf("Multiple partner ports were found. Please use a more specific query.")
return nil, fmt.Errorf("Multiple ports were found. Please use a more specific query.")
}
d.SetId(filtered[0].ProductUid)
return nil
return filtered[0], nil
}

func filterCloudPartnerPorts(ports []*api.MegaportCloud, nameRegex string) (*api.MegaportCloud, error) {
filtered := []*api.MegaportCloud{}
nr := regexp.MustCompile(nameRegex)
for _, port := range ports {
if nr.MatchString(port.Name) {
filtered = append(filtered, port)
}
}
if len(filtered) < 1 {
return nil, fmt.Errorf("No ports were found. You might want to use a less specific query.")
}
if len(filtered) > 1 {
return nil, fmt.Errorf("Multiple ports were found. Please use a more specific query.")
}
return filtered[0], nil
}

0 comments on commit 8d306d6

Please sign in to comment.