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

Commit

Permalink
Merge branch 'vxc'
Browse files Browse the repository at this point in the history
  • Loading branch information
alkar committed Oct 7, 2019
2 parents b70e64b + 344abc0 commit af66266
Show file tree
Hide file tree
Showing 9 changed files with 337 additions and 152 deletions.
24 changes: 16 additions & 8 deletions megaport/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ type Client struct {
UserAgent string

Port *PortService
Vxc *VxcService
}

func NewClient(baseURL string) *Client {
c := &Client{c: &http.Client{}, BaseURL: baseURL}
c.Port = NewPortService(c)
c.Vxc = NewVxcService(c)
return c
}

Expand Down Expand Up @@ -77,12 +79,12 @@ func (c *Client) GetLocations() ([]*Location, error) {
return data, nil
}

func (c *Client) GetMegaports() ([]Megaport, error) {
func (c *Client) GetMegaports() ([]*Megaport, error) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/v2/dropdowns/partner/megaports", c.BaseURL), nil)
if err != nil {
return nil, err
}
data := []Megaport{}
data := []*Megaport{}
if err := c.do(req, &data); err != nil {
return nil, err
}
Expand Down Expand Up @@ -179,17 +181,23 @@ func (c *Client) do(req *http.Request, data interface{}) error {
return ErrNotFound
}
if resp.StatusCode != http.StatusOK {
r.Data = map[string]interface{}{}
if err = parseResponseBody(resp, &r); err != nil {
return err
}
errData := &strings.Builder{}
for k, v := range r.Data.(map[string]interface{}) {
if _, err := fmt.Fprintf(errData, "%s=%#v ", k, v); err != nil {
return err
switch e := r.Data.(type) {
case string:
return fmt.Errorf("megaport-api: %s (%s)", r.Message, e)
case map[string]interface{}:
errData := &strings.Builder{}
for k, v := range e {
if _, err := fmt.Fprintf(errData, "%s=%#v ", k, v); err != nil {
return err
}
}
return fmt.Errorf("megaport-api: %s (%s)", r.Message, strings.TrimSpace(errData.String()))
default:
return fmt.Errorf("megaport-api: %s (cannot process data of type %T: %#v", r.Message, e, e)
}
return fmt.Errorf("megaport-api: %s (%s)", r.Message, strings.TrimSpace(errData.String()))
}
r.Data = data
return parseResponseBody(resp, &r)
Expand Down
1 change: 1 addition & 0 deletions megaport/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type Megaport struct {
ProductUid string
Rank uint64
Speed uint64
Title string
VxcPermitted bool
}

Expand Down
90 changes: 49 additions & 41 deletions megaport/api/vxc.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,65 +8,73 @@ import (
"net/http"
)

type OrderVxc struct {
type vxcOrder struct {
ProductUid string `json:"productUid"`
AssociatedVxcs []OrderVxcAssociatedVxcs `json:"associatedVxcs"`
AssociatedVxcs []vxcOrderAssociatedVxcs `json:"associatedVxcs"`
}

type OrderVxcAssociatedVxcs struct {
type vxcOrderAssociatedVxcs struct {
ProductName string `json:"productName"`
RateLimit uint64 `json:"rateLimit"`
AEnd *OrderVxcEnd `json:"aEnd,omitempty"`
BEnd *OrderVxcEnd `json:"bEnd"`
AEnd *vxcOrderEnd `json:"aEnd,omitempty"`
BEnd *vxcOrderEnd `json:"bEnd"`
}

type OrderVxcEnd struct {
type vxcOrderEnd struct {
ProductUid string `json:"productUid"`
VLan uint64 `json:"vlan,omitempty"`
}

func (c *Client) PostPortOrder(o OrderPort) (string, error) {
p, err := json.Marshal([]OrderPort{o})
type VxcService struct {
c *Client
}

func NewVxcService(c *Client) *VxcService {
return &VxcService{c}
}

func (p *VxcService) Create(productAUid, productBUid, name string, vlanA, vlanB, rateLimit uint64) (string, error) {
order := []vxcOrder{vxcOrder{
ProductUid: productAUid,
AssociatedVxcs: []vxcOrderAssociatedVxcs{
vxcOrderAssociatedVxcs{
ProductName: name,
RateLimit: rateLimit,
BEnd: &vxcOrderEnd{
ProductUid: productBUid,
},
},
},
}}
if vlanA != 0 {
order[0].AssociatedVxcs[0].AEnd = &vxcOrderEnd{VLan: vlanB}
}
if vlanB != 0 {
order[0].AssociatedVxcs[0].BEnd.VLan = vlanB
}
payload, err := json.Marshal(order)
if err != nil {
return "", err
}
b := bytes.NewBuffer(p)
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/v2/networkdesign/buy", c.BaseURL), b)
b := bytes.NewReader(payload)
validate := true // TODO: think
if validate { // TODO: do we really want to make this conditional?
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/v2/networkdesign/validate", p.c.BaseURL), b)
if err != nil {
return "", err
}
if err := p.c.do(req, nil); err != nil {
return "", err
}
b.Seek(0, 0) // TODO: ?
}
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/v2/networkdesign/buy", p.c.BaseURL), b)
if err != nil {
return "", err
}
d := []map[string]interface{}{}
if err := c.do(req, &d); err != nil {
if err := p.c.do(req, &d); err != nil {
return "", err
}
return d[0]["technicalServiceUid"].(string), nil
}

func (c *Client) PostVxcOrder(o []OrderVxc) error {
if o == nil {
o = []OrderVxc{
OrderVxc{
ProductUid: "94ec5655-5bef-4734-b172-97f3aed05382",
AssociatedVxcs: []OrderVxcAssociatedVxcs{
OrderVxcAssociatedVxcs{
ProductName: "bar",
RateLimit: 100,
BEnd: &OrderVxcEnd{
ProductUid: "f2c5b25b-e202-4708-9c25-1130c94689b3",
VLan: 99,
},
},
},
},
}
}
s, err := json.MarshalIndent(o, "", " ")
fmt.Printf("%+v\n", err)
fmt.Printf("%s\n", s)
b := bytes.NewBuffer(s)
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/v2/networkdesign/buy", c.BaseURL), b)
if err != nil {
return nil
}
return c.do(req, nil)
return d[0]["vxcJTechnicalServiceUid"].(string), nil
}
2 changes: 1 addition & 1 deletion megaport/data_source_megaport_location.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func dataSourceUpdateLocations(c *api.Client) error {
if megaportLocations != nil {
return nil
}
log.Printf("Updating Megaport location list")
log.Printf("Updating location list")
loc, err := c.GetLocations()
if err != nil {
return err
Expand Down
39 changes: 0 additions & 39 deletions megaport/data_source_megaport_megaports.go

This file was deleted.

75 changes: 75 additions & 0 deletions megaport/data_source_megaport_partner_port.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package megaport

import (
"fmt"
"log"
"regexp"

"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/utilitywarehouse/terraform-provider-megaport/megaport/api"
)

var (
megaportPartnerPorts []*api.Megaport
)

func dataSourceMegaportPartnerPort() *schema.Resource {
return &schema.Resource{
Read: dataSourceMegaportPartnerPortRead,

Schema: map[string]*schema.Schema{
"name_regex": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.ValidateRegexp,
},
// computed attributes
"uid": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func dataSourceUpdatePartnerPorts(c *api.Client) error {
megaportMutexKV.Lock("partner_ports")
defer megaportMutexKV.Unlock("partner_ports")
if megaportPartnerPorts != nil {
return nil
}
log.Printf("Updating partner port list")
pp, err := c.GetMegaports() // TODO: rename in api
if err != nil {
return err
}
megaportPartnerPorts = pp
return nil
}

func dataSourceMegaportPartnerPortRead(d *schema.ResourceData, m interface{}) error {
cfg := m.(*Config)
if err := dataSourceUpdatePartnerPorts(cfg.Client); err != nil {
return err
}
var filtered []*api.Megaport
if nameRegex, ok := d.GetOk("name_regex"); ok {
nr := regexp.MustCompile(nameRegex.(string))
for _, port := range megaportPartnerPorts {
if nr.MatchString(port.Title) {
filtered = append(filtered, port)
}
}
}
if len(filtered) < 1 {
return fmt.Errorf("No partner ports were found.")
}
if len(filtered) > 1 {
return fmt.Errorf("Multiple partner ports were found. Please use a more specific query.")
}
d.SetId(newUUID(filtered[0].ProductUid)) // TODO: simply use the uuid?
d.Set("uid", filtered[0].ProductUid)
return nil
}
5 changes: 3 additions & 2 deletions megaport/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@ func Provider() terraform.ResourceProvider {
},

ResourcesMap: map[string]*schema.Resource{
"megaport_port": resourceMegaportPort(),
"megaport_port": resourceMegaportPort(),
"megaport_private_vxc": resourceMegaportPrivateVxc(),
},

DataSourcesMap: map[string]*schema.Resource{
"megaport_location": dataSourceMegaportLocation(),
"megaport_megaports": dataSourceMegaportMegaports(),
"megaport_partner_port": dataSourceMegaportPartnerPort(),
"megaport_internet_exchanges": dataSourceMegaportInternetExchanges(),
},

Expand Down
Loading

0 comments on commit af66266

Please sign in to comment.