Skip to content

Commit

Permalink
Merge pull request #8 from equinix/zside_service_token_feature
Browse files Browse the repository at this point in the history
support for feature l2connection PrimaryZSideServiceToken
  • Loading branch information
displague committed Jul 15, 2022
2 parents 52abbf7 + 0d7d6ee commit d178d37
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 55 deletions.
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
## 2.3.0 (July 15, 2022)

DEPRECATION:

* General change in GET L2 connections functions: *ServiceToken* should not be used to populate the
a-side token with which the connection was created. It is maintained for historical compability but
can contain both a-side/z-side tokens. To access the token returned by a GET operation use the
L2Connection.VendorToken string. Change affects below functions:
* `GetL2Connection`
* `GetL2OutgoingConnections`

ENHANCEMENTS:

* **L2Connection** added additional attributes:
* *ZSideServiceToken* can be used (in addition to service profile and zside port) to define the
connection destination. key given by a provider that grants you authorization to enable
connectivity to a shared multi-tenant port (z-side)
* *VendorToken* can be used to populate the Equinix Fabric Token the connection was created with
(if applicable).The token can be any of *ServiceToken* (a-side) or *ZSideServiceToken* (z-side).
Any mechanism to determine the token type (a-side/z-side), must be implemented by the
user/consumer of the SDK.

## 2.2.0 (March 11, 2022)

FEATURES:
Expand Down
17 changes: 17 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,24 @@ type L2Connection struct {
RedundancyType *string
RedundancyGroup *string
Actions []L2ConnectionAction
// ServiceToken is used to create connections with an a-side Equinix Fabric Token
// Applicable for CREATE operations: CreateL2Connection, CreateL2RedundantConnection...
//
// Deprecated: ServiceToken (GET operations) - Starting with v2.3.0 this field should not be
// used to populate the a-side token with which the connection was created. It is maintained
// for historical compability but can contain both a-side/z-side tokens. To access the token
// returned by a GET operation (GetL2Connection, GetL2OutgoingConnections...), use the
// L2Connection.VendorToken string.
ServiceToken *string
// ZSideServiceToken is used to create connections using a z-side Equinix Fabric Token
// Applicable for CREATE operations: CreateL2Connection, CreateL2RedundantConnection...
ZSideServiceToken *string
// VendorToken is used in GET Operations (GetL2Connection, GetL2OutgoingConnections...) to
// populate the Equinix Fabric Token the connection was created with (if applicable). The token
// can be any of ServiceToken (a-side) or ZSideServiceToken (z-side). Any mechanism to
// determine the token type (a-side/z-side), must be implemented by the user/consumer of the
// SDK.
VendorToken *string
}

//L2ConnectionAdditionalInfo additional info object used in L2 connections
Expand Down
3 changes: 2 additions & 1 deletion internal/api/l2_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,14 @@ type L2ConnectionRequest struct {
PurchaseOrderNumber *string `json:"purchaseOrderNumber"`
PrimaryPortUUID *string `json:"primaryPortUUID,omitempty"`
VirtualDeviceUUID *string `json:"virtualDeviceUUID,omitempty"`
PrimaryServiceToken *string `json:"primaryServiceToken,omitempty"`
InterfaceID *int `json:"interfaceId,omitempty"`
PrimaryVlanSTag *int `json:"primaryVlanSTag,omitempty"`
PrimaryVlanCTag *int `json:"primaryVlanCTag,omitempty"`
NamedTag *string `json:"namedTag,omitempty"`
AdditionalInfo []L2ConnectionAdditionalInfo `json:"additionalInfo,omitempty"`
PrimaryServiceToken *string `json:"primaryServiceToken,omitempty"`
PrimaryZSidePortUUID *string `json:"primaryZSidePortUUID,omitempty"`
PrimaryZSideServiceToken *string `json:"primaryZSideServiceToken,omitempty"`
PrimaryZSideVlanSTag *int `json:"primaryZSideVlanSTag,omitempty"`
PrimaryZSideVlanCTag *int `json:"primaryZSideVlanCTag,omitempty"`
SecondaryName *string `json:"secondaryName,omitempty"`
Expand Down
42 changes: 22 additions & 20 deletions rest_l2_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,31 +177,33 @@ func mapGETToL2Connection(getResponse api.L2ConnectionResponse) *L2Connection {
RedundancyGroup: getResponse.RedundancyGroup,
Actions: mapL2ConnectionActionsAPIToDomain(getResponse.ActionDetails),
ServiceToken: getResponse.VendorToken,
VendorToken: getResponse.VendorToken,
}
}

