From 78a41524713feba5dd4a0c1f02d978ee7f9583cc Mon Sep 17 00:00:00 2001 From: Nikita Sorokin Date: Mon, 25 Sep 2023 19:11:33 +0300 Subject: [PATCH] v1.6.0-zeta --- CHANGELOG.md | 2 +- client.go | 192 ++++++++++++++++-- legacy-client.go | 21 +- pkg/cloudapi/k8s/create.go | 5 +- pkg/cloudapi/kvmppc/create.go | 2 +- pkg/cloudapi/kvmx86/create.go | 2 +- pkg/cloudbroker/compute/set_custom_fields.go | 43 ++++ pkg/cloudbroker/extnet/create.go | 45 +++- pkg/cloudbroker/extnet/models.go | 30 +++ .../extnet/static_route_access_grant.go | 48 +++++ .../extnet/static_route_access_revoke.go | 48 +++++ pkg/cloudbroker/extnet/static_route_add.go | 56 +++++ pkg/cloudbroker/extnet/static_route_del.go | 44 ++++ pkg/cloudbroker/extnet/static_route_list.go | 42 ++++ pkg/cloudbroker/k8s/create.go | 85 ++++++++ .../k8s/get_worker_nodes_meta_data.go | 38 ++++ pkg/cloudbroker/k8s/models.go | 5 +- .../k8s/update_worker_nodes_meta_data.go | 48 +++++ pkg/cloudbroker/kvmppc/create.go | 10 +- pkg/cloudbroker/kvmppc/mass_create.go | 2 +- pkg/cloudbroker/kvmx86/create.go | 6 +- pkg/cloudbroker/kvmx86/create_blank.go | 4 + pkg/cloudbroker/kvmx86/mass_create.go | 2 +- pkg/cloudbroker/lb/create.go | 53 ++++- pkg/cloudbroker/lb/make_highly_available.go | 40 ++++ pkg/cloudbroker/lb/models.go | 9 + pkg/cloudbroker/lb/updateSysctParams.go | 72 +++++++ pkg/cloudbroker/vins/models.go | 13 +- .../vins/static_route_access_grant.go | 48 +++++ .../vins/static_route_access_revoke.go | 48 +++++ pkg/cloudbroker/vins/static_route_add.go | 56 +++++ pkg/cloudbroker/vins/static_route_del.go | 44 ++++ pkg/cloudbroker/vins/static_route_list.go | 42 ++++ 33 files changed, 1166 insertions(+), 39 deletions(-) create mode 100644 pkg/cloudbroker/compute/set_custom_fields.go create mode 100644 pkg/cloudbroker/extnet/static_route_access_grant.go create mode 100644 pkg/cloudbroker/extnet/static_route_access_revoke.go create mode 100644 pkg/cloudbroker/extnet/static_route_add.go create mode 100644 pkg/cloudbroker/extnet/static_route_del.go create mode 100644 pkg/cloudbroker/extnet/static_route_list.go create mode 100644 pkg/cloudbroker/k8s/get_worker_nodes_meta_data.go create mode 100644 pkg/cloudbroker/k8s/update_worker_nodes_meta_data.go create mode 100644 pkg/cloudbroker/lb/make_highly_available.go create mode 100644 pkg/cloudbroker/lb/updateSysctParams.go create mode 100644 pkg/cloudbroker/vins/static_route_access_grant.go create mode 100644 pkg/cloudbroker/vins/static_route_access_revoke.go create mode 100644 pkg/cloudbroker/vins/static_route_add.go create mode 100644 pkg/cloudbroker/vins/static_route_del.go create mode 100644 pkg/cloudbroker/vins/static_route_list.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c250f0..2ce0847 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,4 +29,4 @@ - cloudapi/vins/static_route_access_grant - cloudapi/vins/static_route_access_revoke - cloudapi/vins/static_route_add -- cloudapi/vins/static_route_del \ No newline at end of file +- cloudapi/vins/static_route_del diff --git a/client.go b/client.go index 062c6f5..3611848 100644 --- a/client.go +++ b/client.go @@ -7,12 +7,15 @@ import ( "errors" "fmt" "io" + "mime/multipart" "net/http" + "strconv" "strings" "sync" "time" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi" + "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/k8s" "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker" "github.com/google/go-querystring/query" @@ -68,6 +71,144 @@ func (dc *DecortClient) CloudBroker() *cloudbroker.CloudBroker { // DecortApiCall method for sending requests to the platform func (dc *DecortClient) DecortApiCall(ctx context.Context, method, url string, params interface{}) ([]byte, error) { + if k8sCreateReq, ok := params.(k8s.CreateRequest); ok { + reqBody := &bytes.Buffer{} + writer := multipart.NewWriter(reqBody) + if k8sCreateReq.OidcCertificate != "" { + part, _ := writer.CreateFormFile("oidcCertificate", "ca.crt") + _, _ =io.Copy(part, strings.NewReader(k8sCreateReq.OidcCertificate)) + } + + _= writer.WriteField("name", k8sCreateReq.Name) + _= writer.WriteField("rgId", strconv.FormatUint(k8sCreateReq.RGID, 10)) + _= writer.WriteField("k8ciId", strconv.FormatUint(k8sCreateReq.K8SCIID, 10)) + _= writer.WriteField("workerGroupName", k8sCreateReq.WorkerGroupName) + _= writer.WriteField("networkPlugin", k8sCreateReq.NetworkPlugin) + + if k8sCreateReq.MasterSEPID != 0 { + _= writer.WriteField("masterSepId", strconv.FormatUint(k8sCreateReq.MasterSEPID, 10)) + } + if k8sCreateReq.MasterSEPPool != "" { + _= writer.WriteField("masterSepPool", k8sCreateReq.MasterSEPPool) + } + if k8sCreateReq.WorkerSEPID != 0 { + _= writer.WriteField("workerSepId", strconv.FormatUint(k8sCreateReq.WorkerSEPID, 10)) + } + if k8sCreateReq.WorkerSEPPool != "" { + _= writer.WriteField("workerSepPool", k8sCreateReq.WorkerSEPPool) + } + + if k8sCreateReq.Labels != nil { + for _, v := range k8sCreateReq.Labels { + _= writer.WriteField("labels", v) + } + } + if k8sCreateReq.Taints != nil { + for _, v := range k8sCreateReq.Taints { + _= writer.WriteField("taints", v) + } + } + if k8sCreateReq.Annotations != nil { + for _, v := range k8sCreateReq.Annotations { + _= writer.WriteField("annotations", v) + } + } + + if k8sCreateReq.MasterCPU != 0 { + _= writer.WriteField("masterCpu", strconv.FormatUint(uint64(k8sCreateReq.MasterCPU), 10)) + } + if k8sCreateReq.MasterNum != 0 { + _= writer.WriteField("masterNum", strconv.FormatUint(uint64(k8sCreateReq.MasterNum), 10)) + } + if k8sCreateReq.MasterRAM != 0 { + _= writer.WriteField("masterRam", strconv.FormatUint(uint64(k8sCreateReq.MasterRAM), 10)) + } + if k8sCreateReq.MasterDisk != 0 { + _= writer.WriteField("masterDisk", strconv.FormatUint(uint64(k8sCreateReq.MasterDisk), 10)) + } + if k8sCreateReq.WorkerCPU != 0 { + _= writer.WriteField("workerCpu", strconv.FormatUint(uint64(k8sCreateReq.WorkerCPU), 10)) + } + if k8sCreateReq.WorkerNum != 0 { + _= writer.WriteField("workerNum", strconv.FormatUint(uint64(k8sCreateReq.WorkerNum), 10)) + } + if k8sCreateReq.WorkerRAM != 0 { + _= writer.WriteField("workerRam", strconv.FormatUint(uint64(k8sCreateReq.WorkerRAM), 10)) + } + if k8sCreateReq.WorkerDisk != 0 { + _= writer.WriteField("workerDisk", strconv.FormatUint(uint64(k8sCreateReq.WorkerDisk), 10)) + } + if k8sCreateReq.ExtNetID != 0 { + _= writer.WriteField("extnetId", strconv.FormatUint(k8sCreateReq.ExtNetID, 10)) + } + if k8sCreateReq.VinsId != 0 { + _= writer.WriteField("vinsId", strconv.FormatUint(k8sCreateReq.VinsId, 10)) + } + if !k8sCreateReq.WithLB { + _= writer.WriteField("withLB", strconv.FormatBool(k8sCreateReq.WithLB)) + } + + _= writer.WriteField("highlyAvailable", strconv.FormatBool(k8sCreateReq.HighlyAvailable)) + + if k8sCreateReq.AdditionalSANs != nil { + for _, v := range k8sCreateReq.AdditionalSANs { + _= writer.WriteField("additionalSANs", v) + } + } + if k8sCreateReq.InitConfiguration != "" { + _= writer.WriteField("initConfiguration", k8sCreateReq.InitConfiguration) + } + if k8sCreateReq.ClusterConfiguration != "" { + _= writer.WriteField("clusterConfiguration", k8sCreateReq.ClusterConfiguration) + } + if k8sCreateReq.KubeletConfiguration != "" { + _= writer.WriteField("kubeletConfiguration", k8sCreateReq.KubeletConfiguration) + } + if k8sCreateReq.KubeProxyConfiguration != "" { + _= writer.WriteField("kubeProxyConfiguration", k8sCreateReq.KubeProxyConfiguration) + } + if k8sCreateReq.JoinConfiguration != "" { + _= writer.WriteField("joinConfiguration", k8sCreateReq.JoinConfiguration) + } + if k8sCreateReq.Description != "" { + _= writer.WriteField("desc", k8sCreateReq.Description) + } + if k8sCreateReq.UserData != "" { + _= writer.WriteField("userData", k8sCreateReq.UserData) + } + + _= writer.WriteField("extnetOnly", strconv.FormatBool(k8sCreateReq.ExtNetOnly)) + _= writer.FormDataContentType() + + ct := writer.FormDataContentType() + + writer.Close() + req, err := http.NewRequestWithContext(ctx, method, dc.decortURL+"/restmachine"+url, reqBody) + if err != nil { + return nil, err + } + if err = dc.getToken(ctx); err != nil { + return nil, err + } + + resp, err := dc.domp(req, ct) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + respBytes, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + return nil, errors.New(string(respBytes)) + } + + return respBytes, nil + } + values, err := query.Values(params) if err != nil { return nil, err @@ -140,24 +281,51 @@ func (dc *DecortClient) do(req *http.Request) (*http.Response, error) { req.Header.Add("Authorization", "bearer "+dc.cfg.Token) req.Header.Set("Accept", "application/json") - // var resp *http.Response - // var err error + var resp *http.Response + var err error buf, _ := io.ReadAll(req.Body) + req = req.Clone(req.Context()) - // for i := uint64(0); i < dc.cfg.Retries; i++ { - req = req.Clone(req.Context()) + for i := uint64(0); i < dc.cfg.Retries; i++ { req.Body = io.NopCloser(bytes.NewBuffer(buf)) - resp, err := dc.client.Do(req) + resp, err = dc.client.Do(req) // if err == nil { - if resp.StatusCode == 200 { - return resp, err - } - respBytes, _ := io.ReadAll(resp.Body) - err = fmt.Errorf("%s", respBytes) - resp.Body.Close() + if resp.StatusCode == 200 { + return resp, err + } + respBytes, _ := io.ReadAll(resp.Body) + err = fmt.Errorf("%s", respBytes) + resp.Body.Close() // } - // } + } + + return nil, fmt.Errorf("could not execute request: %w", err) +} + +func (dc *DecortClient) domp(req *http.Request, ctype string) (*http.Response, error) { + req.Header.Add("Content-Type", ctype) + req.Header.Add("Authorization", "bearer "+dc.cfg.Token) + req.Header.Set("Accept", "application/json") + + var resp *http.Response + var err error + buf, _ := io.ReadAll(req.Body) + req = req.Clone(req.Context()) + + for i := uint64(0); i < dc.cfg.Retries; i++ { + req.Body = io.NopCloser(bytes.NewBuffer(buf)) + resp, err = dc.client.Do(req) + + // if err == nil { + if resp.StatusCode == 200 { + return resp, err + } + respBytes, _ := io.ReadAll(resp.Body) + err = fmt.Errorf("%s", respBytes) + resp.Body.Close() + // } + } return nil, fmt.Errorf("could not execute request: %w", err) } diff --git a/legacy-client.go b/legacy-client.go index c9849b1..9dbfffc 100644 --- a/legacy-client.go +++ b/legacy-client.go @@ -140,19 +140,20 @@ func (ldc *LegacyDecortClient) do(req *http.Request) (*http.Response, error) { // var resp *http.Response // var err error buf, _ := io.ReadAll(req.Body) + req = req.Clone(req.Context()) // for i := uint64(0); i < ldc.cfg.Retries; i++ { - req = req.Clone(req.Context()) - req.Body = io.NopCloser(bytes.NewBuffer(buf)) - resp, err := ldc.client.Do(req) + req = req.Clone(req.Context()) + req.Body = io.NopCloser(bytes.NewBuffer(buf)) + resp, err := ldc.client.Do(req) - // if err == nil { - if resp.StatusCode == 200 { - return resp, err - } - respBytes, _ := io.ReadAll(resp.Body) - err = fmt.Errorf("%s", respBytes) - resp.Body.Close() + // if err == nil { + if resp.StatusCode == 200 { + return resp, err + } + respBytes, _ := io.ReadAll(resp.Body) + err = fmt.Errorf("%s", respBytes) + resp.Body.Close() // } // } diff --git a/pkg/cloudapi/k8s/create.go b/pkg/cloudapi/k8s/create.go index c67d1f5..496a482 100644 --- a/pkg/cloudapi/k8s/create.go +++ b/pkg/cloudapi/k8s/create.go @@ -160,10 +160,10 @@ type CreateRequest struct { // Use only selected ExtNet for infrastructure connections // Required: false ExtNetOnly bool `url:"extnetOnly,omitempty" json:"extnetOnly,omitempty"` - + // Insert ssl certificate in x509 pem format // Required: false - OidcCertificate []byte `url:"oidcCertificate,omitempty" json:"oidcCertificate,omitempty"` + OidcCertificate string `url:"oidcCertificate,omitempty" json:"oidcCertificate,omitempty"` } // type wrapperCreateRequest struct { @@ -173,6 +173,7 @@ type CreateRequest struct { // Create creates a new Kubernetes cluster in the specified Resource Group func (k8s K8S) Create(ctx context.Context, req CreateRequest) (string, error) { + err := validators.ValidateRequest(req) if err != nil { for _, validationError := range validators.GetErrors(err) { diff --git a/pkg/cloudapi/kvmppc/create.go b/pkg/cloudapi/kvmppc/create.go index 70ea036..b9bf0e9 100644 --- a/pkg/cloudapi/kvmppc/create.go +++ b/pkg/cloudapi/kvmppc/create.go @@ -79,7 +79,7 @@ type CreateRequest struct { // Start VM upon success // Required: false - Start bool `url:"start,omitempty" json:"start,omitempty"` + Start bool `url:"start" json:"start"` // System name // Required: false diff --git a/pkg/cloudapi/kvmx86/create.go b/pkg/cloudapi/kvmx86/create.go index 7c999f8..60374db 100644 --- a/pkg/cloudapi/kvmx86/create.go +++ b/pkg/cloudapi/kvmx86/create.go @@ -79,7 +79,7 @@ type CreateRequest struct { // Start VM upon success // Required: false - Start bool `url:"start,omitempty" json:"start,omitempty"` + Start bool `url:"start" json:"start"` // System name // Required: false diff --git a/pkg/cloudbroker/compute/set_custom_fields.go b/pkg/cloudbroker/compute/set_custom_fields.go new file mode 100644 index 0000000..aea4d9e --- /dev/null +++ b/pkg/cloudbroker/compute/set_custom_fields.go @@ -0,0 +1,43 @@ +package compute + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) +// Request struct for setting customFields values for the Compute +type SetCustomFieldsRequest struct { + // ID of the compute + // Required: true + ComputeID uint64 `url:"computeId" json:"computeId" validate:"required"` + + // Custom fields for Compute. Must be dict. + // Required: true + CustomFields string `url:"customFields" json:"customFields" validate:"required"` +} + +// SetCustomFields sets customFields values for the Compute +func (c Compute) SetCustomFields(ctx context.Context, req SetCustomFieldsRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + for _, validationError := range validators.GetErrors(err) { + return false, validators.ValidationError(validationError) + } + } + + url := "/cloudbroker/compute/setCustomFields" + + 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 +} diff --git a/pkg/cloudbroker/extnet/create.go b/pkg/cloudbroker/extnet/create.go index 48fd109..6745d17 100644 --- a/pkg/cloudbroker/extnet/create.go +++ b/pkg/cloudbroker/extnet/create.go @@ -2,12 +2,24 @@ package extnet import ( "context" + "encoding/json" "net/http" "strconv" "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" ) +type Route struct { + // Destination network + Destination string `url:"destination" json:"destination" validate:"required"` + + //Destination network mask in 255.255.255.255 format + Netmask string `url:"netmask" json:"netmask" validate:"required"` + + //Next hop host, IP address from ViNS ID free IP pool + Gateway string `url:"gateway" json:"gateway" validate:"required"` +} + // Request struct for create external network type CreateRequest struct { // External network name @@ -70,6 +82,15 @@ type CreateRequest struct { // OpenvSwith bridge name for ExtNet connection // Required: false OVSBridge string `url:"ovsBridge,omitempty" json:"ovsBridge,omitempty"` + + // List of static routes, each item must have destination, netmask, and gateway fields + // Required: false + Routes []Route `url:"-" json:"routes,omitempty" validate:"omitempty,dive"` +} + +type wrapperCreateRequest struct { + CreateRequest + Routes []string `url:"routes,omitempty"` } // Create creates new external network into platform @@ -81,9 +102,31 @@ func (e ExtNet) Create(ctx context.Context, req CreateRequest) (uint64, error) { } } + var routes []string + + if len(req.Routes) != 0 { + routes = make([]string, 0, len(req.Routes)) + + for r := range req.Routes { + b, err := json.Marshal(req.Routes[r]) + if err != nil { + return 0, err + } + + routes = append(routes, string(b)) + } + } else { + routes = []string{} + } + + reqWrapped := wrapperCreateRequest{ + CreateRequest: req, + Routes: routes, + } + url := "/cloudbroker/extnet/create" - res, err := e.client.DecortApiCall(ctx, http.MethodPost, url, req) + res, err := e.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped) if err != nil { return 0, err } diff --git a/pkg/cloudbroker/extnet/models.go b/pkg/cloudbroker/extnet/models.go index bcb35c5..c5f0830 100644 --- a/pkg/cloudbroker/extnet/models.go +++ b/pkg/cloudbroker/extnet/models.go @@ -151,3 +151,33 @@ type RecordExtNet struct { // List reservations Reservations ListReservations `json:"reservations"` } + +// List of static routes +type ListStaticRoutes struct { + // Data + Data []ItemRoutes `json:"data"` + + // Entry count + EntryCount uint64 `json:"entryCount"` +} + +// Detailed information about Routes +type ItemRoutes struct { + //Compute Id + ComputeIds []uint64 `json:"computeIds"` + + // Destination network + Destination string `json:"destination"` + + //Next hop host, IP address from ViNS ID free IP pool + Gateway string `json:"gateway"` + + // GUID + GUID string `json:"guid"` + + // ID + ID uint64 `json:"id"` + + //Destination network mask in 255.255.255.255 format + Netmask string `json:"netmask"` +} \ No newline at end of file diff --git a/pkg/cloudbroker/extnet/static_route_access_grant.go b/pkg/cloudbroker/extnet/static_route_access_grant.go new file mode 100644 index 0000000..c75a152 --- /dev/null +++ b/pkg/cloudbroker/extnet/static_route_access_grant.go @@ -0,0 +1,48 @@ +package extnet + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// Request struct for grant access to static route to Compute/ViNS +type StaticRouteAccessGrantRequest struct { + // ExtNet ID to grant access + // Required: true + ExtNetID uint64 `url:"extnetId" json:"extnetId" validate:"required"` + + // Route ID to grant access, can be found in staticRouteList + // Required: true + RouteId uint64 `url:"routeId" json:"routeId" validate:"required"` + + // List of Compute IDs to grant access to this route + // Required: false + ComputeIds []uint64 `url:"computeIds,omitempty" json:"computeIds,omitempty"` +} + +// Grant access to static route to Compute/ViNS +func (v ExtNet) StaticRouteAccessGrant(ctx context.Context, req StaticRouteAccessGrantRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + for _, validationError := range validators.GetErrors(err) { + return false, validators.ValidationError(validationError) + } + } + + url := "/cloudbroker/extnet/staticRouteAccessGrant" + + res, err := v.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 +} diff --git a/pkg/cloudbroker/extnet/static_route_access_revoke.go b/pkg/cloudbroker/extnet/static_route_access_revoke.go new file mode 100644 index 0000000..91be311 --- /dev/null +++ b/pkg/cloudbroker/extnet/static_route_access_revoke.go @@ -0,0 +1,48 @@ +package extnet + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// Request struct for revoke access to static route to Compute/ViNS +type StaticRouteAccessRevokeRequest struct { + // ExtNet ID to revoke access + // Required: true + ExtNetID uint64 `url:"extnetId" json:"extnetId" validate:"required"` + + // Route ID to revoke access, can be found in staticRouteList + // Required: true + RouteId uint64 `url:"routeId" json:"routeId" validate:"required"` + + // List of Compute IDs to revoke access to this route + // Required: false + ComputeIds []uint64 `url:"computeIds,omitempty" json:"computeIds,omitempty"` +} + +// Revoke access to static route to Compute/ViNS +func (v ExtNet) StaticRouteAccessRevoke(ctx context.Context, req StaticRouteAccessRevokeRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + for _, validationError := range validators.GetErrors(err) { + return false, validators.ValidationError(validationError) + } + } + + url := "/cloudbroker/extnet/staticRouteAccessRevoke" + + res, err := v.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 +} diff --git a/pkg/cloudbroker/extnet/static_route_add.go b/pkg/cloudbroker/extnet/static_route_add.go new file mode 100644 index 0000000..6f418cc --- /dev/null +++ b/pkg/cloudbroker/extnet/static_route_add.go @@ -0,0 +1,56 @@ +package extnet + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// Request struct for add static route +type StaticRouteAddRequest struct { + // ExtNet ID to add static route + // Required: true + ExtNetId uint64 `url:"extnetId" json:"extnetId" validate:"required"` + + // Destination network + // Required: true + Destination string `url:"destination" json:"destination" validate:"required"` + + // Destination network mask in 255.255.255.255 format + // Required: true + Netmask string `url:"netmask" json:"netmask" validate:"required"` + + // Next hop host, IP address from ViNS ID free IP pool + // Required: true + Gateway string `url:"gateway" json:"gateway" validate:"required"` + + // List of Compute IDs which have access to this route + // Required: false + ComputeIds []uint64 `url:"computeIds,omitempty" json:"computeIds,omitempty"` +} + +// StaticRouteAdd add new static route to ViNS +func (v ExtNet) StaticRouteAdd(ctx context.Context, req StaticRouteAddRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + for _, validationError := range validators.GetErrors(err) { + return false, validators.ValidationError(validationError) + } + } + + url := "/cloudbroker/extnet/staticRouteAdd" + + res, err := v.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 +} diff --git a/pkg/cloudbroker/extnet/static_route_del.go b/pkg/cloudbroker/extnet/static_route_del.go new file mode 100644 index 0000000..f6c49f6 --- /dev/null +++ b/pkg/cloudbroker/extnet/static_route_del.go @@ -0,0 +1,44 @@ +package extnet + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// Request struct for remove static route from ViNS +type StaticRouteDelRequest struct { + // ExtNet ID to remove static route from + // Required: true + ExtNetID uint64 `url:"extnetId" json:"extnetId" validate:"required"` + + // Route ID to remove, can be found in staticRouteList + // Required: true + RouteId uint64 `url:"routeId" json:"routeId" validate:"required"` +} + +// Remove static route from ViNS +func (v ExtNet) StaticRouteDel(ctx context.Context, req StaticRouteDelRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + for _, validationError := range validators.GetErrors(err) { + return false, validators.ValidationError(validationError) + } + } + + url := "/cloudbroker/extnet/staticRouteDel" + + res, err := v.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 +} diff --git a/pkg/cloudbroker/extnet/static_route_list.go b/pkg/cloudbroker/extnet/static_route_list.go new file mode 100644 index 0000000..9c411a4 --- /dev/null +++ b/pkg/cloudbroker/extnet/static_route_list.go @@ -0,0 +1,42 @@ +package extnet + +import ( + "context" + "encoding/json" + "net/http" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// Request struct for static route list +type StaticRouteListRequest struct { + // ExtNet ID to show list of static routes + // Required: true + ExtNetID uint64 `url:"extnetId" json:"extnetId" validate:"required"` +} + +// Show list of static routes for ViNS +func (v ExtNet) StaticRouteList(ctx context.Context, req StaticRouteListRequest) (*ListStaticRoutes, error) { + err := validators.ValidateRequest(req) + if err != nil { + for _, validationError := range validators.GetErrors(err) { + return nil, validators.ValidationError(validationError) + } + } + + url := "/cloudbroker/extnet/staticRouteList" + + res, err := v.client.DecortApiCall(ctx, http.MethodPost, url, req) + if err != nil { + return nil, err + } + + list := ListStaticRoutes{} + + err = json.Unmarshal(res, &list) + if err != nil { + return nil, err + } + + return &list, nil +} diff --git a/pkg/cloudbroker/k8s/create.go b/pkg/cloudbroker/k8s/create.go index b2d5ad9..a9eb876 100644 --- a/pkg/cloudbroker/k8s/create.go +++ b/pkg/cloudbroker/k8s/create.go @@ -8,6 +8,8 @@ import ( "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" ) +// type Params []string + // Request struct for create K8S type CreateRequest struct { // Name of kubernetes cluster @@ -100,16 +102,77 @@ type CreateRequest struct { // Required: false ExtNetID uint64 `url:"extnetId,omitempty" json:"extnetId,omitempty"` + // ID of the ViNS to connect k8s cluster. If nothing is specified, ViNS will be created automatically + // Required: false + VinsId uint64 `url:"vinsId,omitempty" json:"vinsId,omitempty"` + // Create kubernetes cluster with masters nodes behind load balancer if true. // Otherwise give all cluster nodes direct external addresses from selected external network // Required: false WithLB bool `url:"withLB" json:"withLB"` + // Custom sysctl values for Load Balancer instance. Applied on boot + // Required: false + LbSysctlParams string `url:"-" json:"lbSysctlParams,omitempty" validate:"omitempty,dive"` + + // Use Highly Available schema for LB deploy + // Required: false + HighlyAvailable bool `url:"highlyAvailable,omitempty" json:"highlyAvailable,omitempty"` + + // Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names + // Required: false + AdditionalSANs []string `url:"additionalSANs,omitempty" json:"additionalSANs,omitempty"` + + // Is used to define settings and actions that should be performed before any other component in the cluster starts. + // It allows you to configure things like node registration, network setup, and other initialization tasks. insert a valid JSON string with all levels of nesting + // Required: false + InitConfiguration string `url:"initConfiguration,omitempty" json:"initConfiguration,omitempty"` + + // Is used to define global settings and configurations for the entire cluster. + // It includes parameters such as cluster name, DNS settings, authentication methods, and other cluster-wide configurations. + // Insert a valid JSON string with all levels of nesting + // Required: false + ClusterConfiguration string `url:"clusterConfiguration,omitempty" json:"clusterConfiguration,omitempty"` + + // Is used to configure the behavior and settings of the Kubelet, which is the primary node agent that runs on each node in the cluster. + // It includes parameters such as node IP address, resource allocation, pod eviction policies, and other Kubelet-specific configurations. + // Insert a valid JSON string with all levels of nesting + // Required: false + KubeletConfiguration string `url:"kubeletConfiguration,omitempty" json:"kubeletConfiguration,omitempty"` + + // Is used to configure the behavior and settings of the Kube-proxy, which is responsible for network proxying and load balancing within the cluster. + // It includes parameters such as proxy mode, cluster IP ranges, and other Kube-proxy specific configurations. + // Insert a valid JSON string with all levels of nesting + // Required: false + KubeProxyConfiguration string `url:"kubeProxyConfiguration,omitempty" json:"kubeProxyConfiguration,omitempty"` + + // Is used to configure the behavior and settings for joining a node to a cluster. + // It includes parameters such as the cluster's control plane endpoint, token, and certificate key. insert a valid JSON string with all levels of nesting + // Required: false + JoinConfiguration string `url:"joinConfiguration,omitempty" json:"joinConfiguration,omitempty"` + // Text description of this kubernetes cluster // Required: false Description string `url:"desc,omitempty" json:"desc,omitempty"` + + // Meta data for working group computes, format YAML "user_data": 1111 + // Required: false + UserData string `url:"userData,omitempty" json:"userData,omitempty"` + + // Use only selected ExtNet for infrastructure connections + // Required: false + ExtNetOnly bool `url:"extnetOnly,omitempty" json:"extnetOnly,omitempty"` + + // Insert ssl certificate in x509 pem format + // Required: false + OidcCertificate string `url:"oidcCertificate,omitempty" json:"oidcCertificate,omitempty"` } +// type wrapperCreateRequest struct { +// CreateRequest +// Params []string `url:"lbSysctlParams,omitempty"` +// } + // Create creates a new kubernetes cluster in the specified resource group func (k K8S) Create(ctx context.Context, req CreateRequest) (string, error) { err := validators.ValidateRequest(req) @@ -119,6 +182,28 @@ func (k K8S) Create(ctx context.Context, req CreateRequest) (string, error) { } } + // var params []string + + // if len(req.LbSysctlParams) != 0 { + // params = make([]string, 0, len(req.LbSysctlParams)) + + // for r := range req.LbSysctlParams { + // b, err := json.Marshal(req.LbSysctlParams[r]) + // if err != nil { + // return "", err + // } + + // params = append(params, string(b)) + // } + // } else { + // params = []string{} + // } + + // reqWrapped := wrapperCreateRequest{ + // CreateRequest: req, + // Params: params, + // } + url := "/cloudbroker/k8s/create" res, err := k.client.DecortApiCall(ctx, http.MethodPost, url, req) diff --git a/pkg/cloudbroker/k8s/get_worker_nodes_meta_data.go b/pkg/cloudbroker/k8s/get_worker_nodes_meta_data.go new file mode 100644 index 0000000..536d628 --- /dev/null +++ b/pkg/cloudbroker/k8s/get_worker_nodes_meta_data.go @@ -0,0 +1,38 @@ +package k8s + +import ( + "context" + "net/http" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// Request struct for get worker group metadata by ID +type GetWorkerNodesMetaDataRequest struct { + // Kubernetes cluster ID + // Required: true + K8SID uint64 `url:"k8sId" json:"k8sId" validate:"required"` + + // ID of the workers compute group + // Required: true + WorkersGroupID uint64 `url:"workersGroupId" json:"workersGroupId" validate:"required"` +} + +// Get worker group metadata by ID +func (k K8S) GetWorkerNodesMetaData(ctx context.Context, req GetWorkerNodesMetaDataRequest) (string, error) { + err := validators.ValidateRequest(req) + if err != nil { + for _, validationError := range validators.GetErrors(err) { + return "", validators.ValidationError(validationError) + } + } + + url := "/cloudbroker/k8s/getWorkerNodesMetaData" + + res, err := k.client.DecortApiCall(ctx, http.MethodPost, url, req) + if err != nil { + return "", err + } + + return string(res), nil +} diff --git a/pkg/cloudbroker/k8s/models.go b/pkg/cloudbroker/k8s/models.go index 953b017..fd686b5 100644 --- a/pkg/cloudbroker/k8s/models.go +++ b/pkg/cloudbroker/k8s/models.go @@ -2,6 +2,9 @@ package k8s // Deteiled information type ItemDetailedInfo struct { + // External Ip + ExternalIp string `json:"externalip"` + // ID ID uint64 `json:"id"` @@ -11,7 +14,7 @@ type ItemDetailedInfo struct { // Status Status string `json:"status"` - // Status + // Tech status TechStatus string `json:"techStatus"` } diff --git a/pkg/cloudbroker/k8s/update_worker_nodes_meta_data.go b/pkg/cloudbroker/k8s/update_worker_nodes_meta_data.go new file mode 100644 index 0000000..cb0e81a --- /dev/null +++ b/pkg/cloudbroker/k8s/update_worker_nodes_meta_data.go @@ -0,0 +1,48 @@ +package k8s + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// Request struct for add worker to a kubernetes cluster +type UpdateWorkerNodesMetaDataRequest struct { + // Kubernetes cluster ID + // Required: true + K8SID uint64 `url:"k8sId" json:"k8sId" validate:"required"` + + // ID of the workers compute group + // Required: true + WorkersGroupID uint64 `url:"workersGroupId" json:"workersGroupId" validate:"required"` + + // Meta data for working group computes, format YAML "user_data": 1111 + // Required: true + UserData string `url:"userData" json:"userData" validate:"required"` +} + +// WorkerAdd adds worker nodes to a kubernetes cluster +func (k K8S) UpdateWorkerNodesMetaData(ctx context.Context, req UpdateWorkerNodesMetaDataRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + for _, validationError := range validators.GetErrors(err) { + return false, validators.ValidationError(validationError) + } + } + + url := "/cloudbroker/k8s/updateWorkerNodesMetaData" + + res, err := k.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 +} diff --git a/pkg/cloudbroker/kvmppc/create.go b/pkg/cloudbroker/kvmppc/create.go index 15915c7..083a7d7 100644 --- a/pkg/cloudbroker/kvmppc/create.go +++ b/pkg/cloudbroker/kvmppc/create.go @@ -79,7 +79,11 @@ type CreateRequest struct { // Start VM upon success // Required: false - Start bool `url:"start,omitempty" json:"start,omitempty"` + Start bool `url:"start" json:"start"` + + // Stack ID + // Required: false + StackID uint64 `url:"stackId,omitempty" json:"stackId,omitempty"` // System name // Required: false @@ -88,6 +92,10 @@ type CreateRequest struct { // Compute purpose // Required: false IPAType string `url:"ipaType,omitempty" json:"ipaType,omitempty"` + + // Reason for action + // Required: false + Reason string `url:"reason,omitempty" json:"reason,omitempty"` } type wrapperCreateRequest struct { diff --git a/pkg/cloudbroker/kvmppc/mass_create.go b/pkg/cloudbroker/kvmppc/mass_create.go index 41ff703..d3848ca 100644 --- a/pkg/cloudbroker/kvmppc/mass_create.go +++ b/pkg/cloudbroker/kvmppc/mass_create.go @@ -64,7 +64,7 @@ type MassCreateRequest struct { // Start after create of not // Required: false - Start bool `url:"start,omitempty" json:"start,omitempty"` + Start bool `url:"start" json:"start"` // Reason to action // Required: false diff --git a/pkg/cloudbroker/kvmx86/create.go b/pkg/cloudbroker/kvmx86/create.go index 987721b..9f1b4a7 100644 --- a/pkg/cloudbroker/kvmx86/create.go +++ b/pkg/cloudbroker/kvmx86/create.go @@ -79,7 +79,7 @@ type CreateRequest struct { // Start VM upon success // Required: false - Start bool `url:"start,omitempty" json:"start,omitempty"` + Start bool `url:"start" json:"start"` // Stack ID // Required: false @@ -97,6 +97,10 @@ type CreateRequest struct { // Required: false CustomField string `url:"customFields,omitempty" json:"customFields,omitempty"` + //Type of compute Stateful (KVM_X86) or Stateless (SVA_KVM_X86) + // Required: false + Driver string `url:"driver,omitempty" json:"driver,omitempty"` + // Reason for action // Required: false Reason string `url:"reason,omitempty" json:"reason,omitempty"` diff --git a/pkg/cloudbroker/kvmx86/create_blank.go b/pkg/cloudbroker/kvmx86/create_blank.go index 62d7515..acfeb25 100644 --- a/pkg/cloudbroker/kvmx86/create_blank.go +++ b/pkg/cloudbroker/kvmx86/create_blank.go @@ -50,6 +50,10 @@ type CreateBlankRequest struct { // Text description of this VM // Required: false Description string `url:"desc,omitempty" json:"desc,omitempty"` + + //Type of compute Stateful (KVM_X86) or Stateless (SVA_KVM_X86) + // Required: false + Driver string `url:"driver,omitempty" json:"driver,omitempty"` } type wrapperCreateBlankRequest struct { diff --git a/pkg/cloudbroker/kvmx86/mass_create.go b/pkg/cloudbroker/kvmx86/mass_create.go index 30d8671..d8768a8 100644 --- a/pkg/cloudbroker/kvmx86/mass_create.go +++ b/pkg/cloudbroker/kvmx86/mass_create.go @@ -64,7 +64,7 @@ type MassCreateRequest struct { // Start after create of not // Required: false - Start bool `url:"start,omitempty" json:"start,omitempty"` + Start bool `url:"start" json:"start"` // Reason to action // Required: false diff --git a/pkg/cloudbroker/lb/create.go b/pkg/cloudbroker/lb/create.go index 7048fe0..df30ec2 100644 --- a/pkg/cloudbroker/lb/create.go +++ b/pkg/cloudbroker/lb/create.go @@ -2,12 +2,16 @@ package lb import ( "context" + "encoding/json" + "errors" "net/http" "strconv" "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" ) +type Params []string + // Request struct for create load balancer type CreateRequest struct { // ID of the resource group where this load balancer instance will be located @@ -20,12 +24,20 @@ type CreateRequest struct { Name string `url:"name" json:"name" validate:"required"` // External network to connect this load balancer to - // Required: true - ExtNetID uint64 `url:"extnetId" json:"extnetId" validate:"required"` + // Required: false + ExtNetID uint64 `url:"extnetId" json:"extnetId"` // Internal network (VINS) to connect this load balancer to - // Required: true - VINSID uint64 `url:"vinsId" json:"vinsId" validate:"required"` + // Required: false + VINSID uint64 `url:"vinsId" json:"vinsId"` + + // Custom sysctl values for Load Balancer instance. Applied on boot + // Required: false + SysctlParams Params `url:"-" json:"sysctlParams,omitempty" validate:"omitempty,dive"` + + // Use Highly Available schema for LB deploy + // Required: false + HighlyAvailable bool `url:"highlyAvailable,omitempty" json:"highlyAvailable,omitempty"` // Start now Load balancer // Required: false @@ -36,6 +48,11 @@ type CreateRequest struct { Description string `url:"desc,omitempty" json:"desc,omitempty"` } +type wrapperCreateRequest struct { + CreateRequest + Params []string `url:"sysctlParams,omitempty"` +} + // Create method will create a new load balancer instance func (lb LB) Create(ctx context.Context, req CreateRequest) (uint64, error) { err := validators.ValidateRequest(req) @@ -45,9 +62,35 @@ func (lb LB) Create(ctx context.Context, req CreateRequest) (uint64, error) { } } + if req.ExtNetID == 0 && req.VINSID == 0 { + return 0, errors.New("vinsId and extNetId cannot be both in the value 0") + } + + var params []string + + if len(req.SysctlParams) != 0 { + params = make([]string, 0, len(req.SysctlParams)) + + for r := range req.SysctlParams { + b, err := json.Marshal(req.SysctlParams[r]) + if err != nil { + return 0, err + } + + params = append(params, string(b)) + } + } else { + params = []string{} + } + + reqWrapped := wrapperCreateRequest{ + CreateRequest: req, + Params: params, + } + url := "/cloudbroker/lb/create" - res, err := lb.client.DecortApiCall(ctx, http.MethodPost, url, req) + res, err := lb.client.DecortApiCall(ctx, http.MethodPost, url, reqWrapped) if err != nil { return 0, err } diff --git a/pkg/cloudbroker/lb/make_highly_available.go b/pkg/cloudbroker/lb/make_highly_available.go new file mode 100644 index 0000000..f78b516 --- /dev/null +++ b/pkg/cloudbroker/lb/make_highly_available.go @@ -0,0 +1,40 @@ +package lb + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// Request struct for make Load Balancer Highly available +type HighlyAvailableRequest struct { + // ID of the LB instance + // Required: true + LBID uint64 `url:"lbId" json:"lbId" validate:"required"` +} + +// Make Load Balancer Highly available +func (l LB) HighlyAvailable(ctx context.Context, req HighlyAvailableRequest) (uint64, error) { + err := validators.ValidateRequest(req) + if err != nil { + for _, validationError := range validators.GetErrors(err) { + return 0, validators.ValidationError(validationError) + } + } + + url := "/cloudbroker/lb/makeHighlyAvailable" + + res, err := l.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 +} diff --git a/pkg/cloudbroker/lb/models.go b/pkg/cloudbroker/lb/models.go index d2b89f4..a184757 100644 --- a/pkg/cloudbroker/lb/models.go +++ b/pkg/cloudbroker/lb/models.go @@ -192,6 +192,9 @@ type RecordLB struct { // Name Name string `json:"name"` + // Part K8s + PartK8s bool `json:"partK8s"` + // Primary node PrimaryNode Node `json:"primaryNode"` @@ -204,6 +207,9 @@ type RecordLB struct { // Status Status string `json:"status"` + // Sysctl Params + SysctlParams []string `json:"sysctlParams"` + // Tech status TechStatus string `json:"techStatus"` @@ -279,6 +285,9 @@ type ItemLBList struct { // Status Status string `json:"status"` + // Sysctl Params + SysctlParams []string `json:"sysctlParams"` + // Tech status TechStatus string `json:"techStatus"` diff --git a/pkg/cloudbroker/lb/updateSysctParams.go b/pkg/cloudbroker/lb/updateSysctParams.go new file mode 100644 index 0000000..018f5e8 --- /dev/null +++ b/pkg/cloudbroker/lb/updateSysctParams.go @@ -0,0 +1,72 @@ +package lb + +import ( + "context" + "encoding/json" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// Request struct for update sysct params for lb +type UpdateSysctParamsRequest struct { + // ID of the LB instance + // Required: true + LBID uint64 `url:"lbId" json:"lbId" validate:"required"` + + // Custom sysctl values for Load Balancer instance. Applied on boot + // Required: true + SysctlParams Params `url:"-" json:"sysctlParams" validate:"required,dive"` +} + +type wrapperUpdateSysctParamsRequest struct { + UpdateSysctParamsRequest + Params []string `url:"sysctlParams" validate:"required"` +} + +// Create method will create a new load balancer instance +func (l LB) UpdateSysctParams(ctx context.Context, req UpdateSysctParamsRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + for _, validationError := range validators.GetErrors(err) { + return false, validators.ValidationError(validationError) + } + } + + var params []string + + if len(req.SysctlParams) != 0 { + params = make([]string, 0, len(req.SysctlParams)) + + for r := range req.SysctlParams { + b, err := json.Marshal(req.SysctlParams[r]) + if err != nil { + return false, err + } + + params = append(params, string(b)) + } + } else { + params = []string{} + } + + reqWrapped := wrapperUpdateSysctParamsRequest{ + UpdateSysctParamsRequest: req, + Params: params, + } + + url := "/cloudbroker/lb/updateSysctParams" + + res, err := l.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 +} diff --git a/pkg/cloudbroker/vins/models.go b/pkg/cloudbroker/vins/models.go index 7658d87..cf7d66b 100644 --- a/pkg/cloudbroker/vins/models.go +++ b/pkg/cloudbroker/vins/models.go @@ -411,8 +411,19 @@ type InfoVNF struct { Type string `json:"type"` } +// List of static routes +type ListStaticRoutes struct { + // Data + Data []ItemRoutes `json:"data"` + + // Entry count + EntryCount uint64 `json:"entryCount"` +} + +// List of Routes type ListRoutes []ItemRoutes +// Detailed information about Routes type ItemRoutes struct { //Compute Id ComputeIds []uint64 `json:"computeIds"` @@ -424,7 +435,7 @@ type ItemRoutes struct { Gateway string `json:"gateway"` // GUID - GUID uint64 `json:"guid"` + GUID string `json:"guid"` // ID ID uint64 `json:"id"` diff --git a/pkg/cloudbroker/vins/static_route_access_grant.go b/pkg/cloudbroker/vins/static_route_access_grant.go new file mode 100644 index 0000000..10a139e --- /dev/null +++ b/pkg/cloudbroker/vins/static_route_access_grant.go @@ -0,0 +1,48 @@ +package vins + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// Request struct for grant access to static route to Compute/ViNS +type StaticRouteAccessGrantRequest struct { + // ViNS ID to grant access + // Required: true + VINSID uint64 `url:"vinsId" json:"vinsId" validate:"required"` + + // Route ID to grant access, can be found in staticRouteList + // Required: true + RouteId uint64 `url:"routeId" json:"routeId" validate:"required"` + + // List of Compute IDs to grant access to this route + // Required: false + ComputeIds []uint64 `url:"computeIds,omitempty" json:"computeIds,omitempty"` +} + +// Grant access to static route to Compute/ViNS +func (v VINS) StaticRouteAccessGrant(ctx context.Context, req StaticRouteAccessGrantRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + for _, validationError := range validators.GetErrors(err) { + return false, validators.ValidationError(validationError) + } + } + + url := "/cloudbroker/vins/staticRouteAccessGrant" + + res, err := v.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 +} diff --git a/pkg/cloudbroker/vins/static_route_access_revoke.go b/pkg/cloudbroker/vins/static_route_access_revoke.go new file mode 100644 index 0000000..e18a859 --- /dev/null +++ b/pkg/cloudbroker/vins/static_route_access_revoke.go @@ -0,0 +1,48 @@ +package vins + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// Request struct for revoke access to static route to Compute/ViNS +type StaticRouteAccessRevokeRequest struct { + // ViNS ID to revoke access + // Required: true + VINSID uint64 `url:"vinsId" json:"vinsId" validate:"required"` + + // Route ID to revoke access, can be found in staticRouteList + // Required: true + RouteId uint64 `url:"routeId" json:"routeId" validate:"required"` + + // List of Compute IDs to revoke access to this route + // Required: false + ComputeIds []uint64 `url:"computeIds,omitempty" json:"computeIds,omitempty"` +} + +// Revoke access to static route to Compute/ViNS +func (v VINS) StaticRouteAccessRevoke(ctx context.Context, req StaticRouteAccessRevokeRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + for _, validationError := range validators.GetErrors(err) { + return false, validators.ValidationError(validationError) + } + } + + url := "/cloudbroker/vins/staticRouteAccessRevoke" + + res, err := v.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 +} diff --git a/pkg/cloudbroker/vins/static_route_add.go b/pkg/cloudbroker/vins/static_route_add.go new file mode 100644 index 0000000..b2ad2ce --- /dev/null +++ b/pkg/cloudbroker/vins/static_route_add.go @@ -0,0 +1,56 @@ +package vins + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// Request struct for add static route +type StaticRouteAddRequest struct { + // VINS ID + // Required: true + VINSID uint64 `url:"vinsId" json:"vinsId" validate:"required"` + + // Destination network + // Required: true + Destination string `url:"destination" json:"destination" validate:"required"` + + // Destination network mask in 255.255.255.255 format + // Required: true + Netmask string `url:"netmask" json:"netmask" validate:"required"` + + // Next hop host, IP address from ViNS ID free IP pool + // Required: true + Gateway string `url:"gateway" json:"gateway" validate:"required"` + + // List of Compute IDs which have access to this route + // Required: false + ComputeIds []uint64 `url:"computeIds,omitempty" json:"computeIds,omitempty"` +} + +// StaticRouteAdd add new static route to ViNS +func (v VINS) StaticRouteAdd(ctx context.Context, req StaticRouteAddRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + for _, validationError := range validators.GetErrors(err) { + return false, validators.ValidationError(validationError) + } + } + + url := "/cloudbroker/vins/staticRouteAdd" + + res, err := v.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 +} diff --git a/pkg/cloudbroker/vins/static_route_del.go b/pkg/cloudbroker/vins/static_route_del.go new file mode 100644 index 0000000..d01e50d --- /dev/null +++ b/pkg/cloudbroker/vins/static_route_del.go @@ -0,0 +1,44 @@ +package vins + +import ( + "context" + "net/http" + "strconv" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// Request struct for remove static route from ViNS +type StaticRouteDelRequest struct { + // ViNS ID to remove static route from + // Required: true + VINSID uint64 `url:"vinsId" json:"vinsId" validate:"required"` + + // Route ID to remove, can be found in staticRouteList + // Required: true + RouteId uint64 `url:"routeId" json:"routeId" validate:"required"` +} + +// Remove static route from ViNS +func (v VINS) StaticRouteDel(ctx context.Context, req StaticRouteDelRequest) (bool, error) { + err := validators.ValidateRequest(req) + if err != nil { + for _, validationError := range validators.GetErrors(err) { + return false, validators.ValidationError(validationError) + } + } + + url := "/cloudbroker/vins/staticRouteDel" + + res, err := v.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 +} diff --git a/pkg/cloudbroker/vins/static_route_list.go b/pkg/cloudbroker/vins/static_route_list.go new file mode 100644 index 0000000..40ba122 --- /dev/null +++ b/pkg/cloudbroker/vins/static_route_list.go @@ -0,0 +1,42 @@ +package vins + +import ( + "context" + "encoding/json" + "net/http" + + "repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators" +) + +// Request struct for static route list +type StaticRouteListRequest struct { + // ViNS ID to show list of static routes + // Required: true + VINSID uint64 `url:"vinsId" json:"vinsId" validate:"required"` +} + +// Show list of static routes for ViNS +func (v VINS) StaticRouteList(ctx context.Context, req StaticRouteListRequest) (*ListStaticRoutes, error) { + err := validators.ValidateRequest(req) + if err != nil { + for _, validationError := range validators.GetErrors(err) { + return nil, validators.ValidationError(validationError) + } + } + + url := "/cloudbroker/vins/staticRouteList" + + res, err := v.client.DecortApiCall(ctx, http.MethodPost, url, req) + if err != nil { + return nil, err + } + + list := ListStaticRoutes{} + + err = json.Unmarshal(res, &list) + if err != nil { + return nil, err + } + + return &list, nil +}