Compare commits

...

10 Commits

Author SHA1 Message Date
264538f492 v1.4.6 2023-06-23 15:13:22 +03:00
c06a3198f6 v1.4.5 2023-06-19 15:06:31 +03:00
c9e4ae6afe v1.4.4 2023-06-01 16:50:10 +03:00
2a1593f45f v1.5.0-beta 2023-05-18 13:55:28 +03:00
190f24dac1 v1.4.3 2023-05-18 13:37:48 +03:00
256dba5134 v1.5.0-alfa 2023-05-15 19:27:02 +03:00
b7137683ab v1.4.2 2023-05-15 10:55:36 +03:00
10e3e19892 v1.4.1 2023-05-04 16:15:35 +03:00
aaf0857ff0 v1.4.0 2023-04-28 11:46:58 +03:00
7d6cda7119 v1.3.1 2023-04-20 11:17:35 +03:00
139 changed files with 4757 additions and 270 deletions

3
.gitignore vendored
View File

@@ -1 +1,2 @@
cmd/
cmd/
.idea/

View File

@@ -1,39 +1,12 @@
## Version 1.3.0
### Features
- Created CloudAPI/CloudBroker filtering, sorting and serialization functions for List requests.
- Every handler with present List request has available FilterBy functions. Filtering by ID, Name is common for each handler.
- In case user needs to filter response by uncommon field FilterFunc with user-specified predicate is also available.
- CloudAPI/CloudBroker computes, disks and lb also have specific Filter methods predefined, to name a few:
- computes:
- FilterByK8SID, used to filter computes used by specified k8s cluster;
- FilterByK8SMasters, FilterByK8SWorkers, used to filter master/workers nodes. Best used after FilterByK8SID call;
- FilterByLBID, used to filter computes used by specified load balancer;
- disks:
- FilterByK8SID, used to filter disks attached to computes inside specified k8s cluster;
- FilterByLBID, used to filter disks attached to computes inside specified load balancer;
- lb:
- FilterByK8SID, used to filter load balancers used by specified k8s cluster;
- Reinvented request validation using go-validator. Made easier to manipulate and add on to.
- Request/Config validation now uses tags instead of hard-coded validation functions;
- Added ability to parse client configuration from JSON or YAML formatted files.
### Bug Fixes
- Fixed SSO_URL trailing slash possibly breaking authentication process.
- Fixed cloudbroker/vins/nat_rule_add request model types.
- Fixed cloudbroker/grid DiskSize field type
- Fixed TasksResult, InfoResult in cloudbroker/cloudapi/tasks/models JSON unmarshalling.
### Tests
- Covered CloudAPI/CloudBroker filters with unit tests.
### Other
- Updated module to new repository
## Version 1.4.6
### Bugfix
- Fixed returning value type of VINS.NATRuleAdd()
- Fixed RuleID field type of VINS.NATRuleDel() request struct
- Added wrapper for requests to async methods
- - CloudAPI()/CloudBroker().Compute().CreateTemplate()
### Feature
- Added cloubroker/apiaccess group of endpoints support
- Added cloubroker/group group of endpoints support
- Added cloubroker/user group of endpoints support

View File

@@ -8,6 +8,7 @@ Decort SDK - это библиотека, написанная на языке G
- Версия 1.1.x Decort-SDK соответствует 3.8.5 версии платформы
- Версия 1.2.x Decort-SDK соответствует 3.8.5 версии платформы
- Версия 1.3.x Decort-SDK соответствует 3.8.5 версии платформы
- Версия 1.4.x Decort-SDK соответствует 3.8.6 версии платформы
## Оглавление
@@ -117,6 +118,7 @@ go get -u repository.basistech.ru/BASIS/decort-golang-sdk
| SSOURL | string | Да | URL адрес сервиса аутентификации и авторизации |
| DecortURL | string | Да | URL адрес платформы, с которой будет осуществляться взаимодействие |
| Retries | uint | Нет | Кол-во неудачных попыток выполнения запроса, по умолчанию - 5 |
| Timeout | config.Duration | Нет | Таймаут HTTP клиента, по умолчанию - без ограничений |
| SSLSkipVerify | bool | Нет | Пропуск проверки подлинности сертификата, по умолчанию - true |
| Token | string | Нет | JWT токен |
@@ -126,6 +128,7 @@ go get -u repository.basistech.ru/BASIS/decort-golang-sdk
import (
"repository.basistech.ru/BASIS/decort-golang-sdk/config"
)
func main(){
// Настройка конфигурации
cfg := config.Config{
@@ -135,6 +138,8 @@ func main(){
DecortURL: "https://mr4.digitalenergy.online",
Retries: 5,
}
cfg.SetTimeout(5 * time.Minute)
}
```
@@ -164,6 +169,7 @@ func main() {
"ssoUrl": "https://sso.digitalenergy.online",
"decortUrl": "https://mr4.digitalenergy.online",
"retries": 5,
"timeout": "5m",
"sslSkipVerify": false
}
```
@@ -176,6 +182,7 @@ appSecret: <APP_SECRET>
ssoUrl: https://sso.digitalenergy.online
decortUrl: https://mr4.digitalenergy.online
retries: 5
timeout: 5m
sslSkipVerify: false
```
@@ -203,6 +210,8 @@ func main() {
Retries: 5,
}
cfg.SetTimeout(5 * time.Minute)
// Создание клиента
client := decort.New(cfg)
}
@@ -646,6 +655,8 @@ func main() {
DecortURL: "<DECORT_URL>",
Retries: 5,
}
cfg.SetTimeout(5 * time.Minute)
// Создание клиента
client := decort.New(cfg)
@@ -692,6 +703,7 @@ func main() {
| Password | string | Да | пароль legacy пользователя |
| DecortURL | string | Да | URL адрес платформы, с которой будет осуществляться взаимодействие |
| Retries | uint | Нет | Кол-во неудачных попыток выполнения запроса, по умолчанию - 5 |
| Timeout | config.Duration | Нет | Таймаут HTTP клиента, по умолчанию - без ограничений |
| SSLSkipVerify | bool | Нет | Пропуск проверки подлинности сертификата, по умолчанию - true |
| Token | string | Нет | JWT токен |
@@ -710,6 +722,8 @@ func main(){
DecortURL: "https://mr4.digitalenergy.online",
Retries: 5,
}
legacyCfg.SetTimeout(5 * time.Minute)
}
```
@@ -738,6 +752,7 @@ func main() {
"password": "<PASSWORD>",
"decortUrl": "https://mr4.digitalenergy.online",
"retries": 5,
"timeout": "5m",
"sslSkipVerify": true
}
```
@@ -748,6 +763,7 @@ username: <USERNAME>
password: <PASSWORD>
decortUrl: https://mr4.digitalenergy.online
retries: 5
timeout: 5m
sslSkipVerify: true
```
### Создание legacy клиента
@@ -773,6 +789,8 @@ func main() {
Retries: 5,
}
legacyCfg.SetTimeout(5 * time.Minute)
// Создание клиента
legacyClient := decort.NewLegacy(cfg)
}

View File

@@ -3,6 +3,7 @@ package config
import (
"encoding/json"
"os"
"time"
"gopkg.in/yaml.v3"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
@@ -44,6 +45,15 @@ type Config struct {
// Skip verify, true by default
// Required: false
SSLSkipVerify bool `json:"sslSkipVerify" yaml:"sslSkipVerify"`
// HTTP client timeout, unlimited if left empty
// Required: false
Timeout Duration `json:"timeout" yaml:"timeout"`
}
// SetTimeout is used to set HTTP client timeout.
func (c *Config) SetTimeout(dur time.Duration) {
c.Timeout = Duration(dur)
}
// ParseConfigJSON parses Config from specified JSON-formatted file.

View File

@@ -3,6 +3,7 @@ package config
import (
"encoding/json"
"os"
"time"
"gopkg.in/yaml.v3"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
@@ -38,6 +39,15 @@ type LegacyConfig struct {
// Skip verify, true by default
// Required: false
SSLSkipVerify bool `json:"sslSkipVerify" yaml:"sslSkipVerify"`
// HTTP client timeout, unlimited if left empty
// Required: false
Timeout Duration `json:"timeout" yaml:"timeout"`
}
// SetTimeout is used to set HTTP client timeout.
func (c *LegacyConfig) SetTimeout(dur time.Duration) {
c.Timeout = Duration(dur)
}
// ParseLegacyConfigJSON parses LegacyConfig from specified JSON-formatted file.

50
config/timeouts.go Normal file
View File

@@ -0,0 +1,50 @@
package config
import (
"encoding/json"
"fmt"
"time"
)
// Duration is a wrapper around time.Duration (used for better user experience)
type Duration time.Duration
func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error {
var v interface{}
if err := unmarshal(&v); err != nil {
return err
}
switch value := v.(type) {
case string:
tmp, err := time.ParseDuration(value)
if err != nil {
return err
}
*d = Duration(tmp)
return nil
default:
return fmt.Errorf("Invalid duration %v", value)
}
}
func (d *Duration) UnmarshalJSON(b []byte) error {
var v interface{}
if err := json.Unmarshal(b, &v); err != nil {
return err
}
switch value := v.(type) {
case string:
tmp, err := time.ParseDuration(value)
if err != nil {
return err
}
*d = Duration(tmp)
return nil
default:
return fmt.Errorf("Invalid duration %v", value)
}
}
func (d *Duration) Get() time.Duration {
return time.Duration(*d)
}

3
go.mod
View File

@@ -5,14 +5,15 @@ go 1.20
require (
github.com/go-playground/validator/v10 v10.11.2
github.com/google/go-querystring v1.1.0
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // 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
gopkg.in/yaml.v3 v3.0.1 // indirect
)

6
go.sum
View File

@@ -1,3 +1,4 @@
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/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
@@ -11,10 +12,14 @@ 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-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
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/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=
@@ -26,6 +31,7 @@ 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/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=

View File

@@ -35,6 +35,6 @@ func NewHttpClient(cfg config.Config) *http.Client {
//TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
Timeout: 5 * time.Minute,
Timeout: cfg.Timeout.Get(),
}
}

View File

@@ -4,7 +4,6 @@ import (
"crypto/tls"
"net/http"
"net/url"
"time"
"repository.basistech.ru/BASIS/decort-golang-sdk/config"
)
@@ -28,6 +27,6 @@ func NewLegacyHttpClient(cfg config.LegacyConfig) *http.Client {
decortURL: cfg.DecortURL,
},
Timeout: 5 * time.Minute,
Timeout: cfg.Timeout.Get(),
}
}

View File

@@ -1,6 +1,10 @@
package validators
import "github.com/go-playground/validator/v10"
import (
"github.com/go-playground/validator/v10"
"regexp"
"strings"
)
// protoValidator is used to validate Proto fields.
func protoValidator(fe validator.FieldLevel) bool {
@@ -203,3 +207,52 @@ func sepFieldTypeValidator(fe validator.FieldLevel) bool {
return StringInSlice(fieldValue, sepFieldTypeValues)
}
// hwPathValidator is used to validate HWPath field.
func hwPathValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
ok, _ := regexp.MatchString(`^\b[0-9a-f]{4}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}.\d{1}$`, fieldValue)
return ok
}
// networkPluginValidator is used to validate NetworkPlugin field
func networkPluginValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
fieldValue = strings.ToLower(fieldValue)
return StringInSlice(fieldValue, networkPluginValues)
}
// networkPluginsValidator is used to validate NetworkPlugins field
func networkPluginsValidator(fe validator.FieldLevel) bool {
fieldSlice, ok := fe.Field().Interface().([]string)
if !ok {
return false
}
for _, item := range fieldSlice {
item = strings.ToLower(item)
if !StringInSlice(item, networkPluginValues) {
return false
}
}
return true
}
func interfaceStateValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
fieldValue = strings.ToLower(fieldValue)
return StringInSlice(fieldValue, interfaceStateValues)
}
func strictLooseValidator(fe validator.FieldLevel) bool {
fieldValue := fe.Field().String()
fieldValue = strings.ToLower(fieldValue)
return StringInSlice(fieldValue, strictLooseValues)
}

View File

@@ -187,6 +187,36 @@ func errorMessage(fe validator.FieldError) string {
fe.Field(),
joinValues(sepFieldTypeValues))
// HWPath Validators
case "hwPath":
return fmt.Sprintf("%s %s must be in format 0000:1f:2b.0",
prefix,
fe.Field())
// Network plugin Validators
case "networkPlugin":
return fmt.Sprintf("%s %s must be one of the following: %s",
prefix,
fe.Field(),
joinValues(networkPluginValues))
case "networkPlugins":
return fmt.Sprintf("%s %s must contain only the following: %s",
prefix,
fe.Field(),
joinValues(networkPluginValues))
case "strict_loose":
return fmt.Sprintf("%s %s must be one of the following: %s",
prefix,
fe.Field(),
joinValues(strictLooseValues))
case "interfaceState":
return fmt.Sprintf("%s %s must be one of the following: %s",
prefix,
fe.Field(),
joinValues(interfaceStateValues))
}
return fe.Error()

