From ab91906e0735cfa7d7c73aebffbd17f95b0e1858 Mon Sep 17 00:00:00 2001 From: yuridekim Date: Tue, 26 Dec 2023 16:26:26 +0900 Subject: [PATCH 1/5] Tidy go mod --- go.mod | 6 ++++++ go.sum | 2 +- pkg/server.go | 12 ++++++------ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 8e08394..f06cac5 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,12 @@ go 1.21.1 require ( github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.6.8 // indirect + github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.6.8 + github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 + github.com/stretchr/testify v1.8.4 +) + +require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 github.com/golang/mock v1.6.0 // indirect diff --git a/go.sum b/go.sum index 0be2f8a..4d91ffd 100644 --- a/go.sum +++ b/go.sum @@ -35,7 +35,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -76,6 +75,7 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/pkg/server.go b/pkg/server.go index 94f7a7a..05d76ac 100644 --- a/pkg/server.go +++ b/pkg/server.go @@ -94,7 +94,7 @@ func (server *ServerService) Delete(url string) error { } /// NCP 헤더 설정 SetNCPHeader(request, "", "") - + // httpRequest token 설정 SetAuthToken(request, server.token) @@ -107,12 +107,12 @@ func (server *ServerService) Delete(url string) error { return fmt.Errorf("Error sending request:", err) } defer response.Body.Close() - + // 결과 반환 if response.StatusCode != http.StatusOK { return fmt.Errorf("Unexpected response status code:", err) } - + return nil } @@ -127,7 +127,7 @@ func (server *ServerService) Stop(url string) error { } /// NCP 헤더 설정 SetNCPHeader(request, "", "") - + // httpRequest token 설정 SetAuthToken(request, server.token) @@ -140,12 +140,12 @@ func (server *ServerService) Stop(url string) error { return fmt.Errorf("Error sending request:", err) } defer response.Body.Close() - + // 결과 반환 if response.StatusCode != http.StatusOK { return fmt.Errorf("Unexpected response status code:", err) } - + return nil } From dd0681a1135eef7c76f4e6875c8eee4e0a18225a Mon Sep 17 00:00:00 2001 From: yuridekim Date: Fri, 29 Dec 2023 15:57:46 +0900 Subject: [PATCH 2/5] Implement interace api calls and test get stop --- go.mod | 10 +- go.sum | 17 --- main.go | 33 +++++ pkg/constant.go | 16 ++- pkg/ncp.go | 4 +- pkg/server.go | 158 ++++------------------- types/server/request.go | 179 +++++++++++++++++++++++++- types/server/request_response_func.go | 13 ++ types/server/response.go | 59 --------- 9 files changed, 262 insertions(+), 227 deletions(-) diff --git a/go.mod b/go.mod index f06cac5..b55da16 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,8 @@ module github.com/cloud-club/Aviator-service -go 1.21.1 +go 1.21 require ( - github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.6.8 // indirect github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.6.8 github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 github.com/stretchr/testify v1.8.4 @@ -11,15 +10,8 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 - github.com/golang/mock v1.6.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/objx v0.5.0 // indirect - github.com/stretchr/testify v1.8.4 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.18.0 // indirect - golang.org/x/sys v0.14.0 // indirect - golang.org/x/tools v0.15.0 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 4d91ffd..54f3050 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 h1:CaO/zOnF8VvUfEbhRatPcwKVWamvbYd8tQGRWacE9kU= github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -18,41 +16,29 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -66,12 +52,9 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/main.go b/main.go index da29a2c..e3099f9 100644 --- a/main.go +++ b/main.go @@ -1,4 +1,37 @@ package main +import ( + "fmt" + + pkg "github.com/cloud-club/Aviator-service/pkg" + types "github.com/cloud-club/Aviator-service/types/server" +) + func main() { + vserver := pkg.NewServerService("b7e6Eq3fmVMGKBCCSLbi", "S6ewbCjNSCk5kQLRDHvqXDGPqTUDwDn2LLhmIKma") + serverNo := test_list(0, vserver) + test_stop(serverNo, vserver) + // fmt.Println("return code of response: %s", response.) + // ssr := types.StopServerRequest{ServerNo: "blabla"} + // vserver.CallApi(pkg.API_URL+pkg.STOP_SERVER_INSTANCE_PATH, ssr) +} + +func test_list(server_index int, vserver *pkg.ServerService) string { // server index for choosing which server to target + gsr := types.ListServerRequest{RegionCode: "KR"} + response, err := vserver.CallApi(pkg.API_URL+pkg.GET_SERVER_INSTANCE_PATH, gsr) + responseStruct := response.(*types.ListServerResponse) + serverNo := responseStruct.ServerInstanceList[server_index].ServerInstanceNo + fmt.Println("Error for listing:", err) + fmt.Println("responsestruct for listing: ", responseStruct) + fmt.Println("serverno: ", serverNo) + + return serverNo +} + +func test_stop(serverNo string, vserver *pkg.ServerService) { // server index for choosing which server to target + ssr := types.StopServerRequest{ServerNo: serverNo} + response, err := vserver.CallApi(pkg.API_URL+pkg.STOP_SERVER_INSTANCE_PATH, ssr) + responseStruct := response.(*types.StopServerResponse) + fmt.Println("Error for stopping: ", err) + fmt.Println("responsestruct for stopping:", responseStruct) } diff --git a/pkg/constant.go b/pkg/constant.go index 72e6a24..58ceb3e 100644 --- a/pkg/constant.go +++ b/pkg/constant.go @@ -1,7 +1,13 @@ package pkg -var API_URL = "https://ncloud.apigw.ntruss.com/vserver/v2/" -var CREATE_SERVER_INSTANCE_PATH = "createServerInstances" -var GET_NETWORKINTERFACE_LIST_PATH = "getNetworkInterfaceList" -var GET_SUBNET_LIST_PATH = "getSubnetList" -var GET_ACG_LIST_PATH = "getAccessControlGroupList" +var ( + API_URL = "https://ncloud.apigw.ntruss.com/vserver/v2/" + GET_SERVER_INSTANCE_PATH = "getServerInstanceList" + CREATE_SERVER_INSTANCE_PATH = "createServerInstances" + UPDATE_SERVER_INSTANCE_PATH = "changeServerInstanceSpec" + STOP_SERVER_INSTANCE_PATH = "stopServerInstances" + TERMINATE_SERVER_INSTANCE_PATH = "terminateServerInstances" + GET_NETWORKINTERFACE_LIST_PATH = "getNetworkInterfaceList" + GET_SUBNET_LIST_PATH = "getSubnetList" + GET_ACG_LIST_PATH = "getAccessControlGroupList" +) diff --git a/pkg/ncp.go b/pkg/ncp.go index b153a40..6bf77ff 100644 --- a/pkg/ncp.go +++ b/pkg/ncp.go @@ -14,8 +14,8 @@ const ( ) type NcpService struct { - token string - Server ServerInterface + token string + // Server ServerInterface Network NetworkInterface Subnet SubnetInterface AccessControlGroup AccessControlGroupInterface diff --git a/pkg/server.go b/pkg/server.go index 05d76ac..2c1a4bc 100644 --- a/pkg/server.go +++ b/pkg/server.go @@ -1,39 +1,31 @@ package pkg import ( - "errors" "fmt" "io" "log" "net/http" - serverType "github.com/cloud-club/Aviator-service/types/server" + types "github.com/cloud-club/Aviator-service/types/server" ) type ServerService struct { - token string + accessKey string + secretKey string } //go:generate mockgen -destination=mocks/mock_server.go -package=mocks github.com/cloud-club/Aviator-service/pkg ServerInterface -type ServerInterface interface { - Get(url string) error - List(url string) error - Create(url string, request *serverType.CreateServerRequest) (*serverType.CreateServerResponse, error) - Update(url string) error - Delete(url string) error +func NewServerService(accessKey, secretKey string) *ServerService { + return &ServerService{accessKey: accessKey, secretKey: secretKey} } -func NewServerService(token string) ServerInterface { - return &ServerService{token: token} +func (server *ServerService) GetToken() (string, string) { + return server.accessKey, server.secretKey } -func (server *ServerService) GetToken() string { - return server.token -} - -func (server *ServerService) Create(url string, request *serverType.CreateServerRequest) (*serverType.CreateServerResponse, error) { +func (server *ServerService) CallApi(url string, request types.RequestInterface) (interface{}, error) { // Set url with query parameters - requestParams := serverType.CreateRequestString(request) + requestParams := request.RequestString() // Create an HTTP request req, err := http.NewRequest(http.MethodGet, url+requestParams, nil) @@ -41,17 +33,18 @@ func (server *ServerService) Create(url string, request *serverType.CreateServer return nil, err } // Set HTTP header for NCP authorization - SetNCPHeader(req, "45x3qDmooHFxwJywHbbK", "xUFTKEw2POsYl5AgBSxf4K2ZJm1JHJ51KHN5BDK8") + SetNCPHeader(req, server.accessKey, server.secretKey) // Make the HTTP request resp, err := http.DefaultClient.Do(req) if err != nil { return nil, err } + // Check the response status - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("unexpected response status: %s", resp.Status) - } + // if resp.StatusCode != http.StatusOK { + // return nil, fmt.Errorf("unexpected response status: %s", resp.Status) + // } responseByteData, err := io.ReadAll(resp.Body) if err != nil { @@ -59,123 +52,24 @@ func (server *ServerService) Create(url string, request *serverType.CreateServer return nil, err } - var csr *serverType.CreateServerResponse - responseInterface, err := serverType.MapResponse(responseByteData, &csr) + fmt.Println("request:", requestParams) + fmt.Println(string(responseByteData)) + + responseStruct, err := request.MapResponse(responseByteData) if err != nil { log.Fatal(err) return nil, err } + // var csr *serverType.CreateServerResponse + // responseInterface, err := serverType.MapResponse(responseByteData, &csr) + // if err != nil { + // log.Fatal(err) + // return nil, err + // } + // interface{} 타입으로 변환된 responseInterface를 다시 CreateServerResponse 타입으로 변환 - responseStruct := responseInterface.(*serverType.CreateServerResponse) + // responseStruct := responseInterface.(*types.CreateServerResponse) return responseStruct, err } - -func (server *ServerService) Get(url string) error { - return nil -} - -func (server *ServerService) List(url string) error { - if len(url) == 0 { - return errors.New("please input url") - } - return nil -} - -func (server *ServerService) Delete(url string) error { - // url 정의 - url += "" - - // httpRequest 생성 - request, err := http.NewRequest(http.MethodGet, url, nil) - if err != nil { - return fmt.Errorf("Error creating request: ", err) - } - /// NCP 헤더 설정 - SetNCPHeader(request, "", "") - - // httpRequest token 설정 - SetAuthToken(request, server.token) - - // HTTP 클라이언트 생성 - client := &http.Client{} - - // 요청 보내기 - response, err := client.Do(request) - if err != nil { - return fmt.Errorf("Error sending request:", err) - } - defer response.Body.Close() - - // 결과 반환 - if response.StatusCode != http.StatusOK { - return fmt.Errorf("Unexpected response status code:", err) - } - - return nil -} - -func (server *ServerService) Stop(url string) error { - // url 정의 - url += "" - - // httpRequest 생성 - request, err := http.NewRequest(http.MethodGet, url, nil) - if err != nil { - return fmt.Errorf("Error creating request: ", err) - } - /// NCP 헤더 설정 - SetNCPHeader(request, "", "") - - // httpRequest token 설정 - SetAuthToken(request, server.token) - - // HTTP 클라이언트 생성 - client := &http.Client{} - - // 요청 보내기 - response, err := client.Do(request) - if err != nil { - return fmt.Errorf("Error sending request:", err) - } - defer response.Body.Close() - - // 결과 반환 - if response.StatusCode != http.StatusOK { - return fmt.Errorf("Unexpected response status code:", err) - } - - return nil -} - -func (server *ServerService) Update(url string) error { - // url += fmt.Sprintf("?regionCode=%s&serverInstanceNo=%s&serverProductCode=%s", updateParams.regionCode, updateParams.serverInstanceNo, updateParams.serverProductCode) - url += "temp" - - // Create an HTTP request - req, err := http.NewRequest(http.MethodGet, url, nil) - if err != nil { - return err - } - - // Set common headers - GetCommonHeader(req) - - // Set authorization token - SetAuthToken(req, server.token) - - // Make the HTTP request - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - // Check the response status - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("unexpected response status: %s", resp.Status) - } - - return nil -} diff --git a/types/server/request.go b/types/server/request.go index f74d96c..5d39d49 100644 --- a/types/server/request.go +++ b/types/server/request.go @@ -1,9 +1,25 @@ package types +import ( + "encoding/xml" + "fmt" + "net/url" + "reflect" + "regexp" + "strings" + "time" + // types "github.com/cloud-club/Aviator-service/types/server" +) + // 필수가 아닌 필드(필수 여부: No)는 주석 처리 해두었음. // 필요할 때 주석 해제 // 필수가 아닌 필드 중 (필수 여부: Conditional)는 주석 처리 안 했음. // 필요할 때 주석 처리 + +type RequestInterface interface { + RequestString() string + MapResponse(responseBody []byte) (interface{}, error) +} type CreateServerRequest struct { //RegionCode string `json:"regionCode"` // ServerImageProductCode 와 MemberServerImageInstanceNo 둘 중 하나는 무조건 필수 기재 @@ -72,8 +88,165 @@ type CreateServerRequest struct { //ResponseFormatType string `json:"responseFormatType"` } -type GetServerRequest struct{} +type GetServerRequest struct { + serverInstanceNo string `json:"serverInstanceNo"` +} + +type ListServerRequest struct { + RegionCode string `json:"regionCode"` +} + +func (ssr ListServerRequest) RequestString() string { + v := url.Values{} + s := reflect.ValueOf(ssr) + + for i := 0; i < s.NumField(); i++ { + field := s.Field(i) + jsonTag := strings.Split(s.Type().Field(i).Tag.Get("json"), ",")[0] + v.Add(jsonTag, fmt.Sprint(field.Interface())) + } + + return "?" + v.Encode() +} + +func processTimestamp(input []byte) (resultReponse []byte) { + regex := regexp.MustCompile(`(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})([+-]\d{4})`) + + // Find all occurrences of timestamps in the input + matches := regex.FindAllSubmatchIndex(input, -1) + + if len(matches) > 0 { + // Create a copy of the original input + modifiedInput := make([]byte, len(input)+len(matches)) + copy(modifiedInput, input) + + for i, match := range matches { + start, end := match[2]-4*i, match[3]-4*i + appendingTS := []byte{90} // represents 'Z' in ascii + originalTS := make([]byte, 19) + copy(originalTS, modifiedInput[start:end][:19]) + timestamp := append(originalTS, appendingTS...) + modifiedInput = append(modifiedInput[:start], append([]byte(timestamp), modifiedInput[end+5:]...)...) + } + return modifiedInput + } else { + fmt.Println("Timestamps not found in the input") + } + return input +} + +func (ssr ListServerRequest) MapResponse(responseBody []byte) (interface{}, error) { + v := &ListServerResponse{} + + responseBody = processTimestamp(responseBody) + err := xml.Unmarshal(responseBody, v) // responseBody를 v로 매핑. 만약 CreateServerResponse 타입이면 CreateServerResponse로 매핑 + if err != nil { + return nil, fmt.Errorf("error unmarshalling response: %v", err) + } + + return v, nil +} + +type StopServerRequest struct { + ServerNo string `json:"serverInstanceNoList.1"` +} + +func (ssr StopServerRequest) MapResponse(responseBody []byte) (interface{}, error) { + v := &StopServerResponse{} + + responseBody = processTimestamp(responseBody) + err := xml.Unmarshal(responseBody, v) // responseBody를 v로 매핑. 만약 CreateServerResponse 타입이면 CreateServerResponse로 매핑 + if err != nil { + return nil, fmt.Errorf("error unmarshalling response: %v", err) + } + + return v, nil +} + +func (ssr StopServerRequest) RequestString() string { + v := url.Values{} + s := reflect.ValueOf(ssr) -type ListServerRequest struct{} + for i := 0; i < s.NumField(); i++ { + field := s.Field(i) + jsonTag := strings.Split(s.Type().Field(i).Tag.Get("json"), ",")[0] + v.Add(jsonTag, fmt.Sprint(field.Interface())) + } -type UpdateServerRequest struct{} + return "?" + v.Encode() +} + +type DeleteServerRequest struct { + VpcNo string `json:"vpcNo"` + SubnetNo string `json:"subnetNo"` + niOrder string `json:"networkInterfaceList.N.networkInterfaceOrder"` + serverImageProductCode string `json:"serverImageProductCode"` + niAccessControlGroupNoList string `json:networkInterfaceList.1.accessControlGroupNoList.1"` +} + +// ServerInstance is same as compute server in Naver Cloud (such as AWS EC2) +// 필수가 아닌 필드(필수 여부: No)는 주석 처리 해두었음. +// 필요할 때 주석 해제 +type ServerInstance struct { + ServerInstanceNo string `xml:"serverInstanceNo" json:"serverInstanceNo"` + ServerName string `xml:"serverName" json:"serverName"` + //ServerDescription string + CpuCount int `xml:"cpuCount" json:"cpuCount"` + MemorySize int64 `xml:"memorySize" json:"memorySize"` + PlatformType CommonCode `xml:"platformType" json:"platformType"` + LoginKeyName string `xml:"loginKeyName" json:"loginKeyName"` + //PublicIpInstanceNo string + //PublicIp string + ServerInstanceStatus CommonCode `xml:"serverInstanceStatus" json:"serverInstanceStatus"` + ServerInstanceOperation CommonCode `xml:"serverInstanceOperation" json:"serverInstanceOperation"` + ServerInstanceStatusName string `xml:"serverInstanceStatusName" json:"serverInstanceStatusName"` + CreateDate time.Time `xml:"createDate" json:"createDate"` + Uptime time.Time `xml:"uptime" json:"uptime"` + ServerImageProductCode string `xml:"serverImageProductCode" json:"serverImageProductCode"` + ServerProductCode string `xml:"serverProductCode" json:"serverProductCode"` + IsProtectServerTermination bool `xml:"isProtectServerTermination" json:"isProtectServerTermination"` + ZoneCode string `xml:"zoneCode" json:"zoneCode"` + RegionCode string `xml:"regionCode" json:"regionCode"` + VpcNo string `xml:"vpcNo" json:"vpcNo"` + SubnetNo string `xml:"subnetNo" json:"subnetNo"` + NetworkInterfaceNoList NetworkInterfaceNoList `xml:"networkInterfaceNoList" json:"networkInterfaceNoList"` + //InitScriptNo string + ServerInstanceType CommonCode `xml:"serverInstanceType" json:"serverInstanceType"` + BaseBlockStorageDiskType CommonCode `xml:"baseBlockStorageDiskType" json:"baseBlockStorageDiskType"` + BaseBlockStorageDiskDetailType CommonCode `xml:"baseBlockStorageDiskDetailType" json:"baseBlockStorageDiskDetailType"` + //PlacementGroupNo string + //PlacementGroupName string + //MemberServerImageInstanceNo string + //BlockDevicePartitionList []BlockDevicePartition // Assuming BlockDevicePartition is a defined struct + HypervisorType CommonCode `xml:"hypervisorType" json:"hypervisorType"` + ServerImageNo string `xml:"serverImageNo" json:"serverImageNo"` + ServerSpecCode string `xml:"serverSpecCode" json:"serverSpecCode"` +} + +type CreateServerResponse struct { + RequestId string `xml:"requestId"` + ReturnCode int `xml:"returnCode"` + ReturnMessage string `xml:"returnMessage"` + TotalRows int `xml:"totalRows"` + ServerInstanceList []ServerInstance `xml:"serverInstanceList>serverInstance"` +} + +type GetServerResponse struct{} + +type ListServerResponse struct { + ReturnCode int `xml:"returnCode"` + ReturnMessage string `xml:"returnMessage"` + TotalRows int `xml:"totalRows"` + ServerInstanceList []ServerInstance `xml:"serverInstanceList>serverInstance"` +} + +type UpdateServerResponse struct{} + +type DeleteServerResponse struct{} + +type StopServerResponse struct { + ReturnCode int `xml:"returnCode"` + ReturnMessage string `xml:"returnMessage"` + TotalRows int `xml:"totalRows"` + ServerInstanceList []ServerInstance `xml:"serverInstanceList>serverInstance"` +} diff --git a/types/server/request_response_func.go b/types/server/request_response_func.go index 4698d26..71e2b2a 100644 --- a/types/server/request_response_func.go +++ b/types/server/request_response_func.go @@ -52,3 +52,16 @@ func MapResponse(responseBody []byte, v interface{}) (interface{}, error) { return v, nil } + +func RequestString(req interface{}) string { + v := url.Values{} + s := reflect.ValueOf(req).Elem() + + for i := 0; i < s.NumField(); i++ { + field := s.Field(i) + jsonTag := strings.Split(s.Type().Field(i).Tag.Get("json"), ",")[0] + v.Add(jsonTag, fmt.Sprint(field.Interface())) + } + + return "?" + v.Encode() +} diff --git a/types/server/response.go b/types/server/response.go index 10f7b68..ab1254f 100644 --- a/types/server/response.go +++ b/types/server/response.go @@ -1,60 +1 @@ package types - -import ( - "time" -) - -// ServerInstance is same as compute server in Naver Cloud (such as AWS EC2) -// 필수가 아닌 필드(필수 여부: No)는 주석 처리 해두었음. -// 필요할 때 주석 해제 -type ServerInstance struct { - ServerInstanceNo string `xml:"serverInstanceNo" json:"serverInstanceNo"` - ServerName string `xml:"serverName" json:"serverName"` - //ServerDescription string - CpuCount int `xml:"cpuCount" json:"cpuCount"` - MemorySize int64 `xml:"memorySize" json:"memorySize"` - PlatformType CommonCode `xml:"platformType" json:"platformType"` - LoginKeyName string `xml:"loginKeyName" json:"loginKeyName"` - //PublicIpInstanceNo string - //PublicIp string - ServerInstanceStatus CommonCode `xml:"serverInstanceStatus" json:"serverInstanceStatus"` - ServerInstanceOperation CommonCode `xml:"serverInstanceOperation" json:"serverInstanceOperation"` - ServerInstanceStatusName string `xml:"serverInstanceStatusName" json:"serverInstanceStatusName"` - CreateDate time.Time `xml:"createDate" json:"createDate"` - Uptime time.Time `xml:"uptime" json:"uptime"` - ServerImageProductCode string `xml:"serverImageProductCode" json:"serverImageProductCode"` - ServerProductCode string `xml:"serverProductCode" json:"serverProductCode"` - IsProtectServerTermination bool `xml:"isProtectServerTermination" json:"isProtectServerTermination"` - ZoneCode string `xml:"zoneCode" json:"zoneCode"` - RegionCode string `xml:"regionCode" json:"regionCode"` - VpcNo string `xml:"vpcNo" json:"vpcNo"` - SubnetNo string `xml:"subnetNo" json:"subnetNo"` - NetworkInterfaceNoList NetworkInterfaceNoList `xml:"networkInterfaceNoList" json:"networkInterfaceNoList"` - //InitScriptNo string - ServerInstanceType CommonCode `xml:"serverInstanceType" json:"serverInstanceType"` - BaseBlockStorageDiskType CommonCode `xml:"baseBlockStorageDiskType" json:"baseBlockStorageDiskType"` - BaseBlockStorageDiskDetailType CommonCode `xml:"baseBlockStorageDiskDetailType" json:"baseBlockStorageDiskDetailType"` - //PlacementGroupNo string - //PlacementGroupName string - //MemberServerImageInstanceNo string - //BlockDevicePartitionList []BlockDevicePartition // Assuming BlockDevicePartition is a defined struct - HypervisorType CommonCode `xml:"hypervisorType" json:"hypervisorType"` - ServerImageNo string `xml:"serverImageNo" json:"serverImageNo"` - ServerSpecCode string `xml:"serverSpecCode" json:"serverSpecCode"` -} - -type CreateServerResponse struct { - RequestId string `xml:"requestId"` - ReturnCode int `xml:"returnCode"` - ReturnMessage string `xml:"returnMessage"` - TotalRows int `xml:"totalRows"` - ServerInstanceList []ServerInstance `xml:"serverInstanceList>serverInstance"` -} - -type GetServerResponse struct{} - -type ListServerResponse struct{} - -type UpdateServerResponse struct{} - -type DeleteServerResponse struct{} From e295fb31a666fe6698f78f0d010a26d56ba1eae6 Mon Sep 17 00:00:00 2001 From: yuridekim Date: Fri, 29 Dec 2023 16:24:25 +0900 Subject: [PATCH 3/5] Implement deletion and updating server --- main.go | 39 ++++++++++++++++--- pkg/constant.go | 2 +- pkg/server.go | 14 ------- types/server/request.go | 83 ++++++++++++++++++++++++++++++++++++----- 4 files changed, 107 insertions(+), 31 deletions(-) diff --git a/main.go b/main.go index e3099f9..7f86d85 100644 --- a/main.go +++ b/main.go @@ -2,18 +2,23 @@ package main import ( "fmt" + "time" pkg "github.com/cloud-club/Aviator-service/pkg" types "github.com/cloud-club/Aviator-service/types/server" ) func main() { - vserver := pkg.NewServerService("b7e6Eq3fmVMGKBCCSLbi", "S6ewbCjNSCk5kQLRDHvqXDGPqTUDwDn2LLhmIKma") + vserver := pkg.NewServerService("access key", "secret key") serverNo := test_list(0, vserver) - test_stop(serverNo, vserver) - // fmt.Println("return code of response: %s", response.) - // ssr := types.StopServerRequest{ServerNo: "blabla"} - // vserver.CallApi(pkg.API_URL+pkg.STOP_SERVER_INSTANCE_PATH, ssr) + + stopReturn := test_stop(serverNo, vserver) + fmt.Println("Is stop successful: ", stopReturn) + + time.Sleep(10) //wait for stop to take place + + deleteReturn := test_delete(serverNo, vserver) + fmt.Println("Is deletion(termination) successful: ", deleteReturn) } func test_list(server_index int, vserver *pkg.ServerService) string { // server index for choosing which server to target @@ -28,10 +33,32 @@ func test_list(server_index int, vserver *pkg.ServerService) string { // server return serverNo } -func test_stop(serverNo string, vserver *pkg.ServerService) { // server index for choosing which server to target +func test_stop(serverNo string, vserver *pkg.ServerService) string { // server index for choosing which server to target ssr := types.StopServerRequest{ServerNo: serverNo} response, err := vserver.CallApi(pkg.API_URL+pkg.STOP_SERVER_INSTANCE_PATH, ssr) responseStruct := response.(*types.StopServerResponse) fmt.Println("Error for stopping: ", err) fmt.Println("responsestruct for stopping:", responseStruct) + + return responseStruct.ReturnMessage +} + +func test_delete(serverNo string, vserver *pkg.ServerService) string { // server index for choosing which server to target + dsr := types.DeleteServerRequest{ServerNo: serverNo} + response, err := vserver.CallApi(pkg.API_URL+pkg.DELETE_SERVER_INSTANCE_PATH, dsr) + responseStruct := response.(*types.DeleteServerResponse) + fmt.Println("Error for stopping: ", err) + fmt.Println("responsestruct for stopping:", responseStruct) + + return responseStruct.ReturnMessage +} + +func test_update(serverNo, serverProductCode string, vserver *pkg.ServerService) string { // server index for choosing which server to target + dsr := types.UpdateServerRequest{ServerInstanceNo: serverNo, ServerProductCode: serverProductCode} + response, err := vserver.CallApi(pkg.API_URL+pkg.UPDATE_SERVER_INSTANCE_PATH, dsr) + responseStruct := response.(*types.UpdateServerResponse) + fmt.Println("Error for stopping: ", err) + fmt.Println("responsestruct for stopping:", responseStruct) + + return responseStruct.ReturnMessage } diff --git a/pkg/constant.go b/pkg/constant.go index 58ceb3e..2e95960 100644 --- a/pkg/constant.go +++ b/pkg/constant.go @@ -6,7 +6,7 @@ var ( CREATE_SERVER_INSTANCE_PATH = "createServerInstances" UPDATE_SERVER_INSTANCE_PATH = "changeServerInstanceSpec" STOP_SERVER_INSTANCE_PATH = "stopServerInstances" - TERMINATE_SERVER_INSTANCE_PATH = "terminateServerInstances" + DELETE_SERVER_INSTANCE_PATH = "terminateServerInstances" GET_NETWORKINTERFACE_LIST_PATH = "getNetworkInterfaceList" GET_SUBNET_LIST_PATH = "getSubnetList" GET_ACG_LIST_PATH = "getAccessControlGroupList" diff --git a/pkg/server.go b/pkg/server.go index 2c1a4bc..10b712c 100644 --- a/pkg/server.go +++ b/pkg/server.go @@ -19,10 +19,6 @@ func NewServerService(accessKey, secretKey string) *ServerService { return &ServerService{accessKey: accessKey, secretKey: secretKey} } -func (server *ServerService) GetToken() (string, string) { - return server.accessKey, server.secretKey -} - func (server *ServerService) CallApi(url string, request types.RequestInterface) (interface{}, error) { // Set url with query parameters requestParams := request.RequestString() @@ -61,15 +57,5 @@ func (server *ServerService) CallApi(url string, request types.RequestInterface) return nil, err } - // var csr *serverType.CreateServerResponse - // responseInterface, err := serverType.MapResponse(responseByteData, &csr) - // if err != nil { - // log.Fatal(err) - // return nil, err - // } - - // interface{} 타입으로 변환된 responseInterface를 다시 CreateServerResponse 타입으로 변환 - // responseStruct := responseInterface.(*types.CreateServerResponse) - return responseStruct, err } diff --git a/types/server/request.go b/types/server/request.go index 5d39d49..68eb27f 100644 --- a/types/server/request.go +++ b/types/server/request.go @@ -139,7 +139,7 @@ func (ssr ListServerRequest) MapResponse(responseBody []byte) (interface{}, erro v := &ListServerResponse{} responseBody = processTimestamp(responseBody) - err := xml.Unmarshal(responseBody, v) // responseBody를 v로 매핑. 만약 CreateServerResponse 타입이면 CreateServerResponse로 매핑 + err := xml.Unmarshal(responseBody, v) if err != nil { return nil, fmt.Errorf("error unmarshalling response: %v", err) } @@ -148,14 +148,14 @@ func (ssr ListServerRequest) MapResponse(responseBody []byte) (interface{}, erro } type StopServerRequest struct { - ServerNo string `json:"serverInstanceNoList.1"` + ServerNo string `json:"serverInstanceNoList.1"` // limiting only to a single server instance } func (ssr StopServerRequest) MapResponse(responseBody []byte) (interface{}, error) { v := &StopServerResponse{} responseBody = processTimestamp(responseBody) - err := xml.Unmarshal(responseBody, v) // responseBody를 v로 매핑. 만약 CreateServerResponse 타입이면 CreateServerResponse로 매핑 + err := xml.Unmarshal(responseBody, v) if err != nil { return nil, fmt.Errorf("error unmarshalling response: %v", err) } @@ -177,11 +177,63 @@ func (ssr StopServerRequest) RequestString() string { } type DeleteServerRequest struct { - VpcNo string `json:"vpcNo"` - SubnetNo string `json:"subnetNo"` - niOrder string `json:"networkInterfaceList.N.networkInterfaceOrder"` - serverImageProductCode string `json:"serverImageProductCode"` - niAccessControlGroupNoList string `json:networkInterfaceList.1.accessControlGroupNoList.1"` + ServerNo string `json:"serverInstanceNoList.1"` // limiting only to a single server instance +} + +func (ssr DeleteServerRequest) MapResponse(responseBody []byte) (interface{}, error) { + v := &DeleteServerResponse{} + + responseBody = processTimestamp(responseBody) + err := xml.Unmarshal(responseBody, v) + if err != nil { + return nil, fmt.Errorf("error unmarshalling response: %v", err) + } + + return v, nil +} + +func (ssr DeleteServerRequest) RequestString() string { + v := url.Values{} + s := reflect.ValueOf(ssr) + + for i := 0; i < s.NumField(); i++ { + field := s.Field(i) + jsonTag := strings.Split(s.Type().Field(i).Tag.Get("json"), ",")[0] + v.Add(jsonTag, fmt.Sprint(field.Interface())) + } + + return "?" + v.Encode() +} + +type UpdateServerRequest struct { + ServerInstanceNo string `json:"serverInstanceNo"` + ServerProductCode string `json:"serverProductCode"` //conditional + // ServerSpecCode string `json:"serverSpecCode"` //conditional +} + +func (ssr UpdateServerRequest) MapResponse(responseBody []byte) (interface{}, error) { + v := &UpdateServerResponse{} + + responseBody = processTimestamp(responseBody) + err := xml.Unmarshal(responseBody, v) + if err != nil { + return nil, fmt.Errorf("error unmarshalling response: %v", err) + } + + return v, nil +} + +func (ssr UpdateServerRequest) RequestString() string { + v := url.Values{} + s := reflect.ValueOf(ssr) + + for i := 0; i < s.NumField(); i++ { + field := s.Field(i) + jsonTag := strings.Split(s.Type().Field(i).Tag.Get("json"), ",")[0] + v.Add(jsonTag, fmt.Sprint(field.Interface())) + } + + return "?" + v.Encode() } // ServerInstance is same as compute server in Naver Cloud (such as AWS EC2) @@ -240,9 +292,20 @@ type ListServerResponse struct { ServerInstanceList []ServerInstance `xml:"serverInstanceList>serverInstance"` } -type UpdateServerResponse struct{} +type UpdateServerResponse struct { + RequestId string `xml:"requestId"` + ReturnCode int `xml:"returnCode"` + ReturnMessage string `xml:"returnMessage"` + TotalRows int `xml:"totalRows"` + ServerInstanceList []ServerInstance `xml:"serverInstanceList>serverInstance"` +} -type DeleteServerResponse struct{} +type DeleteServerResponse struct { + ReturnCode int `xml:"returnCode"` + ReturnMessage string `xml:"returnMessage"` + TotalRows int `xml:"totalRows"` + ServerInstanceList []ServerInstance `xml:"serverInstanceList>serverInstance"` +} type StopServerResponse struct { ReturnCode int `xml:"returnCode"` From 2fc795988bf3e6b73ae673da4f81830025d621cd Mon Sep 17 00:00:00 2001 From: yuridekim Date: Fri, 29 Dec 2023 17:14:39 +0900 Subject: [PATCH 4/5] Add time sleep --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 7f86d85..437661f 100644 --- a/main.go +++ b/main.go @@ -15,7 +15,7 @@ func main() { stopReturn := test_stop(serverNo, vserver) fmt.Println("Is stop successful: ", stopReturn) - time.Sleep(10) //wait for stop to take place + time.Sleep(20 * time.Second) //wait for stop to take place deleteReturn := test_delete(serverNo, vserver) fmt.Println("Is deletion(termination) successful: ", deleteReturn) From 80c0b62004f5a2edd381d105b9706275ee31ccfa Mon Sep 17 00:00:00 2001 From: yuridekim Date: Sun, 31 Dec 2023 15:42:46 +0900 Subject: [PATCH 5/5] Implement Update and getting product code list --- main.go | 22 ++++++++++++++++- pkg/constant.go | 1 + pkg/server.go | 10 ++++---- types/server/request.go | 52 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 77 insertions(+), 8 deletions(-) diff --git a/main.go b/main.go index 437661f..33583c1 100644 --- a/main.go +++ b/main.go @@ -15,7 +15,12 @@ func main() { stopReturn := test_stop(serverNo, vserver) fmt.Println("Is stop successful: ", stopReturn) - time.Sleep(20 * time.Second) //wait for stop to take place + time.Sleep(25 * time.Second) //wait for stop to take place + + productCode := "SVR.VSVR.HICPU.C002.M004.NET.SSD.B050.G002" + updateReturn := test_update(serverNo, productCode, vserver) + fmt.Println("Is update successful: ", updateReturn) + time.Sleep(20 * time.Second) //wait for update to take place deleteReturn := test_delete(serverNo, vserver) fmt.Println("Is deletion(termination) successful: ", deleteReturn) @@ -62,3 +67,18 @@ func test_update(serverNo, serverProductCode string, vserver *pkg.ServerService) return responseStruct.ReturnMessage } + +func test_product(serverImageProductCode string, vserver *pkg.ServerService) []string { + gpr := types.GetProductRequest{ServerImageProductCode: serverImageProductCode} + response, err := vserver.CallApi(pkg.API_URL+pkg.GET_PRODUCT_LIST_PATH, gpr) + responseStruct := response.(*types.GetProductResponse) + + productCodeList := []string{} + for _, product := range responseStruct.ProductList { + productCodeList = append(productCodeList, product.ProductCode) + } + + fmt.Println("Error for getting product list: ", err) + + return productCodeList +} diff --git a/pkg/constant.go b/pkg/constant.go index 2e95960..d4e0584 100644 --- a/pkg/constant.go +++ b/pkg/constant.go @@ -3,6 +3,7 @@ package pkg var ( API_URL = "https://ncloud.apigw.ntruss.com/vserver/v2/" GET_SERVER_INSTANCE_PATH = "getServerInstanceList" + GET_PRODUCT_LIST_PATH = "getServerProductList" CREATE_SERVER_INSTANCE_PATH = "createServerInstances" UPDATE_SERVER_INSTANCE_PATH = "changeServerInstanceSpec" STOP_SERVER_INSTANCE_PATH = "stopServerInstances" diff --git a/pkg/server.go b/pkg/server.go index 10b712c..4aabe7a 100644 --- a/pkg/server.go +++ b/pkg/server.go @@ -38,9 +38,9 @@ func (server *ServerService) CallApi(url string, request types.RequestInterface) } // Check the response status - // if resp.StatusCode != http.StatusOK { - // return nil, fmt.Errorf("unexpected response status: %s", resp.Status) - // } + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("unexpected response status: %s", resp.Status) + } responseByteData, err := io.ReadAll(resp.Body) if err != nil { @@ -48,8 +48,8 @@ func (server *ServerService) CallApi(url string, request types.RequestInterface) return nil, err } - fmt.Println("request:", requestParams) - fmt.Println(string(responseByteData)) + // fmt.Println("request:", requestParams) + // fmt.Println(string(responseByteData)) responseStruct, err := request.MapResponse(responseByteData) if err != nil { diff --git a/types/server/request.go b/types/server/request.go index 68eb27f..61ba2f9 100644 --- a/types/server/request.go +++ b/types/server/request.go @@ -88,8 +88,33 @@ type CreateServerRequest struct { //ResponseFormatType string `json:"responseFormatType"` } -type GetServerRequest struct { - serverInstanceNo string `json:"serverInstanceNo"` +type GetProductRequest struct { + ServerImageProductCode string `json:"serverImageProductCode"` +} + +func (ssr GetProductRequest) RequestString() string { + v := url.Values{} + s := reflect.ValueOf(ssr) + + for i := 0; i < s.NumField(); i++ { + field := s.Field(i) + jsonTag := strings.Split(s.Type().Field(i).Tag.Get("json"), ",")[0] + v.Add(jsonTag, fmt.Sprint(field.Interface())) + } + + return "?" + v.Encode() +} + +func (ssr GetProductRequest) MapResponse(responseBody []byte) (interface{}, error) { + v := &GetProductResponse{} + + responseBody = processTimestamp(responseBody) + err := xml.Unmarshal(responseBody, v) + if err != nil { + return nil, fmt.Errorf("error unmarshalling response: %v", err) + } + + return v, nil } type ListServerRequest struct { @@ -313,3 +338,26 @@ type StopServerResponse struct { TotalRows int `xml:"totalRows"` ServerInstanceList []ServerInstance `xml:"serverInstanceList>serverInstance"` } + +type ProductInstance struct { + ProductCode string `xml:"productCode" json:"productCode"` + ProductName string `xml:"productName" json:"productName"` + ProductType CommonCode `xml:"productType" json:"productType"` + ProductDescription string `xml:"productDescription" json:"productDescription"` + InfraResourceType CommonCode `xml:"infraResourceType" json:"infraResourceType"` + CpuCount string `xml:"cpuCount" json:"cpuCount"` + MemorySize string `xml:"memorySize" json:"memorySize"` + BaseBlockStorageSize string `xml:"baseBlockStorageSize" json:"baseBlockStorageSize"` + OsInformation string `xml:"osInformation" json:"osInformation"` + DiskType CommonCode `xml:"diskType" json:"diskType"` + DbKindCode string `xml:"dbKindCode" json:"dbKindCode"` + AddBlockStorageSize string `xml:"addBlockStorageSize" json:"addBlockStorageSize"` + GenerationCode string `xml:"generationCode" json:"generationCode"` +} +type GetProductResponse struct { + RequestId string `xml:"requestId"` + ReturnCode int `xml:"returnCode"` + ReturnMessage string `xml:"returnMessage"` + TotalRows int `xml:"totalRows"` + ProductList []ProductInstance `xml:"productList>product"` +}