diff --git a/go.mod b/go.mod index 8e08394..b55da16 100644 --- a/go.mod +++ b/go.mod @@ -1,19 +1,17 @@ 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/davecgh/go-spew v1.1.1 // indirect + github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.6.8 github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 - github.com/golang/mock v1.6.0 // indirect + github.com/stretchr/testify v1.8.4 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // 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 0be2f8a..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,42 +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 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= -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= @@ -67,15 +52,13 @@ 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= +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/main.go b/main.go index da29a2c..33583c1 100644 --- a/main.go +++ b/main.go @@ -1,4 +1,84 @@ 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("access key", "secret key") + serverNo := test_list(0, vserver) + + stopReturn := test_stop(serverNo, vserver) + fmt.Println("Is stop successful: ", stopReturn) + + 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) +} + +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) 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 +} + +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 72e6a24..d4e0584 100644 --- a/pkg/constant.go +++ b/pkg/constant.go @@ -1,7 +1,14 @@ 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" + GET_PRODUCT_LIST_PATH = "getServerProductList" + CREATE_SERVER_INSTANCE_PATH = "createServerInstances" + UPDATE_SERVER_INSTANCE_PATH = "changeServerInstanceSpec" + STOP_SERVER_INSTANCE_PATH = "stopServerInstances" + DELETE_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 94f7a7a..4aabe7a 100644 --- a/pkg/server.go +++ b/pkg/server.go @@ -1,39 +1,27 @@ 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 { - 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,13 +29,14 @@ 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) @@ -59,123 +48,14 @@ 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 } - // interface{} 타입으로 변환된 responseInterface를 다시 CreateServerResponse 타입으로 변환 - responseStruct := responseInterface.(*serverType.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..61ba2f9 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,276 @@ type CreateServerRequest struct { //ResponseFormatType string `json:"responseFormatType"` } -type GetServerRequest struct{} +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 { + 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})`) -type ListServerRequest struct{} + // Find all occurrences of timestamps in the input + matches := regex.FindAllSubmatchIndex(input, -1) -type UpdateServerRequest struct{} + 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) + if err != nil { + return nil, fmt.Errorf("error unmarshalling response: %v", err) + } + + return v, nil +} + +type StopServerRequest struct { + 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) + 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) + + 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 DeleteServerRequest struct { + 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) +// 필수가 아닌 필드(필수 여부: 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 { + RequestId string `xml:"requestId"` + ReturnCode int `xml:"returnCode"` + ReturnMessage string `xml:"returnMessage"` + TotalRows int `xml:"totalRows"` + ServerInstanceList []ServerInstance `xml:"serverInstanceList>serverInstance"` +} + +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"` + ReturnMessage string `xml:"returnMessage"` + 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"` +} 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{}