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

Commit

Permalink
Refactor VxcService
Browse files Browse the repository at this point in the history
Most of the different products on Megaport are VXCs. Their lifecycle is
controlled through the same endpoints on the Megaport API and the
process is more or less uniform, apart from the different payloads for
each type of VXC as presented on the web ui (eg.: private, partner,
cloud). Therefore, we can reuse the underlying CRUD methods in the
package and export methods specific to each type of VXC.

Signed-off-by: Dimitrios Karagiannis <dhkarag@gmail.com>
  • Loading branch information
alkar committed Oct 16, 2019
1 parent f75d011 commit 3827846
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 83 deletions.
173 changes: 95 additions & 78 deletions megaport/api/vxc.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,81 +16,11 @@ func NewVxcService(c *Client) *VxcService {
return &VxcService{c}
}

type VxcCreateInput struct {
InvoiceReference string
Name string
ProductUidA string
ProductUidB string
RateLimit uint64
VlanA uint64
VlanB uint64
}

func (v *VxcCreateInput) toPayload() ([]byte, error) {
payload := []*vxcCreatePayload{{
ProductUid: v.ProductUidA,
AssociatedVxcs: []vxcCreatePayloadAssociatedVxc{{
ProductName: v.Name,
RateLimit: v.RateLimit,
CostCentre: v.InvoiceReference,
AEnd: &vxcCreatePayloadAssociatedVxcEnd{Vlan: v.VlanA},
BEnd: &vxcCreatePayloadAssociatedVxcEnd{ProductUid: v.ProductUidB, Vlan: v.VlanB},
}},
}}
return json.Marshal(payload)
}

type VxcCreateOutput struct {
ProductUid string
}

type vxcCreatePayload struct {
ProductUid string `json:"productUid"`
AssociatedVxcs []vxcCreatePayloadAssociatedVxc `json:"associatedVxcs"`
}

type vxcCreatePayloadAssociatedVxc struct {
ProductName string `json:"productName"`
RateLimit uint64 `json:"rateLimit"`
CostCentre string `json:"costCentre"`
AEnd *vxcCreatePayloadAssociatedVxcEnd `json:"aEnd"`
BEnd *vxcCreatePayloadAssociatedVxcEnd `json:"bEnd"`
}

