From ed492637001c755299b7bc6e2c5ba82ad73cf8b3 Mon Sep 17 00:00:00 2001 From: kpdhulipala <84343462+kpdhulipala@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:52:55 -0800 Subject: [PATCH] To include projectId attribute(optional) in Create Virtual Device, Create DLG, Create ACL template, Create SSH Public Key APIs (#28) * to include projectId(optional)in CVD,Create DLG, Create ACL template APIs * to include projectId(optional)in create ssh public key API * added in rest APIs and tests * fixed acl tests * fixed acl tests --- client.go | 24 +++++++++++--------- internal/api/acltemplate.go | 9 ++++---- internal/api/device.go | 2 ++ internal/api/device_link.go | 1 + internal/api/sshkey.go | 11 ++++----- rest_acltemplate.go | 16 +++++++------ rest_acltemplate_test.go | 10 ++++++++- rest_device.go | 2 ++ rest_device_link.go | 20 +++++++++-------- rest_device_link_test.go | 1 + rest_device_test.go | 2 ++ rest_sshkey.go | 26 ++++++++++++---------- rest_sshkey_test.go | 8 ++++--- test-fixtures/ne_acltemplate_get_resp.json | 1 + test-fixtures/ne_device_link_get_resp.json | 1 + 15 files changed, 83 insertions(+), 51 deletions(-) diff --git a/client.go b/client.go index e3d13a7..ee51f85 100644 --- a/client.go +++ b/client.go @@ -280,6 +280,7 @@ type Device struct { ASN *int ZoneCode *string ClusterDetails *ClusterDetails + ProjectID *string } // DeviceInterface describes Network Edge device interface @@ -358,10 +359,11 @@ type BGPConfiguration struct { // SSHPublicKey describes Network Edge SSH user public key type SSHPublicKey struct { - UUID *string - Name *string - Value *string - Type *string + UUID *string + Name *string + Value *string + Type *string + ProjectID *string } // ACLTemplate describes Network Edge device ACL template @@ -374,6 +376,7 @@ type ACLTemplate struct { DeviceACLStatus *string InboundRules []ACLTemplateInboundRule DeviceDetails []ACLTemplateDeviceDetails + ProjectID *string } // ACLTemplateInboundRule describes inbound ACL rule that is part of @@ -412,12 +415,13 @@ type DeviceACLDetails struct { // DeviceLinkGroup describes details of a device link group type DeviceLinkGroup struct { - UUID *string - Name *string - Subnet *string - Status *string - Devices []DeviceLinkGroupDevice - Links []DeviceLinkGroupLink + UUID *string + Name *string + Subnet *string + ProjectID *string + Status *string + Devices []DeviceLinkGroupDevice + Links []DeviceLinkGroupLink } // DeviceLinkGroupDevice describes details of a device within device diff --git a/internal/api/acltemplate.go b/internal/api/acltemplate.go index 9d82fbf..4553478 100644 --- a/internal/api/acltemplate.go +++ b/internal/api/acltemplate.go @@ -1,6 +1,6 @@ package api -//ACLTemplate describes Network Edge device ACL template +// ACLTemplate describes Network Edge device ACL template type ACLTemplate struct { UUID *string `json:"uuid,omitempty"` Name *string `json:"name,omitempty"` @@ -10,10 +10,11 @@ type ACLTemplate struct { DeviceACLStatus *string `json:"deviceAclstatus,omitempty"` InboundRules []ACLTemplateInboundRule `json:"inboundRules,omitempty"` DeviceDetails []ACLTemplateDeviceDetails `json:"virtualDeviceDetails,omitempty"` + ProjectID *string `json:"projectId,omitempty"` } -//ACLTemplateInboundRule describes inbound ACL rule that is part of -//Network Edge device ACL template +// ACLTemplateInboundRule describes inbound ACL rule that is part of +// Network Edge device ACL template type ACLTemplateInboundRule struct { SrcType *string `json:"srcType,omitempty"` Protocol *string `json:"protocol,omitempty"` @@ -31,7 +32,7 @@ type ACLTemplateDeviceDetails struct { ACLStatus *string `json:"aclStatus,omitempty"` } -//ACLTemplatesResponse describes response for a get ACL template collection request +// ACLTemplatesResponse describes response for a get ACL template collection request type ACLTemplatesResponse struct { Pagination Pagination `json:"pagination,omitempty"` Data []ACLTemplate `json:"data,omitempty"` diff --git a/internal/api/device.go b/internal/api/device.go index 5cebe1f..f3b2d3b 100644 --- a/internal/api/device.go +++ b/internal/api/device.go @@ -42,6 +42,7 @@ type Device struct { ZoneCode *string `json:"zoneCode,omitempty"` ClusterDetails *ClusterDetails `json:"clusterDetails,omitempty"` Connectivity *string `json:"connectivity,omitempty"` + ProjectID *string `json:"projectId,omitempty"` } // DeviceRequest describes network edge device creation request @@ -75,6 +76,7 @@ type DeviceRequest struct { Secondary *SecondaryDeviceRequest `json:"secondary,omitempty"` ClusterDetails *ClusterDetailsRequest `json:"clusterDetails,omitempty"` Connectivity *string `json:"connectivity,omitempty"` + ProjectID *string `json:"projectId,omitempty"` } // SecondaryDeviceRequest describes secondary device part of device creation request diff --git a/internal/api/device_link.go b/internal/api/device_link.go index 8173cf9..8f0b59a 100644 --- a/internal/api/device_link.go +++ b/internal/api/device_link.go @@ -7,6 +7,7 @@ type DeviceLinkGroup struct { Status *string `json:"status,omitempty"` Devices []DeviceLinkGroupDevice `json:"linkDevices,omitempty"` Links []DeviceLinkGroupLink `json:"links"` + ProjectID *string `json:"projectId,omitempty"` } type DeviceLinkGroupUpdateRequest struct { diff --git a/internal/api/sshkey.go b/internal/api/sshkey.go index 3e1f5be..37cddef 100644 --- a/internal/api/sshkey.go +++ b/internal/api/sshkey.go @@ -1,9 +1,10 @@ package api -//SSHPublicKey describes SSH public key +// SSHPublicKey describes SSH public key type SSHPublicKey struct { - UUID *string `json:"uuid,omitempty"` - KeyName *string `json:"keyName,omitempty"` - KeyValue *string `json:"keyValue,omitempty"` - KeyType *string `json:"keyType,omitempty"` + UUID *string `json:"uuid,omitempty"` + KeyName *string `json:"keyName,omitempty"` + KeyValue *string `json:"keyValue,omitempty"` + KeyType *string `json:"keyType,omitempty"` + ProjectID *string `json:"projectId,omitempty"` } diff --git a/rest_acltemplate.go b/rest_acltemplate.go index e811047..e5808ef 100644 --- a/rest_acltemplate.go +++ b/rest_acltemplate.go @@ -8,8 +8,8 @@ import ( "github.com/equinix/rest-go" ) -//CreateACLTemplate creates new ACL template with a given model -//On successful creation, template's UUID is returned +// CreateACLTemplate creates new ACL template with a given model +// On successful creation, template's UUID is returned func (c RestClient) CreateACLTemplate(template ACLTemplate) (*string, error) { path := "/ne/v1/aclTemplates" reqBody := mapACLTemplateDomainToAPI(template) @@ -25,7 +25,7 @@ func (c RestClient) CreateACLTemplate(template ACLTemplate) (*string, error) { return uuid, nil } -//GetACLTemplates retrieves list of all ACL templates along with their details +// GetACLTemplates retrieves list of all ACL templates along with their details func (c RestClient) GetACLTemplates() ([]ACLTemplate, error) { path := "/ne/v1/aclTemplates" content, err := c.GetOffsetPaginated(path, &api.ACLTemplatesResponse{}, @@ -40,7 +40,7 @@ func (c RestClient) GetACLTemplates() ([]ACLTemplate, error) { return transformed, nil } -//GetACLTemplate retrieves ACL template with a given UUID +// GetACLTemplate retrieves ACL template with a given UUID func (c RestClient) GetACLTemplate(uuid string) (*ACLTemplate, error) { path := "/ne/v1/aclTemplates/" + url.PathEscape(uuid) respBody := api.ACLTemplate{} @@ -52,8 +52,8 @@ func (c RestClient) GetACLTemplate(uuid string) (*ACLTemplate, error) { return &template, nil } -//ReplaceACLTemplate replaces ACL template under given UUID with -//a new one with a given model +// ReplaceACLTemplate replaces ACL template under given UUID with +// a new one with a given model func (c RestClient) ReplaceACLTemplate(uuid string, template ACLTemplate) error { path := "/ne/v1/aclTemplates/" + url.PathEscape(uuid) updateTemplate := ACLTemplate{ @@ -70,7 +70,7 @@ func (c RestClient) ReplaceACLTemplate(uuid string, template ACLTemplate) error return nil } -//DeleteACLTemplate removes ACL template with a given UUID +// DeleteACLTemplate removes ACL template with a given UUID func (c RestClient) DeleteACLTemplate(uuid string) error { path := "/ne/v1/aclTemplates/" + url.PathEscape(uuid) if err := c.Execute(c.R(), http.MethodDelete, path); err != nil { @@ -87,6 +87,7 @@ func mapACLTemplateDomainToAPI(template ACLTemplate) api.ACLTemplate { MetroCode: template.MetroCode, DeviceACLStatus: template.DeviceACLStatus, InboundRules: mapACLTemplateInboundRulesDomainToAPI(template.InboundRules), + ProjectID: template.ProjectID, } } @@ -120,6 +121,7 @@ func mapACLTemplateAPIToDomain(apiTemplate api.ACLTemplate) ACLTemplate { DeviceACLStatus: apiTemplate.DeviceACLStatus, InboundRules: mapACLTemplateInboundRulesAPIToDomain(apiTemplate.InboundRules), DeviceDetails: mapACLTemplateDeviceDetailsAPIToDomain(apiTemplate.DeviceDetails), + ProjectID: apiTemplate.ProjectID, } } diff --git a/rest_acltemplate_test.go b/rest_acltemplate_test.go index cfb46ce..0ecb2fd 100644 --- a/rest_acltemplate_test.go +++ b/rest_acltemplate_test.go @@ -16,6 +16,7 @@ var testACLTemplate = ACLTemplate{ Name: String("test"), Description: String("Test ACL"), MetroCode: String("SV"), + ProjectID: String("68ccfd49-39b1-478e-957a-67c72f719d7a"), InboundRules: []ACLTemplateInboundRule{ { SrcType: String("SUBNET"), @@ -122,7 +123,7 @@ func TestGetACLTemplate(t *testing.T) { func TestReplaceACLTemplate(t *testing.T) { //given templateID := "db66bf49-b2d8-4e64-8719-d46406b54039" - template := testACLTemplate + template := updateACLRequestPayload() reqBody := api.ACLTemplate{} testHc := &http.Client{} httpmock.ActivateNonDefault(testHc) @@ -163,6 +164,7 @@ func TestDeleteACLTemplate(t *testing.T) { } func verifyACLTemplate(t *testing.T, template ACLTemplate, apiTemplate api.ACLTemplate) { + assert.Equal(t, template.ProjectID, apiTemplate.ProjectID, "ProjectID matches") assert.Equal(t, template.UUID, apiTemplate.UUID, "UUID matches") assert.Equal(t, template.Name, apiTemplate.Name, "Name matches") assert.Equal(t, template.Description, apiTemplate.Description, "Description matches") @@ -192,3 +194,9 @@ func verifyACLTemplateDeviceDetails(t *testing.T, template ACLTemplate, apiTempl assert.Equal(t, template.DeviceDetails[i].ACLStatus, apiTemplate.DeviceDetails[i].ACLStatus, "ACL Status matches") } } + +func updateACLRequestPayload() ACLTemplate { + updateRequestPayload := testACLTemplate + updateRequestPayload.ProjectID = nil + return updateRequestPayload +} diff --git a/rest_device.go b/rest_device.go index 772c8b9..a826554 100644 --- a/rest_device.go +++ b/rest_device.go @@ -242,6 +242,7 @@ func mapDeviceAPIToDomain(apiDevice api.Device) *Device { device.RedundancyType = apiDevice.RedundancyType device.RedundantUUID = apiDevice.RedundantUUID device.TermLength = apiDevice.TermLength + device.ProjectID = apiDevice.ProjectID device.AdditionalBandwidth = apiDevice.AdditionalBandwidth device.WanInterfaceId = apiDevice.SshInterfaceID device.OrderReference = apiDevice.OrderReference @@ -395,6 +396,7 @@ func createDeviceRequest(device Device) api.DeviceRequest { } } req.Connectivity = device.Connectivity + req.ProjectID = device.ProjectID req.Core = device.CoreCount req.AdditionalBandwidth = device.AdditionalBandwidth req.SshInterfaceId = device.WanInterfaceId diff --git a/rest_device_link.go b/rest_device_link.go index 55a30a6..836e414 100644 --- a/rest_device_link.go +++ b/rest_device_link.go @@ -17,8 +17,8 @@ type restDeviceLinkUpdateRequest struct { c RestClient } -//GetDeviceLinkGroups retrieves list of existing device link groups -//(along with their details) +// GetDeviceLinkGroups retrieves list of existing device link groups +// (along with their details) func (c RestClient) GetDeviceLinkGroups() ([]DeviceLinkGroup, error) { path := "/ne/v1/links" content, err := c.GetOffsetPaginated(path, &api.DeviceLinkGroupsGetResponse{}, @@ -34,8 +34,8 @@ func (c RestClient) GetDeviceLinkGroups() ([]DeviceLinkGroup, error) { return transformed, nil } -//GetDeviceLinkGroups retrieves details of a device link group -//with a given identifier +// GetDeviceLinkGroups retrieves details of a device link group +// with a given identifier func (c RestClient) GetDeviceLinkGroup(uuid string) (*DeviceLinkGroup, error) { path := "/ne/v1/links/" + url.PathEscape(uuid) result := api.DeviceLinkGroup{} @@ -46,8 +46,8 @@ func (c RestClient) GetDeviceLinkGroup(uuid string) (*DeviceLinkGroup, error) { return mapDeviceLinkGroupAPIToDomain(result), nil } -//CreateDeviceLinkGroup creates given device link group and returns -//its identifier upon successful creation +// CreateDeviceLinkGroup creates given device link group and returns +// its identifier upon successful creation func (c RestClient) CreateDeviceLinkGroup(linkGroup DeviceLinkGroup) (*string, error) { path := "/ne/v1/links" reqBody := mapDeviceLinkGroupDomainToAPI(linkGroup) @@ -59,13 +59,13 @@ func (c RestClient) CreateDeviceLinkGroup(linkGroup DeviceLinkGroup) (*string, e return respBody.UUID, nil } -//NewDeviceLinkGroupUpdateRequest creates new update request for a device link -//group with a given identifier +// NewDeviceLinkGroupUpdateRequest creates new update request for a device link +// group with a given identifier func (c RestClient) NewDeviceLinkGroupUpdateRequest(uuid string) DeviceLinkUpdateRequest { return &restDeviceLinkUpdateRequest{uuid: uuid, c: c} } -//DeleteDeviceLinkGroup removes device link group with a given identifier +// DeleteDeviceLinkGroup removes device link group with a given identifier func (c RestClient) DeleteDeviceLinkGroup(uuid string) error { path := "/ne/v1/links/" + url.PathEscape(uuid) if err := c.Execute(c.R(), http.MethodDelete, path); err != nil { @@ -128,6 +128,7 @@ func mapDeviceLinkGroupAPIToDomain(apiLinkGroup api.DeviceLinkGroup) *DeviceLink linkGroup.Name = apiLinkGroup.GroupName linkGroup.Subnet = apiLinkGroup.Subnet linkGroup.Status = apiLinkGroup.Status + linkGroup.ProjectID = apiLinkGroup.ProjectID linkGroup.Devices = make([]DeviceLinkGroupDevice, len(apiLinkGroup.Devices)) for i := range apiLinkGroup.Devices { linkGroup.Devices[i] = mapDeviceLinkGroupDeviceAPIToDomain(apiLinkGroup.Devices[i]) @@ -165,6 +166,7 @@ func mapDeviceLinkGroupDomainToAPI(linkGroup DeviceLinkGroup) api.DeviceLinkGrou apiLinkGroup := api.DeviceLinkGroup{} apiLinkGroup.GroupName = linkGroup.Name apiLinkGroup.Subnet = linkGroup.Subnet + apiLinkGroup.ProjectID = linkGroup.ProjectID apiLinkGroup.Devices = make([]api.DeviceLinkGroupDevice, len(linkGroup.Devices)) for i := range linkGroup.Devices { apiLinkGroup.Devices[i] = mapDeviceLinkGroupDeviceDomainToAPI(linkGroup.Devices[i]) diff --git a/rest_device_link_test.go b/rest_device_link_test.go index aa66bcd..4d67c1f 100644 --- a/rest_device_link_test.go +++ b/rest_device_link_test.go @@ -228,6 +228,7 @@ func verifyDeviceLinkGroup(t *testing.T, linkGroup DeviceLinkGroup, apiLinkGroup assert.Equal(t, apiLinkGroup.GroupName, linkGroup.Name, "GroupName matches") assert.Equal(t, apiLinkGroup.Subnet, linkGroup.Subnet, "Subnet matches") assert.Equal(t, len(apiLinkGroup.Devices), len(linkGroup.Devices), "Length of []Devices matches") + assert.Equal(t, apiLinkGroup.ProjectID, linkGroup.ProjectID, "Project ID matches") for i := range apiLinkGroup.Devices { verifyDeviceLinkGroupDevice(t, linkGroup.Devices[i], apiLinkGroup.Devices[i]) } diff --git a/rest_device_test.go b/rest_device_test.go index 85ea270..e4cda06 100644 --- a/rest_device_test.go +++ b/rest_device_test.go @@ -26,6 +26,7 @@ var testDevice = Device{ Notifications: []string{"test1@example.com", "test2@example.com"}, PackageCode: String("VM100"), TermLength: Int(24), + ProjectID: String("68ccfd49-39b1-478e-957a-67c72f719d7a"), Throughput: Int(1), ThroughputUnit: String("Gbps"), Name: String("PaloAltoSRmy"), @@ -501,6 +502,7 @@ func verifyDeviceRequest(t *testing.T, device Device, req api.DeviceRequest) { assert.Equal(t, device.TypeCode, req.DeviceTypeCode, "TypeCode matches") termLengthStr := strconv.Itoa(*device.TermLength) assert.Equal(t, &termLengthStr, req.TermLength, "TermLength matches") + assert.Equal(t, device.ProjectID, req.ProjectID, "Project Id matches") if *device.IsBYOL { assert.Equal(t, DeviceLicenseModeBYOL, StringValue(req.LicenseMode), "LicenseMode matches") } else { diff --git a/rest_sshkey.go b/rest_sshkey.go index a5da4ce..3ee7bb1 100644 --- a/rest_sshkey.go +++ b/rest_sshkey.go @@ -7,7 +7,7 @@ import ( "github.com/equinix/ne-go/internal/api" ) -//GetSSHPublicKeys retrieves list of available SSH public keys +// GetSSHPublicKeys retrieves list of available SSH public keys func (c RestClient) GetSSHPublicKeys() ([]SSHPublicKey, error) { path := "/ne/v1/publicKeys" respBody := make([]api.SSHPublicKey, 0) @@ -18,7 +18,7 @@ func (c RestClient) GetSSHPublicKeys() ([]SSHPublicKey, error) { return mapSSHPublicKeysAPIToDomain(respBody), nil } -//GetSSHPublicKey retrieves SSH public key with a given identifier +// GetSSHPublicKey retrieves SSH public key with a given identifier func (c RestClient) GetSSHPublicKey(uuid string) (*SSHPublicKey, error) { path := "/ne/v1/publicKeys/" + url.PathEscape(uuid) respBody := api.SSHPublicKey{} @@ -30,7 +30,7 @@ func (c RestClient) GetSSHPublicKey(uuid string) (*SSHPublicKey, error) { return &mapped, nil } -//CreateSSHPublicKey creates new SSH public key with a given details +// CreateSSHPublicKey creates new SSH public key with a given details func (c RestClient) CreateSSHPublicKey(key SSHPublicKey) (*string, error) { path := "/ne/v1/publicKeys" reqBody := mapSSHPublicKeyDomainToAPI(key) @@ -46,7 +46,7 @@ func (c RestClient) CreateSSHPublicKey(key SSHPublicKey) (*string, error) { return uuid, nil } -//DeleteSSHPublicKey removes SSH Public key with given identifier +// DeleteSSHPublicKey removes SSH Public key with given identifier func (c RestClient) DeleteSSHPublicKey(uuid string) error { path := "/ne/v1/publicKeys/" + url.PathEscape(uuid) if err := c.Execute(c.R(), http.MethodDelete, path); err != nil { @@ -65,18 +65,20 @@ func mapSSHPublicKeysAPIToDomain(apiKeys []api.SSHPublicKey) []SSHPublicKey { func mapSSHPublicKeyAPIToDomain(apiKey api.SSHPublicKey) SSHPublicKey { return SSHPublicKey{ - UUID: apiKey.UUID, - Name: apiKey.KeyName, - Value: apiKey.KeyValue, - Type: apiKey.KeyType, + UUID: apiKey.UUID, + Name: apiKey.KeyName, + Value: apiKey.KeyValue, + Type: apiKey.KeyType, + ProjectID: apiKey.ProjectID, } } func mapSSHPublicKeyDomainToAPI(key SSHPublicKey) api.SSHPublicKey { return api.SSHPublicKey{ - UUID: key.UUID, - KeyName: key.Name, - KeyValue: key.Value, - KeyType: key.Type, + UUID: key.UUID, + KeyName: key.Name, + KeyValue: key.Value, + KeyType: key.Type, + ProjectID: key.ProjectID, } } diff --git a/rest_sshkey_test.go b/rest_sshkey_test.go index bbb2576..c50777c 100644 --- a/rest_sshkey_test.go +++ b/rest_sshkey_test.go @@ -13,9 +13,10 @@ import ( ) var testSSHPublicKey = SSHPublicKey{ - Name: String("testKey"), - Value: String("keyyyyyyyyyyyyyyyyyyyyyyyyy"), - Type: String("RSA"), + Name: String("testKey"), + Value: String("keyyyyyyyyyyyyyyyyyyyyyyyyy"), + Type: String("RSA"), + ProjectID: String("68ccfd49-39b1-478e-957a-67c72f719d7a"), } func TestGetSSHPublicKeys(t *testing.T) { @@ -111,4 +112,5 @@ func verifySSHPublicKey(t *testing.T, apiKey api.SSHPublicKey, key SSHPublicKey) assert.Equal(t, apiKey.KeyName, key.Name, "Name matches") assert.Equal(t, apiKey.KeyValue, key.Value, "Value matches") assert.Equal(t, apiKey.KeyType, key.Type, "Type matches") + assert.Equal(t, apiKey.ProjectID, key.ProjectID, "ProjectID matches") } diff --git a/test-fixtures/ne_acltemplate_get_resp.json b/test-fixtures/ne_acltemplate_get_resp.json index 8195fc5..fe491fc 100644 --- a/test-fixtures/ne_acltemplate_get_resp.json +++ b/test-fixtures/ne_acltemplate_get_resp.json @@ -1,6 +1,7 @@ { "name": "test", "uuid": "db66bf49-b2d8-4e64-8719-d46406b54039", + "projectId": "68ccfd49-39b1-478e-957a-67c72f719d7a", "description": "Test ACL", "inboundRules": [ { diff --git a/test-fixtures/ne_device_link_get_resp.json b/test-fixtures/ne_device_link_get_resp.json index 25e9a00..9f67489 100644 --- a/test-fixtures/ne_device_link_get_resp.json +++ b/test-fixtures/ne_device_link_get_resp.json @@ -8,6 +8,7 @@ "createdDate": "2020-04-29T16:07:16.170Z", "lastUpdatedBy": "test@test.com", "lastUpdatedDate": "2020-11-06T17:15:29.691Z", + "projectId": "68ccfd49-39b1-478e-957a-67c72f719d7a", "links": [], "linkDevices": [ {