diff --git a/megaport/api/vxc.go b/megaport/api/vxc.go index b43fb11..554a8c3 100644 --- a/megaport/api/vxc.go +++ b/megaport/api/vxc.go @@ -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 @@ -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 @@ -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 } @@ -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 @@ -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) +} diff --git a/megaport/resource_megaport_private_vxc.go b/megaport/resource_megaport_private_vxc.go index 0cac2d2..987c4f9 100644 --- a/megaport/resource_megaport_private_vxc.go +++ b/megaport/resource_megaport_private_vxc.go @@ -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("") @@ -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), @@ -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) } @@ -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(), @@ -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 }