type vxcCreatePayloadAssociatedVxcEnd struct {
ProductUid string `json:"productUid,omitempty"`
Vlan uint64 `json:"vlan"`
type networkDesignInput interface {
toPayload() ([]byte, error)
}

type VxcUpdateInput struct {
InvoiceReference string
Name string
ProductUid string
RateLimit uint64
VlanA uint64
VlanB uint64
}

func (v *VxcUpdateInput) toPayload() ([]byte, error) {
payload := &vxcUpdatePayload{
AEndVlan: v.VlanA,
BEndVlan: v.VlanB,
CostCentre: v.InvoiceReference,
Name: v.Name,
RateLimit: v.RateLimit,
}
return json.Marshal(payload)
}

type vxcUpdatePayload struct {
AEndVlan uint64 `json:"aEndVlan"`
BEndVlan uint64 `json:"bEndVlan,omitempty"`
CostCentre string `json:"costCentre"`
Name string `json:"name"`
RateLimit uint64 `json:"rateLimit"`
}

func (p *VxcService) Create(v *VxcCreateInput) (*VxcCreateOutput, error) {
func (p *VxcService) create(v networkDesignInput) (*string, error) {
payload, err := v.toPayload()
if err != nil {
return nil, err
Expand All @@ -112,10 +42,11 @@ func (p *VxcService) Create(v *VxcCreateInput) (*VxcCreateOutput, error) {
if err := p.c.do(req, &d); err != nil {
return nil, err
}
return &VxcCreateOutput{ProductUid: d[0]["vxcJTechnicalServiceUid"].(string)}, nil
uid := d[0]["vxcJTechnicalServiceUid"].(string)
return &uid, nil
}

func (p *VxcService) Get(uid string) (*ProductAssociatedVxc, error) {
func (p *VxcService) get(uid string) (*ProductAssociatedVxc, error) { // TODO: change name
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/v2/product/%s", p.c.BaseURL, uid), nil)
if err != nil {
return nil, err
Expand All @@ -127,13 +58,13 @@ func (p *VxcService) Get(uid string) (*ProductAssociatedVxc, error) {
return data, nil
}

func (p *VxcService) Update(v *VxcUpdateInput) error {
func (p *VxcService) update(uid string, v networkDesignInput) error {
payload, err := v.toPayload()
if err != nil {
return err
}
b := bytes.NewReader(payload)
req, err := http.NewRequest(http.MethodPut, fmt.Sprintf("%s/v2/product/vxc/%s", p.c.BaseURL, v.ProductUid), b)
req, err := http.NewRequest(http.MethodPut, fmt.Sprintf("%s/v2/product/vxc/%s", p.c.BaseURL, uid), b)
if err != nil {
return err
}
Expand All @@ -143,7 +74,7 @@ func (p *VxcService) Update(v *VxcUpdateInput) error {
return nil
}

func (p *VxcService) Delete(uid string) error {
func (p *VxcService) delete(uid string) error {
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/v2/product/%s/action/CANCEL_NOW", p.c.BaseURL, uid), nil)
if err != nil {
return err
Expand All @@ -153,3 +84,89 @@ func (p *VxcService) Delete(uid string) error {
}
return nil
}

type vxcCreatePayload struct {
ProductUid string `json:"productUid"`
AssociatedVxcs []*vxcCreatePayloadAssociatedVxc `json:"associatedVxcs"`
}

type vxcCreatePayloadAssociatedVxc struct {
ProductName string `json:"productName"`
RateLimit uint64 `json:"rateLimit"`
CostCentre string `json:"costCentre"`
AEnd *vxcCreatePayloadAssociatedVxcEnd `json:"aEnd"`
BEnd *vxcCreatePayloadAssociatedVxcEnd `json:"bEnd"`
}

type vxcCreatePayloadAssociatedVxcEnd struct {
ProductUid string `json:"productUid,omitempty"` // XXX extra
Vlan uint64 `json:"vlan"`
}

type PrivateVxcCreateInput struct {
InvoiceReference string
Name string
ProductUidA string
ProductUidB string
RateLimit uint64
VlanA uint64
VlanB uint64
}

func (v *PrivateVxcCreateInput) toPayload() ([]byte, error) {
payload := []*vxcCreatePayload{{
ProductUid: v.ProductUidA,
AssociatedVxcs: []*vxcCreatePayloadAssociatedVxc{{
ProductName: v.Name,
RateLimit: v.RateLimit,
CostCentre: v.InvoiceReference,
AEnd: &vxcCreatePayloadAssociatedVxcEnd{Vlan: v.VlanA},
BEnd: &vxcCreatePayloadAssociatedVxcEnd{ProductUid: v.ProductUidB, Vlan: v.VlanB},
}},
}}
return json.Marshal(payload)
}

type PrivateVxcUpdateInput struct {
InvoiceReference string
Name string
ProductUid string
RateLimit uint64
VlanA uint64
VlanB uint64
}

func (v *PrivateVxcUpdateInput) toPayload() ([]byte, error) {
payload := &vxcUpdatePayload{
AEndVlan: v.VlanA,
BEndVlan: v.VlanB,
CostCentre: v.InvoiceReference,
Name: v.Name,
RateLimit: v.RateLimit,
}
return json.Marshal(payload)
}

type vxcUpdatePayload struct {
AEndVlan uint64 `json:"aEndVlan"`
BEndVlan uint64 `json:"bEndVlan,omitempty"`
CostCentre string `json:"costCentre"`
Name string `json:"name"`
RateLimit uint64 `json:"rateLimit"`
}

func (p *VxcService) CreatePrivateVxc(v *PrivateVxcCreateInput) (*string, error) {
return p.create(v)
}

func (p *VxcService) GetPrivateVxc(uid string) (*ProductAssociatedVxc, error) {
return p.get(uid)
}

func (p *VxcService) UpdatePrivateVxc(v *PrivateVxcUpdateInput) error {
return p.update(v.ProductUid, v)
}

func (p *VxcService) DeletePrivateVxc(uid string) error {
return p.delete(uid)
}
10 changes: 5 additions & 5 deletions megaport/resource_megaport_private_vxc.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func resourceMegaportPrivateVxc() *schema.Resource {

func resourceMegaportPrivateVxcRead(d *schema.ResourceData, m interface{}) error {
cfg := m.(*Config)
p, err := cfg.Client.Vxc.Get(d.Id())
p, err := cfg.Client.Vxc.GetPrivateVxc(d.Id())
if err != nil {
log.Printf("resourceMegaportPrivateVxcRead: %v", err)
d.SetId("")
Expand All @@ -71,7 +71,7 @@ func resourceMegaportPrivateVxcCreate(d *schema.ResourceData, m interface{}) err
cfg := m.(*Config)
a := d.Get("a_end").([]interface{})[0].(map[string]interface{})
b := d.Get("b_end").([]interface{})[0].(map[string]interface{})
o, err := cfg.Client.Vxc.Create(&api.VxcCreateInput{
uid, err := cfg.Client.Vxc.CreatePrivateVxc(&api.PrivateVxcCreateInput{
ProductUidA: a["product_uid"].(string),
ProductUidB: b["product_uid"].(string),
Name: d.Get("name").(string),
Expand All @@ -83,7 +83,7 @@ func resourceMegaportPrivateVxcCreate(d *schema.ResourceData, m interface{}) err
if err != nil {
return err
}
d.SetId(o.ProductUid)
d.SetId(*uid)
return resourceMegaportPrivateVxcRead(d, m)
}

Expand All @@ -98,7 +98,7 @@ func resourceMegaportPrivateVxcUpdate(d *schema.ResourceData, m interface{}) err
//if
log.Printf(">>1 %#v", a)
log.Printf(">>2 %#v", a["vlan"])
if err := cfg.Client.Vxc.Update(&api.VxcUpdateInput{
if err := cfg.Client.Vxc.UpdatePrivateVxc(&api.PrivateVxcUpdateInput{
InvoiceReference: d.Get("invoice_reference").(string),
Name: d.Get("name").(string),
ProductUid: d.Id(),
Expand All @@ -113,7 +113,7 @@ func resourceMegaportPrivateVxcUpdate(d *schema.ResourceData, m interface{}) err

func resourceMegaportPrivateVxcDelete(d *schema.ResourceData, m interface{}) error {
cfg := m.(*Config)
err := cfg.Client.Vxc.Delete(d.Id())
err := cfg.Client.Vxc.DeletePrivateVxc(d.Id())
if err != nil && err != api.ErrNotFound {
return err
}
Expand Down

0 comments on commit 3827846

Please sign in to comment.