Compare commits

...

7 Commits

Author SHA1 Message Date
afcbc7e749 1.6.0-beta 2023-09-14 15:05:38 +03:00
0b3de4df7f 1.6.0-alfa 2023-09-11 13:11:33 +03:00
c0608d08b9 1.5.8-gostech 2023-09-07 18:11:25 +03:00
4d9b8fc9d8 v1.5.7 2023-09-04 18:48:22 +03:00
e8270453cc 1.5.6 2023-08-30 13:54:30 +03:00
7de095302b v1.5.5 2023-08-25 13:53:43 +03:00
a3711057ba v1.5.4 2023-08-22 15:28:39 +03:00
32 changed files with 1054 additions and 66 deletions

View File

@@ -1,10 +1,4 @@
## Version 1.5.3 ## Version 1.6.0-beta
### Bugfix ### Bugfix
- Add a fields SEPID and Pool in ListUnattachedRequest struct in cloudbroker/disks/listUnattached and cloudapi/disks/listUnattached - Fixed RoudTrip bug in HTTP transport, made it concurrent safe
- Delete a field Shared in ListUnattachedRequest struct in cloudbroker/disks/listUnattached
- Delete tag Required at field Permanently in DiskDelRequest struct in cloudbroker/compute/disk_del and cloudapi/compute/disk_del
- Delete tag omitempty at field Permanently in DeleteRequest struct in cloudbroker/image/delete

View File

