Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8a813abfcb | |||
| e7b30fb686 | |||
| cf11855fa3 | |||
| f111787976 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -3,8 +3,3 @@ cmd/
|
||||
.vscode/
|
||||
.fleet/
|
||||
.DS_Store
|
||||
tests/platform_upgrade/.env
|
||||
tests/platform_upgrade/input.json
|
||||
tests/platform_upgrade/*.txt
|
||||
tests/platform_upgrade/*.log
|
||||
*.env
|
||||
|
||||
67
CHANGELOG.md
67
CHANGELOG.md
@@ -1,64 +1,5 @@
|
||||
## Version 1.15.3
|
||||
## Version 1.6.14
|
||||
|
||||
Методы `Audits` в cloudapi/compute, cloudbroker/compute, cloudapi/account, cloudbroker/account, cloudapi/vins, cloudbroker/vins, cloudapi/rg и cloudbroker/rg стали deprecated и будут удалены в версии 1.16, вместо них необходимо использовать метод `List` в cloudapi/audit и cloudbroker/audit с соответствующими фильтрами
|
||||
Методы `AccessGrant`, `AccessGrantToPool`, `AccessRevoke`, `AccessRevokeToPool` в cloudbroker/sep стали deprecated и будут удалены в версии 1.16
|
||||
Методы `ComputeCISet`, `ComputeCIUnset`, `GetAudits` в cloudbroker/compute и `GetAudits` в cloudapi/compute стали deprecated и будут удалены в версии 1.16
|
||||
Методы `ComputeCISet`, `ComputeCIUnset` в cloudbroker/image стали deprecated и будут удалены в версии 1.16
|
||||
Методы `Delete`, `Disable`, `Enable`, `GetConsumedCloudUnitsByType`, `GetReservedAccountUnits` в cloudapi/account стали deprecated и будут удалены в версии 1.16
|
||||
Методы `Disable`, `Enable` в cloudbroker/account стали deprecated и будут удалены в версии 1.16
|
||||
Метод `IsValidInviteUserToken` в cloudapi/user стал deprecated и будет удален в версии 1.16
|
||||
Метод `GetLog` в cloudbroker/compute стал deprecated и будет удален в версии 1.16
|
||||
Методы `ExecuteMaintenanceScript`, `ListEmails`, `ServicesRestart` в cloudbroker/grid стали deprecated и будут удалены в версии 1.16
|
||||
Метод `Get` в cloudbroker/group стал deprecated и будет удален в версии 1.16
|
||||
|
||||
Все методы группы `.SDN()` находятся в альфа-версии.
|
||||
|
||||
|
||||
### Добавлено
|
||||
|
||||
#### compute
|
||||
| Идентификатор задачи | Описание |
|
||||
| --- | --- |
|
||||
| BGOS-922 | Опциональное поле `EnableDefaultGateway` в структуру запроса `NetAttachRequest` в cloudapi/compute и cloudbroker/compute |
|
||||
| BGOS-922 | Вычисляемое поле `EnableDefaultGateway` в структуру ответа `RecordNetAttach` в cloudapi/compute и cloudbroker/compute |
|
||||
| BGOS-922 | Вычисляемое поле `EnableDefaultGateway` в структуру ответа `ItemInterface` в cloudbroker/compute |
|
||||
| BGOS-922 | Вычисляемое поле `EnableDefaultGateway` в структуру ответа `ItemVNFInterface` в cloudapi/compute |
|
||||
| BGOS-931 | Структура ответа `SnapRecordCompute` в cloudapi/compute |
|
||||
| BGOS-936 | Вычисляемое поле `NodeID` в структуры ответа `RecordCompute` и `ItemCompute` в cloudapi/compute |
|
||||
|
||||
#### disks
|
||||
| Идентификатор задачи | Описание |
|
||||
| --- | --- |
|
||||
| BGOS-924 | Вычисляемое поле `Ready` в структуру ответа `MigrateStatus` в cloudbroker/disks |
|
||||
|
||||
#### grid
|
||||
| Идентификатор задачи | Описание |
|
||||
| --- | --- |
|
||||
| BGOS-926 | Метод `SetResourcesLimit` и структура запроса `SetResourcesLimitRequest` в cloudbroker/grid |
|
||||
|
||||
#### kvmx86
|
||||
| Идентификатор задачи | Описание |
|
||||
| --- | --- |
|
||||
| BGOS-937 | Опциональное поле `EnableDefaultGateway` в структуру `Interface` в cloudapi/kvmx86 и cloudbroker/kvmx86 |
|
||||
| BGOS-937 | Опциональное поле `EnableDefaultGateway` в структуру `InterfaceMassCreate` в cloudbroker/kvmx86 |
|
||||
|
||||
#### node
|
||||
| Идентификатор задачи | Описание |
|
||||
| --- | --- |
|
||||
| BGOS-927 | Вычисляемые поля `ReservedCPU` и `ReservedRAM` в структуры ответа `ItemNode` и `RecordNode` в cloudbroker/node |
|
||||
| BGOS-928 | Метод `SetResourcesLimit` и структура запроса `SetResourcesLimitRequest` в cloudbroker/node |
|
||||
|
||||
#### vins
|
||||
| Идентификатор задачи | Описание |
|
||||
| --- | --- |
|
||||
| BGOS-923 | Опциональное поле `EnableDefaultGateway` в структуры запросов `CreateInAccountRequest` и `CreateInRGRequest` в cloudapi/vins и cloudbroker/vins |
|
||||
| BGOS-923 | Опциональное поле `EnableDefaultGateway` в структуру запроса `UpdateRequest` в cloudbroker/vins |
|
||||
| BGOS-923 | Вычисляемое поле `EnableDefaultGateway` в структуру ответа `RecordVINS` в cloudapi/vins и cloudbroker/vins |
|
||||
| BGOS-923 | Вычисляемое поле `EnableDefaultGateway` в структуру ответа `ItemVINS` в cloudbroker/vins |
|
||||
|
||||
#### zone
|
||||
| Идентификатор задачи | Описание |
|
||||
| --- | --- |
|
||||
| BGOS-929 | Вычисляемые поля `ReservedCPU` и `ReservedRAM` в структуры ответа `RecordZone` и `ItemZone` в cloudapi/zone и в cloudbroker/zone |
|
||||
| BGOS-930 | Метод `SetResourcesLimit` и структура запроса `SetResourcesLimitRequest` в cloudbroker/zone |
|
||||
| BGOS-930 | Метод `UpdateCPUAlignmentProfile` и структура запроса `UpdateCPUAlignmentProfileRequest` в cloudbroker/zone |
|
||||
### Bugfix
|
||||
- Delete tag required from DeleteRequest field Permanently in cloudapi/k8s
|
||||
- Delete tag omitempty from DeleteDisksRequest and DisksDeleteRequest field Permanently in cloudapi/disks and cloudbroker/disks
|
||||
2
LICENSE
2
LICENSE
@@ -186,7 +186,7 @@ APPENDIX: How to apply the Apache License to your work.
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2022 Basis LTD
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
62
README_EN.md
Normal file
62
README_EN.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Decort SDK
|
||||
|
||||
Decort SDK is a library, written in GO (Golang) for interact with the **DECORT** API.
|
||||
The library contents structures and methods for requesting to an user (cloudapi) and admin (cloudbroker) groups of API.
|
||||
Also the library have structures for responses.
|
||||
|
||||
## Contents
|
||||
|
||||
- [Install](#install)
|
||||
- [API List](#api-list)
|
||||
- [Examples](#examples)
|
||||
- [Examples2](#examples2)
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
go get -u repository.basistech.ru/BASIS/decort-golang-sdk
|
||||
```
|
||||
|
||||
## API List
|
||||
|
||||
## Examples
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/config"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/kvmx86"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfg := config.Config{
|
||||
AppID: "<APPID>",
|
||||
AppSecret: "<APPSECRET>",
|
||||
SSOURL: "https://sso.digitalenergy.online",
|
||||
DecortURL: "https://mr4.digitalenergy.online",
|
||||
Retries: 5,
|
||||
}
|
||||
client := decort.New(cfg)
|
||||
req := kvmx86.CreateRequest{
|
||||
RGID: 123,
|
||||
Name: "compute",
|
||||
CPU: 4,
|
||||
RAM: 4096,
|
||||
ImageID: 321,
|
||||
}
|
||||
|
||||
res, err := client.KVMX86().Create(context.Background(), req)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(res)
|
||||
}
|
||||
```
|
||||
|
||||
## Examples2
|
||||
106
check.go
106
check.go
@@ -1,106 +0,0 @@
|
||||
package decortsdk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
)
|
||||
|
||||
type CheckInfo struct {
|
||||
Version string `json:"version"`
|
||||
Build uint64 `json:"build"`
|
||||
}
|
||||
|
||||
const versionURL = "/system/info/version"
|
||||
|
||||
func (de DecortClient) Check() (*CheckInfo, error) {
|
||||
res, err := de.DecortApiCall(context.Background(), http.MethodGet, versionURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := CheckInfo{}
|
||||
|
||||
err = json.Unmarshal([]byte(strings.Replace(strings.Trim(string(res), `"`), "\\", "", -1)), &info)
|
||||
if err != nil {
|
||||
var v string
|
||||
json.Unmarshal([]byte(res), &v)
|
||||
if _, exists := constants.VersionMap[v]; exists {
|
||||
info.Version = v
|
||||
} else {
|
||||
return nil, fmt.Errorf("platform version isn't supported")
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := constants.VersionMap[info.Version]; ok {
|
||||
if v == "-" {
|
||||
return &info, nil
|
||||
}
|
||||
return nil, errors.New(fmt.Sprintf("SDK don't support platform version %s, please use %s SDK version", info.Version, v))
|
||||
}
|
||||
|
||||
return nil, errors.New(fmt.Sprintf("platform version %s isn't supported", info.Version))
|
||||
}
|
||||
|
||||
func (bvs BVSDecortClient) Check() (*CheckInfo, error) {
|
||||
res, err := bvs.DecortApiCall(context.Background(), http.MethodGet, versionURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := CheckInfo{}
|
||||
|
||||
err = json.Unmarshal([]byte(strings.Replace(strings.Trim(string(res), `"`), "\\", "", -1)), &info)
|
||||
if err != nil {
|
||||
var v string
|
||||
json.Unmarshal([]byte(res), &v)
|
||||
if _, exists := constants.VersionMap[v]; exists {
|
||||
info.Version = v
|
||||
} else {
|
||||
return nil, fmt.Errorf("platform version isn't supported")
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := constants.VersionMap[info.Version]; ok {
|
||||
if v == "-" {
|
||||
return &info, nil
|
||||
}
|
||||
return nil, errors.New(fmt.Sprintf("SDK don't support platform version %s, please use %s SDK version", info.Version, v))
|
||||
}
|
||||
|
||||
return nil, errors.New(fmt.Sprintf("platform version %s isn't supported", info.Version))
|
||||
}
|
||||
|
||||
func (ldc LegacyDecortClient) Check() (*CheckInfo, error) {
|
||||
res, err := ldc.DecortApiCall(context.Background(), http.MethodGet, versionURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := CheckInfo{}
|
||||
|
||||
err = json.Unmarshal([]byte(strings.Replace(strings.Trim(string(res), `"`), "\\", "", -1)), &info)
|
||||
if err != nil {
|
||||
var v string
|
||||
json.Unmarshal([]byte(res), &v)
|
||||
if _, exists := constants.VersionMap[v]; exists {
|
||||
info.Version = v
|
||||
} else {
|
||||
return nil, fmt.Errorf("platform version isn't supported")
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := constants.VersionMap[info.Version]; ok {
|
||||
if v == "-" {
|
||||
return &info, nil
|
||||
}
|
||||
return nil, errors.New(fmt.Sprintf("SDK don't support platform version %s, please use %s SDK version", info.Version, v))
|
||||
}
|
||||
|
||||
return nil, errors.New(fmt.Sprintf("platform version %s isn't supported", info.Version))
|
||||
}
|
||||
513
client.go
513
client.go
@@ -4,13 +4,10 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -18,14 +15,13 @@ import (
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/config"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi"
|
||||
k8s_ca "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn"
|
||||
k8s_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s"
|
||||
)
|
||||
|
||||
// DecortClient is HTTP-client for platform
|
||||
// HTTP-client for platform
|
||||
type DecortClient struct {
|
||||
decortURL string
|
||||
client *http.Client
|
||||
@@ -36,14 +32,16 @@ type DecortClient struct {
|
||||
|
||||
// Сlient builder
|
||||
func New(cfg config.Config) *DecortClient {
|
||||
if err := validators.ValidateConfig(cfg); err != nil {
|
||||
panic(validators.ValidationErrors(validators.GetErrors(err)))
|
||||
}
|
||||
|
||||
if cfg.Retries == 0 {
|
||||
cfg.Retries = 5
|
||||
}
|
||||
|
||||
var expiryTime time.Time
|
||||
|
||||
if cfg.Token != "" {
|
||||
expiryTime = time.Now().AddDate(0, 0, 1)
|
||||
}
|
||||
|
||||
return &DecortClient{
|
||||
decortURL: cfg.DecortURL,
|
||||
client: &http.Client{
|
||||
@@ -54,7 +52,8 @@ func New(cfg config.Config) *DecortClient {
|
||||
},
|
||||
},
|
||||
},
|
||||
cfg: trimConfig(&cfg),
|
||||
cfg: cfg,
|
||||
expiryTime: expiryTime,
|
||||
mutex: &sync.Mutex{},
|
||||
}
|
||||
}
|
||||
@@ -69,22 +68,17 @@ func (dc *DecortClient) CloudBroker() *cloudbroker.CloudBroker {
|
||||
return cloudbroker.New(dc)
|
||||
}
|
||||
|
||||
// SDN builder
|
||||
func (dc *DecortClient) SDN() *sdn.SDN {
|
||||
return sdn.New(dc)
|
||||
}
|
||||
|
||||
// DecortApiCall method for sending requests to the platform
|
||||
func (dc *DecortClient) DecortApiCall(ctx context.Context, method, url string, params interface{}) ([]byte, error) {
|
||||
|
||||
k8sCaCreateReq, okCa := params.(k8s_ca.CreateRequest)
|
||||
k8sCbCreateReq, okCb := params.(k8s_cb.CreateRequest)
|
||||
var body *bytes.Buffer
|
||||
var ctype string
|
||||
|
||||
byteSlice, ok := params.([]byte)
|
||||
if ok {
|
||||
body = bytes.NewBuffer(byteSlice)
|
||||
// ctype = "application/x-iso9660-image"
|
||||
ctype = "application/octet-stream"
|
||||
if okCa {
|
||||
body, ctype = createK8sCloudApi(k8sCaCreateReq)
|
||||
} else if okCb {
|
||||
body, ctype = createK8sCloudBroker(k8sCbCreateReq)
|
||||
} else {
|
||||
values, err := query.Values(params)
|
||||
if err != nil {
|
||||
@@ -93,87 +87,18 @@ func (dc *DecortClient) DecortApiCall(ctx context.Context, method, url string, p
|
||||
body = bytes.NewBufferString(values.Encode())
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, dc.decortURL+constants.RESTMACHINE+url, body)
|
||||
req, err := http.NewRequestWithContext(ctx, method, dc.decortURL+"/restmachine"+url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// get token
|
||||
if err = dc.getToken(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// perform request
|
||||
respBytes, err := dc.do(req, ctype)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return respBytes, err
|
||||
}
|
||||
|
||||
// DecortApiCallCtype method for sending requests to the platform with content type
|
||||
func (dc *DecortClient) DecortApiCallCtype(ctx context.Context, method, url, ctype string, params interface{}) ([]byte, error) {
|
||||
|
||||
var body *bytes.Buffer
|
||||
|
||||
switch ctype {
|
||||
case constants.MIMESTREAM:
|
||||
body = bytes.NewBuffer(params.([]byte))
|
||||
case constants.MIMEJSON:
|
||||
jsonBody, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body = bytes.NewBuffer(jsonBody)
|
||||
default:
|
||||
ctype = constants.MIMEPOSTForm
|
||||
values, err := query.Values(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body = bytes.NewBufferString(values.Encode())
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, dc.decortURL+constants.RESTMACHINE+url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// get token
|
||||
if err = dc.getToken(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// perform request
|
||||
respBytes, err := dc.do(req, ctype)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return respBytes, err
|
||||
}
|
||||
|
||||
// DecortApiCallMP method for sending requests to the platform
|
||||
func (dc *DecortClient) DecortApiCallMP(ctx context.Context, method, url string, params interface{}) ([]byte, error) {
|
||||
body, ctype, err := multiPartReq(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, dc.decortURL+constants.RESTMACHINE+url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// get token
|
||||
if err = dc.getToken(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// perform request
|
||||
respBytes, err := dc.do(req, ctype)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var respBytes []byte
|
||||
respBytes, err = dc.do(req, ctype)
|
||||
|
||||
return respBytes, err
|
||||
}
|
||||
@@ -182,12 +107,7 @@ func (dc *DecortClient) getToken(ctx context.Context) error {
|
||||
dc.mutex.Lock()
|
||||
defer dc.mutex.Unlock()
|
||||
|
||||
// new token is not needed
|
||||
if dc.cfg.Token != "" && !time.Now().After(dc.expiryTime) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// set up request headers and body
|
||||
if dc.cfg.Token == "" || time.Now().After(dc.expiryTime) {
|
||||
body := fmt.Sprintf("grant_type=client_credentials&client_id=%s&client_secret=%s&response_type=id_token", dc.cfg.AppID, dc.cfg.AppSecret)
|
||||
bodyReader := strings.NewReader(body)
|
||||
|
||||
@@ -196,44 +116,32 @@ func (dc *DecortClient) getToken(ctx context.Context) error {
|
||||
req, _ := http.NewRequestWithContext(ctx, "POST", dc.cfg.SSOURL+"/v1/oauth/access_token", bodyReader)
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
||||
// request token
|
||||
resp, err := dc.client.Do(req)
|
||||
if err != nil || resp == nil {
|
||||
return fmt.Errorf("cannot get token: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var tokenBytes []byte
|
||||
tokenBytes, err = io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot get token: %w", err)
|
||||
}
|
||||
|
||||
tokenBytes, _ := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return fmt.Errorf("cannot get token: %s", tokenBytes)
|
||||
}
|
||||
|
||||
// save token in config
|
||||
token := string(tokenBytes)
|
||||
expiryTime, err := getTokenExp(token)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot get expiry time: %w", err)
|
||||
}
|
||||
|
||||
dc.cfg.Token = token
|
||||
dc.expiryTime = expiryTime
|
||||
dc.expiryTime = time.Now().AddDate(0, 0, 1)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// do method performs request and returns response as an array of bytes and nil error in case of response status code 200.
|
||||
// In any other cases do returns nil response and error.
|
||||
// Retries are implemented in case of connection reset errors.
|
||||
func (dc *DecortClient) do(req *http.Request, ctype string) ([]byte, error) {
|
||||
// set up request headers and body
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
if ctype != "" {
|
||||
req.Header.Set("Content-Type", ctype)
|
||||
req.Header.Add("Content-Type", ctype)
|
||||
} else {
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
}
|
||||
|
||||
req.Header.Add("Authorization", "bearer "+dc.cfg.Token)
|
||||
@@ -244,55 +152,17 @@ func (dc *DecortClient) do(req *http.Request, ctype string) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Body.Close()
|
||||
req.Body = io.NopCloser(bytes.NewBuffer(buf))
|
||||
|
||||
resp, err := dc.client.Do(req)
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
|
||||
// retries logic GOES HERE
|
||||
// get http response
|
||||
//var resp *http.Response
|
||||
//for i := uint64(0); i < dc.cfg.Retries; i++ {
|
||||
// req := req.Clone(req.Context())
|
||||
// req.Body = io.NopCloser(bytes.NewBuffer(buf))
|
||||
//
|
||||
// if i > 0 {
|
||||
// time.Sleep(5 * time.Second) // no time sleep for the first request
|
||||
// }
|
||||
//
|
||||
// resp, err = dc.client.Do(req)
|
||||
//
|
||||
// // stop retries on success and close response body
|
||||
// if resp != nil {
|
||||
// defer resp.Body.Close()
|
||||
// }
|
||||
// if err == nil {
|
||||
// break
|
||||
// }
|
||||
//
|
||||
// // retries in case of connection errors with time sleep
|
||||
// if isConnectionError(err) {
|
||||
// continue
|
||||
// }
|
||||
//
|
||||
// // return error in case of non-connection error
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
// handle http request errors
|
||||
if err != nil {
|
||||
if err != nil || resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp == nil {
|
||||
return nil, fmt.Errorf("got empty response without error")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// handle successful request
|
||||
respBytes, _ := io.ReadAll(resp.Body)
|
||||
if resp.StatusCode == 200 || resp.StatusCode == 204 {
|
||||
if resp.StatusCode == 200 {
|
||||
return respBytes, nil
|
||||
}
|
||||
|
||||
@@ -301,153 +171,230 @@ func (dc *DecortClient) do(req *http.Request, ctype string) ([]byte, error) {
|
||||
return nil, fmt.Errorf("could not execute request: %w", err)
|
||||
}
|
||||
|
||||
// isConnectionError checks if given error falls within specific and associated connection errors
|
||||
//func isConnectionError(err error) bool {
|
||||
// if strings.Contains(err.Error(), "connection reset by peer") {
|
||||
// return true
|
||||
// }
|
||||
// if errors.Is(err, io.EOF) {
|
||||
// return true
|
||||
// }
|
||||
//
|
||||
// return false
|
||||
//}
|
||||
|
||||
// multiPartReq writes the request structure to the request body, and also returns string of the content-type
|
||||
func multiPartReq(params interface{}) (*bytes.Buffer, string, error) {
|
||||
func createK8sCloudApi(req k8s_ca.CreateRequest) (*bytes.Buffer, string) {
|
||||
reqBody := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(reqBody)
|
||||
values := reflect.ValueOf(params)
|
||||
types := values.Type()
|
||||
defer writer.Close()
|
||||
for i := 0; i < values.NumField(); i++ {
|
||||
if !values.Field(i).IsValid() {
|
||||
continue
|
||||
if req.OidcCertificate != "" {
|
||||
part, _ := writer.CreateFormFile("oidcCertificate", "ca.crt")
|
||||
_, _ = io.Copy(part, strings.NewReader(req.OidcCertificate))
|
||||
}
|
||||
|
||||
if values.Field(i).IsZero() {
|
||||
continue
|
||||
_ = writer.WriteField("name", req.Name)
|
||||
_ = writer.WriteField("rgId", strconv.FormatUint(req.RGID, 10))
|
||||
_ = writer.WriteField("k8ciId", strconv.FormatUint(req.K8SCIID, 10))
|
||||
_ = writer.WriteField("workerGroupName", req.WorkerGroupName)
|
||||
_ = writer.WriteField("networkPlugin", req.NetworkPlugin)
|
||||
|
||||
if req.MasterSEPID != 0 {
|
||||
_ = writer.WriteField("masterSepId", strconv.FormatUint(req.MasterSEPID, 10))
|
||||
}
|
||||
if req.MasterSEPPool != "" {
|
||||
_ = writer.WriteField("masterSepPool", req.MasterSEPPool)
|
||||
}
|
||||
if req.WorkerSEPID != 0 {
|
||||
_ = writer.WriteField("workerSepId", strconv.FormatUint(req.WorkerSEPID, 10))
|
||||
}
|
||||
if req.WorkerSEPPool != "" {
|
||||
_ = writer.WriteField("workerSepPool", req.WorkerSEPPool)
|
||||
}
|
||||
|
||||
if file, ok := constants.FileName[types.Field(i).Name]; ok {
|
||||
part, err := writer.CreateFormFile(trimString(types.Field(i)), file)
|
||||
if err != nil {
|
||||
return &bytes.Buffer{}, "", err
|
||||
if req.Labels != nil {
|
||||
for _, v := range req.Labels {
|
||||
_ = writer.WriteField("labels", v)
|
||||
}
|
||||
_, err = io.Copy(part, strings.NewReader(valueToString(values.Field(i).Interface())))
|
||||
if err != nil {
|
||||
return &bytes.Buffer{}, "", err
|
||||
}
|
||||
continue
|
||||
if req.Taints != nil {
|
||||
for _, v := range req.Taints {
|
||||
_ = writer.WriteField("taints", v)
|
||||
}
|
||||
}
|
||||
if req.Annotations != nil {
|
||||
for _, v := range req.Annotations {
|
||||
_ = writer.WriteField("annotations", v)
|
||||
}
|
||||
}
|
||||
|
||||
if values.Field(i).Type().Kind() == reflect.Slice {
|
||||
switch slice := values.Field(i).Interface().(type) {
|
||||
case []string:
|
||||
if validators.IsInSlice(trimString(types.Field(i)), constants.K8sValues) {
|
||||
code, err := json.Marshal(slice)
|
||||
if err != nil {
|
||||
return &bytes.Buffer{}, "", err
|
||||
if req.MasterCPU != 0 {
|
||||
_ = writer.WriteField("masterCpu", strconv.FormatUint(uint64(req.MasterCPU), 10))
|
||||
}
|
||||
err = writer.WriteField(trimString(types.Field(i)), string(code))
|
||||
if err != nil {
|
||||
return &bytes.Buffer{}, "", err
|
||||
if req.MasterNum != 0 {
|
||||
_ = writer.WriteField("masterNum", strconv.FormatUint(uint64(req.MasterNum), 10))
|
||||
}
|
||||
} else {
|
||||
for _, val := range slice {
|
||||
err := writer.WriteField(trimString(types.Field(i)), val)
|
||||
if err != nil {
|
||||
return &bytes.Buffer{}, "", err
|
||||
if req.MasterRAM != 0 {
|
||||
_ = writer.WriteField("masterRam", strconv.FormatUint(uint64(req.MasterRAM), 10))
|
||||
}
|
||||
if req.MasterDisk != 0 {
|
||||
_ = writer.WriteField("masterDisk", strconv.FormatUint(uint64(req.MasterDisk), 10))
|
||||
}
|
||||
if req.WorkerCPU != 0 {
|
||||
_ = writer.WriteField("workerCpu", strconv.FormatUint(uint64(req.WorkerCPU), 10))
|
||||
}
|
||||
case []uint:
|
||||
for _, val := range slice {
|
||||
err := writer.WriteField(trimString(types.Field(i)), strconv.FormatUint(uint64(val), 10))
|
||||
if err != nil {
|
||||
return &bytes.Buffer{}, "", err
|
||||
if req.WorkerNum != 0 {
|
||||
_ = writer.WriteField("workerNum", strconv.FormatUint(uint64(req.WorkerNum), 10))
|
||||
}
|
||||
if req.WorkerRAM != 0 {
|
||||
_ = writer.WriteField("workerRam", strconv.FormatUint(uint64(req.WorkerRAM), 10))
|
||||
}
|
||||
case []uint64:
|
||||
for _, val := range slice {
|
||||
err := writer.WriteField(trimString(types.Field(i)), strconv.FormatUint(val, 10))
|
||||
if err != nil {
|
||||
return &bytes.Buffer{}, "", err
|
||||
if req.WorkerDisk != 0 {
|
||||
_ = writer.WriteField("workerDisk", strconv.FormatUint(uint64(req.WorkerDisk), 10))
|
||||
}
|
||||
if req.ExtNetID != 0 {
|
||||
_ = writer.WriteField("extnetId", strconv.FormatUint(req.ExtNetID, 10))
|
||||
}
|
||||
case []map[string]interface{}:
|
||||
for _, val := range slice {
|
||||
encodeStr, err := json.Marshal(val)
|
||||
if err != nil {
|
||||
return &bytes.Buffer{}, "", err
|
||||
if req.VinsId != 0 {
|
||||
_ = writer.WriteField("vinsId", strconv.FormatUint(req.VinsId, 10))
|
||||
}
|
||||
err = writer.WriteField(trimString(types.Field(i)), string(encodeStr))
|
||||
if err != nil {
|
||||
return &bytes.Buffer{}, "", err
|
||||
}
|
||||
}
|
||||
default:
|
||||
return &bytes.Buffer{}, "", fmt.Errorf("unsupported slice type:%T", slice)
|
||||
}
|
||||
continue
|
||||
if !req.WithLB {
|
||||
_ = writer.WriteField("withLB", strconv.FormatBool(req.WithLB))
|
||||
}
|
||||
|
||||
err := writer.WriteField(trimString(types.Field(i)), valueToString(values.Field(i).Interface()))
|
||||
if err != nil {
|
||||
return &bytes.Buffer{}, "", err
|
||||
_ = writer.WriteField("highlyAvailableLB", strconv.FormatBool(req.HighlyAvailable))
|
||||
|
||||
if req.AdditionalSANs != nil {
|
||||
for _, v := range req.AdditionalSANs {
|
||||
_ = writer.WriteField("additionalSANs", v)
|
||||
}
|
||||
}
|
||||
if req.InitConfiguration != "" {
|
||||
_ = writer.WriteField("initConfiguration", req.InitConfiguration)
|
||||
}
|
||||
if req.ClusterConfiguration != "" {
|
||||
_ = writer.WriteField("clusterConfiguration", req.ClusterConfiguration)
|
||||
}
|
||||
if req.KubeletConfiguration != "" {
|
||||
_ = writer.WriteField("kubeletConfiguration", req.KubeletConfiguration)
|
||||
}
|
||||
if req.KubeProxyConfiguration != "" {
|
||||
_ = writer.WriteField("kubeProxyConfiguration", req.KubeProxyConfiguration)
|
||||
}
|
||||
if req.JoinConfiguration != "" {
|
||||
_ = writer.WriteField("joinConfiguration", req.JoinConfiguration)
|
||||
}
|
||||
if req.Description != "" {
|
||||
_ = writer.WriteField("desc", req.Description)
|
||||
}
|
||||
if req.UserData != "" {
|
||||
_ = writer.WriteField("userData", req.UserData)
|
||||
}
|
||||
|
||||
_ = writer.WriteField("extnetOnly", strconv.FormatBool(req.ExtNetOnly))
|
||||
|
||||
ct := writer.FormDataContentType()
|
||||
return reqBody, ct, nil
|
||||
writer.Close()
|
||||
|
||||
return reqBody, ct
|
||||
}
|
||||
|
||||
func valueToString(a any) string {
|
||||
switch str := a.(type) {
|
||||
case string:
|
||||
return str
|
||||
case uint:
|
||||
return strconv.FormatUint(uint64(str), 10)
|
||||
case uint64:
|
||||
return strconv.FormatUint(str, 10)
|
||||
case bool:
|
||||
return strconv.FormatBool(str)
|
||||
default:
|
||||
return ""
|
||||
func createK8sCloudBroker(req k8s_cb.CreateRequest) (*bytes.Buffer, string) {
|
||||
reqBody := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(reqBody)
|
||||
if req.OidcCertificate != "" {
|
||||
part, _ := writer.CreateFormFile("oidcCertificate", "ca.crt")
|
||||
_, _ = io.Copy(part, strings.NewReader(req.OidcCertificate))
|
||||
}
|
||||
}
|
||||
|
||||
func trimString(el reflect.StructField) string {
|
||||
return strings.TrimSuffix(el.Tag.Get("url"), ",omitempty")
|
||||
}
|
||||
|
||||
func trimConfig(cfg *config.Config) config.Config {
|
||||
cfg.SSOURL = strings.TrimSuffix(cfg.SSOURL, "/")
|
||||
cfg.DecortURL = strings.TrimSuffix(cfg.DecortURL, "/")
|
||||
return *cfg
|
||||
}
|
||||
|
||||
func getTokenExp(token string) (time.Time, error) {
|
||||
parts := strings.Split(token, ".")
|
||||
if len(parts) != 3 {
|
||||
return time.Time{}, fmt.Errorf("invalid token format")
|
||||
}
|
||||
|
||||
payload, err := base64.RawURLEncoding.DecodeString(parts[1])
|
||||
if err != nil {
|
||||
return time.Time{}, fmt.Errorf("error decode payload from token: %w", err)
|
||||
}
|
||||
|
||||
var claims map[string]interface{}
|
||||
if err := json.Unmarshal(payload, &claims); err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
|
||||
exp, ok := claims["exp"]
|
||||
if !ok {
|
||||
return time.Time{}, fmt.Errorf("exp time bot found")
|
||||
}
|
||||
|
||||
expTime := time.Unix(int64(exp.(float64)), 0)
|
||||
|
||||
return expTime, nil
|
||||
|
||||
_ = writer.WriteField("name", req.Name)
|
||||
_ = writer.WriteField("rgId", strconv.FormatUint(req.RGID, 10))
|
||||
_ = writer.WriteField("k8ciId", strconv.FormatUint(req.K8CIID, 10))
|
||||
_ = writer.WriteField("workerGroupName", req.WorkerGroupName)
|
||||
_ = writer.WriteField("networkPlugin", req.NetworkPlugin)
|
||||
|
||||
if req.MasterSEPID != 0 {
|
||||
_ = writer.WriteField("masterSepId", strconv.FormatUint(req.MasterSEPID, 10))
|
||||
}
|
||||
if req.MasterSEPPool != "" {
|
||||
_ = writer.WriteField("masterSepPool", req.MasterSEPPool)
|
||||
}
|
||||
if req.WorkerSEPID != 0 {
|
||||
_ = writer.WriteField("workerSepId", strconv.FormatUint(req.WorkerSEPID, 10))
|
||||
}
|
||||
if req.WorkerSEPPool != "" {
|
||||
_ = writer.WriteField("workerSepPool", req.WorkerSEPPool)
|
||||
}
|
||||
|
||||
if req.Labels != nil {
|
||||
for _, v := range req.Labels {
|
||||
_ = writer.WriteField("labels", v)
|
||||
}
|
||||
}
|
||||
if req.Taints != nil {
|
||||
for _, v := range req.Taints {
|
||||
_ = writer.WriteField("taints", v)
|
||||
}
|
||||
}
|
||||
if req.Annotations != nil {
|
||||
for _, v := range req.Annotations {
|
||||
_ = writer.WriteField("annotations", v)
|
||||
}
|
||||
}
|
||||
|
||||
if req.MasterCPU != 0 {
|
||||
_ = writer.WriteField("masterCpu", strconv.FormatUint(req.MasterCPU, 10))
|
||||
}
|
||||
if req.MasterNum != 0 {
|
||||
_ = writer.WriteField("masterNum", strconv.FormatUint(req.MasterNum, 10))
|
||||
}
|
||||
if req.MasterRAM != 0 {
|
||||
_ = writer.WriteField("masterRam", strconv.FormatUint(req.MasterRAM, 10))
|
||||
}
|
||||
if req.MasterDisk != 0 {
|
||||
_ = writer.WriteField("masterDisk", strconv.FormatUint(req.MasterDisk, 10))
|
||||
}
|
||||
if req.WorkerCPU != 0 {
|
||||
_ = writer.WriteField("workerCpu", strconv.FormatUint(req.WorkerCPU, 10))
|
||||
}
|
||||
if req.WorkerNum != 0 {
|
||||
_ = writer.WriteField("workerNum", strconv.FormatUint(req.WorkerNum, 10))
|
||||
}
|
||||
if req.WorkerRAM != 0 {
|
||||
_ = writer.WriteField("workerRam", strconv.FormatUint(req.WorkerRAM, 10))
|
||||
}
|
||||
if req.WorkerDisk != 0 {
|
||||
_ = writer.WriteField("workerDisk", strconv.FormatUint(req.WorkerDisk, 10))
|
||||
}
|
||||
if req.ExtNetID != 0 {
|
||||
_ = writer.WriteField("extnetId", strconv.FormatUint(req.ExtNetID, 10))
|
||||
}
|
||||
if req.VinsId != 0 {
|
||||
_ = writer.WriteField("vinsId", strconv.FormatUint(req.VinsId, 10))
|
||||
}
|
||||
if !req.WithLB {
|
||||
_ = writer.WriteField("withLB", strconv.FormatBool(req.WithLB))
|
||||
}
|
||||
|
||||
_ = writer.WriteField("highlyAvailableLB", strconv.FormatBool(req.HighlyAvailable))
|
||||
|
||||
if req.AdditionalSANs != nil {
|
||||
for _, v := range req.AdditionalSANs {
|
||||
_ = writer.WriteField("additionalSANs", v)
|
||||
}
|
||||
}
|
||||
if req.InitConfiguration != "" {
|
||||
_ = writer.WriteField("initConfiguration", req.InitConfiguration)
|
||||
}
|
||||
if req.ClusterConfiguration != "" {
|
||||
_ = writer.WriteField("clusterConfiguration", req.ClusterConfiguration)
|
||||
}
|
||||
if req.KubeletConfiguration != "" {
|
||||
_ = writer.WriteField("kubeletConfiguration", req.KubeletConfiguration)
|
||||
}
|
||||
if req.KubeProxyConfiguration != "" {
|
||||
_ = writer.WriteField("kubeProxyConfiguration", req.KubeProxyConfiguration)
|
||||
}
|
||||
if req.JoinConfiguration != "" {
|
||||
_ = writer.WriteField("joinConfiguration", req.JoinConfiguration)
|
||||
}
|
||||
if req.Description != "" {
|
||||
_ = writer.WriteField("desc", req.Description)
|
||||
}
|
||||
if req.UserData != "" {
|
||||
_ = writer.WriteField("userData", req.UserData)
|
||||
}
|
||||
|
||||
_ = writer.WriteField("extnetOnly", strconv.FormatBool(req.ExtNetOnly))
|
||||
|
||||
ct := writer.FormDataContentType()
|
||||
|
||||
writer.Close()
|
||||
return reqBody, ct
|
||||
}
|
||||
|
||||
472
client_bvs.go
472
client_bvs.go
@@ -1,472 +0,0 @@
|
||||
package decortsdk
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/config"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn"
|
||||
)
|
||||
|
||||
// BVSDecortClient is HTTP-client for platform
|
||||
type BVSDecortClient struct {
|
||||
client *http.Client
|
||||
cfg config.BVSConfig
|
||||
mutex *sync.Mutex
|
||||
decortURL string
|
||||
}
|
||||
|
||||
type tokenJSON struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
TokenType string `json:"token_type"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
ExpiresIn uint64 `json:"expires_in"`
|
||||
}
|
||||
|
||||
// Сlient builder
|
||||
func NewBVS(cfg config.BVSConfig) *BVSDecortClient {
|
||||
if err := validators.ValidateConfig(cfg); err != nil {
|
||||
panic(validators.ValidationErrors(validators.GetErrors(err)))
|
||||
}
|
||||
|
||||
if cfg.Retries == 0 {
|
||||
cfg.Retries = 5
|
||||
}
|
||||
if cfg.TimeToRefresh == 0 {
|
||||
cfg.TimeToRefresh = 1
|
||||
}
|
||||
|
||||
return &BVSDecortClient{
|
||||
decortURL: cfg.DecortURL,
|
||||
client: &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
//nolint:gosec
|
||||
InsecureSkipVerify: cfg.SSLSkipVerify,
|
||||
},
|
||||
},
|
||||
},
|
||||
cfg: trimBVSConfig(&cfg),
|
||||
mutex: &sync.Mutex{},
|
||||
}
|
||||
}
|
||||
|
||||
// CloudAPI builder
|
||||
func (bdc *BVSDecortClient) CloudAPI() *cloudapi.CloudAPI {
|
||||
return cloudapi.New(bdc)
|
||||
}
|
||||
|
||||
// CloudBroker builder
|
||||
func (bdc *BVSDecortClient) CloudBroker() *cloudbroker.CloudBroker {
|
||||
return cloudbroker.New(bdc)
|
||||
}
|
||||
|
||||
// SDN builder
|
||||
func (bdc *BVSDecortClient) SDN() *sdn.SDN {
|
||||
return sdn.New(bdc)
|
||||
}
|
||||
|
||||
// DecortApiCall method for sending requests to the platform
|
||||
func (bdc *BVSDecortClient) DecortApiCall(ctx context.Context, method, url string, params interface{}) ([]byte, error) {
|
||||
var body *bytes.Buffer
|
||||
var ctype string
|
||||
|
||||
byteSlice, ok := params.([]byte)
|
||||
if ok {
|
||||
body = bytes.NewBuffer(byteSlice)
|
||||
// ctype = "application/x-iso9660-image"
|
||||
ctype = "application/octet-stream"
|
||||
} else {
|
||||
values, err := query.Values(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body = bytes.NewBufferString(values.Encode())
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, bdc.decortURL+constants.RESTMACHINE+url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// get token
|
||||
if bdc.cfg.Token.AccessToken == "" {
|
||||
if _, err = bdc.GetToken(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// refresh token
|
||||
if bdc.cfg.Token.RefreshToken != "" && bdc.cfg.Token.Expiry.Add(-time.Duration(bdc.cfg.TimeToRefresh)*time.Minute).Before(time.Now()) {
|
||||
if _, err := bdc.RefreshToken(ctx); err != nil {
|
||||
if _, err = bdc.GetToken(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// perform request
|
||||
reqCopy := req.Clone(ctx)
|
||||
respBytes, err := bdc.do(req, ctype)
|
||||
if err == nil {
|
||||
return respBytes, nil
|
||||
}
|
||||
|
||||
// get token and retry in case of access denied
|
||||
if err.Error() == "access is denied" {
|
||||
_, err = bdc.GetToken(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
respBytes, err = bdc.do(reqCopy, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return respBytes, err
|
||||
}
|
||||
|
||||
// DecortApiCallCtype method for sending requests to the platform with content type
|
||||
func (bdc *BVSDecortClient) DecortApiCallCtype(ctx context.Context, method, url, ctype string, params interface{}) ([]byte, error) {
|
||||
var body *bytes.Buffer
|
||||
|
||||
switch ctype {
|
||||
case constants.MIMESTREAM:
|
||||
body = bytes.NewBuffer(params.([]byte))
|
||||
case constants.MIMEJSON:
|
||||
jsonBody, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body = bytes.NewBuffer(jsonBody)
|
||||
default:
|
||||
ctype = constants.MIMEPOSTForm
|
||||
values, err := query.Values(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body = bytes.NewBufferString(values.Encode())
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, bdc.decortURL+constants.RESTMACHINE+url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// get token
|
||||
if bdc.cfg.Token.AccessToken == "" {
|
||||
if _, err = bdc.GetToken(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// refresh token
|
||||
if bdc.cfg.Token.RefreshToken != "" && bdc.cfg.Token.Expiry.Add(-time.Duration(bdc.cfg.TimeToRefresh)*time.Minute).Before(time.Now()) {
|
||||
if _, err := bdc.RefreshToken(ctx); err != nil {
|
||||
if _, err = bdc.GetToken(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// perform request
|
||||
reqCopy := req.Clone(ctx)
|
||||
respBytes, err := bdc.do(req, ctype)
|
||||
if err == nil {
|
||||
return respBytes, nil
|
||||
}
|
||||
|
||||
// get token and retry in case of access denied
|
||||
if err.Error() == "access is denied" {
|
||||
_, err = bdc.GetToken(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
respBytes, err = bdc.do(reqCopy, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return respBytes, err
|
||||
}
|
||||
|
||||
func (bdc *BVSDecortClient) DecortApiCallMP(ctx context.Context, method, url string, params interface{}) ([]byte, error) {
|
||||
body, ctype, err := multiPartReq(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, bdc.decortURL+constants.RESTMACHINE+url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// get token
|
||||
if bdc.cfg.Token.AccessToken == "" {
|
||||
if _, err = bdc.GetToken(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// refresh token
|
||||
if bdc.cfg.Token.RefreshToken != "" && bdc.cfg.Token.Expiry.Add(-time.Duration(bdc.cfg.TimeToRefresh)*time.Minute).Before(time.Now()) {
|
||||
if _, err := bdc.RefreshToken(ctx); err != nil {
|
||||
if _, err = bdc.GetToken(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// perform request
|
||||
reqCopy := req.Clone(ctx)
|
||||
respBytes, err := bdc.do(req, ctype)
|
||||
if err == nil {
|
||||
return respBytes, nil
|
||||
}
|
||||
|
||||
// get token and retry in case of access denied
|
||||
if err.Error() == "access is denied" {
|
||||
_, err = bdc.GetToken(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
respBytes, err = bdc.do(reqCopy, ctype)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return respBytes, err
|
||||
}
|
||||
|
||||
// GetToken allows you to get a token and returns the token structure. When specifying the PathCfg variable,
|
||||
// the token and configuration will be written to a file.
|
||||
// When specifying the PathToken variable, the token will be written to a file.
|
||||
func (bdc *BVSDecortClient) GetToken(ctx context.Context) (config.Token, error) {
|
||||
bdc.mutex.Lock()
|
||||
defer bdc.mutex.Unlock()
|
||||
|
||||
// set up request headers and body
|
||||
body := fmt.Sprintf("grant_type=password&client_id=%s&client_secret=%s&username=%s&password=%s&response_type=token&scope=openid", bdc.cfg.AppID, bdc.cfg.AppSecret, bdc.cfg.Username, bdc.cfg.Password)
|
||||
bodyReader := strings.NewReader(body)
|
||||
|
||||
bdc.cfg.SSOURL = strings.TrimSuffix(bdc.cfg.SSOURL, "/")
|
||||
|
||||
req, _ := http.NewRequestWithContext(ctx, "POST", bdc.cfg.SSOURL+"/realms/"+bdc.cfg.Domain+"/protocol/openid-connect/token", bodyReader)
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
||||
// request token
|
||||
resp, err := bdc.client.Do(req)
|
||||
if err != nil || resp == nil {
|
||||
return config.Token{}, fmt.Errorf("cannot get token: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var tokenBytes []byte
|
||||
tokenBytes, err = io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return config.Token{}, fmt.Errorf("cannot get token: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return config.Token{}, fmt.Errorf("cannot get token: %s", tokenBytes)
|
||||
}
|
||||
|
||||
// save token in config
|
||||
var tj tokenJSON
|
||||
if err = json.Unmarshal(tokenBytes, &tj); err != nil {
|
||||
return config.Token{}, fmt.Errorf("cannot unmarshal token: %w", err)
|
||||
}
|
||||
|
||||
bdc.cfg.Token = config.Token{
|
||||
AccessToken: tj.AccessToken,
|
||||
TokenType: tj.TokenType,
|
||||
RefreshToken: tj.RefreshToken,
|
||||
Expiry: tj.expiry(),
|
||||
}
|
||||
|
||||
if bdc.cfg.PathCfg != "" {
|
||||
ser, _ := bdc.cfg.Serialize("", " ")
|
||||
_ = ser.WriteToFile(bdc.cfg.PathCfg)
|
||||
}
|
||||
|
||||
if bdc.cfg.PathToken != "" {
|
||||
ser, _ := bdc.cfg.Token.Serialize("", " ")
|
||||
_ = ser.WriteToFile(bdc.cfg.PathToken)
|
||||
}
|
||||
|
||||
return bdc.cfg.Token, nil
|
||||
}
|
||||
|
||||
// RefreshToken allows you to refresh a token and returns the token structure. When specifying the PathCfg variable,
|
||||
// the token and configuration will be written to a file.
|
||||
// When specifying the PathToken variable, the token will be written to a file
|
||||
func (bdc *BVSDecortClient) RefreshToken(ctx context.Context) (config.Token, error) {
|
||||
bdc.mutex.Lock()
|
||||
defer bdc.mutex.Unlock()
|
||||
|
||||
// set up request headers and body
|
||||
body := fmt.Sprintf("grant_type=refresh_token&client_id=%s&client_secret=%s&refresh_token=%s&scope=openid", bdc.cfg.AppID, bdc.cfg.AppSecret, bdc.cfg.Token.RefreshToken)
|
||||
bodyReader := strings.NewReader(body)
|
||||
|
||||
bdc.cfg.SSOURL = strings.TrimSuffix(bdc.cfg.SSOURL, "/")
|
||||
|
||||
req, _ := http.NewRequestWithContext(ctx, "POST", bdc.cfg.SSOURL+"/realms/"+bdc.cfg.Domain+"/protocol/openid-connect/token", bodyReader)
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
||||
// refresh token
|
||||
resp, err := bdc.client.Do(req)
|
||||
if err != nil || resp == nil {
|
||||
return config.Token{}, fmt.Errorf("cannot refresh token: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var tokenBytes []byte
|
||||
tokenBytes, err = io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return config.Token{}, fmt.Errorf("cannot refresh token: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return config.Token{}, fmt.Errorf("cannot refresh token: %s", tokenBytes)
|
||||
}
|
||||
|
||||
// save token in config
|
||||
var tj tokenJSON
|
||||
if err = json.Unmarshal(tokenBytes, &tj); err != nil {
|
||||
return config.Token{}, fmt.Errorf("cannot unmarshal after refresh token: %w", err)
|
||||
}
|
||||
|
||||
bdc.cfg.Token = config.Token{
|
||||
AccessToken: tj.AccessToken,
|
||||
TokenType: tj.TokenType,
|
||||
RefreshToken: tj.RefreshToken,
|
||||
Expiry: tj.expiry(),
|
||||
}
|
||||
|
||||
if bdc.cfg.PathCfg != "" {
|
||||
ser, _ := bdc.cfg.Serialize("", " ")
|
||||
_ = ser.WriteToFile(bdc.cfg.PathCfg)
|
||||
}
|
||||
|
||||
if bdc.cfg.PathToken != "" {
|
||||
ser, _ := bdc.cfg.Token.Serialize("", " ")
|
||||
_ = ser.WriteToFile(bdc.cfg.PathToken)
|
||||
}
|
||||
|
||||
return bdc.cfg.Token, nil
|
||||
}
|
||||
|
||||
func (e *tokenJSON) expiry() (t time.Time) {
|
||||
if v := e.ExpiresIn; v != 0 {
|
||||
return time.Now().Add(time.Duration(v) * time.Second)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// do method performs request and returns response as an array of bytes and nil error in case of response status code 200.
|
||||
// In any other cases do returns nil response and error.
|
||||
// Retries are implemented in case of connection reset errors.
|
||||
func (bdc *BVSDecortClient) do(req *http.Request, ctype string) ([]byte, error) {
|
||||
// set up request headers and body
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
if ctype != "" {
|
||||
req.Header.Set("Content-Type", ctype)
|
||||
}
|
||||
|
||||
req.Header.Add("Authorization", "bearer "+bdc.cfg.Token.AccessToken)
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
buf, err := io.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Body.Close()
|
||||
req.Body = io.NopCloser(bytes.NewBuffer(buf))
|
||||
|
||||
resp, err := bdc.client.Do(req)
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
|
||||
// retries logic GOES HERE
|
||||
// get http response
|
||||
//var resp *http.Response
|
||||
//for i := uint64(0); i < bdc.cfg.Retries; i++ {
|
||||
// req := req.Clone(req.Context())
|
||||
// req.Body = io.NopCloser(bytes.NewBuffer(buf))
|
||||
//
|
||||
// if i > 0 {
|
||||
// time.Sleep(5 * time.Second) // no time sleep for the first request
|
||||
// }
|
||||
//
|
||||
// resp, err = bdc.client.Do(req)
|
||||
//
|
||||
// // stop retries on success and close response body
|
||||
// if resp != nil {
|
||||
// defer resp.Body.Close()
|
||||
// }
|
||||
// if err == nil {
|
||||
// break
|
||||
// }
|
||||
//
|
||||
// // retries in case of connection errors with time sleep
|
||||
// if isConnectionError(err) {
|
||||
// continue
|
||||
// }
|
||||
//
|
||||
// // return error in case of non-connection error
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
// handle http request errors
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp == nil {
|
||||
return nil, fmt.Errorf("got empty response without error")
|
||||
}
|
||||
|
||||
var respBytes []byte
|
||||
respBytes, err = io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// handle access denied and successful request
|
||||
if resp.StatusCode == 401 {
|
||||
return respBytes, errors.New("access is denied")
|
||||
}
|
||||
if resp.StatusCode == 200 {
|
||||
return respBytes, nil
|
||||
}
|
||||
|
||||
// handle errors with other status codes
|
||||
err = fmt.Errorf("%s", respBytes)
|
||||
return nil, fmt.Errorf("could not execute request: %w", err)
|
||||
}
|
||||
|
||||
func trimBVSConfig(cfg *config.BVSConfig) config.BVSConfig {
|
||||
cfg.SSOURL = strings.TrimSuffix(cfg.SSOURL, "/")
|
||||
cfg.DecortURL = strings.TrimSuffix(cfg.DecortURL, "/")
|
||||
return *cfg
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package decortsdk
|
||||
|
||||
import (
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn"
|
||||
)
|
||||
|
||||
type MockDecortClient struct {
|
||||
apiCaller *MockCaller
|
||||
}
|
||||
|
||||
func NewMockDecortClient(apiCaller *MockCaller) ClientInterface {
|
||||
return &MockDecortClient{
|
||||
apiCaller: apiCaller,
|
||||
}
|
||||
}
|
||||
|
||||
// CloudAPI builder
|
||||
func (mdc *MockDecortClient) CloudAPI() *cloudapi.CloudAPI {
|
||||
return cloudapi.New(mdc.apiCaller)
|
||||
}
|
||||
|
||||
// CloudBroker builder
|
||||
func (mdc *MockDecortClient) CloudBroker() *cloudbroker.CloudBroker {
|
||||
return cloudbroker.New(mdc.apiCaller)
|
||||
}
|
||||
|
||||
// SDN builder
|
||||
func (mdc *MockDecortClient) SDN() *sdn.SDN {
|
||||
return sdn.New(mdc.apiCaller)
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: interfaces/caller.go
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package decortsdk -source interfaces/caller.go
|
||||
//
|
||||
|
||||
// Package decortsdk is a generated GoMock package.
|
||||
package decortsdk
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockCaller is a mock of Caller interface.
|
||||
type MockCaller struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockCallerMockRecorder
|
||||
isgomock struct{}
|
||||
}
|
||||
|
||||
// MockCallerMockRecorder is the mock recorder for MockCaller.
|
||||
type MockCallerMockRecorder struct {
|
||||
mock *MockCaller
|
||||
}
|
||||
|
||||
// NewMockCaller creates a new mock instance.
|
||||
func NewMockCaller(ctrl *gomock.Controller) *MockCaller {
|
||||
mock := &MockCaller{ctrl: ctrl}
|
||||
mock.recorder = &MockCallerMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockCaller) EXPECT() *MockCallerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// DecortApiCall mocks base method.
|
||||
func (m *MockCaller) DecortApiCall(ctx context.Context, method, url string, params any) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DecortApiCall", ctx, method, url, params)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// DecortApiCall indicates an expected call of DecortApiCall.
|
||||
func (mr *MockCallerMockRecorder) DecortApiCall(ctx, method, url, params any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecortApiCall", reflect.TypeOf((*MockCaller)(nil).DecortApiCall), ctx, method, url, params)
|
||||
}
|
||||
|
||||
// DecortApiCallCtype mocks base method.
|
||||
func (m *MockCaller) DecortApiCallCtype(ctx context.Context, method, url, ctype string, params any) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DecortApiCallCtype", ctx, method, url, ctype, params)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// DecortApiCallCtype indicates an expected call of DecortApiCallCtype.
|
||||
func (mr *MockCallerMockRecorder) DecortApiCallCtype(ctx, method, url, ctype, params any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecortApiCallCtype", reflect.TypeOf((*MockCaller)(nil).DecortApiCallCtype), ctx, method, url, ctype, params)
|
||||
}
|
||||
|
||||
// DecortApiCallMP mocks base method.
|
||||
func (m *MockCaller) DecortApiCallMP(ctx context.Context, method, url string, params any) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DecortApiCallMP", ctx, method, url, params)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// DecortApiCallMP indicates an expected call of DecortApiCallMP.
|
||||
func (mr *MockCallerMockRecorder) DecortApiCallMP(ctx, method, url, params any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecortApiCallMP", reflect.TypeOf((*MockCaller)(nil).DecortApiCallMP), ctx, method, url, params)
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/serialization"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
type BVSConfig struct {
|
||||
// ServiceAccount username
|
||||
// Required: true
|
||||
// Example : "osh_mikoev"
|
||||
Username string `json:"username" yaml:"username" validate:"required"`
|
||||
|
||||
// ServiceAccount password
|
||||
// Required: true
|
||||
// Example: "[1o>hYkjnJr)HI78q7t&#%8Lm"
|
||||
Password string `json:"password" yaml:"password" validate:"required"`
|
||||
|
||||
// Domain name
|
||||
// Required: true
|
||||
// Example: "dynamix"
|
||||
Domain string `json:"domain" yaml:"domain" validate:"required"`
|
||||
|
||||
// Application (client) identifier for authorization
|
||||
// in the cloud platform controller in oauth2 mode.
|
||||
// Required: true
|
||||
// Example: "ewqfrvea7s890avw804389qwguf234h0otfi3w4eiu"
|
||||
AppID string `json:"appId" yaml:"appId" validate:"required"`
|
||||
|
||||
// Application (client) secret code for authorization
|
||||
// in the cloud platform controller in oauth2 mode.
|
||||
// Example: "frvet09rvesfis0c9erv9fsov0vsdfi09ovds0f"
|
||||
AppSecret string `json:"appSecret" yaml:"appSecret" validate:"required"`
|
||||
|
||||
// Platform authentication service address
|
||||
// Required: true
|
||||
// Example: "https://sso.digitalenergy.online"
|
||||
SSOURL string `json:"ssoUrl" yaml:"ssoUrl" validate:"url"`
|
||||
|
||||
// The address of the platform on which the actions are planned
|
||||
// Required: true
|
||||
// Example: "https://mr4.digitalenergy.online"
|
||||
DecortURL string `json:"decortUrl" yaml:"decortUrl" validate:"url"`
|
||||
|
||||
// JWT platform token
|
||||
// Required: false
|
||||
// Example: "qwqwdfwv68979we0q9bfv7e9sbvd89798qrwv97ff"
|
||||
Token Token `json:"token" yaml:"token"`
|
||||
|
||||
// Amount platform request attempts
|
||||
// Default value: 5
|
||||
// Required: false
|
||||
Retries uint64 `json:"retries" yaml:"retries"`
|
||||
|
||||
// Skip verify
|
||||
// Required: false
|
||||
SSLSkipVerify bool `json:"sslSkipVerify" yaml:"sslSkipVerify"`
|
||||
|
||||
// HTTP client timeout, unlimited if left empty
|
||||
// Required: false
|
||||
Timeout Duration `json:"timeout" yaml:"timeout"`
|
||||
|
||||
// The path of the configuration file entry
|
||||
// Required: false
|
||||
PathCfg string `json:"path_cfg" yaml:"path_cfg"`
|
||||
|
||||
// The path of the token file entry
|
||||
// Required: false
|
||||
PathToken string `json:"path_token" yaml:"path_token"`
|
||||
|
||||
// The number of minutes before the expiration of the token, a refresh will be made
|
||||
// Required: false
|
||||
TimeToRefresh int64 `json:"timeToRefresh" yaml:"timeToRefresh"`
|
||||
}
|
||||
|
||||
type Token struct {
|
||||
// AccessToken is the token that authorizes and authenticates
|
||||
// the requests.
|
||||
// Required: false
|
||||
AccessToken string `json:"access_token" yaml:"access_token"`
|
||||
|
||||
// TokenType is the type of token.
|
||||
// The Type method returns either this or "Bearer", the default.
|
||||
// Required: false
|
||||
TokenType string `json:"token_type" yaml:"token_type"`
|
||||
|
||||
// RefreshToken is a token that's used by the application
|
||||
// (as opposed to the user) to refresh the access token
|
||||
// if it expires.
|
||||
// Required: false
|
||||
RefreshToken string `json:"refresh_token" yaml:"refresh_token"`
|
||||
|
||||
// Expiry is the optional expiration time of the access token.
|
||||
// Required: false
|
||||
Expiry time.Time `json:"expiry" yaml:"expiry"`
|
||||
}
|
||||
|
||||
// SetTimeout is used to set HTTP client timeout.
|
||||
func (c *BVSConfig) SetTimeout(dur time.Duration) {
|
||||
c.Timeout = Duration(dur)
|
||||
}
|
||||
|
||||
// ParseConfigJSON parses Config from specified JSON-formatted file.
|
||||
func ParseConfigBVSJSON(path string) (BVSConfig, error) {
|
||||
file, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return BVSConfig{}, err
|
||||
}
|
||||
|
||||
var config BVSConfig
|
||||
|
||||
err = json.Unmarshal(file, &config)
|
||||
if err != nil {
|
||||
return BVSConfig{}, err
|
||||
}
|
||||
|
||||
err = validators.ValidateConfig(config)
|
||||
if err != nil {
|
||||
return BVSConfig{}, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// ParseConfigJSON parses Token from specified JSON-formatted file.
|
||||
func ParseTokenBVSJSON(path string) (Token, error) {
|
||||
file, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return Token{}, err
|
||||
}
|
||||
|
||||
var token Token
|
||||
|
||||
err = json.Unmarshal(file, &token)
|
||||
if err != nil {
|
||||
return Token{}, err
|
||||
}
|
||||
|
||||
err = validators.ValidateConfig(token)
|
||||
if err != nil {
|
||||
return Token{}, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
// ParseTokenBVSYAML parses Token from specified YAML-formatted file.
|
||||
func ParseTokenBVSYAML(path string) (Token, error) {
|
||||
file, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return Token{}, err
|
||||
}
|
||||
|
||||
var token Token
|
||||
|
||||
err = yaml.Unmarshal(file, &token)
|
||||
if err != nil {
|
||||
return Token{}, err
|
||||
}
|
||||
|
||||
err = validators.ValidateConfig(token)
|
||||
if err != nil {
|
||||
return Token{}, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
// ParseConfigYAML parses Config from specified YAML-formatted file.
|
||||
func ParseConfigBVSYAML(path string) (BVSConfig, error) {
|
||||
file, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return BVSConfig{}, err
|
||||
}
|
||||
|
||||
var config BVSConfig
|
||||
|
||||
err = yaml.Unmarshal(file, &config)
|
||||
if err != nil {
|
||||
return BVSConfig{}, err
|
||||
}
|
||||
|
||||
err = validators.ValidateConfig(config)
|
||||
if err != nil {
|
||||
return BVSConfig{}, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func (t Token) Serialize(params ...string) (serialization.Serialized, error) {
|
||||
if len(params) > 1 {
|
||||
prefix := params[0]
|
||||
indent := params[1]
|
||||
|
||||
return json.MarshalIndent(t, prefix, indent)
|
||||
}
|
||||
|
||||
return json.Marshal(t)
|
||||
}
|
||||
|
||||
func (c BVSConfig) Serialize(params ...string) (serialization.Serialized, error) {
|
||||
if len(params) > 1 {
|
||||
prefix := params[0]
|
||||
indent := params[1]
|
||||
|
||||
return json.MarshalIndent(c, prefix, indent)
|
||||
}
|
||||
|
||||
return json.Marshal(c)
|
||||
}
|
||||
@@ -22,8 +22,6 @@ func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
}
|
||||
*d = Duration(tmp)
|
||||
return nil
|
||||
case float64:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("invalid duration %v", value)
|
||||
}
|
||||
@@ -42,8 +40,6 @@ func (d *Duration) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
*d = Duration(tmp)
|
||||
return nil
|
||||
case float64:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("invalid duration %v", value)
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
package config
|
||||
|
||||
// UniversalConfig combines configurations for different types of clients
|
||||
type UniversalConfig struct {
|
||||
Decs3oConfig *Config `json:"decs3oConfig,omitempty" yaml:"decs3oConfig,omitempty"`
|
||||
BVSConfig *BVSConfig `json:"bvsConfig,omitempty" yaml:"bvsConfig,omitempty"`
|
||||
LegacyConfig *LegacyConfig `json:"legacyConfig,omitempty" yaml:"legacyConfig,omitempty"`
|
||||
}
|
||||
20
go.mod
20
go.mod
@@ -1,25 +1,19 @@
|
||||
module repository.basistech.ru/BASIS/decort-golang-sdk
|
||||
|
||||
go 1.24.0
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/go-playground/validator/v10 v10.28.0
|
||||
github.com/go-playground/validator/v10 v10.11.2
|
||||
github.com/google/go-querystring v1.1.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/stretchr/testify v1.9.0
|
||||
go.uber.org/mock v0.6.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.10 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/crypto v0.42.0 // indirect
|
||||
golang.org/x/sys v0.36.0 // indirect
|
||||
golang.org/x/text v0.29.0 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
golang.org/x/crypto v0.5.0 // indirect
|
||||
golang.org/x/sys v0.4.0 // indirect
|
||||
golang.org/x/text v0.6.0 // indirect
|
||||
)
|
||||
|
||||
45
go.sum
45
go.sum
@@ -1,38 +1,37 @@
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0ktULL6FgHdG688=
|
||||
github.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU=
|
||||
github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU=
|
||||
github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s=
|
||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
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/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
||||
golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
|
||||
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
|
||||
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
|
||||
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
|
||||
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
|
||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/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/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
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=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -6,10 +6,4 @@ import "context"
|
||||
type Caller interface {
|
||||
// DecortApiCall method for sending requests to the platform
|
||||
DecortApiCall(ctx context.Context, method, url string, params interface{}) ([]byte, error)
|
||||
|
||||
// DecortApiCallCtype method for sending requests to the platform
|
||||
DecortApiCallCtype(ctx context.Context, method, url, ctype string, params interface{}) ([]byte, error)
|
||||
|
||||
// DecortApiCallMP method for sending requests to the platform
|
||||
DecortApiCallMP(ctx context.Context, method, url string, params interface{}) ([]byte, error)
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package interfaces
|
||||
|
||||
// Interface to valiate RAM values
|
||||
type RequestWithRAM interface {
|
||||
// GetRAM returns RAM values
|
||||
GetRAM() map[string]uint64
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package constants
|
||||
|
||||
const (
|
||||
RESTMACHINE = "/restmachine"
|
||||
)
|
||||
|
||||
const (
|
||||
MIMEJSON = "application/json"
|
||||
MIMEHTML = "text/html"
|
||||
MIMEXML = "application/xml"
|
||||
MIMEXML2 = "text/xml"
|
||||
MIMEPlain = "text/plain"
|
||||
MIMEPOSTForm = "application/x-www-form-urlencoded"
|
||||
MIMEMultipartPOSTForm = "multipart/form-data"
|
||||
MIMEPROTOBUF = "application/x-protobuf"
|
||||
MIMEMSGPACK = "application/x-msgpack"
|
||||
MIMEMSGPACK2 = "application/msgpack"
|
||||
MIMEYAML = "application/x-yaml"
|
||||
MIMEYAML2 = "application/yaml"
|
||||
MIMETOML = "application/toml"
|
||||
MIMESTREAM = "application/octet-stream"
|
||||
)
|
||||
|
||||
var FileName = map[string]string{
|
||||
"OidcCertificate": "ca.crt",
|
||||
}
|
||||
|
||||
var K8sValues = []string{"labels", "taints", "annotations, additionalSANs"}
|
||||
|
||||
var VersionMap = map[string]string{
|
||||
"4.7.0": "-",
|
||||
"4.6.0": "-",
|
||||
"4.5.0": "-",
|
||||
"4.4.0": "-",
|
||||
"4.3.0": "-",
|
||||
"4.2.0": "-",
|
||||
"4.1.1": "-",
|
||||
"4.1.0": "-",
|
||||
}
|
||||
@@ -1,38 +1,31 @@
|
||||
package validators
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/multierror"
|
||||
)
|
||||
|
||||
// computeDriverValidator is used to validate Driver field in kvmx86/kvmppc create.
|
||||
func computeDriverValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return StringInSlice(fieldValue, computeDriverValues)
|
||||
}
|
||||
|
||||
// protoValidator is used to validate Proto fields.
|
||||
func protoValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, protoValues)
|
||||
}
|
||||
|
||||
// apiGroupValidator is used to validate APIGroup fields
|
||||
func apiGroupValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, apiGroupValues)
|
||||
return StringInSlice(fieldValue, protoValues)
|
||||
}
|
||||
|
||||
// accessTypeValidator is used to validate AccessType fields.
|
||||
func accessTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, accessTypeValues)
|
||||
return StringInSlice(fieldValue, accessTypeValues)
|
||||
}
|
||||
|
||||
// resTypesValidator is used to validate ResTypes fields.
|
||||
@@ -43,7 +36,7 @@ func resTypesValidator(fe validator.FieldLevel) bool {
|
||||
}
|
||||
|
||||
for _, value := range fieldSlice {
|
||||
if !IsInSlice(value, resTypesValues) {
|
||||
if !StringInSlice(value, resTypesValues) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -51,74 +44,60 @@ func resTypesValidator(fe validator.FieldLevel) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// driverValidator is used to validate Driver fields.
|
||||
func driverValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return StringInSlice(fieldValue, driverValues)
|
||||
}
|
||||
|
||||
// accountCUTypeValidator is used to validate CUType field.
|
||||
func accountCUTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, accountCUTypeValues)
|
||||
return StringInSlice(fieldValue, accountCUTypeValues)
|
||||
}
|
||||
|
||||
// bserviceModeValidator is used to validate Mode field.
|
||||
func bserviceModeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, bserviceModeValues)
|
||||
return StringInSlice(fieldValue, bserviceModeValues)
|
||||
}
|
||||
|
||||
// computeTopologyValidator is used to validate Topology field.
|
||||
func computeTopologyValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, computeTopologyValues)
|
||||
return StringInSlice(fieldValue, computeTopologyValues)
|
||||
}
|
||||
|
||||
// computePolicyValidator is used to validate Policy field.
|
||||
func computePolicyValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, computePolicyValues)
|
||||
return StringInSlice(fieldValue, computePolicyValues)
|
||||
}
|
||||
|
||||
// computeModeValidator is used to validate Mode field.
|
||||
func computeModeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, computeModeValues)
|
||||
return StringInSlice(fieldValue, computeModeValues)
|
||||
}
|
||||
|
||||
// computeDiskTypeValidator is used to validate DiskType field.
|
||||
func computeDiskTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return StringInSlice(fieldValue, computeDiskTypeValues)
|
||||
}
|
||||
|
||||
// computeNetTypeValidator is used to validate NetType field.
|
||||
func computeNetTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, computeNetTypeValues)
|
||||
}
|
||||
|
||||
// computex86NetTypeValidator is used to validate NetType field.
|
||||
func computex86NetTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, computex86NetTypeValues)
|
||||
}
|
||||
|
||||
// securityGroupDirectionValidator is used to validate Direction field
|
||||
func securityGroupDirectionValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, securityGroupDirectionValues)
|
||||
}
|
||||
|
||||
// securityGroupEthertypeValidator is used to validate Ethertype field
|
||||
func securityGroupEthertypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, securityGroupEthertypeValues)
|
||||
}
|
||||
|
||||
// securityGroupProtocolValidator is used to validate Protocol field
|
||||
func securityGroupProtocolValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, securityGroupProtocolValues)
|
||||
return StringInSlice(fieldValue, computeNetTypeValues)
|
||||
}
|
||||
|
||||
// computeOrderValidator is used to validate Order field.
|
||||
@@ -129,7 +108,7 @@ func computeOrderValidator(fe validator.FieldLevel) bool {
|
||||
}
|
||||
|
||||
for _, value := range fieldSlice {
|
||||
if !IsInSlice(value, computeOrderValues) {
|
||||
if !StringInSlice(value, computeOrderValues) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -141,77 +120,100 @@ func computeOrderValidator(fe validator.FieldLevel) bool {
|
||||
func computeDataDisksValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, computeDataDisksValues)
|
||||
return StringInSlice(fieldValue, computeDataDisksValues)
|
||||
}
|
||||
|
||||
// diskTypeValidator is used to validate Type field.
|
||||
func diskTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return StringInSlice(fieldValue, diskTypeValues)
|
||||
}
|
||||
|
||||
// flipgroupClientTypeValidator is used to validate ClientType field.
|
||||
func flipgroupClientTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, flipgroupClientTypeValues)
|
||||
return StringInSlice(fieldValue, flipgroupClientTypeValues)
|
||||
}
|
||||
|
||||
// massCreateTypeValidator is used to validate net type field when mass creating kvm
|
||||
func massCreateTypeValidator(fe validator.FieldLevel) bool {
|
||||
// kvmNetTypeValidator is used to validate NetType field.
|
||||
func kvmNetTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, massCreateNetTypeValues)
|
||||
return StringInSlice(fieldValue, kvmNetTypeValues)
|
||||
}
|
||||
|
||||
// lbAlgorithmValidator is used to validate Algorithm field.
|
||||
func lbAlgorithmValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, lbAlgorithmValues)
|
||||
return StringInSlice(fieldValue, lbAlgorithmValues)
|
||||
}
|
||||
|
||||
// rgDefNetValidator is used to validate DefNet field.
|
||||
func rgDefNetValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, rgDefNetValues)
|
||||
return StringInSlice(fieldValue, rgDefNetValues)
|
||||
}
|
||||
|
||||
// rgNetTypeValidator is used to validate NetType field.
|
||||
func rgNetTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, rgNetTypeValues)
|
||||
return StringInSlice(fieldValue, rgNetTypeValues)
|
||||
}
|
||||
|
||||
// vinsTypeValidator is used to validate Type field.
|
||||
func vinsTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, vinsTypeValues)
|
||||
return StringInSlice(fieldValue, vinsTypeValues)
|
||||
}
|
||||
|
||||
// imageBootTypeValidator is used to validate BootType field.
|
||||
func imageBootTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, imageBootTypeValues)
|
||||
return StringInSlice(fieldValue, imageBootTypeValues)
|
||||
}
|
||||
|
||||
// imageTypeValidator is used to validate ImageType field.
|
||||
func imageTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, imageTypeValues)
|
||||
return StringInSlice(fieldValue, imageTypeValues)
|
||||
}
|
||||
|
||||
// imageDriversValidator is used to validate Drivers field.
|
||||
func imageDriversValidator(fe validator.FieldLevel) bool {
|
||||
fieldSlice, ok := fe.Field().Interface().([]string)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, item := range fieldSlice {
|
||||
if !StringInSlice(item, imageDriversValues) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// imageArchitectureValidator is used to validate Architecture field.
|
||||
func imageArchitectureValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, imageArchitectureValues)
|
||||
return StringInSlice(fieldValue, imageArchitectureValues)
|
||||
}
|
||||
|
||||
// sepFieldTypeValidator is used to validate FieldType field.
|
||||
func sepFieldTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, sepFieldTypeValues)
|
||||
return StringInSlice(fieldValue, sepFieldTypeValues)
|
||||
}
|
||||
|
||||
// hwPathValidator is used to validate HWPath field.
|
||||
@@ -228,7 +230,7 @@ func networkPluginValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
fieldValue = strings.ToLower(fieldValue)
|
||||
|
||||
return IsInSlice(fieldValue, networkPluginValues)
|
||||
return StringInSlice(fieldValue, networkPluginValues)
|
||||
}
|
||||
|
||||
// networkPluginsValidator is used to validate NetworkPlugins field
|
||||
@@ -241,7 +243,7 @@ func networkPluginsValidator(fe validator.FieldLevel) bool {
|
||||
for _, item := range fieldSlice {
|
||||
item = strings.ToLower(item)
|
||||
|
||||
if !IsInSlice(item, networkPluginValues) {
|
||||
if !StringInSlice(item, networkPluginValues) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -253,35 +255,14 @@ func interfaceStateValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
fieldValue = strings.ToLower(fieldValue)
|
||||
|
||||
return IsInSlice(fieldValue, interfaceStateValues)
|
||||
}
|
||||
|
||||
func interfaceTXModelValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
fieldValue = strings.ToLower(fieldValue)
|
||||
|
||||
return IsInSlice(fieldValue, txModelValues)
|
||||
}
|
||||
|
||||
func interfaceIOEventFDValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
fieldValue = strings.ToLower(fieldValue)
|
||||
|
||||
return IsInSlice(fieldValue, ioEventFDValues)
|
||||
}
|
||||
|
||||
func interfaceEventIDxValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
fieldValue = strings.ToLower(fieldValue)
|
||||
|
||||
return IsInSlice(fieldValue, eventIDxValues)
|
||||
return StringInSlice(fieldValue, interfaceStateValues)
|
||||
}
|
||||
|
||||
func strictLooseValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
fieldValue = strings.ToLower(fieldValue)
|
||||
|
||||
return IsInSlice(fieldValue, strictLooseValues)
|
||||
return StringInSlice(fieldValue, strictLooseValues)
|
||||
}
|
||||
|
||||
// name workerGroup must be more 3 symbol
|
||||
@@ -291,196 +272,3 @@ func workerGroupNameValidator(fe validator.FieldLevel) bool {
|
||||
|
||||
return len(fieldValue) >= 3
|
||||
}
|
||||
|
||||
func sortByValidator(fe validator.FieldLevel) bool {
|
||||
|
||||
sortByRegexp := regexp.MustCompile(`^[+-][a-zA-Z_]+`)
|
||||
|
||||
return sortByRegexp.MatchString(fe.Field().String())
|
||||
}
|
||||
|
||||
func actionValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, actionValues)
|
||||
}
|
||||
|
||||
func vmActionValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, vmActionValues)
|
||||
}
|
||||
|
||||
func mtuValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().Uint()
|
||||
|
||||
return fieldValue >= uint64(mtuMin) && fieldValue <= uint64(mtuMax)
|
||||
}
|
||||
|
||||
func computeFeaturesValidator(fe validator.FieldLevel) bool {
|
||||
field := fe.Field()
|
||||
slice, ok := field.Interface().([]string)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return IsSubSlice(slice, computeFeaturesValues)
|
||||
}
|
||||
|
||||
func networkInterfaceNamingValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, networkInterfaceNamingValues)
|
||||
}
|
||||
|
||||
func numaAffinityValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, numaAffinityValues)
|
||||
}
|
||||
|
||||
// kvmx86NetTypeValidator is used to validate NetType field for x86 compute.
|
||||
func kvmx86NetTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, kvmx86NetTypeValues)
|
||||
}
|
||||
|
||||
func isBoolTypeValidator(fe validator.FieldLevel) bool {
|
||||
return fe.Field().CanConvert(reflect.TypeOf(true))
|
||||
}
|
||||
|
||||
func urlValidartor(fl validator.FieldLevel) bool {
|
||||
fieldValues := fl.Field().String()
|
||||
|
||||
_, err := url.ParseRequestURI(fieldValues)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func chipsetValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, chipsetValues)
|
||||
}
|
||||
|
||||
func preferredCPUValidator(fe validator.FieldLevel) bool {
|
||||
fieldSlice, ok := fe.Field().Interface().([]int64)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, value := range fieldSlice {
|
||||
if value < -1 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// loaderTypeValidator is used to validate loaderType fields
|
||||
func loaderTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, loaderTypeValues)
|
||||
}
|
||||
|
||||
// languageValidator is used to validate language fields
|
||||
func languageValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, languageValues)
|
||||
}
|
||||
|
||||
func userProviderValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, userProviders)
|
||||
}
|
||||
|
||||
// sepTypeValidator is used to validate sepType fields
|
||||
func sepTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, sepTypeValues)
|
||||
}
|
||||
|
||||
// deviceValidator is used to validate extnet device fields
|
||||
func deviceValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, deviceValues)
|
||||
}
|
||||
|
||||
// ipTypesValidator is used to validate ip types version fields
|
||||
func ipTypesValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, ipTypeValues)
|
||||
}
|
||||
|
||||
// ValidateRAM checks if request contains RAM value that is positive integer divisible by divisibility passed.
|
||||
// It is recommended to pass constants.RAM_DIVISIBILITY as divisility arguement
|
||||
func ValidateRAM(r interfaces.RequestWithRAM, divisibility uint64) error {
|
||||
|
||||
if divisibility == 0 {
|
||||
|
||||
return errors.New("second argument of ValidateRAM should be greater than 0")
|
||||
}
|
||||
mapRAM := r.GetRAM()
|
||||
|
||||
errs := make([]error, 0, len(mapRAM))
|
||||
|
||||
for k, v := range mapRAM {
|
||||
|
||||
if v%divisibility != 0 {
|
||||
|
||||
errs = append(errs, fmt.Errorf("expected value of %s: \"%d\" should be divisible by %d", k, v, divisibility))
|
||||
}
|
||||
}
|
||||
return multierror.Join(errs...)
|
||||
}
|
||||
|
||||
// trunkTagsValidator checks if trunk_tags is in range from 1 to 4095
|
||||
func trunkTagsValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
numFieldValue, err := strconv.ParseInt(fieldValue, 10, 64)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return uint64(numFieldValue) >= uint64(trunkTagsMin) && uint64(numFieldValue) <= uint64(trunkTagsMax)
|
||||
}
|
||||
|
||||
// addressPoolNetTypeValidator is used to validate NetAddressType fields
|
||||
func addressPoolNetTypeValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, addressPoolNetTypeValues)
|
||||
}
|
||||
|
||||
// sepTechStatusValidator is used to validate SepTechStatus fields
|
||||
func sepTechStatusValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
return IsInSlice(fieldValue, sepTechStatusValues)
|
||||
}
|
||||
|
||||
// pciDeviceHWPathValidator is used to validate PCI device hardware path fields (e.g. 0000:81:00.0)
|
||||
func pciDeviceHWPathValidator(fe validator.FieldLevel) bool {
|
||||
fieldValue := fe.Field().String()
|
||||
|
||||
ok, _ := regexp.MatchString(`^[0-9a-fA-F]{4}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\.[0-7]$`, fieldValue)
|
||||
return ok
|
||||
}
|
||||
|
||||
// sepNameValidator is used to validate SEP name fields
|
||||
func sepNameValidator(fe validator.FieldLevel) bool {
|
||||
ok, _ := regexp.MatchString(`^[a-zA-Zа-яА-ЯёЁ0-9][a-zA-Zа-яА-ЯёЁ0-9_.\[\]()\-]*$`, fe.Field().String())
|
||||
return ok
|
||||
}
|
||||
|
||||
// sepDescriptionValidator is used to validate SEP description fields
|
||||
func sepDescriptionValidator(fe validator.FieldLevel) bool {
|
||||
ok, _ := regexp.MatchString(`^[a-zA-Zа-яА-ЯёЁ0-9_.\[\]()\-]*$`, fe.Field().String())
|
||||
return ok
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ func GetErrors(err error) validator.ValidationErrors {
|
||||
return err.(validator.ValidationErrors)
|
||||
}
|
||||
|
||||
func IsInSlice(str string, target []string) bool {
|
||||
func StringInSlice(str string, target []string) bool {
|
||||
for _, v := range target {
|
||||
if v == str {
|
||||
return true
|
||||
@@ -42,12 +42,3 @@ func IsInSlice(str string, target []string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsSubSlice(source []string, target []string) bool {
|
||||
for _, s := range source {
|
||||
if !IsInSlice(s, target) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -25,8 +25,12 @@ func errorMessage(fe validator.FieldError) string {
|
||||
return fmt.Sprintf("%s %s: unexpected URL format", prefix, fe.Field())
|
||||
case "email":
|
||||
return fmt.Sprintf("%s %s: unexpected E-Mail format", prefix, fe.Field())
|
||||
case "isBool":
|
||||
return fmt.Sprintf("%s %s: must be bool type", prefix, fe.Field())
|
||||
|
||||
case "driver":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(driverValues))
|
||||
|
||||
case "accessType":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
@@ -46,13 +50,6 @@ func errorMessage(fe validator.FieldError) string {
|
||||
fe.Field(),
|
||||
joinValues(protoValues))
|
||||
|
||||
// apiGroup Validators
|
||||
case "apiGroup":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(apiGroupValues))
|
||||
|
||||
// Account Validators
|
||||
case "accountCUType":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
@@ -86,17 +83,11 @@ func errorMessage(fe validator.FieldError) string {
|
||||
fe.Field(),
|
||||
joinValues(computeModeValues))
|
||||
|
||||
case "mtu":
|
||||
return fmt.Sprint(prefix, fe.Field(), "must be ", mtuMin, "-", mtuMax)
|
||||
|
||||
case "preferredCPU":
|
||||
return fmt.Sprint(prefix, fe.Field(), "must be equal to or greater than", -1)
|
||||
|
||||
case "computex86NetType":
|
||||
case "computeDiskType":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(computex86NetTypeValues))
|
||||
joinValues(computeDiskTypeValues))
|
||||
|
||||
case "computeNetType":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
@@ -116,6 +107,19 @@ func errorMessage(fe validator.FieldError) string {
|
||||
fe.Field(),
|
||||
joinValues(computeDataDisksValues))
|
||||
|
||||
case "computeDriver":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(computeDriverValues))
|
||||
|
||||
// Disk Validators
|
||||
case "diskType":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(diskTypeValues))
|
||||
|
||||
// Flipgroup Validators
|
||||
case "flipgroupClientType":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
@@ -129,12 +133,12 @@ func errorMessage(fe validator.FieldError) string {
|
||||
prefix,
|
||||
fe.Field())
|
||||
|
||||
// KVM_X86 Mass create validators
|
||||
case "massCreateNetType":
|
||||
// KVM_X86/KVM_PPC Validators
|
||||
case "kvmNetType":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(massCreateNetTypeValues))
|
||||
joinValues(kvmNetTypeValues))
|
||||
|
||||
// LB Validators
|
||||
case "lbAlgorithm":
|
||||
@@ -176,6 +180,12 @@ func errorMessage(fe validator.FieldError) string {
|
||||
fe.Field(),
|
||||
joinValues(imageTypeValues))
|
||||
|
||||
case "imageDrivers":
|
||||
return fmt.Sprintf("%s %s must contain only the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(imageDriversValues))
|
||||
|
||||
case "imageArchitecture":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
@@ -219,146 +229,6 @@ func errorMessage(fe validator.FieldError) string {
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(interfaceStateValues))
|
||||
|
||||
case "interfaceTXModel":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(txModelValues))
|
||||
|
||||
case "interfaceIOEventFD":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(ioEventFDValues))
|
||||
|
||||
case "interfaceEventIDx":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(eventIDxValues))
|
||||
|
||||
case "sortBy":
|
||||
return fmt.Sprintf("%s %s must be in format +|-(field)",
|
||||
prefix,
|
||||
fe.Field())
|
||||
|
||||
case "action":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(actionValues))
|
||||
|
||||
case "vmaction":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(vmActionValues))
|
||||
|
||||
case "computeFeatures":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(computeFeaturesValues))
|
||||
|
||||
case "networkInterfaceNaming":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(networkInterfaceNamingValues))
|
||||
|
||||
case "numaAffinity":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(numaAffinityValues))
|
||||
|
||||
case "kvmx86NetType":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(kvmx86NetTypeValues))
|
||||
|
||||
case "chipset":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(chipsetValues))
|
||||
|
||||
case "loaderType":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(loaderTypeValues))
|
||||
|
||||
case "language":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(languageValues))
|
||||
|
||||
case "sepType":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(sepTypeValues))
|
||||
|
||||
// user validators
|
||||
case "userProvider":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(userProviders))
|
||||
|
||||
// security group validators
|
||||
case "securityGroupDirection":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(securityGroupDirectionValues))
|
||||
|
||||
case "securityGroupEthertype":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(securityGroupEthertypeValues))
|
||||
|
||||
case "securityGroupProtocol":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(securityGroupProtocolValues))
|
||||
|
||||
// trunk tags validator
|
||||
case "trunkTags":
|
||||
return fmt.Sprintf("%s %s must be in range from 1 to 4095",
|
||||
prefix,
|
||||
fe.Field())
|
||||
|
||||
// addressPoolNetTypeValidator validator
|
||||
case "addressPoolNetTypeValidator":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(addressPoolNetTypeValues))
|
||||
|
||||
case "device":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(deviceValues))
|
||||
|
||||
case "ipTypes":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(ipTypeValues))
|
||||
|
||||
case "sepTechStatus":
|
||||
return fmt.Sprintf("%s %s must be one of the following: %s",
|
||||
prefix,
|
||||
fe.Field(),
|
||||
joinValues(sepTechStatusValues))
|
||||
}
|
||||
|
||||
return fe.Error()
|
||||
|
||||
@@ -25,13 +25,12 @@ func getDecortValidator() *validator.Validate {
|
||||
|
||||
// registerAllValidators registers all custom validators in DecortValidator.
|
||||
func registerAllValidators(validate *validator.Validate) error {
|
||||
|
||||
err := validate.RegisterValidation("proto", protoValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("apiGroup", apiGroupValidator)
|
||||
err = validate.RegisterValidation("computeDriver", computeDriverValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -46,6 +45,11 @@ func registerAllValidators(validate *validator.Validate) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("driver", driverValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("imageBootType", imageBootTypeValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -56,6 +60,11 @@ func registerAllValidators(validate *validator.Validate) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("imageDrivers", imageDriversValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("imageArchitecture", imageArchitectureValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -86,12 +95,12 @@ func registerAllValidators(validate *validator.Validate) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("computeNetType", computeNetTypeValidator)
|
||||
err = validate.RegisterValidation("computeDiskType", computeDiskTypeValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("computex86NetType", computex86NetTypeValidator)
|
||||
err = validate.RegisterValidation("computeNetType", computeNetTypeValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -106,12 +115,17 @@ func registerAllValidators(validate *validator.Validate) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("diskType", diskTypeValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("flipgroupClientType", flipgroupClientTypeValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("massCreateNetType", massCreateTypeValidator)
|
||||
err = validate.RegisterValidation("kvmNetType", kvmNetTypeValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -166,160 +180,10 @@ func registerAllValidators(validate *validator.Validate) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("interfaceTXModel", interfaceTXModelValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("interfaceIOEventFD", interfaceIOEventFDValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("interfaceEventIDx", interfaceEventIDxValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("workerGroupName", workerGroupNameValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("sortBy", sortByValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("action", actionValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("vmaction", vmActionValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("mtu", mtuValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("computeFeatures", computeFeaturesValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("networkInterfaceNaming", networkInterfaceNamingValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("numaAffinity", numaAffinityValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("kvmx86NetType", kvmx86NetTypeValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("isBool", isBoolTypeValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("url", urlValidartor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("chipset", chipsetValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("preferredCPU", preferredCPUValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("loaderType", loaderTypeValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("language", languageValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("userProvider", userProviderValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("sepType", sepTypeValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("device", deviceValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("trunkTags", trunkTagsValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("securityGroupDirection", securityGroupDirectionValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("securityGroupEthertype", securityGroupEthertypeValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("securityGroupProtocol", securityGroupProtocolValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("addressPoolNetTypeValidator", addressPoolNetTypeValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("ipTypes", ipTypesValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("sepTechStatus", sepTechStatusValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("pciDeviceHWPath", pciDeviceHWPathValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("sepName", sepNameValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validate.RegisterValidation("sepDescription", sepDescriptionValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,39 +1,41 @@
|
||||
package validators
|
||||
|
||||
var (
|
||||
apiGroupValues = []string{"cloudapi", "cloudbroker", "system"}
|
||||
|
||||
driverValues = []string{"KVM_X86", "KVM_PPC"}
|
||||
accessTypeValues = []string{"R", "RCX", "ARCXDU"}
|
||||
resTypesValues = []string{"compute", "vins", "k8s", "openshift", "lb", "flipgroup"}
|
||||
protoValues = []string{"tcp", "udp"}
|
||||
|
||||
accountCUTypeValues = []string{"CU_M", "CU_C", "CU_D", "CU_DM", "CU_I", "gpu_units"}
|
||||
accountCUTypeValues = []string{"CU_M", "CU_C", "CU_D", "CU_DM", "CU_S", "CU_A", "CU_NO", "CU_I", "CU_NP"}
|
||||
|
||||
bserviceModeValues = []string{"ABSOLUTE", "RELATIVE"}
|
||||
|
||||
computeTopologyValues = []string{"compute", "node"}
|
||||
computePolicyValues = []string{"RECOMMENDED", "REQUIRED"}
|
||||
computeModeValues = []string{"EQ", "EN", "ANY"}
|
||||
computeDiskTypeValues = []string{"D", "B"}
|
||||
computeNetTypeValues = []string{"EXTNET", "VINS"}
|
||||
computex86NetTypeValues = []string{"EXTNET", "VINS", "VFNIC", "DPDK", "SDN", "EMPTY", "TRUNK"}
|
||||
computeOrderValues = []string{"cdrom", "network", "hd"}
|
||||
computeDataDisksValues = []string{"KEEP", "DETACH", "DESTROY"}
|
||||
computeDriverValues = []string{"KVM_X86", "SVA_KVM_X86"}
|
||||
|
||||
diskTypeValues = []string{"B", "T", "D"}
|
||||
|
||||
flipgroupClientTypeValues = []string{"compute", "vins"}
|
||||
|
||||
massCreateNetTypeValues = []string{"EXTNET", "VINS", "TRUNK"}
|
||||
kvmx86NetTypeValues = []string{"EXTNET", "VINS", "EMPTY", "VFNIC", "DPDK", "SDN", "TRUNK"}
|
||||
kvmNetTypeValues = []string{"EXTNET", "VINS", "NONE"}
|
||||
|
||||
lbAlgorithmValues = []string{"roundrobin", "static-rr", "leastconn"}
|
||||
|
||||
rgDefNetValues = []string{"PRIVATE", "PUBLIC", "NONE"}
|
||||
rgNetTypeValues = []string{"PUBLIC", "PRIVATE"}
|
||||
|
||||
vinsTypeValues = []string{"DHCP", "VIP", "EXCLUDED"}
|
||||
vinsTypeValues = []string{"DHCP", "VIP", "EXCLUDE"}
|
||||
|
||||
imageBootTypeValues = []string{"uefi", "bios"}
|
||||
imageTypeValues = []string{"windows", "linux", "unknown"}
|
||||
imageArchitectureValues = []string{"X86_64"}
|
||||
imageTypeValues = []string{"windows", "linux", "other"}
|
||||
imageDriversValues = []string{"KVM_X86"}
|
||||
imageArchitectureValues = []string{"X86_64", "PPC64_LE"}
|
||||
|
||||
sepFieldTypeValues = []string{"int", "str", "bool", "list", "dict"}
|
||||
|
||||
@@ -42,50 +44,4 @@ var (
|
||||
strictLooseValues = []string{"strict", "loose"}
|
||||
|
||||
interfaceStateValues = []string{"on", "off"}
|
||||
|
||||
actionValues = []string{"is_powered", "power_on", "shutdown", "force_shutdown", "reboot"}
|
||||
|
||||
vmActionValues = []string{"stop", "move"}
|
||||
|
||||
computeFeaturesValues = []string{"hugepages", "numa", "cpupin", "vfnic", "dpdk", "changemac", "trunk"}
|
||||
|
||||
networkInterfaceNamingValues = []string{"eth", "ens"}
|
||||
|
||||
numaAffinityValues = []string{"none", "strict", "loose"}
|
||||
|
||||
txModelValues = []string{"iothread", "timer", "selected by hypervisor"}
|
||||
|
||||
ioEventFDValues = []string{"on", "off", "selected by hypervisor"}
|
||||
|
||||
eventIDxValues = []string{"on", "off", "selected by hypervisor"}
|
||||
|
||||
chipsetValues = []string{"i440fx", "Q35"}
|
||||
|
||||
loaderTypeValues = []string{"linux", "windows", "unknown"}
|
||||
|
||||
sepTypeValues = []string{"hitachi", "dorado", "tatlin", "shared", "local", "des", "ustor"}
|
||||
|
||||
languageValues = []string{"ru", "en"}
|
||||
|
||||
userProviders = []string{"bvs", "decs3o"}
|
||||
|
||||
deviceValues = []string{"primary", "secondary"}
|
||||
|
||||
securityGroupDirectionValues = []string{"inbound", "outbound"}
|
||||
securityGroupEthertypeValues = []string{"IPv4", "IPv6"}
|
||||
securityGroupProtocolValues = []string{"icmp", "tcp", "udp"}
|
||||
|
||||
addressPoolNetTypeValues = []string{"IPv4", "IPv6", "MAC"}
|
||||
|
||||
ipTypeValues = []string{"v4, v6"}
|
||||
|
||||
sepTechStatusValues = []string{"ENABLED", "DISABLED"}
|
||||
)
|
||||
|
||||
const (
|
||||
mtuMin = 1500
|
||||
mtuMax = 9216
|
||||
|
||||
trunkTagsMin = 1
|
||||
trunkTagsMax = 4095
|
||||
)
|
||||
|
||||
424
legacy-client.go
424
legacy-client.go
@@ -4,25 +4,25 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/config"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi"
|
||||
k8s_ca "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn"
|
||||
k8s_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/k8s"
|
||||
)
|
||||
|
||||
// LegacyDecortClient is Legacy HTTP-client for platform
|
||||
// Legacy HTTP-client for platform
|
||||
type LegacyDecortClient struct {
|
||||
decortURL string
|
||||
client *http.Client
|
||||
@@ -33,10 +33,6 @@ type LegacyDecortClient struct {
|
||||
|
||||
// Legacy client builder
|
||||
func NewLegacy(cfg config.LegacyConfig) *LegacyDecortClient {
|
||||
if err := validators.ValidateConfig(cfg); err != nil {
|
||||
panic(validators.ValidationErrors(validators.GetErrors(err)))
|
||||
}
|
||||
|
||||
if cfg.Retries == 0 {
|
||||
cfg.Retries = 5
|
||||
}
|
||||
@@ -57,7 +53,7 @@ func NewLegacy(cfg config.LegacyConfig) *LegacyDecortClient {
|
||||
},
|
||||
},
|
||||
},
|
||||
cfg: trimLegacyConfig(&cfg),
|
||||
cfg: cfg,
|
||||
expiryTime: expiryTime,
|
||||
mutex: &sync.Mutex{},
|
||||
}
|
||||
@@ -73,25 +69,22 @@ func (ldc *LegacyDecortClient) CloudBroker() *cloudbroker.CloudBroker {
|
||||
return cloudbroker.New(ldc)
|
||||
}
|
||||
|
||||
// SDN builder
|
||||
func (ldc *LegacyDecortClient) SDN() *sdn.SDN {
|
||||
return sdn.New(ldc)
|
||||
}
|
||||
|
||||
// DecortApiCall method for sending requests to the platform
|
||||
func (ldc *LegacyDecortClient) DecortApiCall(ctx context.Context, method, url string, params interface{}) ([]byte, error) {
|
||||
// get token
|
||||
if err := ldc.getToken(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k8sCaCreateReq, okCa := params.(k8s_ca.CreateRequest)
|
||||
k8sCbCreateReq, okCb := params.(k8s_cb.CreateRequest)
|
||||
|
||||
var body *bytes.Buffer
|
||||
var ctype string
|
||||
|
||||
byteSlice, ok := params.([]byte)
|
||||
if ok {
|
||||
body = bytes.NewBuffer(byteSlice)
|
||||
ctype = "application/octet-stream"
|
||||
if okCa {
|
||||
body, ctype = createK8sCloudApiLegacy(k8sCaCreateReq, ldc.cfg.Token)
|
||||
} else if okCb {
|
||||
body, ctype = createK8sCloudBrokerLegacy(k8sCbCreateReq, ldc.cfg.Token)
|
||||
} else {
|
||||
values, err := query.Values(params)
|
||||
if err != nil {
|
||||
@@ -100,82 +93,14 @@ func (ldc *LegacyDecortClient) DecortApiCall(ctx context.Context, method, url st
|
||||
body = bytes.NewBufferString(values.Encode() + fmt.Sprintf("&authkey=%s", ldc.cfg.Token))
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, ldc.decortURL+constants.RESTMACHINE+url, body)
|
||||
req, err := http.NewRequestWithContext(ctx, method, ldc.decortURL+"/restmachine"+url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// perform request
|
||||
respBytes, err := ldc.do(req, ctype)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return respBytes, err
|
||||
}
|
||||
|
||||
// DecortApiCallCtype method for sending requests to the platform with content type
|
||||
func (ldc *LegacyDecortClient) DecortApiCallCtype(ctx context.Context, method, url, ctype string, params interface{}) ([]byte, error) {
|
||||
// get token
|
||||
if err := ldc.getToken(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var body *bytes.Buffer
|
||||
|
||||
switch ctype {
|
||||
case constants.MIMESTREAM:
|
||||
body = bytes.NewBuffer(params.([]byte))
|
||||
case constants.MIMEJSON:
|
||||
jsonBody, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body = bytes.NewBuffer(jsonBody)
|
||||
default:
|
||||
ctype = constants.MIMEPOSTForm
|
||||
values, err := query.Values(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body = bytes.NewBufferString(values.Encode() + fmt.Sprintf("&authkey=%s", ldc.cfg.Token))
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, ldc.decortURL+constants.RESTMACHINE+url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// perform request
|
||||
respBytes, err := ldc.do(req, ctype)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return respBytes, err
|
||||
}
|
||||
|
||||
func (ldc *LegacyDecortClient) DecortApiCallMP(ctx context.Context, method, url string, params interface{}) ([]byte, error) {
|
||||
body, ctype, err := multiPartReq(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, ldc.decortURL+constants.RESTMACHINE+url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// get token
|
||||
if err = ldc.getToken(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// perform request
|
||||
respBytes, err := ldc.do(req, ctype)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var respBytes []byte
|
||||
respBytes, err = ldc.do(req, ctype)
|
||||
|
||||
return respBytes, err
|
||||
}
|
||||
@@ -184,108 +109,60 @@ func (ldc *LegacyDecortClient) getToken(ctx context.Context) error {
|
||||
ldc.mutex.Lock()
|
||||
defer ldc.mutex.Unlock()
|
||||
|
||||
// new token is not needed
|
||||
if ldc.cfg.Token != "" && !time.Now().After(ldc.expiryTime) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// set up request headers and body
|
||||
if ldc.cfg.Token == "" || time.Now().After(ldc.expiryTime) {
|
||||
body := fmt.Sprintf("username=%s&password=%s", url.QueryEscape(ldc.cfg.Username), url.QueryEscape(ldc.cfg.Password))
|
||||
bodyReader := strings.NewReader(body)
|
||||
|
||||
req, _ := http.NewRequestWithContext(ctx, "POST", ldc.cfg.DecortURL+constants.RESTMACHINE+"/cloudapi/user/authenticate", bodyReader)
|
||||
req, _ := http.NewRequestWithContext(ctx, "POST", ldc.cfg.DecortURL+"/restmachine/cloudapi/user/authenticate", bodyReader)
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
||||
// request token
|
||||
resp, err := ldc.client.Do(req)
|
||||
if err != nil || resp == nil {
|
||||
return fmt.Errorf("cannot get token: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var tokenBytes []byte
|
||||
tokenBytes, err = io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot get token: %w", err)
|
||||
return fmt.Errorf("unable to get token: %w", err)
|
||||
}
|
||||
|
||||
tokenBytes, _ := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return fmt.Errorf("cannot get token: %s", tokenBytes)
|
||||
return fmt.Errorf("unable to get token: %s", tokenBytes)
|
||||
}
|
||||
|
||||
// save token in config
|
||||
token := string(tokenBytes)
|
||||
ldc.cfg.Token = token
|
||||
ldc.expiryTime = time.Now().AddDate(0, 0, 1)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// do method performs request and returns response as an array of bytes and nil error in case of response status code 200.
|
||||
// In any other cases do returns nil response and error.
|
||||
// Retries are implemented in case of connection reset errors.
|
||||
func (ldc *LegacyDecortClient) do(req *http.Request, ctype string) ([]byte, error) {
|
||||
// set up request headers and body
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
if ctype != "" {
|
||||
req.Header.Set("Content-Type", ctype)
|
||||
req.Header.Add("Content-Type", ctype)
|
||||
} else {
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
}
|
||||
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
buf, err := io.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Body.Close()
|
||||
req.Body = io.NopCloser(bytes.NewBuffer(buf))
|
||||
|
||||
resp, err := ldc.client.Do(req)
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
|
||||
// retries logic GOES HERE
|
||||
// get http response
|
||||
//var resp *http.Response
|
||||
//for i := uint64(0); i < ldc.cfg.Retries; i++ {
|
||||
// req := req.Clone(req.Context())
|
||||
// req.Body = io.NopCloser(bytes.NewBuffer(buf))
|
||||
//
|
||||
// if i > 0 {
|
||||
// time.Sleep(5 * time.Second) // no time sleep for the first request
|
||||
// }
|
||||
//
|
||||
// resp, err = ldc.client.Do(req)
|
||||
//
|
||||
// // stop retries on success and close response body
|
||||
// if resp != nil {
|
||||
// defer resp.Body.Close()
|
||||
// }
|
||||
// if err == nil {
|
||||
// break
|
||||
// }
|
||||
//
|
||||
// // retries in case of connection errors with time sleep
|
||||
// if isConnectionError(err) {
|
||||
// continue
|
||||
// }
|
||||
//
|
||||
// // return error in case of non-connection error
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
// handle http request errors
|
||||
if err != nil {
|
||||
if err != nil || resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp == nil {
|
||||
return nil, fmt.Errorf("got empty response without error")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
|
||||
// handle successful request
|
||||
respBytes, _ := io.ReadAll(resp.Body)
|
||||
respBytes, err := io.ReadAll(resp.Body)
|
||||
if err!= nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode == 200 {
|
||||
return respBytes, nil
|
||||
}
|
||||
@@ -295,7 +172,234 @@ func (ldc *LegacyDecortClient) do(req *http.Request, ctype string) ([]byte, erro
|
||||
return nil, fmt.Errorf("could not execute request: %w", err)
|
||||
}
|
||||
|
||||
func trimLegacyConfig(cfg *config.LegacyConfig) config.LegacyConfig {
|
||||
cfg.DecortURL = strings.TrimSuffix(cfg.DecortURL, "/")
|
||||
return *cfg
|
||||
func createK8sCloudApiLegacy(req k8s_ca.CreateRequest, token string) (*bytes.Buffer, string) {
|
||||
reqBody := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(reqBody)
|
||||
if req.OidcCertificate != "" {
|
||||
part, _ := writer.CreateFormFile("oidcCertificate", "ca.crt")
|
||||
_, _ = io.Copy(part, strings.NewReader(req.OidcCertificate))
|
||||
}
|
||||
|
||||
_ = writer.WriteField("name", req.Name)
|
||||
_ = writer.WriteField("rgId", strconv.FormatUint(req.RGID, 10))
|
||||
_ = writer.WriteField("k8ciId", strconv.FormatUint(req.K8SCIID, 10))
|
||||
_ = writer.WriteField("workerGroupName", req.WorkerGroupName)
|
||||
_ = writer.WriteField("networkPlugin", req.NetworkPlugin)
|
||||
|
||||
if req.MasterSEPID != 0 {
|
||||
_ = writer.WriteField("masterSepId", strconv.FormatUint(req.MasterSEPID, 10))
|
||||
}
|
||||
if req.MasterSEPPool != "" {
|
||||
_ = writer.WriteField("masterSepPool", req.MasterSEPPool)
|
||||
}
|
||||
if req.WorkerSEPID != 0 {
|
||||
_ = writer.WriteField("workerSepId", strconv.FormatUint(req.WorkerSEPID, 10))
|
||||
}
|
||||
if req.WorkerSEPPool != "" {
|
||||
_ = writer.WriteField("workerSepPool", req.WorkerSEPPool)
|
||||
}
|
||||
|
||||
if req.Labels != nil {
|
||||
for _, v := range req.Labels {
|
||||
_ = writer.WriteField("labels", v)
|
||||
}
|
||||
}
|
||||
if req.Taints != nil {
|
||||
for _, v := range req.Taints {
|
||||
_ = writer.WriteField("taints", v)
|
||||
}
|
||||
}
|
||||
if req.Annotations != nil {
|
||||
for _, v := range req.Annotations {
|
||||
_ = writer.WriteField("annotations", v)
|
||||
}
|
||||
}
|
||||
|
||||
if req.MasterCPU != 0 {
|
||||
_ = writer.WriteField("masterCpu", strconv.FormatUint(uint64(req.MasterCPU), 10))
|
||||
}
|
||||
if req.MasterNum != 0 {
|
||||
_ = writer.WriteField("masterNum", strconv.FormatUint(uint64(req.MasterNum), 10))
|
||||
}
|
||||
if req.MasterRAM != 0 {
|
||||
_ = writer.WriteField("masterRam", strconv.FormatUint(uint64(req.MasterRAM), 10))
|
||||
}
|
||||
if req.MasterDisk != 0 {
|
||||
_ = writer.WriteField("masterDisk", strconv.FormatUint(uint64(req.MasterDisk), 10))
|
||||
}
|
||||
if req.WorkerCPU != 0 {
|
||||
_ = writer.WriteField("workerCpu", strconv.FormatUint(uint64(req.WorkerCPU), 10))
|
||||
}
|
||||
if req.WorkerNum != 0 {
|
||||
_ = writer.WriteField("workerNum", strconv.FormatUint(uint64(req.WorkerNum), 10))
|
||||
}
|
||||
if req.WorkerRAM != 0 {
|
||||
_ = writer.WriteField("workerRam", strconv.FormatUint(uint64(req.WorkerRAM), 10))
|
||||
}
|
||||
if req.WorkerDisk != 0 {
|
||||
_ = writer.WriteField("workerDisk", strconv.FormatUint(uint64(req.WorkerDisk), 10))
|
||||
}
|
||||
if req.ExtNetID != 0 {
|
||||
_ = writer.WriteField("extnetId", strconv.FormatUint(req.ExtNetID, 10))
|
||||
}
|
||||
if req.VinsId != 0 {
|
||||
_ = writer.WriteField("vinsId", strconv.FormatUint(req.VinsId, 10))
|
||||
}
|
||||
if !req.WithLB {
|
||||
_ = writer.WriteField("withLB", strconv.FormatBool(req.WithLB))
|
||||
}
|
||||
|
||||
_ = writer.WriteField("highlyAvailableLB", strconv.FormatBool(req.HighlyAvailable))
|
||||
|
||||
if req.AdditionalSANs != nil {
|
||||
for _, v := range req.AdditionalSANs {
|
||||
_ = writer.WriteField("additionalSANs", v)
|
||||
}
|
||||
}
|
||||
if req.InitConfiguration != "" {
|
||||
_ = writer.WriteField("initConfiguration", req.InitConfiguration)
|
||||
}
|
||||
if req.ClusterConfiguration != "" {
|
||||
_ = writer.WriteField("clusterConfiguration", req.ClusterConfiguration)
|
||||
}
|
||||
if req.KubeletConfiguration != "" {
|
||||
_ = writer.WriteField("kubeletConfiguration", req.KubeletConfiguration)
|
||||
}
|
||||
if req.KubeProxyConfiguration != "" {
|
||||
_ = writer.WriteField("kubeProxyConfiguration", req.KubeProxyConfiguration)
|
||||
}
|
||||
if req.JoinConfiguration != "" {
|
||||
_ = writer.WriteField("joinConfiguration", req.JoinConfiguration)
|
||||
}
|
||||
if req.Description != "" {
|
||||
_ = writer.WriteField("desc", req.Description)
|
||||
}
|
||||
if req.UserData != "" {
|
||||
_ = writer.WriteField("userData", req.UserData)
|
||||
}
|
||||
|
||||
_ = writer.WriteField("extnetOnly", strconv.FormatBool(req.ExtNetOnly))
|
||||
|
||||
_ = writer.WriteField("authkey", token)
|
||||
|
||||
ct := writer.FormDataContentType()
|
||||
writer.Close()
|
||||
|
||||
return reqBody, ct
|
||||
}
|
||||
|
||||
func createK8sCloudBrokerLegacy(req k8s_cb.CreateRequest, token string) (*bytes.Buffer, string) {
|
||||
reqBody := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(reqBody)
|
||||
if req.OidcCertificate != "" {
|
||||
part, _ := writer.CreateFormFile("oidcCertificate", "ca.crt")
|
||||
_, _ = io.Copy(part, strings.NewReader(req.OidcCertificate))
|
||||
}
|
||||
|
||||
_ = writer.WriteField("name", req.Name)
|
||||
_ = writer.WriteField("rgId", strconv.FormatUint(req.RGID, 10))
|
||||
_ = writer.WriteField("k8ciId", strconv.FormatUint(req.K8CIID, 10))
|
||||
_ = writer.WriteField("workerGroupName", req.WorkerGroupName)
|
||||
_ = writer.WriteField("networkPlugin", req.NetworkPlugin)
|
||||
|
||||
if req.MasterSEPID != 0 {
|
||||
_ = writer.WriteField("masterSepId", strconv.FormatUint(req.MasterSEPID, 10))
|
||||
}
|
||||
if req.MasterSEPPool != "" {
|
||||
_ = writer.WriteField("masterSepPool", req.MasterSEPPool)
|
||||
}
|
||||
if req.WorkerSEPID != 0 {
|
||||
_ = writer.WriteField("workerSepId", strconv.FormatUint(req.WorkerSEPID, 10))
|
||||
}
|
||||
if req.WorkerSEPPool != "" {
|
||||
_ = writer.WriteField("workerSepPool", req.WorkerSEPPool)
|
||||
}
|
||||
|
||||
if req.Labels != nil {
|
||||
for _, v := range req.Labels {
|
||||
_ = writer.WriteField("labels", v)
|
||||
}
|
||||
}
|
||||
if req.Taints != nil {
|
||||
for _, v := range req.Taints {
|
||||
_ = writer.WriteField("taints", v)
|
||||
}
|
||||
}
|
||||
if req.Annotations != nil {
|
||||
for _, v := range req.Annotations {
|
||||
_ = writer.WriteField("annotations", v)
|
||||
}
|
||||
}
|
||||
|
||||
if req.MasterCPU != 0 {
|
||||
_ = writer.WriteField("masterCpu", strconv.FormatUint(req.MasterCPU, 10))
|
||||
}
|
||||
if req.MasterNum != 0 {
|
||||
_ = writer.WriteField("masterNum", strconv.FormatUint(req.MasterNum, 10))
|
||||
}
|
||||
if req.MasterRAM != 0 {
|
||||
_ = writer.WriteField("masterRam", strconv.FormatUint(req.MasterRAM, 10))
|
||||
}
|
||||
if req.MasterDisk != 0 {
|
||||
_ = writer.WriteField("masterDisk", strconv.FormatUint(req.MasterDisk, 10))
|
||||
}
|
||||
if req.WorkerCPU != 0 {
|
||||
_ = writer.WriteField("workerCpu", strconv.FormatUint(req.WorkerCPU, 10))
|
||||
}
|
||||
if req.WorkerNum != 0 {
|
||||
_ = writer.WriteField("workerNum", strconv.FormatUint(req.WorkerNum, 10))
|
||||
}
|
||||
if req.WorkerRAM != 0 {
|
||||
_ = writer.WriteField("workerRam", strconv.FormatUint(req.WorkerRAM, 10))
|
||||
}
|
||||
if req.WorkerDisk != 0 {
|
||||
_ = writer.WriteField("workerDisk", strconv.FormatUint(req.WorkerDisk, 10))
|
||||
}
|
||||
if req.ExtNetID != 0 {
|
||||
_ = writer.WriteField("extnetId", strconv.FormatUint(req.ExtNetID, 10))
|
||||
}
|
||||
if req.VinsId != 0 {
|
||||
_ = writer.WriteField("vinsId", strconv.FormatUint(req.VinsId, 10))
|
||||
}
|
||||
if !req.WithLB {
|
||||
_ = writer.WriteField("withLB", strconv.FormatBool(req.WithLB))
|
||||
}
|
||||
|
||||
_ = writer.WriteField("highlyAvailableLB", strconv.FormatBool(req.HighlyAvailable))
|
||||
|
||||
if req.AdditionalSANs != nil {
|
||||
for _, v := range req.AdditionalSANs {
|
||||
_ = writer.WriteField("additionalSANs", v)
|
||||
}
|
||||
}
|
||||
if req.InitConfiguration != "" {
|
||||
_ = writer.WriteField("initConfiguration", req.InitConfiguration)
|
||||
}
|
||||
if req.ClusterConfiguration != "" {
|
||||
_ = writer.WriteField("clusterConfiguration", req.ClusterConfiguration)
|
||||
}
|
||||
if req.KubeletConfiguration != "" {
|
||||
_ = writer.WriteField("kubeletConfiguration", req.KubeletConfiguration)
|
||||
}
|
||||
if req.KubeProxyConfiguration != "" {
|
||||
_ = writer.WriteField("kubeProxyConfiguration", req.KubeProxyConfiguration)
|
||||
}
|
||||
if req.JoinConfiguration != "" {
|
||||
_ = writer.WriteField("joinConfiguration", req.JoinConfiguration)
|
||||
}
|
||||
if req.Description != "" {
|
||||
_ = writer.WriteField("desc", req.Description)
|
||||
}
|
||||
if req.UserData != "" {
|
||||
_ = writer.WriteField("userData", req.UserData)
|
||||
}
|
||||
|
||||
_ = writer.WriteField("extnetOnly", strconv.FormatBool(req.ExtNetOnly))
|
||||
|
||||
_ = writer.WriteField("authkey", token)
|
||||
|
||||
ct := writer.FormDataContentType()
|
||||
|
||||
writer.Close()
|
||||
return reqBody, ct
|
||||
}
|
||||
|
||||
75
pkg/cloudapi/account/create.go
Normal file
75
pkg/cloudapi/account/create.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// CreateRequest struct for creating account
|
||||
type CreateRequest struct {
|
||||
// Display name
|
||||
// Required: true
|
||||
Name string `url:"name" json:"name" validate:"required"`
|
||||
|
||||
// Name of the account
|
||||
// Required: true
|
||||
Username string `url:"username" json:"username" validate:"required"`
|
||||
|
||||
// Email
|
||||
// Required: false
|
||||
EmailAddress string `url:"emailaddress,omitempty" json:"emailaddress,omitempty" validate:"omitempty,email"`
|
||||
|
||||
// Max size of memory in MB
|
||||
// Required: false
|
||||
MaxMemoryCapacity int64 `url:"maxMemoryCapacity,omitempty" json:"maxMemoryCapacity,omitempty"`
|
||||
|
||||
// Max size of aggregated vdisks in GB
|
||||
// Required: false
|
||||
MaxVDiskCapacity int64 `url:"maxVDiskCapacity,omitempty" json:"maxVDiskCapacity,omitempty"`
|
||||
|
||||
// Max number of CPU cores
|
||||
// Required: false
|
||||
MaxCPUCapacity int64 `url:"maxCPUCapacity,omitempty" json:"maxCPUCapacity,omitempty"`
|
||||
|
||||
// Max sent/received network transfer peering
|
||||
// Required: false
|
||||
MaxNetworkPeerTransfer int64 `url:"maxNetworkPeerTransfer,omitempty" json:"maxNetworkPeerTransfer,omitempty"`
|
||||
|
||||
// Max number of assigned public IPs
|
||||
// Required: false
|
||||
MaxNumPublicIP int64 `url:"maxNumPublicIP,omitempty" json:"maxNumPublicIP,omitempty"`
|
||||
|
||||
// If true send emails when a user is granted access to resources
|
||||
// Required: false
|
||||
SendAccessEmails bool `url:"sendAccessEmails" json:"sendAccessEmails"`
|
||||
|
||||
// Limit (positive) or disable (0) GPU resources
|
||||
// Required: false
|
||||
GPUUnits int64 `url:"gpu_units,omitempty" json:"gpu_units,omitempty"`
|
||||
}
|
||||
|
||||
// Create creates account
|
||||
// Setting a cloud unit maximum to -1 or empty will not put any restrictions on the resource
|
||||
func (a Account) Create(ctx context.Context, req CreateRequest) (uint64, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return 0, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/account/create"
|
||||
|
||||
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseUint(string(res), 10, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
@@ -19,18 +19,18 @@ type DeleteRequest struct {
|
||||
}
|
||||
|
||||
// Delete completes delete an account from the system Returns true if account is deleted or was already deleted or never existed
|
||||
func (a Account) Delete(ctx context.Context, req DeleteRequest) (string, error) {
|
||||
func (a Account) Delete(ctx context.Context, req DeleteRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/account/delete"
|
||||
|
||||
result, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
_, err = a.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return false, err
|
||||
}
|
||||
|
||||
return string(result), nil
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -17,6 +17,10 @@ type DeleteUserRequest struct {
|
||||
// ID or emailaddress of the user to remove
|
||||
// Required: true
|
||||
UserID string `url:"userId" json:"userId" validate:"required"`
|
||||
|
||||
// Recursively revoke access rights from owned cloudspaces and vmachines
|
||||
// Required: false
|
||||
RecursiveDelete bool `url:"recursivedelete" json:"recursivedelete"`
|
||||
}
|
||||
|
||||
// DeleteUser revokes user access from the account
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
var accounts = ListAccounts{
|
||||
Data: []ItemAccount{
|
||||
{
|
||||
ACL: []ListRecordACL{
|
||||
ACL: []RecordACL{
|
||||
{
|
||||
IsExplicit: true,
|
||||
GUID: "",
|
||||
@@ -25,7 +25,7 @@ var accounts = ListAccounts{
|
||||
UpdatedTime: 1676645275,
|
||||
},
|
||||
{
|
||||
ACL: []ListRecordACL{
|
||||
ACL: []RecordACL{
|
||||
{
|
||||
IsExplicit: true,
|
||||
GUID: "",
|
||||
@@ -43,7 +43,7 @@ var accounts = ListAccounts{
|
||||
UpdatedTime: 1676645275,
|
||||
},
|
||||
{
|
||||
ACL: []ListRecordACL{
|
||||
ACL: []RecordACL{
|
||||
{
|
||||
IsExplicit: true,
|
||||
GUID: "",
|
||||
|
||||
@@ -27,8 +27,11 @@ type GetConsumedCloudUnitsByTypeRequest struct {
|
||||
// - CU_C: returns number of virtual cpu cores
|
||||
// - CU_D: returns consumed virtual disk storage in GB
|
||||
// - CU_DM: returns consumed max virtual disk storage in GB
|
||||
// - CU_S: returns consumed primary storage (NAS) in TB
|
||||
// - CU_A: returns consumed secondary storage (Archive) in TB
|
||||
// - CU_NO: returns sent/received network transfer in operator in GB
|
||||
// - CU_NP: returns sent/received network transfer peering in GB
|
||||
// - CU_I: returns number of public IPs
|
||||
// - gpu_units: return number of GPU units
|
||||
func (a Account) GetConsumedCloudUnitsByType(ctx context.Context, req GetConsumedCloudUnitsByTypeRequest) (float64, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
|
||||
58
pkg/cloudapi/account/get_consumption.go
Normal file
58
pkg/cloudapi/account/get_consumption.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// GetConsumptionRequest struct to download the resources tracking files for an account
|
||||
type GetConsumptionRequest struct {
|
||||
// ID an account
|
||||
// Required: true
|
||||
AccountID uint64 `url:"accountId" json:"accountId" validate:"required"`
|
||||
|
||||
// Epoch represents the start time
|
||||
// Required: true
|
||||
Start uint64 `url:"start" json:"start" validate:"required"`
|
||||
|
||||
// Epoch represents the end time
|
||||
// Required: true
|
||||
End uint64 `url:"end" json:"end" validate:"required"`
|
||||
}
|
||||
|
||||
// GetConsumption downloads the resources tracking files for an account within a given period
|
||||
func (a Account) GetConsumption(ctx context.Context, req GetConsumptionRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/account/getConsumption"
|
||||
|
||||
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
|
||||
}
|
||||
|
||||
// GetConsumptionGet downloads the resources tracking files for an account within a given period
|
||||
func (a Account) GetConsumptionGet(ctx context.Context, req GetConsumptionRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/account/getConsumption"
|
||||
|
||||
res, err := a.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
@@ -4,8 +4,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// ListRequest struct to get list of accounts
|
||||
@@ -26,15 +24,6 @@ type ListRequest struct {
|
||||
// Required: false
|
||||
Status string `url:"status,omitempty" json:"status,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||
|
||||
// Sort by zone id
|
||||
// Default value: 0
|
||||
// Required: false
|
||||
ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
|
||||
|
||||
// Page number
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
@@ -46,7 +35,6 @@ type ListRequest struct {
|
||||
|
||||
// List gets a list of all accounts the user has access to a ListAccounts struct
|
||||
func (a Account) List(ctx context.Context, req ListRequest) (*ListAccounts, error) {
|
||||
|
||||
res, err := a.ListRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -64,11 +52,6 @@ func (a Account) List(ctx context.Context, req ListRequest) (*ListAccounts, erro
|
||||
|
||||
// ListRaw gets a list of all accounts the user has access to as an array of bytes
|
||||
func (a Account) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/account/list"
|
||||
|
||||
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
|
||||
@@ -46,10 +46,6 @@ type ListComputesRequest struct {
|
||||
// Required: false
|
||||
ExtNetID uint64 `url:"extNetId,omitempty" json:"extNetId,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||
|
||||
// Page number
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
@@ -61,7 +57,6 @@ type ListComputesRequest struct {
|
||||
|
||||
// ListComputes gets list all compute instances under specified account, accessible by the user
|
||||
func (a Account) ListComputes(ctx context.Context, req ListComputesRequest) (*ListComputes, error) {
|
||||
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
|
||||
@@ -4,8 +4,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// ListDeletedRequest struct to get a list of deleted accounts
|
||||
@@ -29,20 +27,10 @@ type ListDeletedRequest struct {
|
||||
// Find by access control list
|
||||
// Required: false
|
||||
ACL string `url:"acl,omitempty" json:"acl,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||
}
|
||||
|
||||
// ListDeleted gets list of all deleted accounts the user has access to
|
||||
func (a Account) ListDeleted(ctx context.Context, req ListDeletedRequest) (*ListAccounts, error) {
|
||||
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/account/listDeleted"
|
||||
|
||||
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
|
||||
@@ -30,10 +30,6 @@ type ListDisksRequest struct {
|
||||
// Required: false
|
||||
Type string `url:"type,omitempty" json:"type,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||
|
||||
// Page number
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
@@ -45,7 +41,6 @@ type ListDisksRequest struct {
|
||||
|
||||
// ListDisks gets list all currently unattached disks under specified account
|
||||
func (a Account) ListDisks(ctx context.Context, req ListDisksRequest) (*ListDisks, error) {
|
||||
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
|
||||
@@ -38,10 +38,6 @@ type ListFLIPGroupsRequest struct {
|
||||
// Required: false
|
||||
FLIPGroupID uint64 `url:"flipGroupId,omitempty" json:"flipGroupId,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||
|
||||
// Page number
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
@@ -53,7 +49,6 @@ type ListFLIPGroupsRequest struct {
|
||||
|
||||
// ListFLIPGroups gets list all FLIPGroups under specified account, accessible by the user
|
||||
func (a Account) ListFLIPGroups(ctx context.Context, req ListFLIPGroupsRequest) (*ListFLIPGroups, error) {
|
||||
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
|
||||
@@ -41,15 +41,10 @@ type ListRGRequest struct {
|
||||
// Find by status
|
||||
// Required: false
|
||||
Status string `url:"status,omitempty" json:"status,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||
}
|
||||
|
||||
// ListRG gets list of all resource groups under specified account, accessible by the user
|
||||
func (a Account) ListRG(ctx context.Context, req ListRGRequest) (*ListRG, error) {
|
||||
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
|
||||
@@ -30,10 +30,6 @@ type ListTemplatesRequest struct {
|
||||
// Required: false
|
||||
Type string `url:"type,omitempty" json:"type,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||
|
||||
// Page number
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
@@ -45,7 +41,6 @@ type ListTemplatesRequest struct {
|
||||
|
||||
// ListTemplates gets list of templates which can be managed by this account
|
||||
func (a Account) ListTemplates(ctx context.Context, req ListTemplatesRequest) (*ListTemplates, error) {
|
||||
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
|
||||
@@ -30,10 +30,6 @@ type ListVINSRequest struct {
|
||||
// Required: false
|
||||
ExtIP string `url:"extIp,omitempty" json:"extIp,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||
|
||||
// Page number
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
@@ -45,7 +41,6 @@ type ListVINSRequest struct {
|
||||
|
||||
// ListVINS gets list of all ViNSes under specified account, accessible by the user
|
||||
func (a Account) ListVINS(ctx context.Context, req ListVINSRequest) (*ListVINS, error) {
|
||||
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
|
||||
@@ -1,34 +1,7 @@
|
||||
package account
|
||||
|
||||
// Access Control List
|
||||
type ListRecordACL struct {
|
||||
// Whether access is explicitly specified
|
||||
IsExplicit bool `json:"explicit"`
|
||||
|
||||
// GUID
|
||||
GUID string `json:"guid"`
|
||||
|
||||
// Access rights
|
||||
Rights string `json:"right"`
|
||||
|
||||
// Status
|
||||
Status string `json:"status"`
|
||||
|
||||
// Account Type
|
||||
Type string `json:"type"`
|
||||
|
||||
// Account owner ID
|
||||
UgroupID string `json:"userGroupId"`
|
||||
|
||||
// Is it possible to remove
|
||||
CanBeDeleted bool `json:"canBeDeleted"`
|
||||
}
|
||||
|
||||
// Access Control List
|
||||
type RecordACL struct {
|
||||
// Emails
|
||||
Emails []string `json:"emails"`
|
||||
|
||||
// Whether access is explicitly specified
|
||||
IsExplicit bool `json:"explicit"`
|
||||
|
||||
@@ -68,26 +41,17 @@ type ResourceLimits struct {
|
||||
// RAM size, MB
|
||||
CUM float64 `json:"CU_M"`
|
||||
|
||||
// Traffic volume, GB
|
||||
CUNP float64 `json:"CU_NP"`
|
||||
|
||||
// Number of graphics cores
|
||||
GPUUnits float64 `json:"gpu_units"`
|
||||
|
||||
// Storage policy
|
||||
StoragePolicy []StoragePolicyItem `json:"storage_policy"`
|
||||
}
|
||||
|
||||
type StoragePolicyItem struct {
|
||||
ID uint64 `json:"id"`
|
||||
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
|
||||
// Main information in one of if the list of accounts
|
||||
type ItemAccount struct {
|
||||
// Access Control List
|
||||
ACL []ListRecordACL `json:"acl"`
|
||||
|
||||
// Compute Features
|
||||
ComputeFeatures []string `json:"computeFeatures"`
|
||||
ACL []RecordACL `json:"acl"`
|
||||
|
||||
// Created time
|
||||
CreatedTime uint64 `json:"createdTime"`
|
||||
@@ -95,12 +59,6 @@ type ItemAccount struct {
|
||||
// Deleted time
|
||||
DeletedTime uint64 `json:"deletedTime"`
|
||||
|
||||
// Deleted by
|
||||
DeletedBy string `json:"deletedBy"`
|
||||
|
||||
// Description
|
||||
Description string `json:"desc"`
|
||||
|
||||
// ID
|
||||
ID uint64 `json:"id"`
|
||||
|
||||
@@ -110,14 +68,8 @@ type ItemAccount struct {
|
||||
// Status
|
||||
Status string `json:"status"`
|
||||
|
||||
// Updated by
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
|
||||
// Updated time
|
||||
UpdatedTime uint64 `json:"updatedTime"`
|
||||
|
||||
// Zones
|
||||
ZoneIDs []uint64 `json:"zoneIds"`
|
||||
}
|
||||
|
||||
// List of accounts
|
||||
@@ -127,18 +79,6 @@ type ListAccounts struct {
|
||||
EntryCount uint64 `json:"entryCount"`
|
||||
}
|
||||
|
||||
// Policy
|
||||
type Policy struct {
|
||||
// Size of the disk
|
||||
DiskSize float64 `json:"disksize"`
|
||||
|
||||
// Max size of the disk
|
||||
DiskSizeMax float64 `json:"disksizemax"`
|
||||
|
||||
// SEPs used
|
||||
SEPs map[string]map[string]DiskUsage `json:"seps"`
|
||||
}
|
||||
|
||||
// Resources used
|
||||
type Resource struct {
|
||||
// Number of cores
|
||||
@@ -153,12 +93,12 @@ type Resource struct {
|
||||
// Number of External IPs
|
||||
ExtIPs int64 `json:"extips"`
|
||||
|
||||
// External traffic
|
||||
ExtTraffic int64 `json:"exttraffic"`
|
||||
|
||||
// Number of grafic cores
|
||||
GPU int64 `json:"gpu"`
|
||||
|
||||
// Policies
|
||||
Policies map[string]Policy `json:"policies"`
|
||||
|
||||
// Number of RAM
|
||||
RAM int64 `json:"ram"`
|
||||
|
||||
@@ -219,20 +159,14 @@ type Machines struct {
|
||||
Halted uint64 `json:"halted"`
|
||||
}
|
||||
|
||||
// Detailed information about the account zone
|
||||
type ZoneID struct {
|
||||
// ID of zone
|
||||
ID int64 `json:"id"`
|
||||
|
||||
// Name of zone
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// Main information about account
|
||||
type RecordAccount struct {
|
||||
// DCLocation
|
||||
DCLocation string `json:"DCLocation"`
|
||||
|
||||
// CKey
|
||||
CKey string `json:"_ckey"`
|
||||
|
||||
// Access control list
|
||||
ACL []RecordACL `json:"acl"`
|
||||
|
||||
@@ -242,9 +176,6 @@ type RecordAccount struct {
|
||||
// Company URL
|
||||
CompanyURL string `json:"companyurl"`
|
||||
|
||||
// Compute Features
|
||||
ComputeFeatures []string `json:"computeFeatures"`
|
||||
|
||||
// Computes
|
||||
Computes Computes `json:"computes"`
|
||||
|
||||
@@ -252,7 +183,7 @@ type RecordAccount struct {
|
||||
CPUAllocationParameter string `json:"cpu_allocation_parameter"`
|
||||
|
||||
// CPU allocation ratio
|
||||
CPUAllocationRatio uint64 `json:"cpu_allocation_ratio"`
|
||||
CPUAllocationRatio float64 `json:"cpu_allocation_ratio"`
|
||||
|
||||
// Created by
|
||||
CreatedBy string `json:"createdBy"`
|
||||
@@ -260,9 +191,6 @@ type RecordAccount struct {
|
||||
// Created time
|
||||
CreatedTime uint64 `json:"createdTime"`
|
||||
|
||||
// Description
|
||||
Description string `json:"desc"`
|
||||
|
||||
// Deactivation time
|
||||
DeactivationTime float64 `json:"deactivationTime"`
|
||||
|
||||
@@ -299,15 +227,9 @@ type RecordAccount struct {
|
||||
// Status
|
||||
Status string `json:"status"`
|
||||
|
||||
// Storage policy ids
|
||||
StoragePolicyIDs []uint64 `json:"storage_policy_ids"`
|
||||
|
||||
// UniqPools
|
||||
UniqPools []interface{} `json:"uniqPools"`
|
||||
|
||||
// Updated By
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
|
||||
// Updated time
|
||||
UpdatedTime uint64 `json:"updatedTime"`
|
||||
|
||||
@@ -319,12 +241,6 @@ type RecordAccount struct {
|
||||
|
||||
// VINSes
|
||||
VINSes uint64 `json:"vinses"`
|
||||
|
||||
// Zone
|
||||
ZoneIDs []ZoneID `json:"zoneIds"`
|
||||
|
||||
// Zones
|
||||
DefaultZoneID uint64 `json:"defaultZoneId"`
|
||||
}
|
||||
|
||||
// Main information about compute
|
||||
@@ -458,12 +374,6 @@ type ItemVINS struct {
|
||||
// External IP
|
||||
ExternalIP string `json:"externalIP"`
|
||||
|
||||
// Extnet ID
|
||||
ExtnetId uint64 `json:"extnetId"`
|
||||
|
||||
// Free IPs
|
||||
FreeIPs int64 `json:"freeIPs"`
|
||||
|
||||
// ID
|
||||
ID uint64 `json:"id"`
|
||||
|
||||
@@ -557,6 +467,9 @@ type LimitsRG struct {
|
||||
// Number of External IPs
|
||||
ExtIPs int64 `json:"extips"`
|
||||
|
||||
// External traffic
|
||||
ExtTraffic int64 `json:"exttraffic"`
|
||||
|
||||
// Number of grafic cores
|
||||
GPU int64 `json:"gpu"`
|
||||
|
||||
@@ -565,9 +478,6 @@ type LimitsRG struct {
|
||||
|
||||
// SEPs
|
||||
SEPs uint64 `json:"seps"`
|
||||
|
||||
// Policies
|
||||
Policies map[string]Policy `json:"policies"`
|
||||
}
|
||||
|
||||
// Main information about resource group
|
||||
@@ -590,9 +500,6 @@ type ItemRG struct {
|
||||
// Deleted time
|
||||
DeletedTime uint64 `json:"deletedTime"`
|
||||
|
||||
// Description
|
||||
Description string `json:"desc"`
|
||||
|
||||
// Resource group ID
|
||||
RGID uint64 `json:"id"`
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package account
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
@@ -15,18 +14,18 @@ type RestoreRequest struct {
|
||||
}
|
||||
|
||||
// Restore restores a deleted account
|
||||
func (a Account) Restore(ctx context.Context, req RestoreRequest) (string, error) {
|
||||
func (a Account) Restore(ctx context.Context, req RestoreRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/account/restore"
|
||||
|
||||
result, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
_, err = a.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return false, err
|
||||
}
|
||||
|
||||
return string(result), nil
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -14,10 +14,6 @@ type UpdateRequest struct {
|
||||
// Required: true
|
||||
AccountID uint64 `url:"accountId" json:"accountId" validate:"required"`
|
||||
|
||||
// Description
|
||||
// Required: false
|
||||
Description string `url:"desc,omitempty" json:"desc,omitempty"`
|
||||
|
||||
// Name of the account
|
||||
// Required: false
|
||||
Name string `url:"name,omitempty" json:"name,omitempty"`
|
||||
@@ -34,6 +30,10 @@ type UpdateRequest struct {
|
||||
// Required: false
|
||||
MaxCPUCapacity int64 `url:"maxCPUCapacity,omitempty" json:"maxCPUCapacity,omitempty"`
|
||||
|
||||
// Max sent/received network transfer peering
|
||||
// Required: false
|
||||
MaxNetworkPeerTransfer int64 `url:"maxNetworkPeerTransfer,omitempty" json:"maxNetworkPeerTransfer,omitempty"`
|
||||
|
||||
// Max number of assigned public IPs
|
||||
// Required: false
|
||||
MaxNumPublicIP int64 `url:"maxNumPublicIP,omitempty" json:"maxNumPublicIP,omitempty"`
|
||||
@@ -45,15 +45,6 @@ type UpdateRequest struct {
|
||||
// Limit (positive) or disable (0) GPU resources
|
||||
// Required: false
|
||||
GPUUnits int64 `url:"gpu_units,omitempty" json:"gpu_units,omitempty"`
|
||||
|
||||
// List of strings with pools
|
||||
// i.e.: ["sep1_poolName1", "sep2_poolName2", etc]
|
||||
// Required: false
|
||||
UniqPools []string `url:"uniqPools,omitempty" json:"uniqPools,omitempty"`
|
||||
|
||||
// Default zone ID
|
||||
// Required: false
|
||||
DefaultZoneID uint64 `url:"defaultZoneId,omitempty" json:"defaultZoneId,omitempty"`
|
||||
}
|
||||
|
||||
// Update updates an account name and resource types and limits
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
package cloudapi
|
||||
|
||||
import (
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/audit"
|
||||
)
|
||||
|
||||
// Accessing the Stack method group
|
||||
func (ca *CloudAPI) Audit() *audit.Audit {
|
||||
return audit.New(ca.client)
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package audit
|
||||
|
||||
import "repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
|
||||
|
||||
// Structure for creating request to audit
|
||||
type Audit struct {
|
||||
client interfaces.Caller
|
||||
}
|
||||
|
||||
// Builder for audit endpoint
|
||||
func New(client interfaces.Caller) *Audit{
|
||||
return &Audit{
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package audit
|
||||
|
||||
// FilterByID returns ListAudits with specified ID.
|
||||
func (la ListAudits) FilterByID(guid string) ListAudits {
|
||||
predicate := func(ia ItemAudit) bool {
|
||||
return ia.GUID == guid
|
||||
}
|
||||
|
||||
return la.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterByCall returns ListAudits with specified call.
|
||||
func (la ListAudits) FilterByCall(call string) ListAudits {
|
||||
predicate := func(ic ItemAudit) bool {
|
||||
return ic.Call == call
|
||||
}
|
||||
|
||||
return la.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterByCorrelationID returns ListAudits with specified correlation id.
|
||||
func (la ListAudits) FilterByCorrelationID(correlationID string) ListAudits {
|
||||
predicate := func(ic ItemAudit) bool {
|
||||
return ic.CorrelationID == correlationID
|
||||
}
|
||||
|
||||
return la.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterByRemoteAddr returns ListAudits with specified remote address.
|
||||
func (la ListAudits) FilterByRemoteAddr(remoteAddr string) ListAudits {
|
||||
predicate := func(ic ItemAudit) bool {
|
||||
return ic.RemoteAddr == remoteAddr
|
||||
}
|
||||
|
||||
return la.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterByUser returns ListAudits with specified user name.
|
||||
func (la ListAudits) FilterByUser(user string) ListAudits {
|
||||
predicate := func(ic ItemAudit) bool {
|
||||
return ic.User == user
|
||||
}
|
||||
|
||||
return la.FilterFunc(predicate)
|
||||
}
|
||||
|
||||
// FilterByStatusCode return ListAudits with specified status code.
|
||||
func (la ListAudits) FilterByStatusCode(statusCode uint64) ListAudits {
|
||||
predicate := func(ic ItemAudit) bool {
|
||||
return ic.StatusCode == statusCode
|
||||
}
|
||||
|
||||
return la.FilterFunc(predicate)
|
||||
|
||||
}
|
||||
|
||||
// FilterFunc allows filtering ListAudits based on a user-specified predicate.
|
||||
func (la ListAudits) FilterFunc(predicate func(ItemAudit) bool) ListAudits {
|
||||
var result ListAudits
|
||||
|
||||
for _, item := range la.Data {
|
||||
if predicate(item) {
|
||||
result.Data = append(result.Data, item)
|
||||
}
|
||||
}
|
||||
|
||||
result.EntryCount = uint64(len(result.Data))
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// FindOne returns first found ItemAudit
|
||||
// If none was found, returns an empty struct.
|
||||
func (la ListAudits) FindOne() ItemAudit {
|
||||
if len(la.Data) == 0 {
|
||||
return ItemAudit{}
|
||||
}
|
||||
|
||||
return la.Data[0]
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
package audit
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var audits = ListAudits{
|
||||
Data: []ItemAudit{
|
||||
{
|
||||
Args: "[]",
|
||||
Call: "/restmachine/cloudapi/audit/linkedJobs",
|
||||
GUID: "550e8400-e29b-41d4-a716-446655440001",
|
||||
CorrelationID: "550e8400-e29b-41d4-a716-446655440001",
|
||||
Kwargs: `{\"audit_guid\":\"dd8623a1-a887-48c1-a500-c10210d404cf\"}`,
|
||||
RemoteAddr: "192.168.1.100",
|
||||
ResponseTime: 1,
|
||||
Result: `[]`,
|
||||
StatusCode: 200,
|
||||
Timestamp: 1640995200,
|
||||
TimestampEnd: 1640995201,
|
||||
User: "test@example.com",
|
||||
TTL: "2025-07-31T14:22:57.028000",
|
||||
},
|
||||
{
|
||||
Args: "[]",
|
||||
Call: "/restmachine/cloudapi/audit/test",
|
||||
GUID: "550e8400-e29b-41d4-a716-446655440002",
|
||||
CorrelationID: "550e8400-e29b-41d4-a716-446655440002",
|
||||
Kwargs: `{\"audit_guid\":\"dd8623a1-a887-48c1-a500-c10210d404cf\"}`,
|
||||
RemoteAddr: "192.168.1.105",
|
||||
ResponseTime: 5,
|
||||
Result: `[]`,
|
||||
StatusCode: 400,
|
||||
Timestamp: 1640995200,
|
||||
TimestampEnd: 1640995201,
|
||||
User: "test2@example.com",
|
||||
TTL: "2025-07-31T14:22:57.028000",
|
||||
},
|
||||
},
|
||||
EntryCount: 2,
|
||||
}
|
||||
|
||||
func TestFilterByID(t *testing.T) {
|
||||
actual := audits.FilterByID("550e8400-e29b-41d4-a716-446655440002").FindOne()
|
||||
|
||||
if actual.GUID != "550e8400-e29b-41d4-a716-446655440002" {
|
||||
t.Fatal("expected GUID 550e8400-e29b-41d4-a716-446655440002, found: ", actual.GUID)
|
||||
}
|
||||
|
||||
actualEmpty := audits.FilterByID("")
|
||||
|
||||
if len(actualEmpty.Data) != 0 {
|
||||
t.Fatal("expected empty, actual: ", len(actualEmpty.Data))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByCorrelationID(t *testing.T) {
|
||||
actual := audits.FilterByCorrelationID("550e8400-e29b-41d4-a716-446655440002").FindOne()
|
||||
|
||||
if actual.CorrelationID != "550e8400-e29b-41d4-a716-446655440002" {
|
||||
t.Fatal("expected GUID 550e8400-e29b-41d4-a716-446655440002, found: ", actual.CorrelationID)
|
||||
}
|
||||
|
||||
actualEmpty := audits.FilterByCorrelationID("")
|
||||
|
||||
if len(actualEmpty.Data) != 0 {
|
||||
t.Fatal("expected empty, actual: ", len(actualEmpty.Data))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByRemoteAddr(t *testing.T) {
|
||||
actual := audits.FilterByRemoteAddr("192.168.1.100").FindOne()
|
||||
|
||||
if actual.RemoteAddr != "192.168.1.100" {
|
||||
t.Fatal("expected remote address 192.168.1.100, found: ", actual.RemoteAddr)
|
||||
}
|
||||
|
||||
actualEmpty := audits.FilterByRemoteAddr("")
|
||||
|
||||
if len(actualEmpty.Data) != 0 {
|
||||
t.Fatal("expected empty, actual: ", len(actualEmpty.Data))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByUser(t *testing.T) {
|
||||
actual := audits.FilterByUser("test@example.com").FindOne()
|
||||
|
||||
if actual.User != "test@example.com" {
|
||||
t.Fatal("expected user test@example.com, found: ", actual.RemoteAddr)
|
||||
}
|
||||
|
||||
actualEmpty := audits.FilterByUser("")
|
||||
|
||||
if len(actualEmpty.Data) != 0 {
|
||||
t.Fatal("expected empty, actual: ", len(actualEmpty.Data))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByCall(t *testing.T) {
|
||||
actual := audits.FilterByCall("/restmachine/cloudapi/audit/test").FindOne()
|
||||
|
||||
if actual.Call != "/restmachine/cloudapi/audit/test" {
|
||||
t.Fatal("expected call /restmachine/cloudapi/audit/test, found: ", actual.Call)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterByStatusCode(t *testing.T) {
|
||||
actual := audits.FilterByStatusCode(200)
|
||||
|
||||
for _, item := range actual.Data {
|
||||
if item.StatusCode != 200 {
|
||||
t.Fatal("expected 200 status code, found: ", item.StatusCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package audit
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// GetRequest struct to get information about account
|
||||
type GetRequest struct {
|
||||
// Audit GUID
|
||||
// Required: true
|
||||
AuditGuid string `url:"audit_guid" json:"audit_guid" validate:"required"`
|
||||
}
|
||||
|
||||
// Get gets information about audit as a RecordAudit struct
|
||||
func (a Audit) Get(ctx context.Context, req GetRequest) (*RecordAudit, error) {
|
||||
res, err := a.GetRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := RecordAudit{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
// GetRaw gets information about audit as an array of bytes
|
||||
func (a Audit) GetRaw(ctx context.Context, req GetRequest) ([]byte, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/audit/get"
|
||||
|
||||
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
return res, err
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
package audit
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// ListRequest struct to give list of account audits
|
||||
type ListRequest struct {
|
||||
|
||||
// Find all audits after point in time (unixtime)
|
||||
// Required: false
|
||||
TimestampAt uint64 `url:"timestamp_at,omitempty" json:"timestamp_at,omitempty"`
|
||||
|
||||
// Find all audits before point in time (unixtime)
|
||||
// Required: false
|
||||
TimestampTo uint64 `url:"timestamp_to,omitempty" json:"timestamp_to,omitempty"`
|
||||
|
||||
// Find by user (Mongo RegExp supported)
|
||||
// Required: false
|
||||
User string `url:"user,omitempty" json:"user,omitempty"`
|
||||
|
||||
// Find by api endpoint (Mongo RegExp supported)
|
||||
// Required: false
|
||||
Call string `url:"call,omitempty" json:"call,omitempty"`
|
||||
|
||||
// Find by request id
|
||||
// Required: false
|
||||
RequestID string `url:"request_id,omitempty" json:"request_id,omitempty"`
|
||||
|
||||
// Find by HTTP min status code
|
||||
// Required: false
|
||||
MinStatusCode uint64 `url:"min_status_code,omitempty" json:"min_status_code,omitempty"`
|
||||
|
||||
// Find by HTTP max status code
|
||||
// Required: false
|
||||
MaxStatusCode uint64 `url:"max_status_code,omitempty" json:"max_status_code,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty" validate:"omitempty,sortBy"`
|
||||
|
||||
// Page number
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
|
||||
// Page size
|
||||
// Required: false
|
||||
Size uint64 `url:"size,omitempty" json:"size,omitempty"`
|
||||
|
||||
// Find by resource group id
|
||||
// Required: false
|
||||
RGID uint64 `url:"resgroup_id,omitempty" json:"resgroup_id,omitempty"`
|
||||
|
||||
// Find by compute id
|
||||
// Required: false
|
||||
ComputeID uint64 `url:"compute_id,omitempty" json:"compute_id,omitempty"`
|
||||
|
||||
// Find by account id
|
||||
// Required: false
|
||||
AccountID uint64 `url:"account_id,omitempty" json:"account_id,omitempty"`
|
||||
|
||||
// Find by vins id
|
||||
// Required: false
|
||||
VINSID uint64 `url:"vins_id,omitempty" json:"vins_id,omitempty"`
|
||||
|
||||
// Find by service id
|
||||
// Required: false
|
||||
ServiceID uint64 `url:"service_id,omitempty" json:"service_id,omitempty"`
|
||||
|
||||
// Find by k8s id
|
||||
// Required: false
|
||||
K8SID uint64 `url:"k8s_id,omitempty" json:"k8s_id,omitempty"`
|
||||
|
||||
// Find by flipgroup id
|
||||
// Required: false
|
||||
FLIPGroupID uint64 `url:"flipgroup_id,omitempty" json:"flipgroup_id,omitempty"`
|
||||
|
||||
// Find by load balancer id
|
||||
// Required: false
|
||||
LBID uint64 `url:"lb_id,omitempty" json:"lb_id,omitempty"`
|
||||
|
||||
// Find by sep id
|
||||
// Required: false
|
||||
SEPID uint64 `url:"sep_id,omitempty" json:"sep_id,omitempty"`
|
||||
|
||||
// Exclude audit lines from response
|
||||
// Required: false
|
||||
ExcludeAuditLines bool `url:"exclude_audit_lines,omitempty" json:"exclude_audit_lines,omitempty"`
|
||||
}
|
||||
|
||||
// List gets audit records for the specified account object
|
||||
func (a Audit) List(ctx context.Context, req ListRequest) (*ListAudits, error) {
|
||||
|
||||
res, err := a.ListRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list := ListAudits{}
|
||||
|
||||
err = json.Unmarshal(res, &list)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &list, nil
|
||||
}
|
||||
|
||||
// ListRaw gets list of audit records an array of bytes
|
||||
func (a Audit) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/audit/list"
|
||||
|
||||
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
return res, err
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
package audit
|
||||
|
||||
// Main info about audit
|
||||
type RecordAudit struct {
|
||||
|
||||
// Arguments
|
||||
Arguments string `json:"args"`
|
||||
|
||||
// Call
|
||||
Call string `json:"call"`
|
||||
|
||||
// GUID
|
||||
GUID string `json:"guid"`
|
||||
|
||||
// Correlation ID
|
||||
CorrelationID string `json:"correlation_id"`
|
||||
|
||||
// Kwargs
|
||||
Kwargs string `json:"kwargs"`
|
||||
|
||||
// RemoteAddr
|
||||
RemoteAddr string `json:"remote_addr"`
|
||||
|
||||
// Response time
|
||||
ResponseTime float64 `json:"responsetime"`
|
||||
|
||||
// Result
|
||||
Result string `json:"result"`
|
||||
|
||||
// Status code
|
||||
StatusCode uint64 `json:"statuscode"`
|
||||
|
||||
// Tags
|
||||
Tags string `json:"tags"`
|
||||
|
||||
// Timestamp
|
||||
Timestamp float64 `json:"timestamp"`
|
||||
|
||||
// TimestampEnd
|
||||
TimestampEnd float64 `json:"timestampEnd"`
|
||||
|
||||
// User
|
||||
User string `json:"user"`
|
||||
}
|
||||
|
||||
// Main info about audit
|
||||
type ItemAudit struct {
|
||||
// Args
|
||||
Args string `json:"args"`
|
||||
|
||||
// Call
|
||||
Call string `json:"call"`
|
||||
|
||||
// GUID
|
||||
GUID string `json:"guid"`
|
||||
|
||||
// Correlation ID
|
||||
CorrelationID string `json:"correlation_id"`
|
||||
|
||||
// Kwargs
|
||||
Kwargs string `json:"kwargs"`
|
||||
|
||||
// RemoteAddr
|
||||
RemoteAddr string `json:"remote_addr"`
|
||||
|
||||
// Response time
|
||||
ResponseTime float64 `json:"responsetime"`
|
||||
|
||||
// Result
|
||||
Result string `json:"result"`
|
||||
|
||||
// Status code
|
||||
StatusCode uint64 `json:"statuscode"`
|
||||
|
||||
// Timestamp
|
||||
Timestamp float64 `json:"timestamp"`
|
||||
|
||||
// Timestamp End
|
||||
TimestampEnd float64 `json:"timestampEnd"`
|
||||
|
||||
// User
|
||||
User string `json:"user"`
|
||||
|
||||
// TTL
|
||||
TTL string `json:"_ttl"`
|
||||
}
|
||||
|
||||
// List of audits
|
||||
type ListAudits struct {
|
||||
// Data
|
||||
Data []ItemAudit `json:"data"`
|
||||
|
||||
// EntryCount
|
||||
EntryCount uint64 `json:"entryCount"`
|
||||
}
|
||||
@@ -25,10 +25,6 @@ type CreateRequest struct {
|
||||
// SSH key to deploy for the specified user. Same key will be deployed to all computes of the service
|
||||
// Required: false
|
||||
SSHKey string `url:"sshKey,omitempty" json:"sshKey,omitempty"`
|
||||
|
||||
// Zone ID
|
||||
// Required: false
|
||||
ZoneID uint64 `url:"zoneId,omitempty" json:"zoneId,omitempty"`
|
||||
}
|
||||
|
||||
// Create creates blank BasicService instance
|
||||
|
||||
@@ -16,7 +16,6 @@ type DeleteRequest struct {
|
||||
|
||||
// If set to False, Basic service will be deleted to recycle bin. Otherwise destroyed immediately
|
||||
// Required: false
|
||||
// Default: false
|
||||
Permanently bool `url:"permanently,omitempty" json:"permanently,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,13 @@ type GroupAddRequest struct {
|
||||
// Required: true
|
||||
ImageID uint64 `url:"imageId" json:"imageId" validate:"required"`
|
||||
|
||||
// Compute driver
|
||||
// should be one of:
|
||||
// - KVM_X86
|
||||
// - KVM_PPC
|
||||
// Required: true
|
||||
Driver string `url:"driver" json:"driver" validate:"driver"`
|
||||
|
||||
// Storage endpoint provider ID
|
||||
// Required: false
|
||||
SEPID uint64 `url:"sepId,omitempty" json:"sepId,omitempty"`
|
||||
@@ -65,25 +72,6 @@ type GroupAddRequest struct {
|
||||
// Meta data for working group computes, format YAML "user_data": 1111
|
||||
// Required: false
|
||||
UserData string `url:"userData,omitempty" json:"userData,omitempty"`
|
||||
|
||||
// Chipset "i440fx" or "Q35
|
||||
// Default value : Q35
|
||||
// Required: false
|
||||
Chipset string `url:"chipset,omitempty" json:"chipset,omitempty" validate:"chipset,omitempty"`
|
||||
|
||||
// ID of the chosen storage policy
|
||||
// Required: false
|
||||
StoragePolicyID uint64 `url:"storage_policy_id,omitempty" json:"storage_policy_id,omitempty"`
|
||||
}
|
||||
|
||||
// GetRAM returns RAM field values
|
||||
func (r GroupAddRequest) GetRAM() map[string]uint64 {
|
||||
|
||||
res := make(map[string]uint64, 1)
|
||||
|
||||
res["RAM"] = r.RAM
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// GroupAdd creates new Compute Group within BasicService.
|
||||
|
||||
@@ -22,18 +22,12 @@ type GroupResizeRequest struct {
|
||||
// Required: true
|
||||
Count int64 `url:"count" json:"count" validate:"required"`
|
||||
|
||||
// Chipset for new computes, either i440fx or Q35 (i440fx by default)
|
||||
// Available values : i440fx, Q35
|
||||
// Default value : Q35
|
||||
// Required: false
|
||||
Chipset string `url:"chipset,omitempty" json:"chipset,omitempty" validate:"omitempty,chipset"`
|
||||
|
||||
// Either delta or absolute value of computes
|
||||
// Should be one of:
|
||||
// - ABSOLUTE
|
||||
// - RELATIVE
|
||||
// Required: false
|
||||
Mode string `url:"mode,omitempty" json:"mode,omitempty" validate:"omitempty,bserviceMode"`
|
||||
// Required: true
|
||||
Mode string `url:"mode" json:"mode" validate:"bserviceMode"`
|
||||
}
|
||||
|
||||
// GroupResize resize the group by changing the number of computes
|
||||
|
||||
@@ -43,16 +43,6 @@ type GroupUpdateRequest struct {
|
||||
Force bool `url:"force,omitempty" json:"force,omitempty"`
|
||||
}
|
||||
|
||||
// GetRAM returns RAM field values
|
||||
func (r GroupUpdateRequest) GetRAM() map[string]uint64 {
|
||||
|
||||
res := make(map[string]uint64, 1)
|
||||
|
||||
res["RAM"] = r.RAM
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// GroupUpdate updates existing Compute group within Basic Service and apply new settings to its computes as necessary
|
||||
func (b BService) GroupUpdate(ctx context.Context, req GroupUpdateRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
|
||||
@@ -4,8 +4,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// ListRequest struct to get list of BasicService instances
|
||||
@@ -42,15 +40,6 @@ type ListRequest struct {
|
||||
// Required: false
|
||||
AccountName string `url:"accountName,omitempty" json:"accountName,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||
|
||||
// Sort by zone id
|
||||
// Default value: 0
|
||||
// Required: false
|
||||
ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
|
||||
|
||||
// Page number
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
@@ -62,7 +51,6 @@ type ListRequest struct {
|
||||
|
||||
// List gets list of BasicService instances associated with the specified Resource Group as a ListBasicServices struct
|
||||
func (b BService) List(ctx context.Context, req ListRequest) (*ListBasicServices, error) {
|
||||
|
||||
res, err := b.ListRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -80,11 +68,6 @@ func (b BService) List(ctx context.Context, req ListRequest) (*ListBasicServices
|
||||
|
||||
// ListRaw gets list of BasicService instances associated with the specified Resource Group as an array of bytes
|
||||
func (b BService) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/bservice/list"
|
||||
|
||||
res, err := b.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
|
||||
@@ -4,8 +4,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// ListDeletedRequest struct to get list of deleted BasicService instances
|
||||
@@ -18,10 +16,6 @@ type ListDeletedRequest struct {
|
||||
// Required: false
|
||||
RGID uint64 `url:"rgId,omitempty" json:"rgId,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||
|
||||
// Page number
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
@@ -33,11 +27,6 @@ type ListDeletedRequest struct {
|
||||
|
||||
// ListDeleted gets list of deleted BasicService instances associated with the specified Resource Group
|
||||
func (b BService) ListDeleted(ctx context.Context, req ListDeletedRequest) (*ListBasicServices, error) {
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/bservice/listDeleted"
|
||||
|
||||
res, err := b.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package bservice
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// MigrateToZone struct to move basic service to another zone
|
||||
type MigrateToZoneRequest struct {
|
||||
// ID of the BasicService to move
|
||||
// Required: true
|
||||
ServiceID uint64 `url:"serviceId" json:"serviceId" validate:"required"`
|
||||
|
||||
// ID of the zone to move
|
||||
// Required: true
|
||||
ZoneID uint64 `url:"zoneId" json:"zoneId" validate:"required"`
|
||||
}
|
||||
|
||||
// MigrateToZone moves basic service instance to new zone
|
||||
func (b BService) MigrateToZone(ctx context.Context, req MigrateToZoneRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/bservice/migrateToZone"
|
||||
|
||||
res, err := b.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseBool(string(res))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
@@ -88,15 +88,12 @@ type RecordBasicService struct {
|
||||
|
||||
// Whether user controlled
|
||||
UserManaged bool `json:"userManaged"`
|
||||
|
||||
// Zone ID
|
||||
ZoneID uint64 `json:"zoneId"`
|
||||
}
|
||||
|
||||
// Main information about Compute
|
||||
type ItemCompute struct {
|
||||
// Account ID
|
||||
AccountID uint64 `json:"accountId"`
|
||||
AccountID uint64
|
||||
|
||||
// Architecture
|
||||
Architecture string `json:"arch"`
|
||||
@@ -119,8 +116,8 @@ type ItemCompute struct {
|
||||
// Resource group ID
|
||||
RGID uint64 `json:"rgId"`
|
||||
|
||||
// NodeID
|
||||
NodeID uint64 `json:"node_id"`
|
||||
// StackID
|
||||
StackID uint64 `json:"stackId"`
|
||||
|
||||
// Status
|
||||
Status string `json:"status"`
|
||||
@@ -171,9 +168,6 @@ type ItemSnapshot struct {
|
||||
Valid bool `json:"valid"`
|
||||
}
|
||||
|
||||
// List of Snapshot
|
||||
type ListSnapshots []ItemSnapshot
|
||||
|
||||
// List of Snapshots
|
||||
type ListInfoSnapshots struct {
|
||||
// Data
|
||||
@@ -183,6 +177,9 @@ type ListInfoSnapshots struct {
|
||||
EntryCount uint64 `json:"entryCount"`
|
||||
}
|
||||
|
||||
// List of Snapshots inside RecordBasicService
|
||||
type ListSnapshots []ItemSnapshot
|
||||
|
||||
// Main information about Group
|
||||
type RecordGroup struct {
|
||||
// Account ID
|
||||
@@ -298,9 +295,6 @@ type ItemGroupCompute struct {
|
||||
|
||||
// List of information about OS Users
|
||||
OSUsers ListOSUsers `json:"osUsers"`
|
||||
|
||||
//Chipset
|
||||
Chipset string `json:"chipset"`
|
||||
}
|
||||
|
||||
// List of Group Computes
|
||||
@@ -385,9 +379,6 @@ type ItemBasicService struct {
|
||||
|
||||
// User Managed or not
|
||||
UserManaged bool `json:"userManaged"`
|
||||
|
||||
// Zone ID
|
||||
ZoneID uint64 `json:"zoneId"`
|
||||
}
|
||||
|
||||
// List of BasicServices
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// AbortSharedSnapshotMergeRequest struct to abort shared snapshots merge
|
||||
type AbortSharedSnapshotMergeRequest struct {
|
||||
// ID of the compute
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
|
||||
|
||||
// Label of the snapshot
|
||||
// Required: true
|
||||
Label string `url:"label" json:"label" validate:"required"`
|
||||
}
|
||||
|
||||
type wrapperAbortSharedSnapshotMergeRequest struct {
|
||||
AbortSharedSnapshotMergeRequest
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// AbortSharedSnapshotMerge shared snapshots merge abort
|
||||
func (c Compute) AbortSharedSnapshotMerge(ctx context.Context, req AbortSharedSnapshotMergeRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperAbortSharedSnapshotMergeRequest{
|
||||
AbortSharedSnapshotMergeRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/abort_shared_snapshot_merge"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
|
||||
// AbortSharedSnapshotMergeAsync shared snapshots merge abort in async mode
|
||||
func (c Compute) AbortSharedSnapshotMergeAsync(ctx context.Context, req AbortSharedSnapshotMergeRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperAbortSharedSnapshotMergeRequest{
|
||||
AbortSharedSnapshotMergeRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/abort_shared_snapshot_merge"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
@@ -38,8 +38,8 @@ type AffinityRuleAddRequest struct {
|
||||
Key string `url:"key" json:"key" validate:"required"`
|
||||
|
||||
// Value that must match the key to be taken into account when analyzing this rule
|
||||
// Required: true
|
||||
Value string `url:"value" json:"value" validate:"required"`
|
||||
// Required: false
|
||||
Value string `url:"value" json:"value"`
|
||||
}
|
||||
|
||||
// AffinityRuleAdd add affinity rule
|
||||
|
||||
@@ -38,8 +38,8 @@ type AffinityRuleRemoveRequest struct {
|
||||
Key string `url:"key" json:"key" validate:"required"`
|
||||
|
||||
// Value that must match the key to be taken into account when analyzing this rule
|
||||
// Required: true
|
||||
Value string `url:"value" json:"value" validate:"required"`
|
||||
// Required: false
|
||||
Value string `url:"value" json:"value"`
|
||||
}
|
||||
|
||||
// AffinityRuleRemove remove affinity rule
|
||||
|
||||
@@ -38,8 +38,8 @@ type AntiAffinityRuleAddRequest struct {
|
||||
Key string `url:"key" json:"key" validate:"required"`
|
||||
|
||||
// Value that must match the key to be taken into account when analyzing this rule
|
||||
// Required: true
|
||||
Value string `url:"value" json:"value" validate:"required"`
|
||||
// Required: false
|
||||
Value string `url:"value" json:"value"`
|
||||
}
|
||||
|
||||
// AntiAffinityRuleAdd add anti affinity rule
|
||||
|
||||
@@ -38,8 +38,8 @@ type AntiAffinityRuleRemoveRequest struct {
|
||||
Key string `url:"key" json:"key" validate:"required"`
|
||||
|
||||
// Value that must match the key to be taken into account when analyzing this rule
|
||||
// Required: true
|
||||
Value string `url:"value" json:"value" validate:"required"`
|
||||
// Required: false
|
||||
Value string `url:"value" json:"value"`
|
||||
}
|
||||
|
||||
// AntiAffinityRuleRemove remove anti affinity rule
|
||||
|
||||
@@ -12,47 +12,11 @@ import (
|
||||
type AuditsRequest struct {
|
||||
// ID of the compute
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
|
||||
|
||||
// Find all audits after point in time
|
||||
// Required: false
|
||||
TimestampAT uint64 `url:"timestamp_at,omitempty" json:"timestamp_at,omitempty"`
|
||||
|
||||
// Find all audits before point in time
|
||||
// Required: false
|
||||
TimestampTO uint64 `url:"timestamp_to,omitempty" json:"timestamp_to,omitempty"`
|
||||
|
||||
// Find by user
|
||||
// Required: false
|
||||
User string `url:"user,omitempty" json:"user,omitempty"`
|
||||
|
||||
// Find by api endpoints
|
||||
// Required: false
|
||||
Call string `url:"call,omitempty" json:"call,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format ±<field>
|
||||
// Required: false
|
||||
SortBy string `url:"sort_by,omitempty" json:"sort_by,omitempty"`
|
||||
|
||||
// Page number
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
|
||||
// Page size
|
||||
// Required: false
|
||||
Size uint64 `url:"size,omitempty" json:"size,omitempty"`
|
||||
|
||||
// Find by HTTP min status code
|
||||
// Required: false
|
||||
MinStatusCode uint64 `url:"min_status_code,omitempty" json:"min_status_code,omitempty"`
|
||||
|
||||
// Find by HTTP max status code
|
||||
// Required: false
|
||||
MaxStatusCode uint64 `url:"max_status_code,omitempty" json:"max_status_code,omitempty"`
|
||||
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
|
||||
}
|
||||
|
||||
// Audits gets audit records for the specified compute object
|
||||
func (c Compute) Audits(ctx context.Context, req AuditsRequest) (*ListAudits, error) {
|
||||
func (c Compute) Audits(ctx context.Context, req AuditsRequest) (ListAudits, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
@@ -60,7 +24,7 @@ func (c Compute) Audits(ctx context.Context, req AuditsRequest) (*ListAudits, er
|
||||
|
||||
url := "/cloudapi/compute/audits"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -72,5 +36,5 @@ func (c Compute) Audits(ctx context.Context, req AuditsRequest) (*ListAudits, er
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &list, nil
|
||||
return list, nil
|
||||
}
|
||||
|
||||
@@ -15,12 +15,6 @@ type CDEjectRequest struct {
|
||||
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
|
||||
}
|
||||
|
||||
type wrapperCDEjectRequest struct {
|
||||
CDEjectRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// CDEject eject CD image to compute's CD-ROM
|
||||
func (c Compute) CDEject(ctx context.Context, req CDEjectRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
@@ -28,14 +22,9 @@ func (c Compute) CDEject(ctx context.Context, req CDEjectRequest) (bool, error)
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperCDEjectRequest{
|
||||
CDEjectRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/cdEject"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -44,28 +33,5 @@ func (c Compute) CDEject(ctx context.Context, req CDEjectRequest) (bool, error)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// CDEjectAsync ejects CD image to compute's CD-ROM with AsyncMode
|
||||
func (c Compute) CDEjectAsync(ctx context.Context, req CDEjectRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperCDEjectRequest{
|
||||
CDEjectRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/cdEject"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
|
||||
@@ -19,12 +19,6 @@ type CDInsertRequest struct {
|
||||
CDROMID uint64 `url:"cdromId" json:"cdromId" validate:"required"`
|
||||
}
|
||||
|
||||
type wrapperCDInsertRequest struct {
|
||||
CDInsertRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// CDInsert insert new CD image to compute's CD-ROM
|
||||
func (c Compute) CDInsert(ctx context.Context, req CDInsertRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
@@ -32,14 +26,9 @@ func (c Compute) CDInsert(ctx context.Context, req CDInsertRequest) (bool, error
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperCDInsertRequest{
|
||||
CDInsertRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/cdInsert"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -48,28 +37,5 @@ func (c Compute) CDInsert(ctx context.Context, req CDInsertRequest) (bool, error
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// CDInsertAsync inserts new CD image to compute's CD-ROM with AsyncMode
|
||||
func (c Compute) CDInsertAsync(ctx context.Context, req CDInsertRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperCDInsertRequest{
|
||||
CDInsertRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/cdInsert"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// ChangeIPRequest struct to change IP for network
|
||||
type ChangeIPRequest struct {
|
||||
// ID of compute instance
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
|
||||
|
||||
// Network type
|
||||
// 'EXTNET' for connect to external network directly
|
||||
// 'VINS' for connect to ViNS
|
||||
// Required: true
|
||||
NetType string `url:"net_type" json:"net_type" validate:"computeNetType"`
|
||||
|
||||
// Network ID for connect to
|
||||
// For EXTNET - external network ID
|
||||
// For VINS - VINS ID
|
||||
// Required: true
|
||||
NetID uint64 `url:"net_id" json:"net_id" validate:"required"`
|
||||
|
||||
// IP address to which we will change the existing one, it must be from the same subnet
|
||||
// Required: true
|
||||
IPAddr string `url:"ip_addr" json:"ip_addr" validate:"required"`
|
||||
}
|
||||
|
||||
type wrapperChangeIPRequest struct {
|
||||
ChangeIPRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// ChangeIP change reserved IP for compute instance
|
||||
func (c Compute) ChangeIP(ctx context.Context, req ChangeIPRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperChangeIPRequest{
|
||||
ChangeIPRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/changeIp"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseBool(string(res))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ChangeIPAsync change reserved IP for compute instance with AsyncMode
|
||||
func (c Compute) ChangeIPAsync(ctx context.Context, req ChangeIPRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperChangeIPRequest{
|
||||
ChangeIPRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/changeIp"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
@@ -3,9 +3,8 @@ package compute
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// ChangeLinkStateRequest struct to change link state
|
||||
@@ -24,12 +23,6 @@ type ChangeLinkStateRequest struct {
|
||||
State string `url:"state" json:"state" validate:"required,interfaceState"`
|
||||
}
|
||||
|
||||
type wrapperChangeLinkStateRequest struct {
|
||||
ChangeLinkStateRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// ChangeLinkState changes the status link virtual of compute
|
||||
func (c Compute) ChangeLinkState(ctx context.Context, req ChangeLinkStateRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
@@ -37,14 +30,9 @@ func (c Compute) ChangeLinkState(ctx context.Context, req ChangeLinkStateRequest
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperChangeLinkStateRequest{
|
||||
ChangeLinkStateRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/changeLinkState"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -53,28 +41,5 @@ func (c Compute) ChangeLinkState(ctx context.Context, req ChangeLinkStateRequest
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ChangeLinkStateAsync changes the status link virtual of compute with AsyncMode
|
||||
func (c Compute) ChangeLinkStateAsync(ctx context.Context, req ChangeLinkStateRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperChangeLinkStateRequest{
|
||||
ChangeLinkStateRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/changeLinkState"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// ChangeMACRequest struct to change MAC for network
|
||||
type ChangeMACRequest struct {
|
||||
// ID of compute instance
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
|
||||
|
||||
// Current mac address
|
||||
// Required: true
|
||||
СurrentMAC string `url:"current_mac_address" json:"current_mac_address" validate:"required"`
|
||||
|
||||
// the MAC address to which we will change the existing one
|
||||
// Required: true
|
||||
NewMAC string `url:"new_mac_address" json:"new_mac_address" validate:"required"`
|
||||
}
|
||||
|
||||
// ChangeMAC change MAC for compute instance
|
||||
func (c Compute) ChangeMAC(ctx context.Context, req ChangeMACRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/changeMac"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseBool(string(res))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// ChangeMTURequest struct to change MTU for a compute
|
||||
type ChangeMTURequest struct {
|
||||
// ID of compute instance
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
|
||||
|
||||
// Interface name or MAC address
|
||||
// Required: true
|
||||
Interface string `url:"interface" json:"interface" validate:"required"`
|
||||
|
||||
// Maximum transmission unit
|
||||
// Required: true
|
||||
MTU uint64 `url:"mtu" json:"mtu" validate:"required" validate:"omitempty,mtu"`
|
||||
}
|
||||
|
||||
type wrapperChangeMTURequest struct {
|
||||
ChangeMTURequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// ChangeMTU change MTU for compute instance
|
||||
func (c Compute) ChangeMTU(ctx context.Context, req ChangeMTURequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperChangeMTURequest{
|
||||
ChangeMTURequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/change_mtu"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseBool(string(res))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ChangeMTUAsync change MTU for compute instance with AsyncMode
|
||||
func (c Compute) ChangeMTUAsync(ctx context.Context, req ChangeMTURequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperChangeMTURequest{
|
||||
ChangeMTURequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/change_mtu"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// ChangeSecGroupsRequest struct to change security groups for compute
|
||||
type ChangeSecGroupsRequest struct {
|
||||
// Identifier compute
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
|
||||
|
||||
// Interface name or MAC address
|
||||
// Required: true
|
||||
Interface string `url:"interface" json:"interface" validate:"required"`
|
||||
|
||||
// List of security group IDs to assign to this interface
|
||||
// Required: false
|
||||
SecGroups []uint64 `url:"security_groups,omitempty" json:"security_groups,omitempty"`
|
||||
|
||||
// Flag indicating whether security groups are enabled for this interface
|
||||
// Required: false
|
||||
EnableSecGroups interface{} `url:"enable_secgroups,omitempty" json:"enable_secgroups,omitempty" validate:"omitempty,isBool"`
|
||||
}
|
||||
|
||||
type wrapperChangeSecGroupsRequest struct {
|
||||
ChangeSecGroupsRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// ChangeSecGroups changes security groups for compute
|
||||
func (c Compute) ChangeSecGroups(ctx context.Context, req ChangeSecGroupsRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperChangeSecGroupsRequest{
|
||||
ChangeSecGroupsRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/change_security_groups"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseBool(string(res))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ChangeSecGroupsAsync changes security groups for compute with AsyncMode
|
||||
func (c Compute) ChangeSecGroupsAsync(ctx context.Context, req ChangeSecGroupsRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperChangeSecGroupsRequest{
|
||||
ChangeSecGroupsRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/change_security_groups"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
@@ -3,8 +3,8 @@ package compute
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
@@ -18,10 +18,6 @@ type CloneRequest struct {
|
||||
// Required: true
|
||||
Name string `url:"name" json:"name" validate:"required"`
|
||||
|
||||
// ID of the Storage Policy
|
||||
// Required: true
|
||||
StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
|
||||
|
||||
// Timestamp of the parent's snapshot to create clone from
|
||||
// Required: false
|
||||
SnapshotTimestamp uint64 `url:"snapshotTimestamp,omitempty" json:"snapshotTimestamp,omitempty"`
|
||||
@@ -29,67 +25,26 @@ type CloneRequest struct {
|
||||
// Name of the parent's snapshot to create clone from
|
||||
// Required: false
|
||||
SnapshotName string `url:"snapshotName,omitempty" json:"snapshotName,omitempty"`
|
||||
|
||||
// true ignore that the compute is running
|
||||
// Default: false
|
||||
// Required: false
|
||||
Force bool `url:"force" json:"force"`
|
||||
|
||||
// The name of the pool to migrate disks to
|
||||
// Required: false
|
||||
PoolName string `url:"pool_name" json:"pool_name"`
|
||||
|
||||
// The ID of the SEP to migrate disks to
|
||||
// Required: false
|
||||
SEPID uint64 `url:"sep_id" json:"sep_id"`
|
||||
}
|
||||
|
||||
type wrapperCloneRequest struct {
|
||||
CloneRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode" json:"asyncMode"`
|
||||
}
|
||||
|
||||
// Clone clones compute instance
|
||||
func (c Compute) Clone(ctx context.Context, req CloneRequest) (string, error) {
|
||||
func (c Compute) Clone(ctx context.Context, req CloneRequest) (uint64, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperCloneRequest{
|
||||
CloneRequest: req,
|
||||
AsyncMode: false,
|
||||
return 0, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/clone"
|
||||
|
||||
res, err := c.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, reqWrapped)
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
|
||||
// CloneAsync clones compute instance with AsyncMode
|
||||
func (c Compute) CloneAsync(ctx context.Context, req CloneRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperCloneRequest{
|
||||
CloneRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/clone"
|
||||
|
||||
res, err := c.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
result, err := strconv.ParseUint(string(res), 10, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// CloneAbortRequest struct to abort a compute clone
|
||||
type CloneAbortRequest struct {
|
||||
// ID of compute instance
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
|
||||
}
|
||||
|
||||
// CloneAbort aborts a compute clone
|
||||
func (c Compute) CloneAbort(ctx context.Context, req CloneAbortRequest) (ListCloneAbort, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/clone_abort"
|
||||
|
||||
res, err := c.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result ListCloneAbort
|
||||
|
||||
err = json.Unmarshal(res, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// GetCloneStatusRequest struct to get information about compute clone status
|
||||
type GetCloneStatusRequest struct {
|
||||
// ID of compute instance
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
|
||||
}
|
||||
|
||||
// GetCloneStatus gets information about compute clone status as a RecordCloneStatus struct
|
||||
func (c Compute) GetCloneStatus(ctx context.Context, req GetCloneStatusRequest) ([]RecordCloneStatus, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/clone_status"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cloneStatus := make([]RecordCloneStatus, 0)
|
||||
|
||||
err = json.Unmarshal(res, &cloneStatus)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cloneStatus, nil
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package compute
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
@@ -22,19 +23,51 @@ type CreateTemplateRequest struct {
|
||||
type wrapperCreateTemplateRequest struct {
|
||||
CreateTemplateRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
Async bool `url:"async"`
|
||||
}
|
||||
|
||||
// CreateTemplate create template from compute instance
|
||||
func (c Compute) CreateTemplate(ctx context.Context, req CreateTemplateRequest) (string, error) {
|
||||
func (c Compute) CreateTemplate(ctx context.Context, req CreateTemplateRequest) (uint64, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return 0, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperCreateTemplateRequest{
|
||||
CreateTemplateRequest: req,
|
||||
Async: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/createTemplate"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseUint(string(res), 10, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// CreateTemplateAsync create template from compute instance
|
||||
func (c Compute) CreateTemplateAsync(ctx context.Context, req CreateTemplateRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperCreateTemplateRequest{
|
||||
CreateTemplateRequest: req,
|
||||
Async: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/createTemplate"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// CreateTemplateFromBlankRequest struct to create template from boot disk of current compute
|
||||
type CreateTemplateFromBlankRequest struct {
|
||||
// ID of the compute to create template from
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
|
||||
|
||||
// Name of the rescue disk
|
||||
// Required: true
|
||||
Name string `url:"name" json:"name" validate:"required"`
|
||||
|
||||
// Boot type of image BIOS or UEFI
|
||||
// Required: true
|
||||
BootType string `url:"boottype" json:"boottype" validate:"imageBootType"`
|
||||
|
||||
// Image type linux, windows or other
|
||||
// Required: true
|
||||
ImageType string `url:"imagetype" json:"imagetype" validate:"imageType"`
|
||||
|
||||
// Storage policy id of disk. The rules of the specified storage policy will be used.
|
||||
// Required: true
|
||||
StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
|
||||
|
||||
// Username for the image
|
||||
// Required: false
|
||||
Username string `url:"username,omitempty" json:"username,omitempty"`
|
||||
|
||||
// Password for the image
|
||||
// Required: false
|
||||
Password string `url:"password,omitempty" json:"password,omitempty"`
|
||||
|
||||
// Account ID to make the image exclusive
|
||||
// Required: false
|
||||
AccountID uint64 `url:"accountId,omitempty" json:"accountId,omitempty"`
|
||||
|
||||
// Pool for image create
|
||||
// Required: false
|
||||
PoolName string `url:"poolName,omitempty" json:"poolName,omitempty"`
|
||||
|
||||
// Does this machine supports hot resize
|
||||
// Default: false
|
||||
// Required: false
|
||||
HotResize bool `url:"hotresize" json:"hotresize"`
|
||||
}
|
||||
|
||||
type wrapperCreateTemplateFromBlankRequest struct {
|
||||
CreateTemplateFromBlankRequest
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// CreateTemplateFromBlank creates template from boot disk of current compute in sync mode.
|
||||
// It returns id of created compute and error.
|
||||
func (c Compute) CreateTemplateFromBlank(ctx context.Context, req CreateTemplateFromBlankRequest) (uint64, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return 0, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperCreateTemplateFromBlankRequest{
|
||||
CreateTemplateFromBlankRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/createTemplateFromBlank"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseUint(string(res), 10, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// CreateTemplateFromBlankAsync creates template from boot disk of current compute in async mode.
|
||||
// It returns guid of task and error.
|
||||
func (c Compute) CreateTemplateFromBlankAsync(ctx context.Context, req CreateTemplateFromBlankRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperCreateTemplateFromBlankRequest{
|
||||
CreateTemplateFromBlankRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/createTemplateFromBlank"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
result := strings.ReplaceAll(string(res), "\"", "")
|
||||
|
||||
return result, nil
|
||||
}
|
||||
@@ -23,12 +23,6 @@ type DeleteRequest struct {
|
||||
DetachDisks bool `url:"detachDisks,omitempty" json:"detachDisks,omitempty"`
|
||||
}
|
||||
|
||||
type wrapperDeleteRequest struct {
|
||||
DeleteRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// Delete deletes compute
|
||||
func (c Compute) Delete(ctx context.Context, req DeleteRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
@@ -36,14 +30,9 @@ func (c Compute) Delete(ctx context.Context, req DeleteRequest) (bool, error) {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDeleteRequest{
|
||||
DeleteRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/delete"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -55,25 +44,3 @@ func (c Compute) Delete(ctx context.Context, req DeleteRequest) (bool, error) {
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DeleteAsync deletes compute with AsyncMode
|
||||
func (c Compute) DeleteAsync(ctx context.Context, req DeleteRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDeleteRequest{
|
||||
DeleteRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/delete"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// DeleteCPUAlignmentProfileRequest struct to delete CPU alignment profile for computes
|
||||
type DeleteCPUAlignmentProfileRequest struct {
|
||||
// IDs of the compute instances
|
||||
// Required: true
|
||||
ComputeIDs []uint64 `url:"compute_ids" json:"compute_ids" validate:"min=1"`
|
||||
}
|
||||
|
||||
// DeleteCPUAlignmentProfile deletes CPU alignment profile for computes
|
||||
func (c Compute) DeleteCPUAlignmentProfile(ctx context.Context, req DeleteCPUAlignmentProfileRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/delete_cpu_alignment_profile"
|
||||
|
||||
res, err := c.client.DecortApiCallCtype(ctx, http.MethodPost, url, constants.MIMEJSON, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseBool(string(res))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
@@ -15,12 +15,6 @@ type DisableRequest struct {
|
||||
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
|
||||
}
|
||||
|
||||
type wrapperDisableRequest struct {
|
||||
DisableRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// Disable disables compute
|
||||
func (c Compute) Disable(ctx context.Context, req DisableRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
@@ -28,14 +22,9 @@ func (c Compute) Disable(ctx context.Context, req DisableRequest) (bool, error)
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDisableRequest{
|
||||
DisableRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/disable"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -47,25 +36,3 @@ func (c Compute) Disable(ctx context.Context, req DisableRequest) (bool, error)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DisableAsync disables compute with AsyncMode
|
||||
func (c Compute) DisableAsync(ctx context.Context, req DisableRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDisableRequest{
|
||||
DisableRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/disable"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
|
||||
@@ -22,9 +22,12 @@ type DiskAddRequest struct {
|
||||
// Required: true
|
||||
Size uint64 `url:"size" json:"size" validate:"required"`
|
||||
|
||||
// Storage policy id of disk. The rules of the specified storage policy will be used.
|
||||
// Required: true
|
||||
StoragePolicyID uint64 `url:"storage_policy_id" json:"storage_policy_id" validate:"required"`
|
||||
// Type of the disk
|
||||
// Should be one of:
|
||||
// - D
|
||||
// - B
|
||||
// Required: false
|
||||
DiskType string `url:"diskType,omitempty" json:"diskType,omitempty" validate:"omitempty,computeDiskType"`
|
||||
|
||||
// Storage endpoint provider ID
|
||||
// By default the same with boot disk
|
||||
@@ -43,24 +46,6 @@ type DiskAddRequest struct {
|
||||
// Specify image id for create disk from template
|
||||
// Required: false
|
||||
ImageID uint64 `url:"imageId,omitempty" json:"imageId,omitempty"`
|
||||
|
||||
// Desired PCI slot (hex string, e.g. "0x1A")
|
||||
// Required: false
|
||||
PCISlot string `url:"pci_slot,omitempty" json:"pci_slot,omitempty"`
|
||||
|
||||
// Desired bus number (hex string, e.g. "0x03")
|
||||
// Required: false
|
||||
BusNumber string `url:"bus_number,omitempty" json:"bus_number,omitempty"`
|
||||
|
||||
// Mount disk in read-only mode
|
||||
// Required: false
|
||||
ReadOnly bool `url:"read_only,omitempty" json:"read_only,omitempty"`
|
||||
}
|
||||
|
||||
type wrapperDiskAddRequest struct {
|
||||
DiskAddRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// DiskAdd creates new disk and attach to compute
|
||||
@@ -70,14 +55,9 @@ func (c Compute) DiskAdd(ctx context.Context, req DiskAddRequest) (uint64, error
|
||||
return 0, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDiskAddRequest{
|
||||
DiskAddRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/diskAdd"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -89,25 +69,3 @@ func (c Compute) DiskAdd(ctx context.Context, req DiskAddRequest) (uint64, error
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DiskAddAsync creates new disk and attach to compute with AsyncMode
|
||||
func (c Compute) DiskAddAsync(ctx context.Context, req DiskAddRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDiskAddRequest{
|
||||
DiskAddRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/diskAdd"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
|
||||
@@ -18,23 +18,9 @@ type DiskAttachRequest struct {
|
||||
// Required: true
|
||||
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
|
||||
|
||||
// Desired PCI slot (hex string, e.g. "0x1A")
|
||||
// Type of the disk B;D
|
||||
// Required: false
|
||||
PCISlot string `url:"pci_slot,omitempty" json:"pci_slot,omitempty"`
|
||||
|
||||
// Desired bus number (hex string, e.g. "0x03")
|
||||
// Required: false
|
||||
BusNumber string `url:"bus_number,omitempty" json:"bus_number,omitempty"`
|
||||
|
||||
// Mount disk in read-only mode
|
||||
// Required: false
|
||||
ReadOnly bool `url:"read_only,omitempty" json:"read_only,omitempty"`
|
||||
}
|
||||
|
||||
type wrapperDiskAttachRequest struct {
|
||||
DiskAttachRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
DiskType string `url:"diskType,omitempty" json:"diskType,omitempty" validate:"omitempty,computeDiskType"`
|
||||
}
|
||||
|
||||
// DiskAttach attach disk to compute
|
||||
@@ -44,14 +30,9 @@ func (c Compute) DiskAttach(ctx context.Context, req DiskAttachRequest) (bool, e
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDiskAttachRequest{
|
||||
DiskAttachRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/diskAttach"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -63,25 +44,3 @@ func (c Compute) DiskAttach(ctx context.Context, req DiskAttachRequest) (bool, e
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DiskAttachAsync attaches disk to compute with AsyncMode
|
||||
func (c Compute) DiskAttachAsync(ctx context.Context, req DiskAttachRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDiskAttachRequest{
|
||||
DiskAttachRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/diskAttach"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
|
||||
@@ -23,12 +23,6 @@ type DiskDelRequest struct {
|
||||
Permanently bool `url:"permanently" json:"permanently"`
|
||||
}
|
||||
|
||||
type wrapperDiskDelRequest struct {
|
||||
DiskDelRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// DiskDel delete disk and detach from compute
|
||||
func (c Compute) DiskDel(ctx context.Context, req DiskDelRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
@@ -36,14 +30,9 @@ func (c Compute) DiskDel(ctx context.Context, req DiskDelRequest) (bool, error)
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDiskDelRequest{
|
||||
DiskDelRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/diskDel"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -55,25 +44,3 @@ func (c Compute) DiskDel(ctx context.Context, req DiskDelRequest) (bool, error)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DiskDelAsync deletes disk and detaches from compute with AsyncMode
|
||||
func (c Compute) DiskDelAsync(ctx context.Context, req DiskDelRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDiskDelRequest{
|
||||
DiskDelRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/diskDel"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
|
||||
@@ -19,12 +19,6 @@ type DiskDetachRequest struct {
|
||||
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
|
||||
}
|
||||
|
||||
type wrapperDiskDetachRequest struct {
|
||||
DiskDetachRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// DiskDetach detach disk from compute
|
||||
func (c Compute) DiskDetach(ctx context.Context, req DiskDetachRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
@@ -32,14 +26,9 @@ func (c Compute) DiskDetach(ctx context.Context, req DiskDetachRequest) (bool, e
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDiskDetachRequest{
|
||||
DiskDetachRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/diskDetach"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -51,25 +40,3 @@ func (c Compute) DiskDetach(ctx context.Context, req DiskDetachRequest) (bool, e
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DiskDetachAsync detaches disk from compute with AsyncMode
|
||||
func (c Compute) DiskDetachAsync(ctx context.Context, req DiskDetachRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDiskDetachRequest{
|
||||
DiskDetachRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/diskDetach"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// DiskMigrateRequest struct to migrate compute's disk to target disk
|
||||
type DiskMigrateRequest struct {
|
||||
// ID of compute instance
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
|
||||
|
||||
// ID source disk
|
||||
// Required: true
|
||||
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
|
||||
|
||||
// ID target disk
|
||||
// Required: true
|
||||
TargetDiskID uint64 `url:"targetDiskId" json:"targetDiskId" validate:"required"`
|
||||
|
||||
// Migration mode. 1 - Data migration and domain update were already completed by third-party software.
|
||||
// Use this if target disk already connected to compute and you only need to save changes for next reboot.
|
||||
// Required: false
|
||||
Mode int64 `url:"mode,omitempty" json:"mode,omitempty"`
|
||||
}
|
||||
|
||||
// DiskMigrate - migrate compute's disk to target disk. Source disk will be detached, target disk will be attached to the same PCI slot.
|
||||
// (WARNING) Current realisation is limited. No actual data migration will be performed.
|
||||
// Use this API if target disk already connected to compute and you only need to save changes for next reboot (mode: 1).
|
||||
func (c Compute) DiskMigrate(ctx context.Context, req DiskMigrateRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/diskMigrate"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseBool(string(res))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
@@ -23,12 +23,6 @@ type DiskQOSRequest struct {
|
||||
Limits string `url:"limits" json:"limits" validate:"required"`
|
||||
}
|
||||
|
||||
type wrapperDiskQOSRequest struct {
|
||||
DiskQOSRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// DiskQOS change QoS of the disk
|
||||
func (c Compute) DiskQOS(ctx context.Context, req DiskQOSRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
@@ -36,14 +30,9 @@ func (c Compute) DiskQOS(ctx context.Context, req DiskQOSRequest) (bool, error)
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDiskQOSRequest{
|
||||
DiskQOSRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/diskQos"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -55,25 +44,3 @@ func (c Compute) DiskQOS(ctx context.Context, req DiskQOSRequest) (bool, error)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DiskQOSAsync changes QoS of the disk with AsyncMode
|
||||
func (c Compute) DiskQOSAsync(ctx context.Context, req DiskQOSRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDiskQOSRequest{
|
||||
DiskQOSRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/diskQos"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
|
||||
@@ -23,12 +23,6 @@ type DiskResizeRequest struct {
|
||||
Size uint64 `url:"size" json:"size" validate:"required"`
|
||||
}
|
||||
|
||||
type wrapperDiskResizeRequest struct {
|
||||
DiskResizeRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// DiskResize change disk size
|
||||
func (c Compute) DiskResize(ctx context.Context, req DiskResizeRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
@@ -36,14 +30,9 @@ func (c Compute) DiskResize(ctx context.Context, req DiskResizeRequest) (bool, e
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDiskResizeRequest{
|
||||
DiskResizeRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/diskResize"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -55,25 +44,3 @@ func (c Compute) DiskResize(ctx context.Context, req DiskResizeRequest) (bool, e
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DiskResizeAsync changes disk size with AsyncMode
|
||||
func (c Compute) DiskResizeAsync(ctx context.Context, req DiskResizeRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDiskResizeRequest{
|
||||
DiskResizeRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/diskResize"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// DiskSwitchToReplicationRequest struct to switch disk to it's replication
|
||||
type DiskSwitchToReplicationRequest struct {
|
||||
// ID of compute instance
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
|
||||
|
||||
// ID of the disk to switch
|
||||
// Required: true
|
||||
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
|
||||
|
||||
// Delete replication relationship
|
||||
// Required: false
|
||||
StopReplication bool `url:"stopReplication" json:"stopReplication"`
|
||||
}
|
||||
|
||||
type wrapperDiskSwitchToReplicationRequest struct {
|
||||
DiskSwitchToReplicationRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// DiskSwitchToReplication switches disk to it's replication
|
||||
func (c Compute) DiskSwitchToReplication(ctx context.Context, req DiskSwitchToReplicationRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDiskSwitchToReplicationRequest{
|
||||
DiskSwitchToReplicationRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/diskSwitchToReplication"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseBool(string(res))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DiskSwitchToReplicationAsync switches disk to it's replication with AsyncMode
|
||||
func (c Compute) DiskSwitchToReplicationAsync(ctx context.Context, req DiskSwitchToReplicationRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperDiskSwitchToReplicationRequest{
|
||||
DiskSwitchToReplicationRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/diskSwitchToReplication"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
@@ -49,12 +49,14 @@ var computes = ListComputes{
|
||||
Disks: []InfoDisk{
|
||||
{
|
||||
ID: 65191,
|
||||
PCISlot: 6,
|
||||
},
|
||||
},
|
||||
Driver: "KVM_X86",
|
||||
GID: 212,
|
||||
GUID: 48500,
|
||||
ID: 48500,
|
||||
ImageID: 9884,
|
||||
Interfaces: []ItemVNFInterface{},
|
||||
LockStatus: "UNLOCKED",
|
||||
ManagerID: 0,
|
||||
@@ -62,7 +64,7 @@ var computes = ListComputes{
|
||||
MigrationJob: 0,
|
||||
Milestones: 363500,
|
||||
Name: "test",
|
||||
PinnedToNode: true,
|
||||
Pinned: false,
|
||||
RAM: 4096,
|
||||
ReferenceID: "c7cb19ac-af4a-4067-852f-c5572949207e",
|
||||
Registered: true,
|
||||
@@ -81,7 +83,7 @@ var computes = ListComputes{
|
||||
UserManaged: true,
|
||||
VGPUs: []uint64{},
|
||||
VINSConnected: 0,
|
||||
ZoneID: 1,
|
||||
VirtualImageID: 0,
|
||||
},
|
||||
{
|
||||
ACL: ListACL{},
|
||||
@@ -110,12 +112,14 @@ var computes = ListComputes{
|
||||
Disks: []InfoDisk{
|
||||
{
|
||||
ID: 65248,
|
||||
PCISlot: 6,
|
||||
},
|
||||
},
|
||||
Driver: "KVM_X86",
|
||||
GID: 212,
|
||||
GUID: 48556,
|
||||
ID: 48556,
|
||||
ImageID: 9884,
|
||||
Interfaces: []ItemVNFInterface{},
|
||||
LockStatus: "UNLOCKED",
|
||||
ManagerID: 0,
|
||||
@@ -123,10 +127,10 @@ var computes = ListComputes{
|
||||
MigrationJob: 0,
|
||||
Milestones: 363853,
|
||||
Name: "compute_2",
|
||||
Pinned: false,
|
||||
RAM: 4096,
|
||||
ReferenceID: "a542c449-5b1c-4f90-88c5-7bb5f8ae68ff",
|
||||
Registered: true,
|
||||
PinnedToNode: true,
|
||||
ResName: "compute-48556",
|
||||
RGID: 79727,
|
||||
RGName: "sdk_negative_fields_test",
|
||||
@@ -142,7 +146,7 @@ var computes = ListComputes{
|
||||
UserManaged: true,
|
||||
VGPUs: []uint64{},
|
||||
VINSConnected: 0,
|
||||
ZoneID: 5,
|
||||
VirtualImageID: 0,
|
||||
},
|
||||
},
|
||||
EntryCount: 2,
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// GetCPUAlignmentProfileRequest struct to get CPU alignment profile for compute
|
||||
type GetCPUAlignmentProfileRequest struct {
|
||||
// ID of the compute instance
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
|
||||
}
|
||||
|
||||
// GetCPUAlignmentProfile gets CPU alignment profile for compute
|
||||
func (c Compute) GetCPUAlignmentProfile(ctx context.Context, req GetCPUAlignmentProfileRequest) (*CPUAlignmentProfile, error) {
|
||||
res, err := c.GetCPUAlignmentProfileRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := CPUAlignmentProfile{}
|
||||
|
||||
err = json.Unmarshal(res, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
// GetCPUAlignmentProfileRaw gets CPU alignment profile for compute as an array of bytes
|
||||
func (c Compute) GetCPUAlignmentProfileRaw(ctx context.Context, req GetCPUAlignmentProfileRequest) ([]byte, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/get_cpu_alignment_profile"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
return res, err
|
||||
}
|
||||
@@ -27,7 +27,7 @@ func (c Compute) GetLog(ctx context.Context, req GetLogRequest) (string, error)
|
||||
|
||||
url := "/cloudapi/compute/getLog"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -42,7 +42,7 @@ func (c Compute) GetLogGet(ctx context.Context, req GetLogRequest) (string, erro
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/getLog"
|
||||
url := "/cloudapi//compute/getLog"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodGet, url, req)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// GuestAgentDisableRequest struct to disable guest agent
|
||||
type GuestAgentDisableRequest struct {
|
||||
// ID of compute instance
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
|
||||
}
|
||||
|
||||
type wrapperGuestAgentDisableRequest struct {
|
||||
GuestAgentDisableRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// Disable guest agent at a specific compute
|
||||
func (c Compute) GuestAgentDisable(ctx context.Context, req GuestAgentDisableRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperGuestAgentDisableRequest{
|
||||
GuestAgentDisableRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/guest_agent_disable"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseBool(string(res))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GuestAgentDisableAsync disables guest agent at a specific compute with AsyncMode
|
||||
func (c Compute) GuestAgentDisableAsync(ctx context.Context, req GuestAgentDisableRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperGuestAgentDisableRequest{
|
||||
GuestAgentDisableRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/guest_agent_disable"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// GuestAgentEnableRequest struct to enable guest agent
|
||||
type GuestAgentEnableRequest struct {
|
||||
// ID of compute instance
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
|
||||
}
|
||||
|
||||
type wrapperGuestAgentEnableRequest struct {
|
||||
GuestAgentEnableRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// Enable guest agent at a specific compute
|
||||
func (c Compute) GuestAgentEnable(ctx context.Context, req GuestAgentEnableRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperGuestAgentEnableRequest{
|
||||
GuestAgentEnableRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/guest_agent_enable"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseBool(string(res))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GuestAgentEnableAsync enables guest agent at a specific compute with AsyncMode
|
||||
func (c Compute) GuestAgentEnableAsync(ctx context.Context, req GuestAgentEnableRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperGuestAgentEnableRequest{
|
||||
GuestAgentEnableRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/guest_agent_enable"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// GuestAgentExecuteRequest struct to execute command from user to agent
|
||||
type GuestAgentExecuteRequest struct {
|
||||
// ID of compute instance
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
|
||||
|
||||
// Custom command from user to agent
|
||||
// Required: true
|
||||
Command string `url:"command" json:"command" validate:"required"`
|
||||
|
||||
// Arguments to command
|
||||
// Required: true
|
||||
Arguments string `url:"arguments" json:"arguments" validate:"required"`
|
||||
}
|
||||
|
||||
type wrapperGuestAgentExecuteRequest struct {
|
||||
GuestAgentExecuteRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// Execute guest agent command
|
||||
func (c Compute) GuestAgentExecuteRequest(ctx context.Context, req GuestAgentExecuteRequest) (map[string]interface{}, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperGuestAgentExecuteRequest{
|
||||
GuestAgentExecuteRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/guest_agent_execute"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result map[string]interface{}
|
||||
|
||||
err = json.Unmarshal(res, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GuestAgentExecuteRequestAsync executes guest agent command with AsyncMode
|
||||
func (c Compute) GuestAgentExecuteRequestAsync(ctx context.Context, req GuestAgentExecuteRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperGuestAgentExecuteRequest{
|
||||
GuestAgentExecuteRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/guest_agent_execute"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// GuestAgentFeatureGetRequest struct to feature get guest agent
|
||||
type GuestAgentFeatureGetRequest struct {
|
||||
// ID of compute instance
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
|
||||
}
|
||||
|
||||
// List of features
|
||||
func (c Compute) GuestAgentFeatureGet(ctx context.Context, req GuestAgentFeatureGetRequest) ([]string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/guest_agent_feature_get"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
features := make([]string, 0)
|
||||
|
||||
err = json.Unmarshal(res, &features)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return features, nil
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// GuestAgentFeatureUpdateRequest struct to feature update guest agent
|
||||
type GuestAgentFeatureUpdateRequest struct {
|
||||
// ID of compute instance
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"compute_id" json:"compute_id" validate:"required"`
|
||||
}
|
||||
|
||||
type wrapperGuestAgentFeatureUpdateRequest struct {
|
||||
GuestAgentFeatureUpdateRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// Feature update guest agent
|
||||
func (c Compute) GuestAgentFeatureUpdate(ctx context.Context, req GuestAgentFeatureUpdateRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperGuestAgentFeatureUpdateRequest{
|
||||
GuestAgentFeatureUpdateRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/guest_agent_feature_update"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseBool(string(res))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GuestAgentFeatureUpdateAsync feature updates guest agent with AsyncMode
|
||||
func (c Compute) GuestAgentFeatureUpdateAsync(ctx context.Context, req GuestAgentFeatureUpdateRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperGuestAgentFeatureUpdateRequest{
|
||||
GuestAgentFeatureUpdateRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/guest_agent_feature_update"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
@@ -4,8 +4,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// ListRequest struct to get list of available computes
|
||||
@@ -54,15 +52,6 @@ type ListRequest struct {
|
||||
// Required: false
|
||||
IncludeDeleted bool `url:"includedeleted,omitempty" json:"includedeleted,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||
|
||||
// Sort by zone id
|
||||
// Default value: 0
|
||||
// Required: false
|
||||
ZoneID uint64 `url:"zone_id,omitempty" json:"zone_id,omitempty"`
|
||||
|
||||
// Page number
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
@@ -75,7 +64,6 @@ type ListRequest struct {
|
||||
// List gets list of the available computes.
|
||||
// Filtering based on status is possible
|
||||
func (c Compute) List(ctx context.Context, req ListRequest) (*ListComputes, error) {
|
||||
|
||||
res, err := c.ListRaw(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -93,11 +81,6 @@ func (c Compute) List(ctx context.Context, req ListRequest) (*ListComputes, erro
|
||||
|
||||
// ListRaw gets list of the available computes.
|
||||
func (c Compute) ListRaw(ctx context.Context, req ListRequest) ([]byte, error) {
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/list"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
|
||||
@@ -4,8 +4,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// ListDeletedRequest struct to get deleted computes list
|
||||
@@ -46,10 +44,6 @@ type ListDeletedRequest struct {
|
||||
// Required: false
|
||||
ExtNetID uint64 `url:"extNetId,omitempty" json:"extNetId,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||
|
||||
// Page number
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
@@ -61,11 +55,6 @@ type ListDeletedRequest struct {
|
||||
|
||||
// ListDeleted gets list all deleted computes
|
||||
func (c Compute) ListDeleted(ctx context.Context, req ListDeletedRequest) (*ListComputes, error) {
|
||||
|
||||
if err := validators.ValidateRequest(req); err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/listDeleted"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
|
||||
|
||||
@@ -30,10 +30,6 @@ type ListPCIDeviceRequest struct {
|
||||
// Required: false
|
||||
Status string `url:"status,omitempty" json:"status,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||
|
||||
// Page number
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
@@ -45,7 +41,6 @@ type ListPCIDeviceRequest struct {
|
||||
|
||||
// ListPCIDevice gets list PCI device
|
||||
func (c Compute) ListPCIDevice(ctx context.Context, req ListPCIDeviceRequest) (*ListPCIDevices, error) {
|
||||
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
|
||||
@@ -26,10 +26,6 @@ type ListVGPURequest struct {
|
||||
// Required: false
|
||||
Status string `url:"status,omitempty" json:"status,omitempty"`
|
||||
|
||||
// Sort by one of supported fields, format +|-(field)
|
||||
// Required: false
|
||||
SortBy string `url:"sortBy,omitempty" json:"sortBy,omitempty" validate:"omitempty,sortBy"`
|
||||
|
||||
// Page number
|
||||
// Required: false
|
||||
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
|
||||
@@ -45,7 +41,6 @@ type ListVGPURequest struct {
|
||||
|
||||
// ListVGPU gets list vGPU
|
||||
func (c Compute) ListVGPU(ctx context.Context, req ListVGPURequest) (*ListVGPUs, error) {
|
||||
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return nil, validators.ValidationErrors(validators.GetErrors(err))
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
|
||||
)
|
||||
|
||||
// MigrateToRGZone struct to move compute to another zone
|
||||
type MigrateToZoneRequest struct {
|
||||
// ID of the compute instance to move
|
||||
// Required: true
|
||||
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
|
||||
|
||||
// ID of the zone to move
|
||||
// Required: true
|
||||
ZoneID uint64 `url:"zoneId" json:"zoneId " validate:"required"`
|
||||
}
|
||||
|
||||
type wrapperMigrateToZoneRequest struct {
|
||||
MigrateToZoneRequest
|
||||
|
||||
AsyncMode bool `url:"asyncMode"`
|
||||
}
|
||||
|
||||
// MoveToRG moves compute instance to new resource group
|
||||
func (c Compute) MigrateToZone(ctx context.Context, req MigrateToZoneRequest) (bool, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return false, validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperMigrateToZoneRequest{
|
||||
MigrateToZoneRequest: req,
|
||||
AsyncMode: false,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/migrateToZone"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseBool(string(res))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// MigrateToZoneAsync moves compute to another zone with AsyncMode
|
||||
func (c Compute) MigrateToZoneAsync(ctx context.Context, req MigrateToZoneRequest) (string, error) {
|
||||
err := validators.ValidateRequest(req)
|
||||
if err != nil {
|
||||
return "", validators.ValidationErrors(validators.GetErrors(err))
|
||||
}
|
||||
|
||||
reqWrapped := wrapperMigrateToZoneRequest{
|
||||
MigrateToZoneRequest: req,
|
||||
AsyncMode: true,
|
||||
}
|
||||
|
||||
url := "/cloudapi/compute/migrateToZone"
|
||||
|
||||
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user