func createL2ConnectionRequest(l2connection L2Connection) api.L2ConnectionRequest {
return api.L2ConnectionRequest{
PrimaryName: l2connection.Name,
ProfileUUID: l2connection.ProfileUUID,
Speed: l2connection.Speed,
SpeedUnit: l2connection.SpeedUnit,
Notifications: l2connection.Notifications,
PurchaseOrderNumber: l2connection.PurchaseOrderNumber,
PrimaryPortUUID: l2connection.PortUUID,
VirtualDeviceUUID: l2connection.DeviceUUID,
InterfaceID: l2connection.DeviceInterfaceID,
PrimaryVlanSTag: l2connection.VlanSTag,
PrimaryVlanCTag: l2connection.VlanCTag,
NamedTag: l2connection.NamedTag,
AdditionalInfo: mapAdditionalInfoDomainToAPI(l2connection.AdditionalInfo),
PrimaryZSidePortUUID: l2connection.ZSidePortUUID,
PrimaryZSideVlanSTag: l2connection.ZSideVlanSTag,
PrimaryZSideVlanCTag: l2connection.ZSideVlanCTag,
SellerRegion: l2connection.SellerRegion,
SellerMetroCode: l2connection.SellerMetroCode,
AuthorizationKey: l2connection.AuthorizationKey,
PrimaryServiceToken: l2connection.ServiceToken,
PrimaryName: l2connection.Name,
ProfileUUID: l2connection.ProfileUUID,
Speed: l2connection.Speed,
SpeedUnit: l2connection.SpeedUnit,
Notifications: l2connection.Notifications,
PurchaseOrderNumber: l2connection.PurchaseOrderNumber,
PrimaryPortUUID: l2connection.PortUUID,
VirtualDeviceUUID: l2connection.DeviceUUID,
InterfaceID: l2connection.DeviceInterfaceID,
PrimaryVlanSTag: l2connection.VlanSTag,
PrimaryVlanCTag: l2connection.VlanCTag,
NamedTag: l2connection.NamedTag,
AdditionalInfo: mapAdditionalInfoDomainToAPI(l2connection.AdditionalInfo),
PrimaryZSidePortUUID: l2connection.ZSidePortUUID,
PrimaryZSideVlanSTag: l2connection.ZSideVlanSTag,
PrimaryZSideVlanCTag: l2connection.ZSideVlanCTag,
SellerRegion: l2connection.SellerRegion,
SellerMetroCode: l2connection.SellerMetroCode,
AuthorizationKey: l2connection.AuthorizationKey,
PrimaryServiceToken: l2connection.ServiceToken,
PrimaryZSideServiceToken: l2connection.ZSideServiceToken,
}
}

Expand Down
39 changes: 5 additions & 34 deletions rest_l2_connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ var testPrimaryConnection = L2Connection{
ZSideVlanCTag: Int(201),
SellerRegion: String("EMEA"),
SellerMetroCode: String("AM"),
AuthorizationKey: String("authorizationKey")}
AuthorizationKey: String("authorizationKey"),
ServiceToken: String("serviceToken"),
ZSideServiceToken: String("zsideServiceToken"),
}

func TestGetL2OutgoingConnections(t *testing.T) {
//Given
Expand Down Expand Up @@ -159,39 +162,6 @@ func TestCreateDeviceL2Connection(t *testing.T) {
assert.Equal(t, uuid, respBody.PrimaryConnectionID, "UUID matches")
}

func TestCreateServiceTokenL2Connection(t *testing.T) {
//Given
respBody := api.CreateL2ConnectionResponse{}
if err := readJSONData("./test-fixtures/ecx_l2connection_post_resp.json", &respBody); err != nil {
assert.Failf(t, "Cannot read test response due to %s", err.Error())
}
reqBody := api.L2ConnectionRequest{}
testHc := &http.Client{}
httpmock.ActivateNonDefault(testHc)
httpmock.RegisterResponder("POST", fmt.Sprintf("%s/ecx/v3/l2/connections", baseURL),
func(r *http.Request) (*http.Response, error) {
if err := json.NewDecoder(r.Body).Decode(&reqBody); err != nil {
return httpmock.NewStringResponse(400, ""), nil
}
resp, _ := httpmock.NewJsonResponse(200, respBody)
return resp, nil
},
)
defer httpmock.DeactivateAndReset()
newConnection := testPrimaryConnection
newConnection.ServiceToken = String("serviceToken")

//When
ecxClient := NewClient(context.Background(), baseURL, testHc)
uuid, err := ecxClient.CreateL2Connection(newConnection)

//Then
assert.Nil(t, err, "Client should not return an error")
assert.NotNil(t, uuid, "Client should return a response")
verifyL2ConnectionRequest(t, newConnection, reqBody)
assert.Equal(t, uuid, respBody.PrimaryConnectionID, "UUID matches")
}

func TestCreateRedundantL2Connection(t *testing.T) {
//Given
respBody := api.CreateL2ConnectionResponse{}
Expand Down Expand Up @@ -359,6 +329,7 @@ func verifyL2ConnectionRequest(t *testing.T, conn L2Connection, req api.L2Connec
assert.Equal(t, conn.SellerMetroCode, req.SellerMetroCode, "SellerMetroCode matches")
assert.Equal(t, conn.AuthorizationKey, req.AuthorizationKey, "AuthorizationKey matches")
assert.Equal(t, conn.ServiceToken, req.PrimaryServiceToken, "PrimaryServiceToken matches")
assert.Equal(t, conn.ZSideServiceToken, req.PrimaryZSideServiceToken, "PrimaryZSideServiceToken matches")

assert.Equal(t, len(conn.AdditionalInfo), len(req.AdditionalInfo), "AdditionalInfo array size matches")
for i := range conn.AdditionalInfo {
Expand Down

0 comments on commit d178d37

Please sign in to comment.