diff --git a/test/address_pair_test.go b/test/address_pair_test.go index e96f50a..7c2ca2e 100644 --- a/test/address_pair_test.go +++ b/test/address_pair_test.go @@ -53,3 +53,24 @@ func TestDeleteAddressPair(t *ltesting.T) { t.Log("PASS") } + +func TestCreateAddressPair(t *ltesting.T) { + vngcloud := validSdkConfigHanRegion() + + virtualAddressId := "vip-0d2402cf-49e8-43bf-abbe-b707597320e9" + internalNicId := "net-in-3b076753-6561-4e3e-8a66-e10dc79cab2d" + + opt := lsnetworkSvcV2.NewCreateAddressPairRequest(virtualAddressId, internalNicId). + WithMode(lsnetworkSvcV2.AddressPairModeActiveActive) + + ap, err := vngcloud.VServerGateway().V2().NetworkService().CreateAddressPair(opt) + if err != nil { + t.Fatalf("Expect error to be nil but got %+v", err) + } + + if ap == nil { + t.Fatalf("Expect portal not to be nil but got nil") + } + + t.Log("RESULT:", ap) +} diff --git a/vngcloud/sdk_error/network.go b/vngcloud/sdk_error/network.go index 4807adc..17a8873 100644 --- a/vngcloud/sdk_error/network.go +++ b/vngcloud/sdk_error/network.go @@ -9,7 +9,7 @@ const ( patternNetworkNotFound = "is not found" patternSubnetNotFound = `subnet with id [^.]+ is not found` patternSubnetNotBelongNetwork = `subnet id: [^.]+ belong to network id: [^.]+ not found` - patternInternalNetworkInterfaceNotFound = `interface network interface with id [^.]+ is not found` + patternInternalNetworkInterfaceNotFound = `internal network interface with id [^.]+ is not found` patternWanIpAvailable = "wan ip is available" pattermWapIdNotFound = "cannot get wan ip with id" ) diff --git a/vngcloud/services/network/inetwork.go b/vngcloud/services/network/inetwork.go index 98db233..c088e66 100644 --- a/vngcloud/services/network/inetwork.go +++ b/vngcloud/services/network/inetwork.go @@ -46,6 +46,7 @@ type INetworkServiceV2 interface { GetAllAddressPairByVirtualSubnetId(popts lsnetworkSvcV2.IGetAllAddressPairByVirtualSubnetIdRequest) ([]*lsentity.AddressPair, lserr.IError) SetAddressPairInVirtualSubnet(popts lsnetworkSvcV2.ISetAddressPairInVirtualSubnetRequest) (*lsentity.AddressPair, lserr.IError) DeleteAddressPair(popts lsnetworkSvcV2.IDeleteAddressPairRequest) lserr.IError + CreateAddressPair(popts lsnetworkSvcV2.ICreateAddressPairRequest) (*lsentity.AddressPair, lserr.IError) // Servers ListAllServersBySecgroupId(popts lsnetworkSvcV2.IListAllServersBySecgroupIdRequest) (*lsentity.ListServers, lserr.IError) diff --git a/vngcloud/services/network/v2/address_pair.go b/vngcloud/services/network/v2/address_pair.go index 245d41c..29e2e31 100644 --- a/vngcloud/services/network/v2/address_pair.go +++ b/vngcloud/services/network/v2/address_pair.go @@ -58,3 +58,23 @@ func (s *NetworkServiceV2) DeleteAddressPair(popts IDeleteAddressPairRequest) ls } return nil } + +func (s *NetworkServiceV2) CreateAddressPair(popts ICreateAddressPairRequest) (*lsentity.AddressPair, lserr.IError) { + url := createAddressPairUrl(s.VserverClient, popts) + resp := new(CreateAddressPairResponse) + errResp := lserr.NewErrorResponse(lserr.NormalErrorType) + req := lsclient.NewRequest(). + WithHeader("User-Agent", popts.ParseUserAgent()). + WithOkCodes(201). + WithJsonBody(popts.ToRequestBody()). + WithJsonResponse(resp). + WithJsonError(errResp) + + if _, sdkErr := s.VserverClient.Post(url, req); sdkErr != nil { + return nil, lserr.SdkErrorHandler(sdkErr, errResp, + lserr.WithErrorInternalNetworkInterfaceNotFound(errResp)). + WithErrorCategories(lserr.ErrCatVServer, lserr.ErrCatVirtualAddress) + } + + return resp.ToAddressPair(), nil +} diff --git a/vngcloud/services/network/v2/address_pair_request.go b/vngcloud/services/network/v2/address_pair_request.go index 392e284..eaf3d7d 100644 --- a/vngcloud/services/network/v2/address_pair_request.go +++ b/vngcloud/services/network/v2/address_pair_request.go @@ -66,3 +66,49 @@ func (s *DeleteAddressPairRequest) GetAddressPairID() string { } // -------------------------------------------------------- + +// Api create address pair + +type AddressPairMode string + +const ( + AddressPairModeActiveActive AddressPairMode = "active-active" +) + +type CreateAddressPairRequest struct { + // Is the ID of the network interface that the address pair will be attached to. + InternalNetworkInterfaceId string `json:"internalNetworkInterfaceId"` // required + + // Is the pair mode of the address pair. + Mode *AddressPairMode `json:"mode,omitempty"` + + lscommon.InternalNetworkInterfaceCommon + lscommon.UserAgent + lscommon.VirtualAddressCommon +} + +func (s *CreateAddressPairRequest) ToRequestBody() interface{} { + return s +} + +func (s *CreateAddressPairRequest) ToMap() map[string]interface{} { + mode := "active-standby" + if s.Mode != nil { + mode = string(*s.Mode) + } + + return map[string]interface{}{ + "internalNetworkInterfaceId": s.InternalNetworkInterfaceId, + "mode": mode, + } +} + +func (s *CreateAddressPairRequest) AddUserAgent(pagent ...string) ICreateAddressPairRequest { + s.UserAgent.AddUserAgent(pagent...) + return s +} + +func (s *CreateAddressPairRequest) WithMode(pmode AddressPairMode) ICreateAddressPairRequest { + s.Mode = &pmode + return s +} diff --git a/vngcloud/services/network/v2/address_pair_response.go b/vngcloud/services/network/v2/address_pair_response.go index f622406..8f720f8 100644 --- a/vngcloud/services/network/v2/address_pair_response.go +++ b/vngcloud/services/network/v2/address_pair_response.go @@ -21,17 +21,21 @@ type AddressPairResponse struct { // DeletedAt string `json:"deletedAt"` } +func (s *AddressPairResponse) toAddressPair() *lsentity.AddressPair { + return &lsentity.AddressPair{ + Id: s.UUID, + VirtualIpAddressId: s.VirtualIpAddressId, + VirtualSubnetId: s.VirtualSubnetId, + NetworkInterfaceIp: s.NetworkInterfaceIp, + NetworkInterfaceId: s.NetworkInterfaceId, + CIDR: s.CIDR, + } +} + func (s *GetAllAddressPairByVirtualSubnetIdResponse) ToListAddressPair() []*lsentity.AddressPair { addressPairs := make([]*lsentity.AddressPair, 0) for _, addressPair := range s.Data { - addressPairs = append(addressPairs, &lsentity.AddressPair{ - Id: addressPair.UUID, - VirtualIpAddressId: addressPair.VirtualIpAddressId, - VirtualSubnetId: addressPair.VirtualSubnetId, - NetworkInterfaceIp: addressPair.NetworkInterfaceIp, - NetworkInterfaceId: addressPair.NetworkInterfaceId, - CIDR: addressPair.CIDR, - }) + addressPairs = append(addressPairs, addressPair.toAddressPair()) } return addressPairs } @@ -41,12 +45,13 @@ type SetAddressPairInVirtualSubnetResponse struct { } func (s *SetAddressPairInVirtualSubnetResponse) ToAddressPair() *lsentity.AddressPair { - return &lsentity.AddressPair{ - Id: s.Data.UUID, - VirtualIpAddressId: s.Data.VirtualIpAddressId, - VirtualSubnetId: s.Data.VirtualSubnetId, - NetworkInterfaceIp: s.Data.NetworkInterfaceIp, - NetworkInterfaceId: s.Data.NetworkInterfaceId, - CIDR: s.Data.CIDR, - } + return s.Data.toAddressPair() +} + +type CreateAddressPairResponse struct { + Data AddressPairResponse `json:"data"` +} + +func (s *CreateAddressPairResponse) ToAddressPair() *lsentity.AddressPair { + return s.Data.toAddressPair() } diff --git a/vngcloud/services/network/v2/irequest.go b/vngcloud/services/network/v2/irequest.go index 498b8c8..ef15eaa 100644 --- a/vngcloud/services/network/v2/irequest.go +++ b/vngcloud/services/network/v2/irequest.go @@ -54,7 +54,9 @@ type IUpdateSubnetByIdRequest interface { ToRequestBody() interface{} } -// Address Pair +/** + * The interface request group of Address Pair API + */ type IGetAllAddressPairByVirtualSubnetIdRequest interface { GetVirtualSubnetId() string @@ -76,6 +78,15 @@ type IListAllServersBySecgroupIdRequest interface { GetSecgroupId() string } +type ICreateAddressPairRequest interface { + GetVirtualAddressId() string + ToRequestBody() interface{} + ParseUserAgent() string + ToMap() map[string]interface{} + AddUserAgent(pagent ...string) ICreateAddressPairRequest + WithMode(pmode AddressPairMode) ICreateAddressPairRequest +} + /** * The interface request group of Virtual Address API */ @@ -97,7 +108,6 @@ type IDeleteVirtualAddressByIdRequest interface { ToMap() map[string]interface{} } - // Request interface for getting virtual address by ID type IGetVirtualAddressByIdRequest interface { GetVirtualAddressId() string @@ -106,7 +116,6 @@ type IGetVirtualAddressByIdRequest interface { ToMap() map[string]interface{} } - // Request interface for listing address pairs of virtual address by ID type IListAddressPairsByVirtualAddressIdRequest interface { @@ -114,4 +123,4 @@ type IListAddressPairsByVirtualAddressIdRequest interface { ParseUserAgent() string AddUserAgent(pagent ...string) IListAddressPairsByVirtualAddressIdRequest ToMap() map[string]interface{} -} \ No newline at end of file +} diff --git a/vngcloud/services/network/v2/requests.go b/vngcloud/services/network/v2/requests.go index ed80ee5..8592a62 100644 --- a/vngcloud/services/network/v2/requests.go +++ b/vngcloud/services/network/v2/requests.go @@ -25,3 +25,10 @@ func NewListAddressPairsByVirtualAddressIdRequest(pvirtualAddressId string) ILis opts.VirtualAddressId = pvirtualAddressId return opts } + +func NewCreateAddressPairRequest(pvirtualAddressId, pinternalNicId string) ICreateAddressPairRequest { + opts := new(CreateAddressPairRequest) + opts.VirtualAddressId = pvirtualAddressId + opts.InternalNetworkInterfaceId = pinternalNicId + return opts +} diff --git a/vngcloud/services/network/v2/url.go b/vngcloud/services/network/v2/url.go index b9bd5c9..117aaf1 100644 --- a/vngcloud/services/network/v2/url.go +++ b/vngcloud/services/network/v2/url.go @@ -102,6 +102,15 @@ func deleteAddressPairUrl(psc lsclient.IServiceClient, popts IDeleteAddressPairR popts.GetAddressPairID()) } + +func createAddressPairUrl(psc lsclient.IServiceClient, popts ICreateAddressPairRequest) string { + return psc.ServiceURL( + psc.GetProjectId(), + "virtualIpAddress", + popts.GetVirtualAddressId(), + "addressPairs") +} + func listAllServersBySecgroupIdUrl(psc lsclient.IServiceClient, popts IListAllServersBySecgroupIdRequest) string { return psc.ServiceURL( psc.GetProjectId(),