View File

@@ -7,29 +7,20 @@ import (
)
var (
once sync.Once
instance *DecortValidator
once sync.Once
decortValidator = validator.New()
)
type DecortValidator struct {
decortValidator *validator.Validate
}
// getDecortValidator returns singleton instance of DecortValidator.
func getDecortValidator() *validator.Validate {
if instance == nil {
once.Do(func() {
instance = new(DecortValidator)
instance.decortValidator = validator.New()
once.Do(func() {
err := registerAllValidators(decortValidator)
if err != nil {
panic(err)
}
})
err := registerAllValidators(instance.decortValidator)
if err != nil {
panic(err)
}
})
}
return instance.decortValidator
return decortValidator
}
// registerAllValidators registers all custom validators in DecortValidator.
@@ -159,5 +150,30 @@ func registerAllValidators(validate *validator.Validate) error {
return err
}
err = validate.RegisterValidation("hwPath", hwPathValidator)
if err != nil {
return err
}
err = validate.RegisterValidation("networkPlugin", networkPluginValidator)
if err != nil {
return err
}
err = validate.RegisterValidation("networkPlugins", networkPluginsValidator)
if err != nil {
return err
}
err = validate.RegisterValidation("strict_loose", strictLooseValidator)
if err != nil {
return err
}
err = validate.RegisterValidation("interfaceState", interfaceStateValidator)
if err != nil {
return err
}
return nil
}

View File

@@ -37,4 +37,10 @@ var (
imageArchitectureValues = []string{"X86_64", "PPC64_LE"}
sepFieldTypeValues = []string{"int", "str", "bool", "list", "dict"}
networkPluginValues = []string{"flannel", "weawenet", "calico"}
strictLooseValues = []string{"strict", "loose"}
interfaceStateValues = []string{"on", "off"}
)

View File

@@ -44,7 +44,7 @@ type CreateRequest struct {
// If true send emails when a user is granted access to resources
// Required: false
SendAccessEmails bool `url:"sendAccessEmails,omitempty" json:"sendAccessEmails,omitempty"`
SendAccessEmails bool `url:"sendAccessEmails" json:"sendAccessEmails"`
// Limit (positive) or disable (0) GPU resources
// Required: false

View File

@@ -158,6 +158,12 @@ type RecordAccount struct {
// Computes
Computes Computes `json:"computes"`
// CPU allocation parameter
CPUAllocationParameter string `json:"cpu_allocation_parameter"`
// CPU allocation ratio
CPUAllocationRatio float64 `json:"cpu_allocation_ratio"`
// Created by
CreatedBy string `json:"createdBy"`
@@ -165,7 +171,7 @@ type RecordAccount struct {
CreatedTime uint64 `json:"createdTime"`
// Deactivation time
DeactivationTime uint64 `json:"deactivationTime"`
DeactivationTime float64 `json:"deactivationTime"`
// Deleted by
DeletedBy string `json:"deletedBy"`
@@ -192,7 +198,7 @@ type RecordAccount struct {
ResourceLimits ResourceLimits `json:"resourceLimits"`
// Resource types
ResourceTypes []string `json:"resourceTypes"`
ResTypes []string `json:"resourceTypes"`
// Send access emails
SendAccessEmails bool `json:"sendAccessEmails"`

View File

@@ -3,8 +3,6 @@ package account
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
@@ -26,15 +24,10 @@ func (a Account) Restore(ctx context.Context, req RestoreRequest) (bool, error)
url := "/cloudapi/account/restore"
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
_, err = a.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
return true, nil
}

View File

@@ -20,31 +20,31 @@ type UpdateRequest struct {
// Max size of memory in MB
// Required: false
MaxMemoryCapacity uint64 `url:"maxMemoryCapacity,omitempty" json:"maxMemoryCapacity,omitempty"`
MaxMemoryCapacity int64 `url:"maxMemoryCapacity,omitempty" json:"maxMemoryCapacity,omitempty"`
// Max size of aggregated vdisks in GB
// Required: false
MaxVDiskCapacity uint64 `url:"maxVDiskCapacity,omitempty" json:"maxVDiskCapacity,omitempty"`
MaxVDiskCapacity int64 `url:"maxVDiskCapacity,omitempty" json:"maxVDiskCapacity,omitempty"`
// Max number of CPU cores
// Required: false
MaxCPUCapacity uint64 `url:"maxCPUCapacity,omitempty" json:"maxCPUCapacity,omitempty"`
MaxCPUCapacity int64 `url:"maxCPUCapacity,omitempty" json:"maxCPUCapacity,omitempty"`
// Max sent/received network transfer peering
// Required: false
MaxNetworkPeerTransfer uint64 `url:"maxNetworkPeerTransfer,omitempty" json:"maxNetworkPeerTransfer,omitempty"`
MaxNetworkPeerTransfer int64 `url:"maxNetworkPeerTransfer,omitempty" json:"maxNetworkPeerTransfer,omitempty"`
// Max number of assigned public IPs
// Required: false
MaxNumPublicIP uint64 `url:"maxNumPublicIP,omitempty" json:"maxNumPublicIP,omitempty"`
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,omitempty" json:"sendAccessEmails,omitempty"`
SendAccessEmails bool `url:"sendAccessEmails" json:"sendAccessEmails"`
// Limit (positive) or disable (0) GPU resources
// Required: false
GPUUnits uint64 `url:"gpu_units,omitempty" json:"gpu_units,omitempty"`
GPUUnits int64 `url:"gpu_units,omitempty" json:"gpu_units,omitempty"`
}
// Update updates an account name and resource types and limits

View File

@@ -35,11 +35,8 @@ type RecordBasicService struct {
// Grid ID
GID uint64 `json:"gid"`
// List of Service Compute Group IDs
Groups []uint64 `json:"groups"`
// List of compute groups by name
GroupsName []string `json:"groupsName"`
// List of Service Compute Groups
Groups ListGroups `json:"groups"`
// GUID
GUID uint64 `json:"guid"`
@@ -95,6 +92,12 @@ type RecordBasicService struct {
// Main information about Compute
type ItemCompute struct {
// Account ID
AccountID uint64
// Architecture
Architecture string `json:"arch"`
// Compute group ID
CompGroupID uint64 `json:"compgroupId"`
@@ -109,11 +112,47 @@ type ItemCompute struct {
// Name
Name string `json:"name"`
// Resource group ID
RGID uint64 `json:"rgId"`
// StackID
StackID uint64 `json:"stackId"`
// Status
Status string `json:"status"`
// Tech status
TechStatus string `json:"techStatus"`
}
// List of Computes
type ListComputes []ItemCompute
// Main information about Group
type ItemGroup struct {
// Amount of computes
Computes uint64 `json:"computes"`
// Consistency
Consistency bool `json:"consistency"`
// Group ID
ID uint64 `json:"id"`
// Group name
Name string `json:"name"`
// Status
Status string `json:"status"`
// TechStatus
TechStatus string `json:"techStatus"`
}
// List of Groups
type ListGroups []ItemGroup
// Main information about Snapshot
type ItemSnapshot struct {
// GUID

View File

@@ -0,0 +1,41 @@
package compute
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for getting boot order
type BootOrderGetRequest struct {
// Compute ID
// Required: true
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
}
// BootOrderGet gets actual compute boot order information
func (c Compute) BootOrderGet(ctx context.Context, req BootOrderGetRequest) ([]string, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudapi/compute/bootOrderGet"
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
orders := make([]string, 0)
err = json.Unmarshal(res, &orders)
if err != nil {
return nil, err
}
return orders, nil
}

View File

@@ -0,0 +1,49 @@
package compute
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for setting boot order
type BootOrderSetRequest struct {
// ID of compute instance
// Required: true
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
// List of boot devices
// Should be one of:
// - cdrom
// - network
// - hd
// Required: true
Order []string `url:"order" json:"order" validate:"min=1,computeOrder"`
}
// BootOrderSet sets compute boot order
func (c Compute) BootOrderSet(ctx context.Context, req BootOrderSetRequest) ([]string, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudapi/compute/bootOrderSet"
res, err := c.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
orders := make([]string, 0)
err = json.Unmarshal(res, &orders)
if err != nil {
return nil, err
}
return orders, nil
}

View File

@@ -0,0 +1,47 @@
package compute
import (
"context"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
"strconv"
)
// Request struct for changing link state
type ChangeLinkStateRequest struct {
// Compute ID
// Required: true
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
// Interface name or MAC address
// Required: true
Interface string `url:"interface" json:"interface" validate:"required"`
// Interface state
// Must be either "on" or "off"
// Required: true
State string `url:"state" json:"state" validate:"required,interfaceState"`
}
// ChangeLinkState changes the status link virtual of compute
func (c Compute) ChangeLinkState(ctx context.Context, req ChangeLinkStateRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
}
}
url := "/cloudapi/compute/changeLinkState"
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
}

View File

@@ -18,12 +18,12 @@ type CreateTemplateRequest struct {
// Name to assign to the template being created
// Required: true
Name string `url:"name" json:"name" validate:"required"`
}
// Async API call
// For async call use CreateTemplateAsync
// For sync call use CreateTemplate
// Required: true
async bool `url:"async"`
type wrapperCreateTemplateRequest struct {
CreateTemplateRequest
Async bool `url:"async"`
}
// CreateTemplate create template from compute instance
@@ -35,11 +35,14 @@ func (c Compute) CreateTemplate(ctx context.Context, req CreateTemplateRequest)
}
}
req.async = false
reqWrapped := wrapperCreateTemplateRequest{
CreateTemplateRequest: req,
Async: false,
}
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 0, err
}
@@ -61,11 +64,14 @@ func (c Compute) CreateTemplateAsync(ctx context.Context, req CreateTemplateRequ
}
}
req.async = true
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
}

View File