@@ -3,6 +3,7 @@ package client
import ( import (
"crypto/tls" "crypto/tls"
"net/http" "net/http"
"sync"
"time" "time"
"repository.basistech.ru/BASIS/decort-golang-sdk/config" "repository.basistech.ru/BASIS/decort-golang-sdk/config"
@@ -32,6 +33,7 @@ func NewHttpClient(cfg config.Config) *http.Client {
ssoURL: cfg.SSOURL, ssoURL: cfg.SSOURL,
token: cfg.Token, token: cfg.Token,
expiryTime: expiredTime, expiryTime: expiredTime,
mutex: &sync.Mutex{},
//TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, //TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}, },

View File

@@ -4,6 +4,7 @@ import (
"crypto/tls" "crypto/tls"
"net/http" "net/http"
"net/url" "net/url"
"sync"
"time" "time"
"repository.basistech.ru/BASIS/decort-golang-sdk/config" "repository.basistech.ru/BASIS/decort-golang-sdk/config"
@@ -33,6 +34,7 @@ func NewLegacyHttpClient(cfg config.LegacyConfig) *http.Client {
token: cfg.Token, token: cfg.Token,
decortURL: cfg.DecortURL, decortURL: cfg.DecortURL,
expiryTime: expiredTime, expiryTime: expiredTime,
mutex: &sync.Mutex{},
}, },
Timeout: cfg.Timeout.Get(), Timeout: cfg.Timeout.Get(),

View File

@@ -5,6 +5,7 @@ import (
"io" "io"
"net/http" "net/http"
"strings" "strings"
"sync"
"time" "time"
) )
@@ -15,6 +16,7 @@ type transportLegacy struct {
retries uint64 retries uint64
token string token string
decortURL string decortURL string
mutex *sync.Mutex
expiryTime time.Time expiryTime time.Time
} }
@@ -56,7 +58,9 @@ func (t *transportLegacy) RoundTrip(request *http.Request) (*http.Response, erro
var resp *http.Response var resp *http.Response
var err error var err error
for i := uint64(0); i < t.retries; i++ { for i := uint64(0); i < t.retries; i++ {
t.mutex.Lock()
resp, err = t.base.RoundTrip(req) resp, err = t.base.RoundTrip(req)
t.mutex.Unlock()
if err == nil { if err == nil {
if resp.StatusCode == 200 { if resp.StatusCode == 200 {
return resp, nil return resp, nil

View File

@@ -5,6 +5,7 @@ import (
"io" "io"
"net/http" "net/http"
"strings" "strings"
"sync"
"time" "time"
) )
@@ -16,6 +17,7 @@ type transport struct {
token string token string
ssoURL string ssoURL string
expiryTime time.Time expiryTime time.Time
mutex *sync.Mutex
} }
func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) { func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
@@ -53,7 +55,9 @@ func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
var resp *http.Response var resp *http.Response
var err error var err error
for i := uint64(0); i < t.retries; i++ { for i := uint64(0); i < t.retries; i++ {
t.mutex.Lock()
resp, err = t.base.RoundTrip(req) resp, err = t.base.RoundTrip(req)
t.mutex.Unlock()
if err == nil { if err == nil {
if resp.StatusCode == 200 { if resp.StatusCode == 200 {
return resp, nil return resp, nil
@@ -65,5 +69,6 @@ func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
//logrus.Errorf("Could not execute request: %v. Retrying %d/%d", err, i+1, t.retries) //logrus.Errorf("Could not execute request: %v. Retrying %d/%d", err, i+1, t.retries)
time.Sleep(time.Second * 5) time.Sleep(time.Second * 5)
} }
return nil, fmt.Errorf("could not execute request: %w", err) return nil, fmt.Errorf("could not execute request: %w", err)
} }

View File

@@ -106,6 +106,10 @@ type CreateRequest struct {
// Text description of this Kubernetes cluster // Text description of this Kubernetes cluster
// Required: false // Required: false
Description string `url:"desc,omitempty" json:"desc,omitempty"` Description string `url:"desc,omitempty" json:"desc,omitempty"`
//Use only selected ExtNet for infrastructure connections
// Required: false
ExtNetOnly bool `url:"extnetOnly,omitempty" json:"extnetOnly,omitempty"`
} }
// Create creates a new Kubernetes cluster in the specified Resource Group // Create creates a new Kubernetes cluster in the specified Resource Group

View File

@@ -2,6 +2,7 @@ package lb
import ( import (
"context" "context"
"errors"
"net/http" "net/http"
"strings" "strings"
@@ -20,16 +21,16 @@ type CreateRequest struct {
Name string `url:"name" json:"name" validate:"required"` Name string `url:"name" json:"name" validate:"required"`
// External network to connect this load balancer to // External network to connect this load balancer to
// Required: true // Required: false
ExtNetID uint64 `url:"extnetId" json:"extnetId" validate:"required"` ExtNetID uint64 `url:"extnetId" json:"extnetId"`
// Internal network (VINS) to connect this load balancer to // Internal network (VINS) to connect this load balancer to
// Required: true // Required: false
VINSID uint64 `url:"vinsId" json:"vinsId" validate:"required"` VINSID uint64 `url:"vinsId" json:"vinsId"`
// Start now Load balancer // Start now Load balancer
// Required: true // Required: false
Start bool `url:"start" json:"start" validate:"required"` Start bool `url:"start" json:"start"`
// Text description of this load balancer // Text description of this load balancer
// Required: false // Required: false
@@ -45,6 +46,10 @@ func (l LB) Create(ctx context.Context, req CreateRequest) (string, error) {
} }
} }
if req.ExtNetID == 0 && req.VINSID == 0 {
return "", errors.New ("vinsId and extNetId cannot be both in the value 0")
}
url := "/cloudapi/lb/create" url := "/cloudapi/lb/create"
res, err := l.client.DecortApiCall(ctx, http.MethodPost, url, req) res, err := l.client.DecortApiCall(ctx, http.MethodPost, url, req)

View File

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

View File

@@ -0,0 +1,44 @@
package flipgroup
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for add compute instance
type ComputeAddRequest struct {
// ID of the Floating IP group to add compute instance to
// Required: true
FLIPGroupID uint64 `url:"flipgroupId" json:"flipgroupId" validate:"required"`
// ID of the compute instance to add to this group
// Required: true
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
}
// ComputeAdd add compute instance to the Floating IP group
func (f FLIPGroup) ComputeAdd(ctx context.Context, req ComputeAddRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/flipgroup/computeAdd"
res, err := f.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 flipgroup
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for remove compute instance
type ComputeRemoveRequest struct {
// ID of the Floating IP group to remove compute instance from
// Required: true
FLIPGroupID uint64 `url:"flipgroupId" json:"flipgroupId" validate:"required"`
// ID of the compute instance to remove
// Required: true
ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"`
}
// ComputeRemove remove compute instance from the Floating IP group
func (f FLIPGroup) ComputeRemove(ctx context.Context, req ComputeRemoveRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/flipgroup/computeRemove"
res, err := f.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,71 @@
package flipgroup
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for create FLIPGroup
type CreateRequest struct {
// Account ID
// Required: true
AccountID uint64 `url:"accountId" json:"accountId" validate:"required"`
// FLIPGroup name
// Required: true
Name string `url:"name" json:"name" validate:"required"`
// Network type
// Should be one of:
// - EXTNET
// - VINS
// Required: true
NetType string `url:"netType" json:"netType" validate:"computeNetType"`
// ID of external network or VINS
// Required: true
NetID uint64 `url:"netId" json:"netId" validate:"required"`
// Type of client
// - 'compute'
// - 'vins' (will be later)
// Required: true
ClientType string `url:"clientType" json:"clientType" validate:"flipgroupClientType"`
// IP address to associate with this group. If empty, the platform will autoselect IP address
// Required: false
IP string `url:"ip,omitempty" json:"ip,omitempty"`
// Text description of this FLIPGorup instance
// Required: false
Description string `url:"desc,omitempty" json:"desc,omitempty"`
}
// Create method will create a new FLIPGorup in the specified Account
func (f FLIPGroup) Create(ctx context.Context, req CreateRequest) (*RecordFLIPGroupCreated, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/flipgroup/create"
res, err := f.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
info := RecordFLIPGroupCreated{}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

View File

@@ -0,0 +1,40 @@
package flipgroup
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for delete FLIPGroup
type DeleteRequest struct {
// FLIPGroup ID
// Required: true
FLIPGroupID uint64 `url:"flipgroupId" json:"flipgroupId" validate:"required"`
}
// Delete method wil delete Floating IP group
func (f FLIPGroup) 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/flipgroup/delete"
res, err := f.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,48 @@
package flipgroup
import (
"context"
"net/http"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for edit FLIPGroup
type EditRequest struct {
// FLIPGroup ID
// Required: true
FLIPGroupID uint64 `url:"flipgroupId" json:"flipgroupId" validate:"required"`
// FLIPGroup name
// Required: false
Name string `url:"name,omitempty" json:"name,omitempty"`
// FLIPGroup description
// Required: false
Description string `url:"desc,omitempty" json:"desc,omitempty"`
}
// Edit edits FLIPGroup fields
func (f FLIPGroup) Edit(ctx context.Context, req EditRequest) (bool, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return false, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/flipgroup/edit"
res, err := f.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,18 @@
// API to manage FLIPGroup instances
package flipgroup
import (
"repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
)
// Structure for creating request to FLIPGroup
type FLIPGroup struct {
client interfaces.Caller
}
// Builder for FLIPGroup endpoints
func New(client interfaces.Caller) *FLIPGroup {
return &FLIPGroup{
client: client,
}
}

View File

@@ -0,0 +1,42 @@
package flipgroup
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for get information about FLIPGroup
type GetRequest struct {
// FLIPGroup ID
// Required: true
FLIPGroupID uint64 `url:"flipgroupId" json:"flipgroupId" validate:"required"`
}
// Get gets details of the specified Floating IP group
func (f FLIPGroup) Get(ctx context.Context, req GetRequest) (*RecordFLIPGroup, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/flipgroup/get"
res, err := f.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
info := RecordFLIPGroup{}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

View File

@@ -0,0 +1,65 @@
package flipgroup
import (
"context"
"encoding/json"
"net/http"
)
// Request struct for get list FLIPGroup available to the current user
type ListRequest struct {
// Find by name
// Required: false
Name string `url:"name,omitempty" json:"name,omitempty"`
// Find by vinsId
// Required: false
VINSID uint64 `url:"vinsId,omitempty" json:"vinsId,omitempty"`
// Find by VINS name
// Required: false
VINSName string `url:"vinsName,omitempty" json:"vinsName,omitempty"`
// Find by extnetId
// Required: false
ExtNetID uint64 `url:"extnetId,omitempty" json:"extnetId,omitempty"`
// Find by IP
// Reuqired: false
ByIP string `url:"byIp,omitempty" json:"byIp,omitempty"`
// Find by resource group ID
// Reuqired: false
RGID uint64 `url:"rgId,omitempty" json:"rgId,omitempty"`
// Find by id
// Required: false
ByID uint64 `url:"by_id,omitempty" json:"by_id,omitempty"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
// Page size
// Required: false
Size uint64 `url:"size,omitempty" json:"size,omitempty"`
}
// List gets list FLIPGroup managed cluster instances available to the current user
func (f FLIPGroup) List(ctx context.Context, req ListRequest) (*ListFLIPGroups, error) {
url := "/cloudbroker/flipgroup/list"
res, err := f.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
list := ListFLIPGroups{}
err = json.Unmarshal(res, &list)
if err != nil {
return nil, err
}
return &list, nil
}

View File

@@ -0,0 +1,169 @@
package flipgroup
// Main information about FLIPGroup
type RecordFLIPGroupCreated struct {
// Default GW
DefaultGW string `json:"defaultGW"`
// ID
ID uint64 `json:"id"`
// IP
IP string `json:"ip"`
// Name
Name string `json:"name"`
// Network mask
NetMask uint64 `json:"netmask"`
}
type RecordFLIPGroup struct {
// Account ID
AccountID uint64 `json:"accountId"`
// Account name
AccountName string `json:"accountName"`
// List of client IDs
ClientIDs []uint64 `json:"clientIds"`
// Client names
ClientNames []string `json:"clientNames"`
// Client type
ClientType string `json:"clientType"`
// Connection ID
ConnID uint64 `json:"connId"`
// Connection type
ConnType string `json:"connType"`
// Created by
CreatedBy string `json:"createdBy"`
// Created time
CreatedTime uint64 `json:"createdTime"`
// Default GW
DefaultGW string `json:"defaultGW"`
// Deleted by
DeletedBy string `json:"deletedBy"`
// Deleted time
DeletedTime uint64 `json:"deletedTime"`
// Description
Description string `json:"desc"`
// Grid ID
GID uint64 `json:"gid"`
// GUID
GUID uint64 `json:"guid"`
// ID
ID uint64 `json:"id"`
// IP
IP string `json:"ip"`
// Milestones
Milestones uint64 `json:"milestones"`
// Name
Name string `json:"name"`
// Network ID
NetID uint64 `json:"netId"`
// Network type
NetType string `json:"netType"`
// Network
Network string `json:"network"`
// Resource group ID
RGID uint64 `json:"rgId"`
// Resource group name
RGName string `json:"rgName"`
// Status
Status string `json:"status"`
// Updated by
UpdatedBy string `json:"updatedBy"`
// Updated time
UpdatedTime uint64 `json:"updatedTime"`
}
// Detailed information about FLIPGroup
type ItemFLIPGroup struct {
// CKey
CKey string `json:"_ckey"`
// Meta
Meta []interface{} `json:"_meta"`
// Account ID
AccountID uint64 `json:"accountId"`
// List of client IDs
ClientIDs []uint64 `json:"clientIds"`
// Client type
ClientType string `json:"clientType"`
// Connection ID
ConnID uint64 `json:"connId"`
// Connection type
ConnType string `json:"connType"`
// Default GW
DefaultGW string `json:"defaultGW"`
// Description
Description string `json:"desc"`
// Grid ID
GID uint64 `json:"gid"`
// GUID
GUID uint64 `json:"guid"`
// ID
ID uint64 `json:"id"`
// IP
IP string `json:"ip"`
// Milestones
Milestones uint64 `json:"milestones"`
// Name
Name string `json:"name"`
// Network ID
NetID uint64 `json:"netId"`
// Network type
NetType string `json:"netType"`
// NetMask
NetMask uint64 `json:"netmask"`
// Status
Status string `json:"status"`
}
// List of FLIPGroup
type ListFLIPGroups struct {
Data []ItemFLIPGroup `json:"data"`
EntryCount uint64 `json:"entryCount"`
}

View File

@@ -0,0 +1,43 @@
package flipgroup
import (
"encoding/json"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/serialization"
)
// 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 (lfg ListFLIPGroups) Serialize(params ...string) (serialization.Serialized, error) {
if len(lfg.Data) == 0 {
return []byte{}, nil
}
if len(params) > 1 {
prefix := params[0]
indent := params[1]
return json.MarshalIndent(lfg, prefix, indent)
}
return json.Marshal(lfg)
}
// 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 (ifg ItemFLIPGroup) Serialize(params ...string) (serialization.Serialized, error) {
if len(params) > 1 {
prefix := params[0]
indent := params[1]
return json.MarshalIndent(ifg, prefix, indent)
}
return json.Marshal(ifg)
}

View File

@@ -2,7 +2,7 @@ package grid
// FilterByID returns ListGrids with specified ID. // FilterByID returns ListGrids with specified ID.
func (lg ListGrids) FilterByID(id uint64) ListGrids { func (lg ListGrids) FilterByID(id uint64) ListGrids {
predicate := func(rg RecordGrid) bool { predicate := func(rg ItemGridList) bool {
return rg.ID == id return rg.ID == id
} }
@@ -11,7 +11,7 @@ func (lg ListGrids) FilterByID(id uint64) ListGrids {
// FilterByName returns ListGrids with specified Name. // FilterByName returns ListGrids with specified Name.
func (lg ListGrids) FilterByName(name string) ListGrids { func (lg ListGrids) FilterByName(name string) ListGrids {
predicate := func(rg RecordGrid) bool { predicate := func(rg ItemGridList) bool {
return rg.Name == name return rg.Name == name
} }
@@ -20,7 +20,7 @@ func (lg ListGrids) FilterByName(name string) ListGrids {
// FilterByLocationCode returns ListGrids with specified LocationCode. // FilterByLocationCode returns ListGrids with specified LocationCode.
func (lg ListGrids) FilterByLocationCode(locationCode string) ListGrids { func (lg ListGrids) FilterByLocationCode(locationCode string) ListGrids {
predicate := func(rg RecordGrid) bool { predicate := func(rg ItemGridList) bool {
return rg.LocationCode == locationCode return rg.LocationCode == locationCode
} }
@@ -28,7 +28,7 @@ func (lg ListGrids) FilterByLocationCode(locationCode string) ListGrids {
} }
// FilterFunc allows filtering ListGrids based on a user-specified predicate. // FilterFunc allows filtering ListGrids based on a user-specified predicate.
func (lg ListGrids) FilterFunc(predicate func(RecordGrid) bool) ListGrids { func (lg ListGrids) FilterFunc(predicate func(ItemGridList) bool) ListGrids {
var result ListGrids var result ListGrids
for _, item := range lg.Data { for _, item := range lg.Data {
@@ -44,9 +44,9 @@ func (lg ListGrids) FilterFunc(predicate func(RecordGrid) bool) ListGrids {
// FindOne returns first found RecordGrid. // FindOne returns first found RecordGrid.
// If none was found, returns an empty struct. // If none was found, returns an empty struct.
func (lg ListGrids) FindOne() RecordGrid { func (lg ListGrids) FindOne() ItemGridList {
if len(lg.Data) == 0 { if len(lg.Data) == 0 {
return RecordGrid{} return ItemGridList{}
} }
return lg.Data[0] return lg.Data[0]

View File

@@ -3,7 +3,7 @@ package grid
import "testing" import "testing"
var grids = ListGrids{ var grids = ListGrids{
Data: []RecordGrid{ Data: []ItemGridList{
{ {
Resources: Resources{ Resources: Resources{
Current: RecordResource{ Current: RecordResource{
@@ -123,7 +123,7 @@ func TestFilterByLocationCode(t *testing.T) {
} }
func TestFilterFunc(t *testing.T) { func TestFilterFunc(t *testing.T) {
actual := grids.FilterFunc(func(rg RecordGrid) bool { actual := grids.FilterFunc(func(rg ItemGridList) bool {
return rg.GID == 777 return rg.GID == 777
}). }).
FindOne() FindOne()

View File

@@ -18,7 +18,7 @@ type RecordResourcesConsumption struct {
Reserved RecordResource `json:"Reserved"` Reserved RecordResource `json:"Reserved"`
// GID // GID
GID uint64 `json:"gid"` GID uint64 `json:"id"`
} }
type ListResourceConsumption struct { type ListResourceConsumption struct {
@@ -67,6 +67,27 @@ type DiskUsage struct {
// Detailed information about grid // Detailed information about grid
type RecordGrid struct { type RecordGrid struct {
// Flag
Flag string `json:"flag"`
// Grid ID
GID uint64 `json:"gid"`
// GUID
GUID uint64 `json:"guid"`
// ID
ID uint64 `json:"id"`
// Location code
LocationCode string `json:"locationCode"`
// Name
Name string `json:"name"`
}
// Information about grid
type ItemGridList struct {
// Resource information // Resource information
Resources Resources `json:"Resources"` Resources Resources `json:"Resources"`
@@ -92,7 +113,7 @@ type RecordGrid struct {
// List Grids // List Grids
type ListGrids struct { type ListGrids struct {
//Data //Data
Data []RecordGrid `json:"data"` Data []ItemGridList `json:"data"`
// Entry count // Entry count
EntryCount uint64 `json:"entryCount"` EntryCount uint64 `json:"entryCount"`

View File

@@ -162,7 +162,7 @@ type ListACL []ACL
// History information // History information
type History struct { type History struct {
// GUID // GUID
GUID uint64 `json:"guid"` GUID GUID `json:"guid"`
// ID // ID
ID uint64 `json:"id"` ID uint64 `json:"id"`
@@ -171,6 +171,20 @@ type History struct {
Timestamp uint64 `json:"timestamp"` Timestamp uint64 `json:"timestamp"`
} }
type GUID string
func (r *GUID) UnmarshalJSON(b []byte) error {
if b[0] == '"' {
*r = GUID(string(b[1:len(b)-1]))
return nil
}
*r = GUID(string(b))
return nil
}
// List history // List history
type ListHistory []History type ListHistory []History

View File

@@ -29,7 +29,7 @@ type CreateRequest struct {
// Start now Load balancer // Start now Load balancer
// Required: false // Required: false
Start bool `url:"start" json:"start" validate:"required"` Start bool `url:"start" json:"start"`
// Text description of this load balancer // Text description of this load balancer
// Required: false // Required: false

View File

@@ -9,7 +9,7 @@ import (
// FilterByID returns ListLB with specified ID. // FilterByID returns ListLB with specified ID.
func (ll ListLB) FilterByID(id uint64) ListLB { func (ll ListLB) FilterByID(id uint64) ListLB {
predicate := func(rlb RecordLB) bool { predicate := func(rlb ItemLBList) bool {
return rlb.ID == id return rlb.ID == id
} }
@@ -18,7 +18,7 @@ func (ll ListLB) FilterByID(id uint64) ListLB {
// FilterByName returns ListLB with specified Name. // FilterByName returns ListLB with specified Name.
func (ll ListLB) FilterByName(name string) ListLB { func (ll ListLB) FilterByName(name string) ListLB {
predicate := func(rlb RecordLB) bool { predicate := func(rlb ItemLBList) bool {
return rlb.Name == name return rlb.Name == name
} }
@@ -27,22 +27,13 @@ func (ll ListLB) FilterByName(name string) ListLB {
// FilterByExtNetID returns ListLB with specified ExtNetID. // FilterByExtNetID returns ListLB with specified ExtNetID.
func (ll ListLB) FilterByExtNetID(extNetID uint64) ListLB { func (ll ListLB) FilterByExtNetID(extNetID uint64) ListLB {
predicate := func(rlb RecordLB) bool { predicate := func(rlb ItemLBList) bool {
return rlb.ExtNetID == extNetID return rlb.ExtNetID == extNetID
} }
return ll.FilterFunc(predicate) return ll.FilterFunc(predicate)
} }
// FilterByImageID returns ListLB with specified ImageID.
func (ll ListLB) FilterByImageID(imageID uint64) ListLB {
predicate := func(rlb RecordLB) bool {
return rlb.ImageID == imageID
}
return ll.FilterFunc(predicate)
}
// FilterByK8SID returns ListLB used by specified K8S cluster. // FilterByK8SID returns ListLB used by specified K8S cluster.
func (ll ListLB) FilterByK8SID(ctx context.Context, k8sID uint64, decortClient interfaces.Caller) (*ListLB, error) { func (ll ListLB) FilterByK8SID(ctx context.Context, k8sID uint64, decortClient interfaces.Caller) (*ListLB, error) {
caller := k8s.New(decortClient) caller := k8s.New(decortClient)
@@ -56,7 +47,7 @@ func (ll ListLB) FilterByK8SID(ctx context.Context, k8sID uint64, decortClient i
return nil, err return nil, err
} }
predicate := func(rlb RecordLB) bool { predicate := func(rlb ItemLBList) bool {
return cluster.LBID == rlb.ID return cluster.LBID == rlb.ID
} }
@@ -66,7 +57,7 @@ func (ll ListLB) FilterByK8SID(ctx context.Context, k8sID uint64, decortClient i
} }
// FilterFunc allows filtering ListLB based on a user-specified predicate. // FilterFunc allows filtering ListLB based on a user-specified predicate.
func (ll ListLB) FilterFunc(predicate func(RecordLB) bool) ListLB { func (ll ListLB) FilterFunc(predicate func(ItemLBList) bool) ListLB {
var result ListLB var result ListLB
for _, item := range ll.Data { for _, item := range ll.Data {
@@ -82,9 +73,9 @@ func (ll ListLB) FilterFunc(predicate func(RecordLB) bool) ListLB {
// FindOne returns first found RecordLB // FindOne returns first found RecordLB
// If none was found, returns an empty struct. // If none was found, returns an empty struct.
func (ll ListLB) FindOne() RecordLB { func (ll ListLB) FindOne() ItemLBList {
if len(ll.Data) == 0 { if len(ll.Data) == 0 {
return RecordLB{} return ItemLBList{}
} }
return ll.Data[0] return ll.Data[0]

View File

@@ -3,11 +3,9 @@ package lb
import "testing" import "testing"
var lbs = ListLB{ var lbs = ListLB{
Data: []RecordLB{ Data: []ItemLBList{
{ {
HAMode: true, HAMode: true,
CKey: "",
Meta: []interface{}{},
ACL: []interface{}{}, ACL: []interface{}{},
Backends: []ItemBackend{}, Backends: []ItemBackend{},
CreatedBy: "test_user_1", CreatedBy: "test_user_1",
@@ -22,7 +20,6 @@ var lbs = ListLB{
GID: 212, GID: 212,
GUID: 1, GUID: 1,
ID: 1, ID: 1,
ImageID: 2121,
Milestones: 129000, Milestones: 129000,
Name: "k8s-lb-test-1", Name: "k8s-lb-test-1",
PrimaryNode: Node{}, PrimaryNode: Node{},
@@ -37,8 +34,6 @@ var lbs = ListLB{
}, },
{ {
HAMode: false, HAMode: false,
CKey: "",
Meta: []interface{}{},
ACL: []interface{}{}, ACL: []interface{}{},
Backends: []ItemBackend{}, Backends: []ItemBackend{},
CreatedBy: "test_user_2", CreatedBy: "test_user_2",
@@ -53,7 +48,6 @@ var lbs = ListLB{
GID: 212, GID: 212,
GUID: 2, GUID: 2,
ID: 2, ID: 2,
ImageID: 2129,
Milestones: 129013, Milestones: 129013,
Name: "k8s-lb-test-2", Name: "k8s-lb-test-2",
PrimaryNode: Node{}, PrimaryNode: Node{},
@@ -68,8 +62,6 @@ var lbs = ListLB{
}, },
{ {
HAMode: true, HAMode: true,
CKey: "",
Meta: []interface{}{},
ACL: []interface{}{}, ACL: []interface{}{},
Backends: []ItemBackend{}, Backends: []ItemBackend{},
CreatedBy: "te2t_user_3", CreatedBy: "te2t_user_3",
@@ -84,7 +76,6 @@ var lbs = ListLB{
GID: 212, GID: 212,
GUID: 3, GUID: 3,
ID: 3, ID: 3,
ImageID: 2139,
Milestones: 129025, Milestones: 129025,
Name: "k8s-lb-test-3", Name: "k8s-lb-test-3",
PrimaryNode: Node{}, PrimaryNode: Node{},
@@ -125,16 +116,8 @@ func TestFilterByExtNetID(t *testing.T) {
} }
} }
func TestFilterByImageID(t *testing.T) {
actual := lbs.FilterByImageID(2139).FindOne()
if actual.ImageID != 2139 {
t.Fatal("expected ImageID 2139, found: ", actual.ImageID)
}
}
func TestFilterFunc(t *testing.T) { func TestFilterFunc(t *testing.T) {
actual := lbs.FilterFunc(func(rl RecordLB) bool { actual := lbs.FilterFunc(func(rl ItemLBList) bool {
return rl.Status == "DISABLED" return rl.Status == "DISABLED"
}) })

View File

@@ -136,7 +136,7 @@ type Node struct {
// List of load balancers // List of load balancers
type ListLB struct { type ListLB struct {
// Data // Data
Data []RecordLB `json:"data"` Data []ItemLBList `json:"data"`
// Entry count // Entry count
EntryCount uint64 `json:"entryCount"` EntryCount uint64 `json:"entryCount"`
@@ -159,6 +159,69 @@ type RecordLB struct {
// List of load balancer backends // List of load balancer backends
Backends ListBackends `json:"backends"` Backends ListBackends `json:"backends"`
// Description
Description string `json:"desc"`
// DPAPI password
DPAPIPassword string `json:"dpApiPassword"`
// DPAPI user
DPAPIUser string `json:"dpApiUser"`
// External network ID
ExtNetID uint64 `json:"extnetId"`
// List of load balancer frontends
Frontends ListFrontends `json:"frontends"`
// Grid ID
GID uint64 `json:"gid"`
// GUID
GUID uint64 `json:"guid"`
// ID
ID uint64 `json:"id"`
// Image ID
ImageID uint64 `json:"imageId"`
// Milestones
Milestones uint64 `json:"milestones"`
// Name
Name string `json:"name"`
// Primary node
PrimaryNode Node `json:"primaryNode"`
// Resource group ID
RGID uint64 `json:"rgId"`
// Secondary node
SecondaryNode Node `json:"secondaryNode"`
// Status
Status string `json:"status"`
// Tech status
TechStatus string `json:"techStatus"`
// VINS ID
VINSID uint64 `json:"vinsId"`
}
// Detailed information about load balancer in List
type ItemLBList struct {
// HAMode
HAMode bool `json:"HAmode"`
// Access Control List
ACL []interface{} `json:"acl"`
// List of load balancer backends
Backends ListBackends `json:"backends"`
// Created by // Created by
CreatedBy string `json:"createdBy"` CreatedBy string `json:"createdBy"`
@@ -195,9 +258,6 @@ type RecordLB struct {
// ID // ID
ID uint64 `json:"id"` ID uint64 `json:"id"`
// Image ID
ImageID uint64 `json:"imageId"`
// Milestones // Milestones
Milestones uint64 `json:"milestones"` Milestones uint64 `json:"milestones"`

View File

@@ -24,10 +24,31 @@ type Total struct {
UsageLimit uint64 `json:"usage_limit"` UsageLimit uint64 `json:"usage_limit"`
} }
type ByPool struct {
// Disk count
DiskCount uint64 `json:"disk_count"`
// Disk usage
DiskUsage uint64 `json:"disk_usage"`
// Snapshot count
SnapshotCount uint64 `json:"snapshot_count"`
// Snapshot usage
SnapshotUsage uint64 `json:"snapshot_usage"`
// Usage
Usage uint64 `json:"usage"`
// Usage limit
UsageLimit uint64 `json:"usage_limit"`
}
// Main information about consumption // Main information about consumption
type RecordConsumption struct { type RecordConsumption struct {
// By pool // By pool
ByPool map[string]interface{} `json:"byPool"` ByPool map[string]ByPool `json:"byPool"`
// Total resource information // Total resource information
Total Total `json:"total"` Total Total `json:"total"`
@@ -70,6 +91,9 @@ type RecordPool struct {
// List URIs // List URIs
URIs ListURIs `json:"uris"` URIs ListURIs `json:"uris"`
// Usage Limit
UsageLimit uint64 `json:"usage_limit"`
} }
// SEP config // SEP config

10
pkg/cloudbroker/stack.go Normal file
View File

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

View File

@@ -0,0 +1,42 @@
package stack
import (
"context"
"encoding/json"
"net/http"
"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
)
// Request struct for get list stack
type GetRequest struct {
// Find by ID
// Required: true
StackId uint64 `url:"stackId" json:"stackId" validate:"required"`
}
// Get stack details by ID
func (i Stack) Get(ctx context.Context, req GetRequest) (*InfoStack, error) {
err := validators.ValidateRequest(req)
if err != nil {
for _, validationError := range validators.GetErrors(err) {
return nil, validators.ValidationError(validationError)
}
}
url := "/cloudbroker/stack/get"
res, err := i.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
info := InfoStack{}
err = json.Unmarshal(res, &info)
if err != nil {
return nil, err
}
return &info, nil
}

View File

@@ -0,0 +1,53 @@
package stack
import (
"context"
"encoding/json"
"net/http"
)
// Request struct for get list stack
type ListRequest struct {
// Find by ID
// Required: false
ByID uint64 `url:"by_id,omitempty" json:"by_id,omitempty"`
// Find by name
// Required: false
Name string `url:"name,omitempty" json:"name,omitempty"`
// Find by type
// Required: false
Type string `url:"type,omitempty" json:"type,omitempty"`
// Find by status
// Required: false
Status string `url:"status,omitempty" json:"status,omitempty"`
// Page number
// Required: false
Page uint64 `url:"page,omitempty" json:"page,omitempty"`
// Page size
// Required: false
Size uint64 `url:"size,omitempty" json:"size,omitempty"`
}
// ListStacks gets list stack
func (i Stack) List(ctx context.Context, req ListRequest) (*ListStacks, error) {
url := "/cloudbroker/stack/list"
res, err := i.client.DecortApiCall(ctx, http.MethodPost, url, req)
if err != nil {
return nil, err
}
list := ListStacks{}
err = json.Unmarshal(res, &list)
if err != nil {
return nil, err
}
return &list, nil
}

View File

@@ -0,0 +1,164 @@
package stack
// Main information about stack
type InfoStack struct {
// CKey
Ckey string `json:"_ckey"`
// Meta
Meta []interface{} `json:"_meta"`
//API URL
APIURL string `json:"apiUrl"`
//API key
Apikey string `json:"apikey"`
// App ID
AppID string `json:"appId"`
// CPU allocation ratio
CPUAllocationRatio float64 `json:"cpu_allocation_ratio"`
// Description
Description string `json:"desc"`
// Descr
Descr string `json:"descr"`
// Drivers
Drivers []string `json:"drivers"`
// Eco
Eco interface{} `json:"eco"`
// Error
Error uint64 `json:"error"`
// Grid ID
GID uint64 `json:"gid"`
// GID
GUID uint64 `json:"guid"`
// ID
ID uint64 `json:"id"`
// List image IDs
Images []uint64 `json:"images"`
// Login
Login string `json:"login"`
// Mem allocation ratio
MemAllocationRatio float64 `json:"mem_allocation_ratio"`
// Name
Name string `json:"name"`
// Packegas
Packages Packages `json:"packages"`
//Password
Password string `json:"passwd"`
// Reference ID
ReferenceID string `json:"referenceId"`
// Status
Status string `json:"status"`
// Type
Type string `json:"type"`
}
// List of stacks
type ListStacks struct {
//List
Data []InfoStack `json:"data"`
//Entry count
EntryCount uint64 `json:"entryCount"`
}
// Package
type Packages struct {
// LibvirtBin
LibvirtBin LibvirtBin `json:"libvirt-bin"`
// Lvm2Lockd
Lvm2Lockd Lvm2Lockd `json:"lvm2-lockd"`
// OpenvswitchCommon
OpenvswitchCommon OpenvswitchCommon `json:"openvswitch-common"`
// OpenvswitchSwitch
OpenvswitchSwitch OpenvswitchSwitch `json:"openvswitch-switch"`
// QemuSystemX86
QemuSystemX86 QemuSystemX86 `json:"qemu-system-x86"`
// Sanlock
Sanlock Sanlock `json:"sanlock"`
}
// LibvirtBin
type LibvirtBin struct {
// InstalledSize
InstalledSize string `json:"installed_size"`
// Version
Ver string `json:"ver"`
}
// Lvm2Lockd
type Lvm2Lockd struct {
// InstalledSize
InstalledSize string `json:"installed_size"`
// Version
Ver string `json:"ver"`
}
// OpenvswitchCommon
type OpenvswitchCommon struct {
// InstalledSize
InstalledSize string `json:"installed_size"`
// Version
Ver string `json:"ver"`
}
// OpenvswitchSwitch
type OpenvswitchSwitch struct {
// InstalledSize
InstalledSize string `json:"installed_size"`
// Version
Ver string `json:"ver"`
}
// QemuSystemX86
type QemuSystemX86 struct {
// InstalledSize
InstalledSize string `json:"installed_size"`
// Version
Ver string `json:"ver"`
}
// Sanlock
type Sanlock struct {
// InstalledSize
InstalledSize string `json:"installed_size"`
// Version
Ver string `json:"ver"`
}

View File

@@ -0,0 +1,16 @@
// Lists all the stack.
package stack
import "repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
// Structure for creating request to stack
type Stack struct {
client interfaces.Caller
}
// Builder for stack endpoint
func New(client interfaces.Caller) *Stack {
return &Stack{
client: client,
}
}