@@ -22,6 +22,11 @@ type DiskAddRequest struct {
// Required: true
Size uint64 `url:"size" json:"size" validate:"required"`
// Storage endpoint provider ID
// By default the same with boot disk
// Required: false
SepID uint64 `url:"sepId,omitempty" json:"sepId,omitempty"`
// Type of the disk
// Should be one of:
// - D
@@ -29,11 +34,6 @@ type DiskAddRequest struct {
// Required: false
DiskType string `url:"diskType,omitempty" json:"diskType,omitempty" validate:"omitempty,computeDiskType"`
// Storage endpoint provider ID
// By default the same with boot disk
// Required: false
SepID uint64 `url:"sepId,omitempty" json:"sepId,omitempty"`
// Pool name
// By default will be chosen automatically
// Required: false

View File

@@ -17,6 +17,10 @@ type DiskAttachRequest struct {
// ID of the disk to attach
// Required: true
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
// Type of the disk B;D
// Required: false
DiskType string `url:"diskType,omitempty" json:"diskType,omitempty" validate:"omitempty,computeDiskType"`
}
// DiskAttach attach disk to compute

View File

@@ -4,7 +4,7 @@ import "testing"
var computes = ListComputes{
ItemCompute{
ACL: []interface{}{},
ACL: ListACL{},
AccountID: 132847,
AccountName: "std_2",
AffinityLabel: "",
@@ -85,7 +85,7 @@ var computes = ListComputes{
VirtualImageID: 0,
},
ItemCompute{
ACL: []interface{}{},
ACL: ListACL{},
AccountID: 132848,
AccountName: "std_broker",
AffinityLabel: "",
@@ -150,92 +150,92 @@ var computes = ListComputes{
}
func TestFilterByID(t *testing.T) {
actual := computes.FilterByID(48500).FindOne()
actual := computes.FilterByID(48500).FindOne()
if actual.ID != 48500 {
t.Fatal("expected ID 48500, found: ", actual.ID)
}
if actual.ID != 48500 {
t.Fatal("expected ID 48500, found: ", actual.ID)
}
actualEmpty := computes.FilterByID(0)
actualEmpty := computes.FilterByID(0)
if len(actualEmpty) != 0 {
t.Fatal("expected empty, actual: ", len(actualEmpty))
}
if len(actualEmpty) != 0 {
t.Fatal("expected empty, actual: ", len(actualEmpty))
}
}
func TestFilterByName(t *testing.T) {
actual := computes.FilterByName("test").FindOne()
actual := computes.FilterByName("test").FindOne()
if actual.Name != "test" {
t.Fatal("expected compute with name 'test', found: ", actual.Name)
}
if actual.Name != "test" {
t.Fatal("expected compute with name 'test', found: ", actual.Name)
}
}
func TestFilterByStatus(t *testing.T) {
actual := computes.FilterByStatus("ENABLED")
actual := computes.FilterByStatus("ENABLED")
for _, item := range actual {
if item.Status != "ENABLED" {
t.Fatal("expected ENABLED status, found: ", item.Status)
}
}
for _, item := range actual {
if item.Status != "ENABLED" {
t.Fatal("expected ENABLED status, found: ", item.Status)
}
}
}
func TestFilterByTechStatus(t *testing.T) {
actual := computes.FilterByTechStatus("STARTED").FindOne()
actual := computes.FilterByTechStatus("STARTED").FindOne()
if actual.ID != 48556 {
t.Fatal("expected 48556 with STARTED techStatus, found: ", actual.ID)
}
if actual.ID != 48556 {
t.Fatal("expected 48556 with STARTED techStatus, found: ", actual.ID)
}
}
func TestFilterByDiskID(t *testing.T) {
actual := computes.FilterByDiskID(65248).FindOne()
actual := computes.FilterByDiskID(65248).FindOne()
if actual.ID != 48556 {
t.Fatal("expected 48556 with DiskID 65248, found: ", actual.ID)
}
if actual.ID != 48556 {
t.Fatal("expected 48556 with DiskID 65248, found: ", actual.ID)
}
}
func TestFilterFunc(t *testing.T) {
actual := computes.FilterFunc(func(ic ItemCompute) bool {
return ic.Registered == true
})
actual := computes.FilterFunc(func(ic ItemCompute) bool {
return ic.Registered == true
})
if len(actual) != 2 {
t.Fatal("expected 2 elements found, actual: ", len(actual))
}
if len(actual) != 2 {
t.Fatal("expected 2 elements found, actual: ", len(actual))
}
for _, item := range actual {
if item.Registered != true {
t.Fatal("expected Registered to be true, actual: ", item.Registered)
}
}
for _, item := range actual {
if item.Registered != true {
t.Fatal("expected Registered to be true, actual: ", item.Registered)
}
}
}
func TestSortingByCreatedTime(t *testing.T) {
actual := computes.SortByCreatedTime(false)
actual := computes.SortByCreatedTime(false)
if actual[0].Name != "test" {
t.Fatal("expected 'test', found: ", actual[0].Name)
}
if actual[0].Name != "test" {
t.Fatal("expected 'test', found: ", actual[0].Name)
}
actual = computes.SortByCreatedTime(true)
if actual[0].Name != "compute_2" {
t.Fatal("expected 'compute_2', found: ", actual[0].Name)
}
actual = computes.SortByCreatedTime(true)
if actual[0].Name != "compute_2" {
t.Fatal("expected 'compute_2', found: ", actual[0].Name)
}
}
func TestSortingByCPU(t *testing.T) {
actual := computes.SortByCPU(false)
actual := computes.SortByCPU(false)
if actual[0].CPU != 4{
t.Fatal("expected 4 CPU cores, found: ", actual[0].CPU)
}
if actual[0].CPU != 4 {
t.Fatal("expected 4 CPU cores, found: ", actual[0].CPU)
}
actual = computes.SortByCPU(true)
actual = computes.SortByCPU(true)
if actual[0].CPU != 6 {
t.Fatal("expected 6 CPU cores, found: ", actual[0].CPU)
}
if actual[0].CPU != 6 {
t.Fatal("expected 6 CPU cores, found: ", actual[0].CPU)
}
}

View File

@@ -1,5 +1,7 @@
package compute
import "strconv"
// Access Control List
type RecordACL struct {
// Account ACL list
@@ -12,10 +14,27 @@ type RecordACL struct {
RGACL ListACL `json:"rgAcl"`
}
type Explicit bool
func (e *Explicit) UnmarshalJSON(b []byte) error {
if b[0] == '"' {
b = b[1 : len(b)-1]
}
res, err := strconv.ParseBool(string(b))
if err != nil {
return err
}
*e = Explicit(res)
return nil
}
// ACL information
type ItemACL struct {
// Explicit
Explicit bool `json:"explicit"`
Explicit Explicit `json:"explicit"`
// GUID
GUID string `json:"guid"`
@@ -131,6 +150,9 @@ type RecordNetAttach struct {
// Default GW
DefGW string `json:"defGw"`
// Enabled
Enabled bool `json:"enabled"`
// FLIPGroup ID
FLIPGroupID uint64 `json:"flipgroupId"`
@@ -159,7 +181,7 @@ type RecordNetAttach struct {
NetType string `json:"netType"`
// PCI slot
PCISlot uint64 `json:"pciSlot"`
PCISlot int64 `json:"pciSlot"`
// QOS
QOS QOS `json:"qos"`
@@ -464,6 +486,9 @@ type ItemVNFInterface struct {
// Default GW
DefGW string `json:"defGw"`
// Enabled
Enabled bool `json:"enabled"`
// FLIPGroup ID
FLIPGroupID uint64 `json:"flipgroupId"`
@@ -492,7 +517,7 @@ type ItemVNFInterface struct {
NetType string `json:"netType"`
// PCI slot
PCISlot uint64 `json:"pciSlot"`
PCISlot int64 `json:"pciSlot"`
// QOS
QOS QOS `json:"qos"`
@@ -592,7 +617,7 @@ type ItemComputeDisk struct {
Passwd string `json:"passwd"`
// PCI slot
PCISlot uint64 `json:"pciSlot"`
PCISlot int64 `json:"pciSlot"`
// Pool
Pool string `json:"pool"`
@@ -709,8 +734,7 @@ type IOTune struct {
// Main information about compute
type ItemCompute struct {
// Access Control List
ACL []interface{} `json:"acl"`
ACL ListACL `json:"acl"`
// Account ID
AccountID uint64 `json:"accountId"`
@@ -877,7 +901,7 @@ type InfoDisk struct {
ID uint64 `json:"id"`
// PCISlot
PCISlot uint64 `json:"pciSlot"`
PCISlot int64 `json:"pciSlot"`
}
// List information about computes

View File

@@ -19,8 +19,9 @@ type PFWAddRequest struct {
PublicPortStart uint64 `url:"publicPortStart" json:"publicPortStart" validate:"required"`
// End port number (inclusive) for the ranged rule
// Default value: -1
// Required: false
PublicPortEnd uint64 `url:"publicPortEnd,omitempty" json:"publicPortEnd,omitempty"`
PublicPortEnd int64 `url:"publicPortEnd,omitempty" json:"publicPortEnd,omitempty"`
// Internal base port number
// Required: true

View File

@@ -130,3 +130,62 @@ func (ld ListDisks) FindOne() ItemDisk {
return ld[0]
}
// FilterByID returns ListDisksUnattached with specified ID.
func (lu ListDisksUnattached) FilterByID(id uint64) ListDisksUnattached {
predicate := func(idisk ItemDiskUnattached) bool {
return idisk.ID == id
}
return lu.FilterFunc(predicate)
}
// FilterByName returns ListDisksUnattached with specified Name.
func (lu ListDisksUnattached) FilterByName(name string) ListDisksUnattached {
predicate := func(idisk ItemDiskUnattached) bool {
return idisk.Name == name
}
return lu.FilterFunc(predicate)
}
// FilterByStatus returns ListDisksUnattached with specified Status.
func (lu ListDisksUnattached) FilterByStatus(status string) ListDisksUnattached {
predicate := func(idisk ItemDiskUnattached) bool {
return idisk.Status == status
}
return lu.FilterFunc(predicate)
}
// FilterByTechStatus returns ListDisksUnattached with specified TechStatus.
func (lu ListDisksUnattached) FilterByTechStatus(techStatus string) ListDisksUnattached {
predicate := func(idisk ItemDiskUnattached) bool {
return idisk.TechStatus == techStatus
}
return lu.FilterFunc(predicate)
}
// FilterFunc allows filtering ListDisksUnattached based on a user-specified predicate.
func (lu ListDisksUnattached) FilterFunc(predicate func(ItemDiskUnattached) bool) ListDisksUnattached {
var result ListDisksUnattached
for _, item := range lu {
if predicate(item) {
result = append(result, item)
}
}
return result
}
// FindOne returns first found ItemDiskUnattached
// If none was found, returns an empty struct.
func (lu ListDisksUnattached) FindOne() ItemDiskUnattached {
if len(lu) == 0 {
return ItemDiskUnattached{}
}
return lu[0]
}

View File

@@ -1,6 +1,8 @@
package disks
import "testing"
import (
"testing"
)
var disks = ListDisks{
ItemDisk{
@@ -175,3 +177,198 @@ func TestSortByCreatedTime(t *testing.T) {
t.Fatal("expected ID 65193, found: ", actual[0].ID)
}
}
var unattachedDisks = ListDisksUnattached{
{
CKey: "",
Meta: []interface{}{
"cloudbroker",
"disk",
1,
},
AccountID: 149,
AccountName: "test_account1",
ACL: map[string]interface{}{},
BootPartition: 0,
CreatedTime: 1681477547,
DeletedTime: 0,
Description: "",
DestructionTime: 0,
DiskPath: "",
GID: 2002,
GUID: 22636,
ID: 22636,
ImageID: 0,
Images: []uint64{},
IOTune: IOTune{
TotalIOPSSec: 2000,
},
IQN: "",
Login: "",
Milestones: 43834,
Name: "test_disk",
Order: 0,
Params: "",
ParentID: 0,
Password: "",
PCISlot: -1,
Pool: "data05",
PresentTo: []uint64{},
PurgeAttempts: 0,
PurgeTime: 0,
RealityDeviceNumber: 0,
ReferenceID: "",
ResID: "79bd3bd8-3424-48d3-963f-1870d506f169",
ResName: "volumes/volume_22636",
Role: "",
SEPID: 1,
Shareable: false,
SizeMax: 0,
SizeUsed: 0,
Snapshots: nil,
Status: "CREATED",
TechStatus: "ALLOCATED",
Type: "D",
VMID: 0,
},
{
CKey: "",
Meta: []interface{}{
"cloudbroker",
"disk",
1,
},
AccountID: 150,
AccountName: "test_account",
ACL: map[string]interface{}{},
BootPartition: 0,
CreatedTime: 1681477558,
DeletedTime: 0,
Description: "",
DestructionTime: 0,
DiskPath: "",
GID: 2002,
GUID: 22637,
ID: 22637,
ImageID: 0,
Images: []uint64{},
IOTune: IOTune{
TotalIOPSSec: 2000,
},
IQN: "",
Login: "",
Milestones: 43834,
Name: "test_disk",
Order: 0,
Params: "",
ParentID: 0,
Password: "",
PCISlot: -1,
Pool: "data05",
PresentTo: []uint64{
27,
27,
},
PurgeAttempts: 0,
PurgeTime: 0,
RealityDeviceNumber: 0,
ReferenceID: "",
ResID: "79bd3bd8-3424-48d3-963f-1870d506f169",
ResName: "volumes/volume_22637",
Role: "",
SEPID: 1,
Shareable: false,
SizeMax: 0,
SizeUsed: 0,
Snapshots: nil,
Status: "CREATED",
TechStatus: "ALLOCATED",
Type: "B",
VMID: 0,
},
}
func TestListDisksUnattached_FilterByID(t *testing.T) {
actual := unattachedDisks.FilterByID(22636)
if len(actual) == 0 {
t.Fatal("No elements were found")
}
actualItem := actual.FindOne()
if actualItem.ID != 22636 {
t.Fatal("expected ID 22636, found: ", actualItem.ID)
}
}
func TestListDisksUnattached_FilterByName(t *testing.T) {
actual := unattachedDisks.FilterByName("test_disk")
if len(actual) != 2 {
t.Fatal("expected 2 elements, found: ", len(actual))
}
for _, item := range actual {
if item.Name != "test_disk" {
t.Fatal("expected 'test_disk' name, found: ", item.Name)
}
}
}
func TestListDisksUnattached_FilterByStatus(t *testing.T) {
actual := unattachedDisks.FilterByStatus("CREATED")
if len(actual) == 0 {
t.Fatal("No elements were found")
}
for _, item := range actual {
if item.Status != "CREATED" {
t.Fatal("expected 'CREATED' status, found: ", item.Status)
}
}
}
func TestListDisksUnattached_FilterByTechStatus(t *testing.T) {
actual := unattachedDisks.FilterByTechStatus("ALLOCATED")
if len(actual) == 0 {
t.Fatal("No elements were found")
}
for _, item := range actual {
if item.TechStatus != "ALLOCATED" {
t.Fatal("expected 'ALLOCATED' techStatus, found: ", item.TechStatus)
}
}
}
func TestListDisksUnattached_FilterFunc(t *testing.T) {
actual := unattachedDisks.FilterFunc(func(id ItemDiskUnattached) bool {
return len(id.PresentTo) == 2
})
if len(actual) == 0 {
t.Fatal("No elements were found")
}
if len(actual[0].PresentTo) != 2 {
t.Fatal("expected 2 elements in PresentTo, found: ", len(actual[0].PresentTo))
}
}
func TestListDisksUnattached_SortByCreatedTime(t *testing.T) {
actual := unattachedDisks.SortByCreatedTime(false)
if actual[0].ID != 22636 {
t.Fatal("expected ID 22636, found: ", actual[0].ID)
}
actual = unattachedDisks.SortByCreatedTime(true)
if actual[0].ID != 22637 {
t.Fatal("expected ID 22637, found: ", actual[0].ID)
}
}

View File

@@ -9,8 +9,8 @@ import (
// Request struct for get list types of disks
type ListTypesRequest struct {
// Show detailed disk types by seps
// Required: false
Detailed bool `url:"detailed,omitempty" json:"detailed,omitempty"`
// Required: true
Detailed bool `url:"detailed" json:"detailed" validate:"required"`
}
// ListTypes gets list defined disk types

View File

@@ -14,7 +14,7 @@ type ListUnattachedRequest struct {
}
// ListUnattached gets list of unattached disks
func (d Disks) ListUnattached(ctx context.Context, req ListUnattachedRequest) (ListDisks, error) {
func (d Disks) ListUnattached(ctx context.Context, req ListUnattachedRequest) (ListDisksUnattached, error) {
url := "/cloudapi/disks/listUnattached"
res, err := d.client.DecortApiCall(ctx, http.MethodPost, url, req)
@@ -22,7 +22,7 @@ func (d Disks) ListUnattached(ctx context.Context, req ListUnattachedRequest) (L
return nil, err
}
list := ListDisks{}
list := ListDisksUnattached{}
err = json.Unmarshal(res, &list)
if err != nil {

View File

@@ -114,9 +114,146 @@ type ItemDisk struct {
VMID uint64 `json:"vmid"`
}
type ItemDiskUnattached struct {
// CKey
CKey string `json:"_ckey"`
// Meta
Meta []interface{} `json:"_meta"`
// Account ID
AccountID uint64 `json:"accountId"`
// Account name
AccountName string `json:"accountName"`
// Access Control List
ACL map[string]interface{} `json:"acl"`
// Boot Partition
BootPartition uint64 `json:"bootPartition"`
// Created time
CreatedTime uint64 `json:"createdTime"`
// Deleted time
DeletedTime uint64 `json:"deletedTime"`
// Description
Description string `json:"desc"`
// Destruction time
DestructionTime uint64 `json:"destructionTime"`
// Disk path
DiskPath string `json:"diskPath"`
// Grid ID
GID uint64 `json:"gid"`
// GUID
GUID uint64 `json:"guid"`
// ID
ID uint64 `json:"id"`
// Image ID
ImageID uint64 `json:"imageId"`
// Images
Images []uint64 `json:"images"`
// IOTune
IOTune IOTune `json:"iotune"`
// IQN
IQN string `json:"iqn"`
// Login
Login string `json:"login"`
// Milestones
Milestones uint64 `json:"milestones"`
// Name
Name string `json:"name"`
// Order
Order uint64 `json:"order"`
// Params
Params string `json:"params"`
// Parent ID
ParentID uint64 `json:"parentId"`
// Password
Password string `json:"passwd"`
//PCISlot
PCISlot int64 `json:"pciSlot"`
// Pool
Pool string `json:"pool"`
// Present to
PresentTo []uint64 `json:"presentTo"`
// Purge attempts
PurgeAttempts uint64 `json:"purgeAttempts"`
// Purge time
PurgeTime uint64 `json:"purgeTime"`
// Reality device number
RealityDeviceNumber uint64 `json:"realityDeviceNumber"`
// Reference ID
ReferenceID string `json:"referenceId"`
// Resource ID
ResID string `json:"resId"`
// Resource name
ResName string `json:"resName"`
// Role
Role string `json:"role"`
// ID SEP
SEPID uint64 `json:"sepId"`
// Shareable
Shareable bool `json:"shareable"`
// Size max
SizeMax uint64 `json:"sizeMax"`
// Size used
SizeUsed float64 `json:"sizeUsed"`
// List of snapshots
Snapshots ListSnapshots `json:"snapshots"`
// Status
Status string `json:"status"`
// Tech status
TechStatus string `json:"techStatus"`
// Type
Type string `json:"type"`
// Virtual machine ID
VMID uint64 `json:"vmid"`
}
// List of disks
type ListDisks []ItemDisk
// List of unattached disks
type ListDisksUnattached []ItemDiskUnattached
// Main information about snapshot
type ItemSnapshot struct {
// GUID
@@ -240,7 +377,7 @@ type RecordDisk struct {
ParentID uint64 `json:"parentId"`
// PCI slot
PCISlot uint64 `json:"pciSlot"`
PCISlot int64 `json:"pciSlot"`
// Pool
Pool string `json:"pool"`

View File

@@ -41,3 +41,39 @@ func (idisk ItemDisk) Serialize(params ...string) (serialization.Serialized, err
return json.Marshal(idisk)
}
// Serialize returns JSON-serialized []byte. Used as a wrapper over json.Marshal and json.MarshalIndent functions.
//
// In order to serialize with indent make sure to follow these guidelines:
// - First argument -> prefix
// - Second argument -> indent
func (lu ListDisksUnattached) Serialize(params ...string) (serialization.Serialized, error) {
if len(lu) == 0 {
return []byte{}, nil
}
if len(params) > 1 {
prefix := params[0]
indent := params[1]
return json.MarshalIndent(lu, prefix, indent)
}
return json.Marshal(lu)
}
// Serialize returns JSON-serialized []byte. Used as a wrapper over json.Marshal and json.MarshalIndent functions.
//
// In order to serialize with indent make sure to follow these guidelines:
// - First argument -> prefix
// - Second argument -> indent
func (idisk ItemDiskUnattached) Serialize(params ...string) (serialization.Serialized, error) {
if len(params) > 1 {
prefix := params[0]
indent := params[1]
return json.MarshalIndent(idisk, prefix, indent)
}
return json.Marshal(idisk)
}

View File

@@ -58,3 +58,60 @@ func (ld ListDisks) SortByDeletedTime(inverse bool) ListDisks {
return ld
}
// SortByCreatedTime sorts ListDisksUnattached by the CreatedTime field in ascending order.
//
// If inverse param is set to true, the order is reversed.
func (lu ListDisksUnattached) SortByCreatedTime(inverse bool) ListDisksUnattached {
if len(lu) < 2 {
return lu
}
sort.Slice(lu, func(i, j int) bool {
if inverse {
return lu[i].CreatedTime > lu[j].CreatedTime
}
return lu[i].CreatedTime < lu[j].CreatedTime
})
return lu
}
// SortByDestructionTime sorts ListDisksUnattached by the DestructionTime field in ascending order.
//
// If inverse param is set to true, the order is reversed.
func (lu ListDisksUnattached) SortByDestructionTime(inverse bool) ListDisksUnattached {
if len(lu) < 2 {
return lu
}
sort.Slice(lu, func(i, j int) bool {
if inverse {
return lu[i].DestructionTime > lu[j].DestructionTime
}
return lu[i].DestructionTime < lu[j].DestructionTime
})
return lu
}
// SortByDeletedTime sorts ListDisksUnattached by the DeletedTime field in ascending order.
//
// If inverse param is set to true, the order is reversed.
func (lu ListDisksUnattached) SortByDeletedTime(inverse bool) ListDisksUnattached {
if len(lu) < 2 {
return lu
}
sort.Slice(lu, func(i, j int) bool {
if inverse {
return lu[i].DeletedTime > lu[j].DeletedTime
}
return lu[i].DeletedTime < lu[j].DeletedTime
})
return lu
}

View File

@@ -59,6 +59,9 @@ type ListExtNetComputes []ItemExtNetCompute
// QOS
type QOS struct {
// EBurst
EBurst uint64 `json:"eBurst"`
// ERate
ERate uint64 `json:"eRate"`
@@ -107,6 +110,23 @@ type VNFs struct {
DHCP uint64 `json:"dhcp"`
}
type Excluded struct {
// ClientType
ClientType string `json:"clientType"`
// IP
IP string `json:"ip"`
// MAC
MAC string `json:"mac"`
// Type
Type string `json:"type"`
// VMID
VMID uint64 `json:"vmId"`
}
// Detailed information about external network
type RecordExtNet struct {
// CKey
@@ -134,7 +154,7 @@ type RecordExtNet struct {
DNS []string `json:"dns"`
// Excluded
Excluded []string `json:"excluded"`
Excluded []Excluded `json:"excluded"`
// Free IPs
FreeIPs uint64 `json:"free_ips"`

View File

@@ -23,6 +23,9 @@ type RecordK8CI struct {
// Name
Name string `json:"name"`
// Network plugins
NetworkPlugins []string `json:"networkPlugins"`
// Version
Version string `json:"version"`
}

View File

@@ -26,6 +26,11 @@ type CreateRequest struct {
// Required: true
WorkerGroupName string `url:"workerGroupName" json:"workerGroupName" validate:"required"`
// Network plugin
// Must be one of these values: flannel, weawenet, calico
// Required: true
NetworkPlugin string `url:"networkPlugin" json:"networkPlugin" validate:"required,networkPlugin"`
// ID of SEP to create boot disks for master nodes. Uses images SEP ID if not set
// Required: false
MasterSEPID uint64 `url:"masterSepId,omitempty" json:"masterSepId,omitempty"`
@@ -96,7 +101,7 @@ type CreateRequest struct {
// Create Kubernetes cluster with masters nodes behind load balancer if true.
// Otherwise give all cluster nodes direct external addresses from selected ExtNet
// Required: false
WithLB bool `url:"withLB,omitempty" json:"withLB,omitempty"`
WithLB bool `url:"withLB" json:"withLB"`
// Text description of this Kubernetes cluster
// Required: false

View File

@@ -9,14 +9,14 @@ import (
)
// Request struct for disable/enable kubernetes cluster
type DisabelEnableRequest struct {
type DisableEnableRequest struct {
// Kubernetes cluster ID
// Required: true
K8SID uint64 `url:"k8sId" json:"k8sId" validate:"required"`
}
// Disable disables kubernetes cluster by ID
func (k8s K8S) Disable(ctx context.Context, req DisabelEnableRequest) (bool, error) {
func (k8s K8S) Disable(ctx context.Context, req DisableEnableRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
@@ -40,7 +40,7 @@ func (k8s K8S) Disable(ctx context.Context, req DisabelEnableRequest) (bool, err
}
// Enable enables kubernetes cluster by ID
func (k8s K8S) Enable(ctx context.Context, req DisabelEnableRequest) (bool, error) {
func (k8s K8S) Enable(ctx context.Context, req DisableEnableRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {

View File

@@ -101,6 +101,9 @@ type RecordK8S struct {
// Name
Name string `json:"name"`
// Network plugin
NetworkPlugin string `json:"networkPlugin"`
// Resource group ID
RGID uint64 `json:"rgId"`
@@ -246,6 +249,9 @@ type ItemK8SCluster struct {
// Name
Name string `json:"name"`
// Network plugin
NetworkPlugin string `json:"networkPlugin"`
// Resource group ID
RGID uint64 `json:"rgId"`

View File

@@ -2,9 +2,8 @@ package k8s
import (
"context"
"encoding/json"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
@@ -24,11 +23,11 @@ type WorkerAddRequest struct {
}
// WorkerAdd add worker nodes to a Kubernetes cluster
func (k8s K8S) WorkerAdd(ctx context.Context, req WorkerAddRequest) (bool, error) {
func (k8s K8S) WorkerAdd(ctx context.Context, req WorkerAddRequest) ([]uint64, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
return nil, validators.ValidationError(validationError)
}
}
@@ -36,12 +35,14 @@ func (k8s K8S) WorkerAdd(ctx context.Context, req WorkerAddRequest) (bool, error
res, err := k8s.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return false, err
return nil, err
}
result, err := strconv.ParseBool(string(res))
result := make([]uint64, 0)
err = json.Unmarshal(res, &result)
if err != nil {
return false, err
return nil, err
}
return result, nil

View File

@@ -59,11 +59,11 @@ type WorkersGroupAddRequest struct {
}
// WorkersGroupAdd adds workers group to Kubernetes cluster
func (k8s K8S) WorkersGroupAdd(ctx context.Context, req WorkersGroupAddRequest) (bool, error) {
func (k8s K8S) WorkersGroupAdd(ctx context.Context, req WorkersGroupAddRequest) (uint64, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
return 0, validators.ValidationError(validationError)
}
}
@@ -71,12 +71,12 @@ func (k8s K8S) WorkersGroupAdd(ctx context.Context, req WorkersGroupAddRequest)
res, err := k8s.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return false, err
return 0, err
}
result, err := strconv.ParseBool(string(res))
result, err := strconv.ParseUint(string(res), 10, 64)
if err != nil {
return false, err
return 0, err
}
return result, nil

View File

@@ -18,6 +18,15 @@ func (ll ListLocations) FilterByName(name string) ListLocations {
return ll.FilterFunc(predicate)
}
// FilterByGID returns ListLocations with specified GID.
func (ll ListLocations) FilterByGID(gid uint64) ListLocations {
predicate := func(il ItemLocation) bool {
return il.GID == gid
}
return ll.FilterFunc(predicate)
}
// FilterFunc allows filtering ListLocations based on a user-specified predicate.
func (ll ListLocations) FilterFunc(predicate func(ItemLocation) bool) ListLocations {
var result ListLocations

View File

@@ -59,6 +59,12 @@ type RecordResourceGroup struct {
// Access Control List
ACL ListACL `json:"acl"`
// CPU allocation parameter
CPUAllocationParameter string `json:"cpu_allocation_parameter"`
// CPU allocation ratio
CPUAllocationRatio float64 `json:"cpu_allocation_ratio"`
// Created by
CreatedBy string `json:"createdBy"`
@@ -107,12 +113,18 @@ type RecordResourceGroup struct {
// Resource limits
ResourceLimits ResourceLimits `json:"resourceLimits"`
// List of resource types
ResTypes []string `json:"resourceTypes"`
// Secret
Secret string `json:"secret"`
// Status
Status string `json:"status"`
// UniqPools
UniqPools []string `json:"uniqPools"`
// Updated by
UpdatedBy string `json:"updatedBy"`
@@ -124,12 +136,6 @@ type RecordResourceGroup struct {
// List of compute IDs
Computes []uint64 `json:"vms"`
// List of resource types
ResTypes []string `json:"resourceTypes"`
// UniqPools
UniqPools []string `json:"uniqPools"`
}
// Main information about resource group
@@ -146,6 +152,12 @@ type ItemResourceGroup struct {
// Access Control List
ACL ListACL `json:"acl"`
// CPU allocation parameter
CPUAllocationParameter string `json:"cpu_allocation_parameter"`
// CPU allocation ratio
CPUAllocationRatio float64 `json:"cpu_allocation_ratio"`
// Created by
CreatedBy string `json:"createdBy"`
@@ -194,12 +206,18 @@ type ItemResourceGroup struct {
// Resource limits
ResourceLimits ResourceLimits `json:"resourceLimits"`
// List of resource types
ResTypes []string `json:"resourceTypes"`
// Secret
Secret string `json:"secret"`
// Status
Status string `json:"status"`
// UniqPools
UniqPools []string `json:"uniqPools"`
// Updated by
UpdatedBy string `json:"updatedBy"`
@@ -211,12 +229,6 @@ type ItemResourceGroup struct {
// List of compute IDs
Computes []uint64 `json:"vms"`
// List of resource types
ResTypes []string `json:"resourceTypes"`
// UniqPools
UniqPools []string `json:"uniqPools"`
}
// List of resource groups
@@ -735,7 +747,10 @@ type RecordResourceUsage struct {
CPU uint64 `json:"cpu"`
// Disk size
DiskSize uint64 `json:"disksize"`
DiskSize float64 `json:"disksize"`
// Max disk size
DiskSizeMax uint64 `json:"disksizemax"`
// Number of external IPs
ExtIPs uint64 `json:"extips"`
@@ -748,4 +763,7 @@ type RecordResourceUsage struct {
// Number of RAM
RAM uint64 `json:"ram"`
// SEPs
SEPs map[string]map[string]DiskUsage `json:"seps"`
}

View File

@@ -24,23 +24,23 @@ type UpdateRequest struct {
// Max size of memory in MB
// Required: false
MaxMemoryCapacity uint64 `url:"maxMemoryCapacity,omitempty" json:"maxMemoryCapacity,omitempty"`
MaxMemoryCapacity int64 `url:"maxMemoryCapacity,omitempty" json:"maxMemoryCapacity,omitempty"`
// Max size of aggregated virtual disks in GB
// Required: false
MaxVDiskCapacity uint64 `url:"maxVDiskCapacity,omitempty" json:"maxVDiskCapacity,omitempty"`
MaxVDiskCapacity int64 `url:"maxVDiskCapacity,omitempty" json:"maxVDiskCapacity,omitempty"`
// Max number of CPU cores
// Required: false
MaxCPUCapacity uint64 `url:"maxCPUCapacity,omitempty" json:"maxCPUCapacity,omitempty"`
MaxCPUCapacity int64 `url:"maxCPUCapacity,omitempty" json:"maxCPUCapacity,omitempty"`
// Max sent/received network transfer peering
// Required: false
MaxNetworkPeerTransfer uint64 `url:"maxNetworkPeerTransfer,omitempty" json:"maxNetworkPeerTransfer,omitempty"`
MaxNetworkPeerTransfer int64 `url:"maxNetworkPeerTransfer,omitempty" json:"maxNetworkPeerTransfer,omitempty"`
// Max number of assigned public IPs
// Required: false
MaxNumPublicIP uint64 `url:"maxNumPublicIP,omitempty" json:"maxNumPublicIP,omitempty"`
MaxNumPublicIP int64 `url:"maxNumPublicIP,omitempty" json:"maxNumPublicIP,omitempty"`
// Register computes in registration system
// Required: false

View File

@@ -261,7 +261,7 @@ type ItemVNFInterface struct {
NetType string `json:"netType"`
// PCI slot
PCISlot uint64 `json:"pciSlot"`
PCISlot int64 `json:"pciSlot"`
// QOS
QOS QOS `json:"qos"`

View File

@@ -39,11 +39,11 @@ type NATRuleAddRequest struct {
}
// NATRuleAdd create NAT (port forwarding) rule on VINS
func (v VINS) NATRuleAdd(ctx context.Context, req NATRuleAddRequest) (bool, error) {
func (v VINS) NATRuleAdd(ctx context.Context, req NATRuleAddRequest) (uint64, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
return 0, validators.ValidationError(validationError)
}
}
@@ -51,12 +51,12 @@ func (v VINS) NATRuleAdd(ctx context.Context, req NATRuleAddRequest) (bool, erro
res, err := v.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return false, err
return 0, err
}
result, err := strconv.ParseBool(string(res))
result, err := strconv.ParseUint(string(res), 10, 64)
if err != nil {
return false, err
return 0, err
}
return result, nil

View File

@@ -17,7 +17,7 @@ type NATRuleDelRequest struct {
// ID of the rule to delete.
// Pass -1 to clear all rules at once
// Required: true
RuleID uint64 `url:"ruleId" json:"ruleId" validate:"required"`
RuleID int64 `url:"ruleId" json:"ruleId" validate:"required"`
}
// NATRuleDel delete NAT (port forwarding) rule on VINS

View File

@@ -44,7 +44,7 @@ type CreateRequest struct {
// If true send emails when a user is granted access to resources
// Required: false
SendAccessEmails bool `url:"sendAccessEmails,omitempty" json:"sendAccessEmails,omitempty"`
SendAccessEmails bool `url:"sendAccessEmails" json:"sendAccessEmails"`
// Limit (positive) or disable (0) GPU resources
// Required: false

View File

@@ -123,6 +123,12 @@ type InfoAccount struct {
// Company URL
CompanyURL string `json:"companyurl"`
// CPU allocation parameter
CPUAllocationParameter string `json:"cpu_allocation_parameter"`
// CPU allocation ratio
CPUAllocationRatio float64 `json:"cpu_allocation_ratio"`
// Created by
CreatedBy string `json:"createdBy"`
@@ -154,7 +160,7 @@ type InfoAccount struct {
ResourceLimits ResourceLimits `json:"resourceLimits"`
// Resource types
ResourceTypes []string `json:"resourceTypes"`
ResTypes []string `json:"resourceTypes"`
// Send access emails
SendAccessEmails bool `json:"sendAccessEmails"`

View File

@@ -0,0 +1,45 @@
package account
import (
"context"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
"strconv"
)
// Request for setting CPU allocation parameter
type SetCPUAllocationParameterRequest struct {
// Account ID
// Required: true
AccountID uint64 `url:"accountId" json:"accoutnId" validate:"required"`
// CPU allocation parameter.
// If "strict" VM can't be run if not enough CPU resources.
// "loose" allow running VM if not enough resources.
// Required: true
StrictLoose string `url:"strict_loose" json:"strict_loose" validate:"required,strict_loose"`
}
// SetCPUAllocationParameter sets CPU allocation parameter
func (a Account) SetCPUAllocationParameter(ctx context.Context, req SetCPUAllocationParameterRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/account/setCpuAllocationParameter"
res, err := a.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
}

View File

@@ -0,0 +1,43 @@
package account
import (
"context"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
"strconv"
)
// Request for setting CPU allocation ratio
type SetCPUAllocationRatioRequest struct {
// Account ID
// Required: true
AccountID uint64 `url:"accountId" json:"accoutnId" validate:"required"`
// CPU allocation ratio, i.e. one pCPU = ratio*vCPU
// Required: true
Ratio float64 `url:"ratio" json:"ratio" validate:"required"`
}
// SetCPUAllocationRatio sets CPU allocation ratio
func (a Account) SetCPUAllocationRatio(ctx context.Context, req SetCPUAllocationRatioRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/account/setCpuAllocationRatio"
res, err := a.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
}

View File

@@ -15,8 +15,8 @@ type UpdateRequest struct {
AccountID uint64 `url:"accountId" json:"accountId" validate:"required"`
// Display name
// Required: true
Name string `url:"name" json:"name" validate:"required"`
// Required: false
Name string `url:"name" json:"name"`
// Name of the account
// Required: true
@@ -24,35 +24,35 @@ type UpdateRequest struct {
// Email
// Required: false
EmailAddress string `url:"emailaddress,omitempty" json:"emailaddress,omitempty" validate:"omitempty,email"`
EmailAddress string `url:"emailaddress,omitempty" json:"emailaddress,omitempty" validate:"omitempty,email"`
// Max size of memory in MB
// Required: false
MaxMemoryCapacity uint64 `url:"maxMemoryCapacity,omitempty" json:"maxMemoryCapacity,omitempty"`
MaxMemoryCapacity int64 `url:"maxMemoryCapacity,omitempty" json:"maxMemoryCapacity,omitempty"`
// Max size of aggregated vdisks in GB
// Required: false
MaxVDiskCapacity uint64 `url:"maxVDiskCapacity,omitempty" json:"maxVDiskCapacity,omitempty"`
MaxVDiskCapacity int64 `url:"maxVDiskCapacity,omitempty" json:"maxVDiskCapacity,omitempty"`
// Max number of CPU cores
// Required: false
MaxCPUCapacity uint64 `url:"maxCPUCapacity,omitempty" json:"maxCPUCapacity,omitempty"`
MaxCPUCapacity int64 `url:"maxCPUCapacity,omitempty" json:"maxCPUCapacity,omitempty"`
// Max sent/received network transfer peering
// Required: false
MaxNetworkPeerTransfer uint64 `url:"maxNetworkPeerTransfer,omitempty" json:"maxNetworkPeerTransfer,omitempty"`
MaxNetworkPeerTransfer int64 `url:"maxNetworkPeerTransfer,omitempty" json:"maxNetworkPeerTransfer,omitempty"`
// Max number of assigned public IPs
// Required: false
MaxNumPublicIP uint64 `url:"maxNumPublicIP,omitempty" json:"maxNumPublicIP,omitempty"`
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,omitempty" json:"sendAccessEmails,omitempty"`
SendAccessEmails bool `url:"sendAccessEmails" json:"sendAccessEmails"`
// Limit (positive) or disable (0) GPU resources
// Required: false
GPUUnits uint64 `url:"gpu_units,omitempty" json:"gpu_units,omitempty"`
GPUUnits int64 `url:"gpu_units,omitempty" json:"gpu_units,omitempty"`
// List of strings with pools
// i.e.: ["sep1_poolName1", "sep2_poolName2", etc]

View File

@@ -0,0 +1,8 @@
package cloudbroker
import "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/apiaccess"
// Accessing the APIAccess method group
func (cb *CloudBroker) APIAccess() *apiaccess.APIAccess {
return apiaccess.New(cb.client)
}

View File

@@ -0,0 +1,43 @@
package apiaccess
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for finding apiaccess groups.
type APIFindRequest struct {
// API function to find
// Example: cloudbroker/k8s/create
// Required: true
APIName string `url:"apiName" json:"apiName" validate:"required"`
}
// APIFind outputs a list of apiaccess groups that mention the specified API function.
func (a APIAccess) APIFind(ctx context.Context, req APIFindRequest) ([]uint64, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/apiaccess/apiFind"
list := make([]uint64, 0)
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
err = json.Unmarshal(res, &list)
if err != nil {
return nil, err
}
return list, nil
}

View File

@@ -0,0 +1,15 @@
package apiaccess
import "repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
// Structure for creating request to APIAccess
type APIAccess struct {
client interfaces.Caller
}
// Builder for APIAccess endpoints
func New(client interfaces.Caller) *APIAccess {
return &APIAccess{
client: client,
}
}

View File

@@ -0,0 +1,69 @@
package apiaccess
import (
"context"
"encoding/json"
"fmt"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for removing api from access group.
type APIsExcludeRequest struct {
// APIAccess group ID
// Required: true
APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"`
// APIs to remove from APIAccess group
// Required: true
APIs APIsEndpoints `url:"-" json:"-" validate:"required"`
}
type wrapperAPIsExcludeRequest struct {
APIsExcludeRequest
APIString string `url:"apis"`
}
// APIsExclude removes the listed API functions from the specified apiaccess group.
func (a APIAccess) APIsExclude(ctx context.Context, req APIsExcludeRequest) (*APIsEndpoints, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/apiaccess/apisExclude"
info := APIsEndpoints{}
apiJSON, err := json.Marshal(&req.APIs)
if err != nil {
return nil, err
}
apiJSONPretty, err := json.MarshalIndent(&req.APIs, "", " ")
if err != nil {
return nil, err
}
fmt.Println(string(apiJSONPretty))
reqWrapped := wrapperAPIsExcludeRequest{
APIsExcludeRequest: req,
APIString: string(apiJSON),
}
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
if err != nil {
return nil, err
}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

View File

@@ -0,0 +1,62 @@
package apiaccess
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for adding api to access group.
type APIsIncludeRequest struct {
// APIAccess group ID.
// Required: true
APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"`
// APIs to add to APIAccess group.
// Required: true
APIs APIsEndpoints `url:"-" json:"-" validate:"required"`
}
type wrapperAPIsIncludeRequest struct {
APIsIncludeRequest
APIString string `url:"apis"`
}
// APIsInclude adds the listed API functions to the specified apiaccess group.
func (a APIAccess) APIsInclude(ctx context.Context, req APIsIncludeRequest) (*APIsEndpoints, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/apiaccess/apisInclude"
info := APIsEndpoints{}
apiJSON, err := json.Marshal(&req.APIs)
if err != nil {
return nil, err
}
reqWrapped := wrapperAPIsIncludeRequest{
APIsIncludeRequest: req,
APIString: string(apiJSON),
}
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
if err != nil {
return nil, err
}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

View File

@@ -0,0 +1,44 @@
package apiaccess
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for copying apiaccess group.
type CopyRequest struct {
// ID of the API access group to make copy from
// Required: true
APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"`
// Name of the target API access group, which will be created on successful copy
// Required: true
Name string `url:"name" json:"name" validate:"required"`
}
// Copy creates a copy of the specified apiaccess group with a new name (and a new unique ID).
func (a APIAccess) Copy(ctx context.Context, req CopyRequest) (uint64, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return 0, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/apiaccess/copy"
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
}

View File

@@ -0,0 +1,44 @@
package apiaccess
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for creating apiaccess group.
type CreateRequest struct {
// Name of this apiaccess group.
// Required: true
Name string `url:"name" json:"name" validate:"required"`
// Description of this apiaccess group.
// Required: false
Description string `url:"desc,omitempty" json:"desc,omitempty"`
}
// Create creates apiaccess group.
func (a APIAccess) Create(ctx context.Context, req CreateRequest) (uint64, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return 0, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/apiaccess/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
}

View File

@@ -0,0 +1,44 @@
package apiaccess
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for deleting apiaccess group.
type DeleteRequest struct {
// APIAccess group ID.
// Required: true
APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"`
// Set True to delete apiaccess group with attached users.
// Required: false
Force bool `url:"force,omitempty" json:"force,omitempty"`
}
// Delete deletes apiaccess group
func (a APIAccess) Delete(ctx context.Context, req DeleteRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/apiaccess/delete"
res, err := a.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
}

View File

@@ -0,0 +1,44 @@
package apiaccess
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for updating apiaccess group description.
type DescUpdateRequest struct {
// APIAccess group ID.
// Required: true
APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"`
// New description to set for the apiaccess group.
// Required: true
Description string `url:"desc" json:"desc" validate:"required"`
}
// DescUpdate sets a new text description of the apiaccess group.
func (a APIAccess) DescUpdate(ctx context.Context, req DescUpdateRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/apiaccess/descUpdate"
res, err := a.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
}

View File

@@ -0,0 +1,42 @@
package apiaccess
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for getting apiaccess group.
type GetRequest struct {
// APIAccess group ID.
// Required: true
APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"`
}
// Get gets apiaccess group.
func (a APIAccess) Get(ctx context.Context, req GetRequest) (*ItemAPIAccess, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/apiaccess/get"
info := ItemAPIAccess{}
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

View File

@@ -0,0 +1,26 @@
package apiaccess
import (
"context"
"encoding/json"
"net/http"
)
// GetFull gets full current endpoints dictionary
func (a APIAccess) GetFull(ctx context.Context) (*APIsEndpoints, error) {
url := "/cloudbroker/apiaccess/getFull"
info := APIsEndpoints{}
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, nil)
if err != nil {
return nil, err
}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

View File

@@ -0,0 +1,26 @@
package apiaccess
import (
"context"
"encoding/json"
"net/http"
)
// GetPreGroups gets list of pre default groups from spec
func (a APIAccess) GetPreGroups(ctx context.Context) (map[string]APIsEndpoints, error) {
url := "/cloudbroker/apiaccess/getPreGroups"
info := make(map[string]APIsEndpoints)
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, nil)
if err != nil {
return nil, err
}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return info, nil
}

View File

@@ -0,0 +1,70 @@
package apiaccess
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for getting list of all non deleted apiaccess instances.
type ListRequest struct {
// Find by ID
// Required: false
ByID uint64 `url:"by_id,omitempty" json:"by_id,omitempty"`
// Find by name apiaccess
// Required: false
Name string `url:"name,omitempty" json:"name,omitempty"`
// Find by status apiaccess
// Required: false
Status string `url:"status,omitempty" json:"status,omitempty"`
// Find by created actor
// Required: false
CreatedBy string `url:"createdBy,omitempty" json:"createdBy,omitempty"`
// Find by created after time (unix timestamp)
// Required: false
CreatedAfter uint64 `url:"createdAfter,omitempty" json:"createdAfter,omitempty"`
// Find by created before time (unix timestamp)
// Required: false
CreatedBefore uint64 `url:"createdBefore,omitempty" json:"createdBefore,omitempty"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
// Page size, maximum - 100
// Required: false
Size uint64 `url:"size,omitempty" json:"size,omitempty"`
}
// List gets list of all non deleted apiaccess instances.
func (a APIAccess) List(ctx context.Context, req ListRequest) (*ListAPIAccess, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/apiaccess/list"
info := ListAPIAccess{}
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

View File

@@ -0,0 +1,46 @@
package apiaccess
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for getting list of all deleted apiaccess instances.
type ListDeletedRequest struct {
// Page number.
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
// Page size.
// Required: false
Size uint64 `url:"size,omitempty" json:"size,omitempty"`
}
// ListDeleted gets list of all deleted apiaccess instances.
func (a APIAccess) ListDeleted(ctx context.Context, req ListDeletedRequest) (*ListAPIAccess, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/apiaccess/listDeleted"
info := ListAPIAccess{}
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

View File

@@ -0,0 +1,182 @@
package apiaccess
type ItemAPIAccess struct {
// APIs
APIs APIsEndpoints `json:"apis"`
// Created by
CreatedBy string `json:"createdBy"`
// Created time
CreatedTime uint64 `json:"createdTime"`
// Is default
Default bool `json:"default"`
// Deleted by
DeletedBy string `json:"deletedBy"`
// Deleted time
DeletedTime uint64 `json:"deletedTime"`
// Description
Description string `json:"decs"`
// GID
GID uint64 `json:"gid"`
// GUID
GUID uint64 `json:"guid"`
// ID
ID uint64 `json:"id"`
// Milestones
Milestones uint64 `json:"milestones"`
// Name
Name string `json:"name"`
// Is protected
Protected bool `json:"protected"`
// Status
Status string `json:"status"`
//Updated by
UpdatedBy string `json:"updatedBy"`
// Updated time
UpdatedTime uint64 `json:"updatedTime"`
}
type ListAPIAccess struct {
Data []ItemAPIAccess `json:"data"`
EntryCount uint64 `json:"entryCount"`
}
type APIsEndpoints struct {
// CloudAPI endpoints
CloudAPI CloudAPIEndpoints `json:"cloudapi,omitempty"`
// CloudBroker endpoints
CloudBroker CloudBrokerEndpoints `json:"cloudbroker,omitempty"`
// LibCloud endpoints
LibCloud LibCloudEndpoints `json:"libcloud,omitempty"`
// System endpoints
System SystemEndpoints `json:"system,omitempty"`
}
type CloudAPIEndpoints struct {
Account []string `json:"account,omitempty"`
BService []string `json:"bservice,omitempty"`
CloudSpace []string `json:"cloudspace,omitempty"`
Compute []string `json:"compute,omitempty"`
ComputeCI []string `json:"computeci,omitempty"`
Disks []string `json:"disks,omitempty"`
ExtNet []string `json:"extnet,omitempty"`
FLIPGroup []string `json:"flipgroup,omitempty"`
GPU []string `json:"gpu,omitempty"`
Image []string `json:"image,omitempty"`
K8CI []string `json:"k8ci,omitempty"`
K8S []string `json:"k8s,omitempty"`
KVMPPC []string `json:"kvmppc,omitempty"`
KVMX86 []string `json:"kvmx86,omitempty"`
LB []string `json:"lb,omitempty"`
Loactions []string `json:"locations,omitempty"`
Machine []string `json:"machine,omitempty"`
Openshift []string `json:"openshift,omitempty"`
OpenshiftCI []string `json:"openshiftci,omitempty"`
PCIDevice []string `json:"pcidevice,omitempty"`
PortForwarding []string `json:"portforwarding,omitempty"`
Prometheus []string `json:"prometheus,omitempty"`
RG []string `json:"rg,omitempty"`
Sizes []string `json:"sizes,omitempty"`
Tasks []string `json:"tasks,omitempty"`
User []string `json:"user,omitempty"`
VGPU []string `json:"vgpu,omitempty"`
VINS []string `json:"vins,omitempty"`
All bool `json:"ALL,omitempty"`
}
type CloudBrokerEndpoints struct {
Account []string `json:"account,omitempty"`
APIAccess []string `json:"apiaccess,omitempty"`
Audit []string `json:"audit,omitempty"`
AuditBeat []string `json:"auditbeat,omitempty"`
AuditCollector []string `json:"auditcollector,omitempty"`
BackupCreator []string `json:"backupcreator,omitempty"`
BService []string `json:"bservice,omitempty"`
CloudSpace []string `json:"cloudspace,omitempty"`
Compute []string `json:"compute,omitempty"`
ComputeCI []string `json:"computeci,omitempty"`
Desnode []string `json:"desnode,omitempty"`
Diagnostics []string `json:"diagnostics,omitempty"`
Disks []string `json:"disks,omitempty"`
Eco []string `json:"eco,omitempty"`
ExtNet []string `json:"extnet,omitempty"`
FlIPgroup []string `json:"flipgroup,omitempty"`
Grid []string `json:"grid,omitempty"`
Group []string `json:"group,omitempty"`
Health []string `json:"health,omitempty"`
IaaS []string `json:"iaas,omitempty"`
Image []string `json:"image,omitempty"`
Job []string `json:"job,omitempty"`
K8CI []string `json:"k8ci,omitempty"`
K8S []string `json:"k8s,omitempty"`
KVMPPC []string `json:"kvmppc,omitempty"`
KVMX86 []string `json:"kvmx86,omitempty"`
LB []string `json:"lb,omitempty"`
Machine []string `json:"machine,omitempty"`
Metering []string `json:"metering,omitempty"`
Milestones []string `json:"milestones,omitempty"`
Node []string `json:"node,omitempty"`
Openshift []string `json:"openshift,omitempty"`
OpenshiftCI []string `json:"openshiftci,omitempty"`
Ovsnode []string `json:"ovsnode,omitempty"`
PCIDevice []string `json:"pcidevice,omitempty"`
PGPU []string `json:"pgpu,omitempty"`
Prometheus []string `json:"prometheus,omitempty"`
QOS []string `json:"qos,omitempty"`
Resmon []string `json:"resmon,omitempty"`
RG []string `json:"rg,omitempty"`
Sep []string `json:"sep,omitempty"`
Stack []string `json:"stack,omitempty"`
Tasks []string `json:"tasks,omitempty"`
TLock []string `json:"tlock,omitempty"`
User []string `json:"user,omitempty"`
VGPU []string `json:"vgpu,omitempty"`
VINS []string `json:"vins,omitempty"`
VNFDev []string `json:"vnfdev,omitempty"`
ZeroAccess []string `json:"zeroaccess,omitempty"`
All bool `json:"ALL,omitempty"`
}
type LibCloudEndpoints struct {
Libvirt []string `json:"libvirt,omitempty"`
All bool `json:"ALL,omitempty"`
}
type SystemEndpoints struct {
AgentController []string `json:"agentcontroller,omitempty"`
Alerts []string `json:"alerts,omitempty"`
Audits []string `json:"audits,omitempty"`
ContentManager []string `json:"contentmanager,omitempty"`
DocGenerator []string `json:"docgenerator,omitempty"`
EmailSender []string `json:"emailsender,omitempty"`
ErrorConditionHandler []string `json:"errorconditionhandler,omitempty"`
GridManager []string `json:"gridmanager,omitempty"`
Health []string `json:"health,omitempty"`
Info []string `json:"info,omitempty"`
InfoMGR []string `json:"infomgr,omitempty"`
Job []string `json:"job,omitempty"`
Log []string `json:"log,omitempty"`
Logo []string `json:"logo,omitempty"`
Oauth []string `json:"oauth,omitempty"`
Task []string `json:"task,omitempty"`
UserManager []string `json:"usermanager,omitempty"`
All bool `json:"ALL,omitempty"`
}

View File

@@ -0,0 +1,40 @@
package apiaccess
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Reqeust struct for setting default apiaccess group.
type SetDefaultRequest struct {
// APIAccess group ID
// Required: true
APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"`
}
// SetDefault sets current apiaccess group default.
func (a APIAccess) SetDefault(ctx context.Context, req SetDefaultRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/apiaccess/setDefault"
res, err := a.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
}

View File

@@ -0,0 +1,45 @@
package apiaccess
import (
"encoding/json"
"net/http"
"context"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for subtracting.
type SubtractRequest struct {
// ID of the API access group to subtract from. This group will contain the difference.
MinuendID uint64 `url:"minuendId" json:"minuendId" validate:"required"`
// ID of the API access group which is subtracted. This group is unchanged.
SubtrahendID uint64 `url:"subtrahendId" json:"subtrahendId" validate:"required"`
}
// Subtract removes such APIs from MinuendID that match APIs from SubtrahendID.
func (a APIAccess) Subtruct(ctx context.Context, req SubtractRequest) (*APIsEndpoints, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/apiaccess/subtract"
info := APIsEndpoints{}
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

View File

@@ -0,0 +1,47 @@
package apiaccess
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for union.
type UnionRequest struct {
// Recipient apiaccess group ID
// Required: true
RecipientID uint64 `url:"recipientId" json:"recipientId" validate:"required"`
// Donor apiaccess group ID
// Required: true
DonorID uint64 `url:"donorId" json:"donorId" validate:"required"`
}
// Combines the API list of group #1 ("recipient") and group #2 ("donor"),
// writing the result to group #1 and avoiding duplicates in the list
func (a APIAccess) Union(ctx context.Context, req UnionRequest) (*APIsEndpoints, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/apiaccess/union"
info := APIsEndpoints{}
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

View File

@@ -0,0 +1,62 @@
package apiaccess
import (
"context"
"encoding/json"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for updating apis of apiaccess group.
type UpdateRequest struct {
// APIAccess group ID
// Required: true
APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"`
// APIs to remove from APIAccess group
// Required: false
APIs APIsEndpoints `url:"-" json:"-"`
}
type wrapperUpdateRequest struct {
UpdateRequest
APIString string `url:"apis"`
}
// Update updates apis of apiaccess group.
func (a APIAccess) Update(ctx context.Context, req UpdateRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/apiaccess/update"
reqWrapped := wrapperUpdateRequest{
UpdateRequest: req,
}
apiJSON, err := json.Marshal(&req.APIs)
if err != nil {
return false, err
}
reqWrapped.APIString = string(apiJSON)
res, err := a.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
}

View File

@@ -0,0 +1,42 @@
package apiaccess
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for getting a list of users currently included in the specified group.
type UserListRequest struct {
// APIAccess group ID
// Required: true
APIAccessID uint64 `url:"apiaccessId" json:"apiaccessId" validate:"required"`
}
// UserList gets a list of users currently included in the specified group.
func (a APIAccess) UserList(ctx context.Context, req UserListRequest) ([]string, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/apiaccess/userList"
list := make([]string, 0)
res, err := a.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
err = json.Unmarshal(res, &list)
if err != nil {
return nil, err
}
return list, nil
}

View File

@@ -0,0 +1,8 @@
package cloudbroker
import "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/backup"
// Accessing the Backup method group
func (cb *CloudBroker) Backup() *backup.Backup {
return backup.New(cb.client)
}

View File

@@ -0,0 +1,17 @@
package backup
import (
"repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
)
// Structure for creating request to backup
type Backup struct {
client interfaces.Caller
}
// Builder for backup endpoints
func New(client interfaces.Caller) *Backup {
return &Backup{
client: client,
}
}

View File

@@ -0,0 +1,88 @@
package backup
import (
"context"
"encoding/json"
"net/http"
"strings"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for creating disk backup
type CreateDiskBackupRequest struct {
// Compute ID
// Required: true
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
// Disk ID
// Required: true
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
// Backup path
// Required: true
BackupPath string `url:"backupPath" json:"backupPath" validate:"required"`
}
type wrapperCreateDiskBackupRequest struct {
CreateDiskBackupRequest
Async bool `url:"async"`
}
// CreateDiskBackup creates disk backup
func (b Backup) CreateDiskBackup(ctx context.Context, req CreateDiskBackupRequest) (ListInfoBackup, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
reqWrapped := wrapperCreateDiskBackupRequest{
CreateDiskBackupRequest: req,
Async: false,
}
url := "/cloudbroker/backup/createDiskBackup"
res, err := b.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
if err != nil {
return nil, err
}
result := make(ListInfoBackup, 0)
err = json.Unmarshal(res, &result)
if err != nil {
return nil, err
}
return result, nil
}
// CreateDiskBackupAsync creates disk backup
func (b Backup) CreateDiskBackupAsync(ctx context.Context, req CreateDiskBackupRequest) (string, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return "", validators.ValidationError(validationError)
}
}
reqWrapped := wrapperCreateDiskBackupRequest{
CreateDiskBackupRequest: req,
Async: true,
}
url := "/cloudbroker/backup/createDiskBackup"
res, err := b.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
if err != nil {
return "", err
}
result := strings.ReplaceAll(string(res), "\"", "")
return result, nil
}

View File

@@ -0,0 +1,90 @@
package backup
import (
"context"
"encoding/json"
"net/http"
"strings"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
type Disk struct {
// Disk ID
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
// Backup path
BackupPath string `url:"backupPath" json:"backupPath" validate:"required"`
}
// Request struct for creating disks backup
type CreateDisksBackupRequest struct {
// Compute ID
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
// Disks
Disks []Disk `url:"disks" json:"disks" validate:"required,dive"`
}
type wrapperCreateDisksBackupRequest struct {
CreateDisksBackupRequest
Async bool `url:"async"`
}
// CreateDisksBackup creates disks backup
func (b Backup) CreateDisksBackup(ctx context.Context, req CreateDisksBackupRequest) (ListInfoBackup, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
reqWrapped := wrapperCreateDisksBackupRequest{
CreateDisksBackupRequest: req,
Async: false,
}
url := "/cloudbroker/backup/createDisksBackup"
res, err := b.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
if err != nil {
return nil, err
}
result := make(ListInfoBackup, 0)
err = json.Unmarshal(res, &result)
if err != nil {
return nil, err
}
return result, nil
}
// CreateDisksBackupAsync creates disks backup
func (b Backup) CreateDisksBackupAsync(ctx context.Context, req CreateDisksBackupRequest) (string, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return "", validators.ValidationError(validationError)
}
}
reqWrapped := wrapperCreateDisksBackupRequest{
CreateDisksBackupRequest: req,
Async: true,
}
url := "/cloudbroker/backup/createDisksBackup"
res, err := b.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
if err != nil {
return "", err
}
result := strings.ReplaceAll(string(res), "\"", "")
return result, nil
}

View File

@@ -0,0 +1,80 @@
package backup
import (
"context"
"net/http"
"strconv"
"strings"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for deleting disk backup
type DeleteDiskBackupRequest struct {
// Backup path
BackupPath string `url:"backupPath" json:"backupPath" validate:"required"`
// Backup file
BackupFile string `url:"backupFile" json:"backupFile" validate:"required"`
}
type wrapperDeleteDiskBackupRequest struct {
DeleteDiskBackupRequest
Async bool `url:"async"`
}
// DeleteDiskBackup deletes disk backup
func (b Backup) DeleteDiskBackup(ctx context.Context, req DeleteDiskBackupRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
}
}
reqWrapped := wrapperDeleteDiskBackupRequest{
DeleteDiskBackupRequest: req,
Async: false,
}
url := "/cloudbroker/backup/deleteDiskBackup"
res, err := b.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
}
// DeleteDiskBackupAsync deletes disk backup
func (b Backup) DeleteDiskBackupAsync(ctx context.Context, req DeleteDiskBackupRequest) (string, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return "", validators.ValidationError(validationError)
}
}
reqWrapped := wrapperDeleteDiskBackupRequest{
DeleteDiskBackupRequest: req,
Async: true,
}
url := "/cloudbroker/backup/deleteDiskBackup"
res, err := b.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
if err != nil {
return "", err
}
result := strings.ReplaceAll(string(res), "\"", "")
return result, nil
}

View File

@@ -0,0 +1,40 @@
package backup
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for getting list of backup paths
type ListBackupPathsRequest struct {
// Grid ID
GID uint64 `url:"gridId" json:"gridId" validate:"required"`
}
// ListBackupPaths gets list of backup paths
func (b Backup) ListBackupPaths(ctx context.Context, req ListBackupPathsRequest) ([]string, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/backup/listBackupPaths"
res, err := b.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
list := make([]string, 0)
err = json.Unmarshal(res, &list)
if err != nil {
return nil, err
}
return list, nil
}

View File

@@ -0,0 +1,31 @@
package backup
// Main info about backup
type InfoBackup struct {
// Compute ID
ComputeID uint64 `json:"computeId"`
// Disk ID
DiskID uint64 `json:"diskId"`
// Backup path
BackupPath string `json:"backupPath"`
// Possible error
Error string `json:"error"`
}
// CreateDisksBackup response
type ListInfoBackup []InfoBackup
// RestoreDiskFromFile response
type InfoRestoredDisk struct {
// Compute ID
ComputeID uint64 `json:"computeId"`
// Disk ID
DiskID uint64 `json:"diskId"`
}
// RestoreDisksFromFile response
type ListInfoRestoredDisk []InfoRestoredDisk

View File

@@ -0,0 +1,88 @@
package backup
import (
"context"
"encoding/json"
"net/http"
"strings"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for restoring disk from backup
type RestoreDiskFromBackupRequest struct {
// Compute ID
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
// Disk ID
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
// Backup path
BackupPath string `url:"backupPath" json:"backupPath" validate:"required"`
// Backup file
BackupFile string `url:"backupFile" json:"backupFile" validate:"required"`
}
type wrapperRestoreDiskFromBackupRequest struct {
RestoreDiskFromBackupRequest
Async bool `url:"async"`
}
// RestoreDiskFromBackup restores disk from backup
func (b Backup) RestoreDiskFromBackup(ctx context.Context, req RestoreDiskFromBackupRequest) (ListInfoRestoredDisk, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
reqWrapped := wrapperRestoreDiskFromBackupRequest{
RestoreDiskFromBackupRequest: req,
Async: false,
}
url := "/cloudbroker/backup/restoreDiskFromBackup"
res, err := b.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
if err != nil {
return nil, err
}
result := make(ListInfoRestoredDisk, 0)
err = json.Unmarshal(res, &result)
if err != nil {
return nil, err
}
return result, nil
}
// RestoreDiskFromBackupAsync restores disk from backup
func (b Backup) RestoreDiskFromBackupAsync(ctx context.Context, req RestoreDiskFromBackupRequest) (string, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return "", validators.ValidationError(validationError)
}
}
reqWrapped := wrapperRestoreDiskFromBackupRequest{
RestoreDiskFromBackupRequest: req,
Async: true,
}
url := "/cloudbroker/backup/restoreDiskFromBackup"
res, err := b.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
if err != nil {
return "", err
}
result := strings.ReplaceAll(string(res), "\"", "")
return result, nil
}

View File

@@ -0,0 +1,93 @@
package backup
import (
"context"
"encoding/json"
"net/http"
"strings"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
type BackupFile struct {
// Disk ID
DiskID uint64 `url:"diskId" json:"diskId" validate:"required"`
// Backup path
BackupPath string `url:"backupPath" json:"backupPath" validate:"required"`
// Backup file
BackupFile string `url:"backupFile" json:"backupFile" validate:"required"`
}
// Request struct for restoring disks from backup
type RestoreDisksFromBackupRequest struct {
// Compute ID
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
//Backup files
BackupFiles []BackupFile `url:"backupFiles" json:"backupFiles" validate:"required,dive"`
}
type wrapperRestoreDisksFromBackupRequest struct {
RestoreDisksFromBackupRequest
Async bool `url:"async"`
}
// RestoreDisksFromBackup restores disks from backup
func (b Backup) RestoreDisksFromBackup(ctx context.Context, req RestoreDisksFromBackupRequest) (ListInfoRestoredDisk, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
reqWrapped := wrapperRestoreDisksFromBackupRequest{
RestoreDisksFromBackupRequest: req,
Async: false,
}
url := "/cloudbroker/backup/restoreDisksFromBackup"
res, err := b.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
if err != nil {
return nil, err
}
result := make(ListInfoRestoredDisk, 0)
err = json.Unmarshal(res, &result)
if err != nil {
return nil, err
}
return result, nil
}
// RestoreDisksFromBackupAsync restores disks from backup
func (b Backup) RestoreDisksFromBackupAsync(ctx context.Context, req RestoreDisksFromBackupRequest) (string, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return "", validators.ValidationError(validationError)
}
}
reqWrapped := wrapperRestoreDisksFromBackupRequest{
RestoreDisksFromBackupRequest: req,
Async: true,
}
url := "/cloudbroker/backup/restoreDisksFromBackup"
res, err := b.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped)
if err != nil {
return "", err
}
result := strings.ReplaceAll(string(res), "\"", "")
return result, nil
}

View File

@@ -0,0 +1,47 @@
package compute
import (
"context"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
"strconv"
)
// Request struct for changing link state
type ChangeLinkStateRequest struct {
// Compute ID
// Required: true
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
// Interface name or MAC address
// Required: true
Interface string `url:"interface" json:"interface" validate:"required"`
// Interface state
// Must be either "on" or "off"
// Required: true
State string `url:"state" json:"state" validate:"required,interfaceState"`
}
// ChangeLinkState changes the status link virtual of compute
func (c Compute) ChangeLinkState(ctx context.Context, req ChangeLinkStateRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/compute/changeLinkState"
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
}

View File

@@ -22,12 +22,12 @@ type CreateTemplateRequest struct {
// Reason for action
// Required: false
Reason string `url:"reason,omitempty" json:"reason,omitempty"`
}
// Async API call
// For async call use CreateTemplateAsync
// For sync call use CreateTemplate
// Required: true
async bool `url:"async"`
type wrapperCreateTemplateRequest struct {
CreateTemplateRequest
Async bool `url:"async"`
}
// CreateTemplateAsync create template from compute instance
@@ -39,11 +39,14 @@ func (c Compute) CreateTemplateAsync(ctx context.Context, req CreateTemplateRequ
}
}
req.async = true
reqWrapped := wrapperCreateTemplateRequest{
CreateTemplateRequest: req,
Async: true,
}
url := "/cloudbroker/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
}
@@ -62,11 +65,14 @@ func (c Compute) CreateTemplate(ctx context.Context, req CreateTemplateRequest)
}
}
req.async = false
reqWrapped := wrapperCreateTemplateRequest{
CreateTemplateRequest: req,
Async: false,
}
url := "/cloudbroker/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 0, err
}

View File

@@ -12,27 +12,27 @@ import (
type DiskAddRequest struct {
// ID of compute instance
// Required: true
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
// Name for disk
// Required: true
DiskName string `url:"diskName" json:"diskName" validate:"required"`
DiskName string `url:"diskName" json:"diskName" validate:"required"`
// Disk size in GB
// Required: true
Size uint64 `url:"size" json:"size" validate:"required"`
Size uint64 `url:"size" json:"size" validate:"required"`
// Storage endpoint provider ID
// By default the same with boot disk
// Required: false
SepID uint64 `url:"sepId,omitempty" json:"sepId,omitempty"`
// 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
// Required: false
SepID uint64 `url:"sepId,omitempty" json:"sepId,omitempty"`
DiskType string `url:"diskType,omitempty" json:"diskType,omitempty" validate:"omitempty,computeDiskType"`
// Pool name
// By default will be chosen automatically

View File

@@ -147,7 +147,7 @@ type RecordNetAttach struct {
NetType string `json:"netType"`
// PCI slot
PCISlot uint64 `json:"pciSlot"`
PCISlot int64 `json:"pciSlot"`
// QOS
QOS QOS `json:"qos"`
@@ -396,7 +396,7 @@ type ItemDisk struct {
Password string `json:"passwd"`
// PCI slot
PCISlot uint64 `json:"pciSlot"`
PCISlot int64 `json:"pciSlot"`
// Pool
Pool string `json:"pool"`
@@ -498,7 +498,7 @@ type ItemInterface struct {
NetType string `json:"netType"`
// PCI slot
PCISlot uint64 `json:"pciSlot"`
PCISlot int64 `json:"pciSlot"`
// QOS
QOS QOS `json:"qos"`
@@ -738,7 +738,7 @@ type InfoDisk struct {
ID uint64 `json:"id"`
// PCISlot
PCISlot uint64 `json:"pciSlot"`
PCISlot int64 `json:"pciSlot"`
}
// List computes

View File

@@ -19,8 +19,9 @@ type PFWAddRequest struct {
PublicPortStart uint64 `url:"publicPortStart" json:"publicPortStart" validate:"required"`
// End port number (inclusive) for the ranged rule
// Default value: -1
// Required: false
PublicPortEnd uint64 `url:"publicPortEnd,omitempty" json:"publicPortEnd,omitempty"`
PublicPortEnd int64 `url:"publicPortEnd,omitempty" json:"publicPortEnd,omitempty"`
// Internal base port number
// Required: true

View File

@@ -0,0 +1,45 @@
package grid
import (
"context"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
"strconv"
)
// Request for setting CPU allocation parameter
type SetCPUAllocationParameterRequest struct {
// Grid ID
// Required: true
GridID uint64 `url:"gridId" json:"gridId" validate:"required"`
// CPU allocation parameter.
// If "strict" VM can't be run if not enough CPU resources.
// "loose" allow running VM if not enough resources.
// Required: true
StrictLoose string `url:"strict_loose" json:"strict_loose" validate:"required,strict_loose"`
}
// SetCPUAllocationParameter sets CPU allocation parameter
func (g Grid) SetCPUAllocationParameter(ctx context.Context, req SetCPUAllocationParameterRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/grid/setCpuAllocationParameter"
res, err := g.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
}

View File

@@ -0,0 +1,43 @@
package grid
import (
"context"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
"strconv"
)
// Request for setting CPU allocation ratio for computes
type SetCPUAllocationRatioForVMRequest struct {
// Grid ID
// Required: true
GridID uint64 `url:"gridId" json:"gridId" validate:"required"`
// Default CPU allocation ratio for computes
// Required: true
Ratio float64 `url:"ratio" json:"ratio" validate:"required"`
}
// SetCPUAllocationRatio sets CPU allocation ratio for computes
func (g Grid) SetCPUAllocationRatioForVM(ctx context.Context, req SetCPUAllocationRatioForVMRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/grid/setCpuAllocationRatioForVM"
res, err := g.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
}

8
pkg/cloudbroker/group.go Normal file
View File

@@ -0,0 +1,8 @@
package cloudbroker
import "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/group"
// Accessing the Group method group
func (cb *CloudBroker) Group() *group.Group {
return group.New(cb.client)
}

View File

@@ -0,0 +1,42 @@
package group
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Reuqest struct for getting details of the specified group.
type GetRequest struct {
// Group ID
// Required: true
GroupID string `url:"groupId" json:"groupId" validate:"required"`
}
// Get gets details of the specified group.
func (g Group) Get(ctx context.Context, req GetRequest) (*ItemGroup, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/group/get"
res, err := g.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
info := ItemGroup{}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

View File

@@ -0,0 +1,15 @@
package group
import "repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
// Structure for creating request to group
type Group struct {
client interfaces.Caller
}
// Builder for group endpoints
func New(client interfaces.Caller) *Group {
return &Group{
client: client,
}
}

View File

@@ -0,0 +1,57 @@
package group
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for getting list of group instances.
type ListRequest struct {
// Find by id.
// Requires: false
ByID uint64 `url:"by_id,omitempty" json:"by_id,omitempty"`
// Find by list users.
// Required: false
User string `url:"user,omitempty" json:"user,omitempty"`
// Page number.
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
// Page size, maximum - 100.
// Required: false
Size uint64 `url:"size,omitempty" json:"size,omitempty"`
// Find by active True or False.
// Required: true
Active bool `url:"active" json:"active" validate:"required"`
}
func (g Group) List(ctx context.Context, req ListRequest) (*ListGroups, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/group/list"
res, err := g.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
info := ListGroups{}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

View File

@@ -0,0 +1,42 @@
package group
type ItemGroup struct {
// CKey
CKey string `json:"_ckey"`
// Meta
Meta []interface{} `json:"meta"`
// Is active
Actice bool `json:"active"`
// Description
Description string `json:"description"`
// Domain
Domain string `json:"domain"`
// GID
GID uint64 `json:"gid"`
// GUID
GUID string `json:"guid"`
// ID
ID string
// Last check
LastCheck uint64 `json:"lastcheck"`
// Roles
Roles []interface{} `json:"roles"`
// Users
Users []string `json:"users"`
}
type ListGroups struct {
Data []ItemGroup `json:"data"`
EntryCount uint64 `json:"entryCount"`
}

View File

@@ -34,6 +34,11 @@ type CreateRequest struct {
// Required: true
MasterDriver string `url:"masterDriver" json:"masterDriver" validate:"driver"`
// Network plugins
// Values of slice must be flannel, weawenet or calico
//Required: true
NetworkPlugins []string `url:"networkPlugins" json:"networkPlugins" validate:"required,networkPlugins"`
// Image ID for worker K8S node
// Required: true
WorkerImageID uint64 `url:"workerImageId" json:"workerImageId" validate:"required"`

View File

@@ -26,6 +26,11 @@ type CreateRequest struct {
// Required: true
WorkerGroupName string `url:"workerGroupName" json:"workerGroupName" validate:"required"`
// Network plugin
// Must be one of these values: flunnel, weawenet, calico
// Required: true
NetworkPlugin string `url:"networkPlugin" json:"networkPlugin" validate:"required,networkPlugin"`
// ID of SEP to create boot disks for master nodes.
// Uses images SEP ID if not set
// Required: false

View File

@@ -101,6 +101,9 @@ type RecordK8S struct {
// Name
Name string `json:"name"`
// Network plugin
NetworkPlugin string `json:"networkPlugin"`
// Resource group ID
RGID uint64 `json:"rgId"`
@@ -245,6 +248,9 @@ type ItemK8S struct {
// Name
Name string `json:"name"`
// Network plugin
NetworkPlugin string `json:"networkPlugin"`
// Resource group ID
RGID uint64 `json:"rgId"`

View File

@@ -0,0 +1,8 @@
package cloudbroker
import "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/pcidevice"
// Accessing the PCI Device method group
func (cb *CloudBroker) PCIDevice() *pcidevice.PCIDevice {
return pcidevice.New(cb.client)
}

View File

@@ -0,0 +1,56 @@
package pcidevice
import (
"context"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
"strconv"
)
// Request struct for creating PCI device
type CreateRequest struct {
// StackID
// Required: true
StackID uint64 `url:"stackId" json:"stackId" validate:"required"`
// Resource group ID
// Required: true
RGID uint64 `url:"rgId" json:"rgId" validate:"required"`
// Name of device
// Required: true
Name string `url:"name" json:"name" validate:"required"`
// PCI address of the device
// Must be in format 0000:1f:2b.0
// Required: true
HWPath string `url:"hwPath" json:"hwPath" validate:"required,hwPath"`
// Description, just for information
// Required: false
Description string `url:"description,omitempty" json:"description,omitempty"`
}
// Create creates PCI Device
func (p PCIDevice) Create(ctx context.Context, req CreateRequest) (uint64, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return 0, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/pcidevice/create"
res, err := p.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
}

View File

@@ -0,0 +1,43 @@
package pcidevice
import (
"context"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
"strconv"
)
// Request struct for deleting PCI device
type DeleteRequest struct {
// PCI device ID
// Required: true
DeviceID uint64 `url:"deviceId" json:"deviceId" validate:"required"`
// Force delete
// Required: false
Force bool `url:"force,omitempty" json:"force,omitempty"`
}
// Delete PCI device
func (p PCIDevice) Delete(ctx context.Context, req DeleteRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/pcidevice/delete"
res, err := p.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
}

Some files were not shown because too many files have changed in this diff Show More