You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
decort-golang-sdk/README.md

68 KiB

Decort SDK

Decort SDK - это библиотека, написанная на языке GO, позволяющая взаимодействовать с API облачной платформы DECORT. Библиотека содержит в себе структуры и методы, необходимые для отправки запросов. Decort SDK имеет встроенный http-клиент и поддерживает разные способы авторизации на платформе. Библиотека так же содержит в себе модели ответов от платформы.

Версии

- Версия 1.0.x Decort-SDK соответствует 3.8.4 версии платформы
- Версия 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 версии платформы
- Версия 1.5.x Decort-SDK соответствует 3.8.7 версии платформы
- Версия 1.6.x Decort-SDK соответствует 3.8.8 версии платформы
- Версия 1.7.х Decort-SDK соответствует 3.8.9 версии платформы
- Версия 1.8.х Decort-SDK соответствует 4.0.0 версии платформы
- Версия 1.9.х Decort-SDK соответствует 4.1.0 версии платформы
- Версия 1.10.х Decort-SDK соответствует 4.2.0 версии платформы

Оглавление

Установка

Выполните команду в терминале:

go get -u repository.basistech.ru/BASIS/decort-golang-sdk

Список API

Библиотека поддерживает две группы API платформы:

  • cloudapi - пользовательская группа, которая позволяет воспользоваться всем стардартным функционалом платформы;
  • cloudbroker - административная группа, которая позволяет воспользоваться всем стандартным функционалом платформы и расширенными возможностями, включающими в себя управление пользователями, ресурсами, платформами размещения ресурсов и т.д.

Cloudapi

Cloudapi позволяет выполнять запросы к группе пользовательских конечных точек Данная группа ручек позволяет выполнять следующие операции в платформе:

  • Account - управление аккаунтами - внутренними учетными записями платформы, которые являются владельцами вычислительных ресурсов;
  • Audit - получение информации о событиях системы;
  • BService - управление группами виртуальных машин (computes);
  • Compute - управление виртуальными машинами (индивидуально);
  • Disks - управление виртуальными дисками;
  • DPDK - управление виртуальными сетями DPDK;
  • ExtNet - управление виртуальными сетями, отвечающими за внешний доступ;
  • FLIPgroup - управление группами "плавающими" ip - адресами;
  • Image - управление образами операционных систем;
  • K8CI - получение информации о конвейере для создания кластера;
  • K8S - управление кластерами kubernetes;
  • KVMx86 - создание виртуальной машины x86;
  • LB - управление балансировщиками нагрузки;
  • Locations - получение информации о grid площадки;
  • RG - управление ресурсными группами аккаунта;
  • Stack - получение информации о вычислительных узлах;
  • Tasks - получение информации о ходе выполнения асинхронных задач (например, создание кластера);
  • VFPool - управление пулом виртуальных сетевых функций;
  • VINS - управление виртуальными изолированными сетями.

Cloudbroker

Cloudbroker позволяет выполнять запросы к группе пользовательских конечных точек Данная группа ручек позволяет выполнять следующие операции в платформе:

  • Account - управление аккаунтами - внутренними учетными записями платформы, которые являются владельцами вычислительных ресурсов;
  • Audit - получение информации о событиях системы;
  • APIAccess - управление доступом к API и его объектам;
  • Backup - управление резервным копированием;
  • Compute - управление виртуальными машинами (индивидуально);
  • Disks - управление виртуальными дисками;
  • DPDK - управление виртуальными сетями DPDK;
  • ExtNet - управление виртуальными сетями, отвечающими за внешний доступ;
  • FLIPGroup - управление группами с «плавающими» ip адресами;
  • Grid - управление площадками;
  • Group - управление группами пользователей;
  • Image - управление образами операционных систем;
  • K8CI - управление конвейром для создания кластера;
  • K8S - управление кластерами kubernetes;
  • KVMx86 - создание виртуальной машины x86;
  • LB - управление балансировщиками нагрузки;
  • Node - управление нодами платформы;
  • PCIDevice - управление устройствами;
  • RG - управление ресурсными группами аккаунта;
  • SEP - управление storage endpoint (sep);
  • Stack - получение информации о вычислительных узлах;
  • Tasks - получение информации о ходе выполнения асинхронных задач (например, создание кластера);
  • User - управление пользователями (индивидуально);
  • VGPU - управление виртуальными графическими процессорами;
  • VFPool - управление пулом виртуальных сетевых функций;
  • VINS - управление виртуальными изолированными сетями.

Работа с библиотекой

Алгоритм работы с библиотекой выглядит следующим образом:

  1. Выполнение одного из действий:
  • настройка конфигурации клиента;
  • парсинг конфигурации из файла.
  1. Создание клиента.
  2. Создание структуры запроса.
  3. Выполнение запроса.

Настройка конфигурации клиента

Сначала, необходимо создать переменную конфигурации клиента. Конфигурация состоит как из обязательных, так и необязательных полей.

Поле Тип Обязательный Описание
AppID string Да app_id ключа для выполнения запросов
AppSecret string Да app_secret ключ для выполнения запроса
SSOURL string Да URL адрес сервиса аутентификации и авторизации
DecortURL string Да URL адрес платформы, с которой будет осуществляться взаимодействие
Retries uint Нет Кол-во неудачных попыток выполнения запроса, по умолчанию - 5
Timeout config.Duration Нет Таймаут HTTP клиента, по умолчанию - без ограничений
SSLSkipVerify bool Нет Пропуск проверки подлинности сертификата
Token string Нет JWT токен
Пример конфигурации клиента
import (
    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
)

func main(){
    // Настройка конфигурации
    cfg := config.Config{
        AppID:     "<APP_ID>",
        AppSecret: "<APP_SECRET>",
        SSOURL:    "https://sso.digitalenergy.online",
        DecortURL: "https://mr4.digitalenergy.online",
        Retries:   5,
    }

    cfg.SetTimeout(5 * time.Minute)
}

Парсинг конфигурации из файла

Также возможно создать переменную конфигурации из JSON или YAML файла, используя функцию ParseConfigJSON (или ParseConfigYAML) из пакета config.
См. пример файлов конфигурации ниже и в директории samples/.

import (
	"repository.basistech.ru/BASIS/decort-golang-sdk/config"
)

func main() {
	// Парсинг конфигурации из JSON-файла
	cfg, _ := config.ParseConfigJSON("<PATH>")
}

Пример JSON конфигурации

{
    "appId": "<APP_ID>",
    "appSecret": "<APP_SECRET>",
    "ssoUrl": "https://sso.digitalenergy.online",
    "decortUrl": "https://mr4.digitalenergy.online",
    "retries": 5,
    "timeout": "5m",
    "sslSkipVerify": false
}

Пример YAML конфигурации

appId: <APP_ID>
appSecret: <APP_SECRET>
ssoUrl: https://sso.digitalenergy.online
decortUrl: https://mr4.digitalenergy.online
retries: 5
timeout: 5m
sslSkipVerify: false

Создание клиента

Создание клиента происходит с помощью функции-строителя New из основного пакета decort-sdk, для избежания проблем с именами, пакету можно присвоить алиас decort. Функция принимает конфигурацию, возвращает структуру DecortClient, с помощью которой можно взаимодействовать с платформой.

Пример

package main

import (
    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
    decort "repository.basistech.ru/BASIS/decort-golang-sdk"
)

func main() {
    // Настройка конфигурации
    cfg := config.Config{
        AppID:     "<APPID>",
        AppSecret: "<APPSECRET>",
        SSOURL:    "https://sso.digitalenergy.online",
        DecortURL: "https://mr4.digitalenergy.online",
        Retries:   5,
    }

    cfg.SetTimeout(5 * time.Minute)

    // Создание клиента
    client := decort.New(cfg)
}

Создание структуры запроса

Структуры запросов определены в пакетах:

  • pkg/cloudapi - для cloudapi
  • pkg/cloudbroker - для cloudbroker

В каждом пакете находятся пакеты групп API:

  • cloudapi:
    • pkg/cloudapi/account - для Account
    • pkg/cloudapi/audit - для Audit
    • pkg/cloudapi/bservice - для Basic Service
    • pkg/cloudapi/compute - для Compute
    • pkg/cloudapi/disks - для Disks
    • pkg/cloudapi/dpdknet - для DPDK
    • pkg/cloudapi/extnet - для ExtNet
    • pkg/cloudapi/flipgroup - для FLIPGroup
    • pkg/cloudapi/image - для Image
    • pkg/cloudapi/k8ci - для K8CI
    • pkg/cloudapi/k8s - для K8S
    • pkg/cloudapi/kvmx86 - для KVMX86
    • pkg/cloudapi/lb - для LB
    • pkg/cloudapi/locations - для Locations
    • pkg/cloudapi/rg - для RG
    • pkg/cloudapi/stack - для Stack
    • pkg/cloudapi/tasks - для Tasks
    • pkg/cloudapi/vfpool - для VFPool
    • pkg/cloudapi/vins - для VINS
  • cloudbroker:
    • pkg/cloudbroker/account - для Account
    • pkg/cloudbroker/audit - для Audit
    • pkg/cloudbroker/apiaccess - для APIAccess
    • pkg/cloudbroker/backup - для Backup
    • pkg/cloudbroker/compute - для Compute
    • pkg/cloudbroker/disks - для Disks
    • pkg/cloudbroker/dpdknet - для DPDK
    • pkg/cloudbroker/extnet - для ExtNet
    • pkg/cloudbroker/flipgroup - для FLIPGroup
    • pkg/cloudbroker/grid - для Grid
    • pkg/cloudbroker/group - для Group
    • pkg/cloudbroker/image - для Image
    • pkg/cloudbroker/k8ci - для K8CI
    • pkg/cloudbroker/k8s - для K8S
    • pkg/cloudbroker/kvmx86 - для KVMX86
    • pkg/cloudbroker/lb - для LB
    • pkg/cloudbroker/node - для Node
    • pkg/cloudbroker/pcidevice - для PCIDevice
    • pkg/cloudbroker/rg - для RG
    • pkg/cloudbroker/sep - для SEP
    • pkg/cloudbroker/stack - для Stack
    • pkg/cloudbroker/tasks - для Tasks
    • pkg/cloudbroker/user - для User
    • pkg/cloudbroker/vgpu - для VGPU
    • pkg/cloudbroker/vfpool - для VFPool
    • pkg/cloudbroker/vins - для VINS

Все поля структуры имеют описание, в которых содержится:

  • Их назначение;
  • Обязательный или нет - поле required в комментариях;
  • Доп. информация (допустимые значения, значения по умолчанию).

Пример комментариев структуры

type CreateRequest struct {
	// ID of the resource group, which will own this VM
	// Required: true
	RGID uint64 `url:"rgId" json:"rgId"` 

	// Name of this VM.
	// Must be unique among all VMs (including those in DELETED state) in target resource group
	// Required: true
	Name string `url:"name" json:"name"`

	// Number CPUs to allocate to this VM
	// Required: true
	CPU uint64 `url:"cpu" json:"cpu"`

	// Volume of RAM in MB to allocate to this VM
	// Required: true
	RAM uint64 `url:"ram" json:"ram"`

	// ID of the OS image to base this VM on;
	// Could be boot disk image or CD-ROM image
	// Required: true
	ImageID uint64 `url:"imageId" json:"imageId"`

	// Size of the boot disk in GB
	// Required: false
	BootDisk uint64 `url:"bootDisk,omitempty" json:"bootDisk,omitempty"`

	// ID of SEP to create boot disk on.
	// Uses images SEP ID if not set
	// Required: false
	SEPID uint64 `url:"sepId,omitempty" json:"sepId,omitempty"`

	// Pool to use if SEP ID is set, can be also empty if needed to be chosen by system
	// Required: false
	Pool string `url:"pool,omitempty" json:"pool,omitempty"`

	// Network type
	// Should be one of:
	//	- VINS
	//	- EXTNET
	//	- NONE
	// Required: false
	NetType string `url:"netType,omitempty" json:"netType,omitempty"`

	// Network ID for connect to,
	// for EXTNET - external network ID,
	// for VINS - VINS ID,
	// when network type is not "NONE"
	// Required: false
	NetID uint64 `url:"netId,omitempty" json:"netId,omitempty"`

	// IP address to assign to this VM when connecting to the specified network
	// Required: false
	IPAddr string `url:"ipAddr,omitempty" json:"ipAddr,omitempty"`

	// Input data for cloud-init facility
	// Required: false
	Userdata string `url:"userdata,omitempty" json:"userdata,omitempty"`

	// Text description of this VM
	// Required: false
	Description string `url:"desc,omitempty" json:"desc,omitempty"`

	// Start VM upon success
	// Required: false
	Start bool `url:"start,omitempty" json:"start,omitempty"`

	// Stack ID
	// Required: false
	StackID uint64 `url:"stackId,omitempty" json:"stackId,omitempty"`

	// System name
	// Required: false
	IS string `url:"IS,omitempty" json:"IS,omitempty"`

	// Compute purpose
	// Required: false
	IPAType string `url:"ipaType,omitempty" json:"ipaType,omitempty"`

	
}

Пример создания запроса для развертывания виртуальной машины:

package main

import (
    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
    decort "repository.basistech.ru/BASIS/decort-golang-sdk"
    "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/kvmx86"
)

func main() {
    // Настройка конфигурации
    cfg := config.Config{
        AppID:     "<APPID>",
        AppSecret: "<APPSECRET>",
        SSOURL:    "https://sso.digitalenergy.online",
        DecortURL: "https://mr4.digitalenergy.online",
        Retries:   5,
    }

    // Создание клиента
    client := decort.New(cfg)

    // Создание структуры запроса
    // CreateRequest - реквест на создание виртуальной машины
    req := kvmx86.CreateRequest{
        RGID:    123,
        Name:    "compute",
        CPU:     4,
        RAM:     4096,
        ImageID: 321,
    }
}

Выполнение запроса

Чтобы выполнить запрос, необходимо:

  1. Вызвать у клиента метод, отвечаеющий за определение группы API для взаимодействия, это может быть .CloudAPI(), либо .CloudBroker(). Данные методы возвращаеют соответствующие структуры, с помощью которых можно совершать запросы.

  2. Вызвать у возвращенной структуры метод, определяющий группу ручек для взаимодействия.

    Доступные методы для .CloudAPI():

    • .Account() - для работы с Account
    • .Audit() - для работы с Audit
    • .BService() - для работы с BService
    • .Compute() - для работы с Compute
    • .Disks() - для работы с Disks
    • .DPDKNet() - для работы с DPDK
    • .ExtNet() - для работы с ExtNet
    • .FLIPgroup() - для работы с FLIPGroup
    • .Image() - для работы с Image
    • .K8CI() - для работы с K8CI
    • .K8S() - для работы с K8S
    • .KVMx86() - для работы с KVMX86
    • .LB() - для работы с LB
    • .Locations() - для работы с Locations
    • .RG() - для работы с RG
    • .Stack() - для работы с Stack
    • .Tasks() - для работы с Tasks
    • .VFPool() - для работы с VFPool
    • .VINS() - для работы с VINS

    Доступные методы для .CloudBroker():

    • .Account() - для работы с Account
    • .Audit() - для работы с Audit
    • .APIAccess() - для работы с APIAccess
    • .Backup() - для работы с Backup
    • .Compute() - для работы с Compute
    • .Disks() - для работы с Disks
    • .DPDKNet() - для работы с DPDK
    • .ExtNet() - для работы с ExtNet
    • .FLIPGroup() - для работы с FLIPGroup
    • .Grid() - для работы с Grid
    • .Group() - для работы с Group
    • .Image() - для работы с Image
    • .K8CI() - для работы с K8CI
    • .K8S() - для работы с K8S
    • .KVMx86() - для работы с KVMX86
    • .LB() - для работы с LB
    • .Node() - для работы с Node
    • .PCIDevice() - для работы с PCIDevice
    • .RG() - для работы с RG
    • .SEP() - для работы с SEP
    • .Stack() - для работы с Stack
    • .Tasks() - для работы с Tasks
    • .User() - для работы с User
    • .VGPU() - для работы с VGPU
    • .VFPool() - для работы с VFPool
    • .VINS() - для работы с VINS
  3. Вызвать метод, отвечающий за выполнение запроса и передать в него:

  • контекст;
  • структуру запроса. У каждой группы ручек API имеются свои доступные методы, которые определяются платформой.
  1. Обработать результат и ошибки.

Т.к. все вызовы методов идут последовательно, можно их объеденить в конвейер: Общий вид конвейера будет выглядеть так:

  client.<API>.<группа>.<метод>

Пример выполнения запроса

package main

import (
    "log"
    "fmt"

    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
    decort "repository.basistech.ru/BASIS/decort-golang-sdk"
    "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/kvmx86"
)

func main() {
    // Настройка конфигурации
    cfg := config.Config{
        AppID:     "<APPID>",
        AppSecret: "<APPSECRET>",
        SSOURL:    "https://sso.digitalenergy.online",
        DecortURL: "https://mr4.digitalenergy.online",
        Retries:   5,
    }

    // Создание клиента
    client := decort.New(cfg)

    // Создание структуры запроса
    // CreateRequest - реквест на создание виртуальной машины
    req := kvmx86.CreateRequest{
        RGID:    123,
        Name:    "compute",
        CPU:     4,
        RAM:     4096,
        ImageID: 321,
    }

    //Выполнение запроса с помощью конвейера
    res, err := client.CloudAPI().KVMX86().Create(context.Background(), req)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(res)
}

Для запросов Get и List реализованы запросы GetRaw и ListRaw, которые возвращают ответ не в виде соответствующей структуры, а в виде массива байт (JSON). Выполнение таких запросов происходит аналогично.

Пример выполнения GetRaw и ListRaw запросов

package main

import (
    "log"
    "fmt"

    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
    decort "repository.basistech.ru/BASIS/decort-golang-sdk"
    "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account"
)

func main() {
    // Настройка конфигурации
    cfg := config.Config{
        AppID:     "<APPID>",
        AppSecret: "<APPSECRET>",
        SSOURL:    "https://sso.digitalenergy.online",
        DecortURL: "https://mr4.digitalenergy.online",
        Retries:   5,
    }

    // Создание клиента
    client := decort.New(cfg)

    // 1. Создание структуры запроса GetRequest на получение информации об аккаунте и выполнение GetRaw запроса с помощью конвейера
    req1 := account.GetRequest{
        AccountID:    123,
    }
    res1, err := client.CloudAPI().Account().GetRaw(context.Background(), req1)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(res1))

    // 2. Создание структуры запроса ListRequest на получение информации об аккаунтах и выполнение ListRaw запроса с помощью конвейера
    req2 := account.ListRequest{}
    res2, err := client.CloudAPI().Account().ListRaw(context.Background(), req2)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(res2))
}

Фильтрация

Для каждого ListRequest в SDK есть группа функций для фильтрации ответа платформы. Для того чтобы произвести фильтрацию по заданным полям, достаточно описать анонимную функцию (предикат) в .FilterFunc(), например:

// Создание запроса account/list
req := account.ListRequest{}

resp, err := client.CloudAPI().Account().List(context.Background(), req)
if err != nil {
	log.Fatal(err)
}

// Тип filtered - ListAccount, тот же, что и у ответа платформы.
filtered := resp.
	FilterFunc(func(ia account.ItemAccount) bool {
	// ItemAccount открывает доступ к полям модели ответа платформы.
		for _, itemAcl := range ia.ACL {
			if itemAcl.UgroupID == "<UserGroupID>" { // Фильтр по ACL/UgroupID
				return true
			}
		}
		return false
	})

Для удобства пользователей, особенно важные фильтры вынесены в отдельные функции, что облегчает фильтрацию сразу по нескольким полям:

// Создание запроса account/list
req := account.ListRequest{}

resp, err := client.CloudAPI().Account().List(context.Background(), req)
if err != nil {
	log.Fatal(err)
}

// Несколько фильтров объединены в конвейер
filtered := resp.
	FilterByName("<NAME>").
	FilterByStatus("<STATUS>")
	// ....

Также у compute, disks, и lb присутствуют специфические функции фильтрации, отправляющие дополнительные запросы. В качестве параметров принимают:

  • context.Context - контекст для доп. запроса
  • id (или другое поле, по которому производится фильтрация)
  • interfaces.Caller - DECORT-клиент для запроса

Так как эти функции возвращают не только результирующий слайс, но и возможную ошибку - конвейер придется прервать для обработки ошибки.

Использование на примере compute.FilterByK8SID:

func main() {
    // Чтение конфигурации из файла
    cfg, _ :=  config.ParseConfigJSON("<PATH>")

    // Создание клиента
    client := decort.New(cfg)

    // Создание структуры запроса compute/list
    req := compute.ListRequest{}

    // Запрос
    resp, err := client.CloudAPI().Compute().List(context.Background(), req)
    if err != nil {
        log.Fatal(err)
    }

    // Фильтрация по id кластера.
    // Первый аргумент - контекст
    // Второй - ID кластера
    // Третий - DECORT-клиент
    filtered, err := resp.FilterByK8SID(context.Background(), <k8sID>, client)
    if err != nil {
        log.Fatal(err) // Возможная ошибка запроса
    }

    // Доп. фильтрация и сортировка результата - worker ноды кластера
    workers := filtered.FilterByK8SWorkers().SortByCreatedTime(false)

    // Доп. фильтрация и сортировка результата - master ноды кластера
    masters := filtered.FilterByK8SMasters().SortByCreatedTime(true)

    // ....
}

Сортировка

Функции сортировки так же могут быть объединены в конвейер:

// Создание запроса compute/list
req := compute.ListRequest{}

resp, err := client.CloudAPI().Compute().List(context.Background(), req)
if err != nil {
	log.Fatal(err)
}

// Функции сортировки имеют параметр inverse (bool):
// При значении false -> сортировка по возрастанию
// При true -> сортировка по убыванию
sorted := resp.
	SortByCPU(false).
	SortByRAM(false).
	SortByCreatedTime(true)
	// ....

Сериализация

Результат преобразований легко сериализовать в JSON при помощи функции .Serialize(). Она принимает в себя 2 необязательных аргумента: префикс (prefix) и отступ (Indent).

В случае если функция вызывается без аргументов, то маршализация пройдет успешно, но без отступов и префиксов.

// Сериализация данных с префиксом "" и отступом "\t"
serialized, err := filtered.Serialize("", "\t")
if err != nil {
	log.Fatal(err)
}

// Запись сериализованных данных в файл
err = serialized.WriteToFile("<PATH>")
if err != nil {
	log.Fatal(err)
}

Комплексный пример

package main

import (
	"context"
	"log"

	decort "repository.basistech.ru/BASIS/decort-golang-sdk"
	"repository.basistech.ru/BASIS/decort-golang-sdk/config"
	"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute"
)

func main() {
	cfg := config.Config{
		AppID:         "<APP_ID>",
		AppSecret:     "<APP_SECRET>",
		SSOURL:        "<SSO_URL>",
		DecortURL:     "<DECORT_URL>",
		Retries:       5,
	}

	cfg.SetTimeout(5 * time.Minute)
	
	// Создание клиента
	client := decort.New(cfg)

	// Создание запроса compute/list
	req := compute.ListRequest{}

	resp, err := client.CloudBroker().Compute().List(context.Background(), req)
	if err != nil {
		log.Fatal(err)
	}

	// Цепь преобразований.
	filtered, _ := resp.
        FilterFunc(func(ic compute.ItemCompute) bool {
            return ic.GUID == 123 // Фильтр по GUID
        }).
        FilterByName("<NAME>"). // Фильтр по имени
        SortByCPU(false). // Сортировка по кол-ву ядер CPU по возрастанию
        SortByCreatedTime(true). // Сортировка по времени создания по убыванию
        Serialize("", "\t") // Сериализация с префиксом "" и отступом "\t"
        // Serialize - терминальная функция, возвращает Serialized (обертку над []byte)

	// Запись данных в файл
    err = filtered.WriteToFile("<PATH>")
	if err != nil {
		log.Fatal(err)
	}
}

Получение списка уникальных идентификаторов ID объекта

Для всех структур, имеющих поля со списками объектов с уникальными числовыми идентификаторами (ID), добавлены методы IDs(), возвращающие массивы уникальных идентификаторов объектов в этих списках.

package main

import (
    "log"
    "fmt"

    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
    decort "repository.basistech.ru/BASIS/decort-golang-sdk"
    "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/bservice"
)

func main() {
    // Настройка конфигурации
    cfg := config.Config{
        AppID:     "<APPID>",
        AppSecret: "<APPSECRET>",
        SSOURL:    "https://sso.digitalenergy.online",
        DecortURL: "https://mr4.digitalenergy.online",
        Retries:   5,
    }

    // Создание клиента
    client := decort.New(cfg)

    // Создание структуры запроса GetRequest на получение информации о сервисе и выполнение запроса с помощью конвейера
    req := bservice.GetRequest{
        ServiceID:    123,
    }
    res, err := client.CloudAPI().BService().Get(context.Background(), req)
    if err != nil {
        log.Fatal(err)
    }
	
    // Получение списков ID ComputeIDs и GroupIDs экземпляра res типа RecordBasicService по полям Computes и Groups, соответственно
    computeIDs := res.Computes.IDs()
    groupIDs := res.Groups.IDs()
    fmt.Println(computeIDs)
    fmt.Println(groupIDs)
}

Методы поля Result для группы tasks

Поле Result внутри структур группы tasks имеет тип интерфейс и может содержать:

  • строку о результате выполнения задачи, например true
  • массив, содержащий ID и имя созданного ресурса, например [12345, "resource_name"]
  • массив, содержащий информацию о восстновленных дисках, например [{"computeId": 123, "diskId": 456}, {"computeId": 789, "diskId": 10}]

Соответственно, для получения информации из поля Result доступны следующие методы:

  • ToString(): строковое представление результата выполнения задачи
  • ID() и Name(): получение ID и имени созданного в результате выполнения задачи ресурса
  • ToMaps(): получение списка карт, содержащих информацию о дисках, восстановленных в результате выполнения задачи. Все методы оборудованы возвратом ошибок. Непустая ошибка означает, что из поля Result нельзя получить информацию, которую предоставляет метод.
package main

import (
    "log"
    "fmt"

    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
    decort "repository.basistech.ru/BASIS/decort-golang-sdk"
    "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks"
	tasks_cb "repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/tasks"
)

func main() {
    // Настройка конфигурации
    cfg := config.Config{
        AppID:     "<APPID>",
        AppSecret: "<APPSECRET>",
        SSOURL:    "https://sso.digitalenergy.online",
        DecortURL: "https://mr4.digitalenergy.online",
        Retries:   5,
    }

    // Создание клиента
    client := decort.New(cfg)

    // Создание структуры запроса GetRequest на получение информации о конкретной задаче и выполнение запроса с помощью конвейера
    getReq := tasks.GetRequest{
		AuditID: "b6316",
    }
    task, err := client.CloudAPI().Tasks().Get(context.Background(), getReq)
    if err != nil {
        log.Fatal(err)
    }

	// Получение списка карт с информацией о восстановленных дисках
	maps, err := task.Result.ToMaps()
	if err != nil {
		log.Fatal(err)
    }
	fmt.Println(maps)
	
	// Получение строкового результата выполнения задачи task
	res, _ := task.Result.ToString()
	fmt.Println(res)

	// Создание структуры запроса ListRequest на получение информации о всех задачах и выполнение запроса с помощью конвейера
	listReq := tasks_cb.ListRequest{}
	tasks, err := client.CloudBroker().Tasks().List(context.Background(), listReq)
	if err != nil {
		log.Fatal(err)
	}
	
	for _, t := range tasks {
		// Получение id ресурса, созданного в результате выполнения задачи t
		id, err := task.Result.ID()
		if err != nil {
			log.Fatal(err)
        }
		fmt.Println(id)

		// Получение имени ресурса, созданного в результате выполнения задачи t
		name, _ := task.Result.Name()
		fmt.Println(name)
    }
}

Работа с legacy клиентом

Работа с legacy клиентом применяется для пользователей, которые не используют для авторизации decs3o.

Настройка конфигурации legacy клиента

Сначала, необходимо создать переменную конфигурации клиента. Конфигурация состоит как из обязательных, так и необязательных полей.

Поле Тип Обязательный Описание
Username string Да username legacy пользователя
Password string Да пароль legacy пользователя
DecortURL string Да URL адрес платформы, с которой будет осуществляться взаимодействие
Retries uint Нет Кол-во неудачных попыток выполнения запроса, по умолчанию - 5
Timeout config.Duration Нет Таймаут HTTP клиента, по умолчанию - без ограничений
SSLSkipVerify bool Нет Пропуск проверки подлинности сертификата
Token string Нет JWT токен

Пример конфигурации legacy клиента

import (
    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
)

func main(){
    // Настройка конфигурации
    legacyCfg := config.LegacyConfig{
        Username:  "<USERNAME>",
        Password:  "<PASSWORD>",
        DecortURL: "https://mr4.digitalenergy.online",
        Retries:   5,
    }

    legacyCfg.SetTimeout(5 * time.Minute)
}

Парсинг legacy конфигурации из файла

Также возможно создать переменную конфигурации из JSON или YAML файла, используя функцию ParseLegacyConfigJSON (или ParseLegacyConfigYAML) из пакета config.
См. пример файлов конфигурации ниже и в директории samples/.

import (
	"repository.basistech.ru/BASIS/decort-golang-sdk/config"
)

func main() {
	// Парсинг конфигурации из YAML-файла
	legacyCfg, _ := config.ParseLegacyConfigYAML("<PATH>")
}

Пример legacy JSON конфигурации

{
    "username": "<USERNAME>",
    "password": "<PASSWORD>",
    "decortUrl": "https://mr4.digitalenergy.online",
    "retries": 5,
    "timeout": "5m",
    "sslSkipVerify": true
}

Пример legacy YAML конфигурации

username: <USERNAME>
password: <PASSWORD>
decortUrl: https://mr4.digitalenergy.online
retries: 5
timeout: 5m
sslSkipVerify: true

Создание legacy клиента

Создание клиента происходит с помощью функции-строителя NewLegacy из основного пакета decort-sdk, для избежания проблем с именами, пакету можно присвоить алиас decort. Функция принимает конфигурацию, возвращает структуру DecortClient, с помощью которой можно взаимодействовать с платформой.

Пример создания legacy клиента

package main

import (
    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
    decort "repository.basistech.ru/BASIS/decort-golang-sdk"
)

func main() {
    // Настройка конфигурации
    legacyCfg := config.LegacyConfig{
        Username:  "<USERNAME>",
        Password:  "<PASSWORD>",
        DecortURL: "https://mr4.digitalenergy.online",
        Retries:   5,
    }

    legacyCfg.SetTimeout(5 * time.Minute)

    // Создание клиента
    legacyClient := decort.NewLegacy(legacyCfg)
}

Пример выполнения запроса

package main

import (
	"fmt"

    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
    decort "repository.basistech.ru/BASIS/decort-golang-sdk"
)

func main() {
    // Настройка конфигурации
    legacyCfg := config.LegacyConfig{
        Username:  "<USERNAME>",
        Password:  "<PASSWORD>",
        Domain:    "dynamix",
        DecortURL: "https://mr4.digitalenergy.online",
        Retries:   5,
    }

    // Создание клиента
    legacyClient := decort.NewLegacy(legacyCfg)
    
    // Создание структуры запроса
    // CreateRequest - реквест на создание виртуальной машины
    req := kvmx86.CreateRequest{
        RGID:    123,
        Name:    "compute",
        CPU:     4,
        RAM:     4096,
        ImageID: 321,
    }

    // Выполнение запроса
    res, err := legacyClient.CloudAPI().KVMX86().Create(context.Background(), req)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(res)
}

Работа с BVS клиентом

Работа с BVS клиентом применяется для пользователей, которые используют для авторизации BVS.

Настройка параметров BVS в кабинете администратора

Для корректной работы функции обновления токена необходимо соблюдать следующие условия:

на странице администратора по следующему пути: домены-<имя вашего домена>-(символ i)-токены

  • параметр "Время жизни токена доступа" - устанавливается для всего домена. Не применяется есть по следующему пути: безопасность-клиентские_системы-(символ i)-токены-"Время жизни токена доступа" не выставлено иное время, которое имеет больший приоритет для конкретной клиентской системы
  • параметр "Время простоя сессии" - время жизни токена обновления. В случае указания количества минут меньше, чем время жизни токена, то обновление токена будет работать некорректно. Редомендуется указывать время или равное или больше времени жизни токена
  • параметр "Максимальное время жизни сессии" - время в течение которого возможно производить обновление токена. Если данный параметр будет равен времени жизни токена, то обновление токена будет работать некорректно. Редомендуется указывать время больше времени жизни токена

Настройка конфигурации BVS клиента

Сначала, необходимо создать переменную конфигурации клиента. Конфигурация состоит как из обязательных, так и необязательных полей.

Поле Тип Обязательный Описание
Username string Да username пользователя
Password string Да пароль пользователя
AppID string Да app_id ключа для выполнения запросов
AppSecret string Да app_secret ключ для выполнения запроса
DecortURL string Да URL адрес платформы, с которой будет осуществляться взаимодействие
SSOURL string Да URL адрес сервиса аутентификации и авторизации
Domain string Да Имя домена
Retries uint Нет Кол-во неудачных попыток выполнения запроса, по умолчанию - 5
Timeout config.Duration Нет Таймаут HTTP клиента, по умолчанию - без ограничений
SSLSkipVerify bool Нет Пропуск проверки подлинности сертификата
Token struct{} см. ниже Нет JWT токен
PathCfg string Нет Путь записи конфигурации в файл
PathToken string Нет Путь записи токена в файл
TimeToRefresh uint Нет Количество минут, за сколько до истечения срока действия токена выполнится его обновление, по умолчанию - 1 минута

Описание структуры token

Параметр Тип Описание
AccessToken string Токен
TokenType string Тип токена
RefreshToken string Токен для запроса на обновление
Expiry time Время жизни токена

Пример конфигурации BVS клиента

import (
    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
)

func main(){
    // Настройка конфигурации
    BvsCfg := config.BVSConfig{
        AppID:     "<APP_ID>",
        AppSecret: "<APP_SECRET>",
        Username:  "<USERNAME>",
        Password:  "<PASSWORD>",
        SSOURL:    "https://bvs-delta.qa.loc:8443",
        DecortURL: "https://delta.qa.loc",
        Domain:    "dynamix",
        Retries:   5,
    }

    BvsCfg.SetTimeout(5 * time.Minute)
}

Парсинг BVS конфигурации из файла

Также возможно создать переменную конфигурации из JSON или YAML файла, используя функцию ParseConfigBVSJSON (или ParseConfigBVSYAML) из пакета config.
См. пример файлов конфигурации ниже и в директории samples/.

import (
	"repository.basistech.ru/BASIS/decort-golang-sdk/config"
)

func main() {
	// Парсинг конфигурации из YAML-файла
	BVSCfg, _ := config.ParseConfigBVSYAML("<PATH>")
}

Парсинг BVS токена из файла

Также возможно создать переменную токена из JSON или YAML файла, используя функцию ParseTokenBVSJSON (или ParseTokenBVSYAML) из пакета config.
См. пример файлов конфигурации ниже и в директории samples/.

import (
	"repository.basistech.ru/BASIS/decort-golang-sdk/config"
)

func main() {
	// Парсинг токена из json-файла
	BVSToken, _ := config.ParseTokenBVSJSON("<PATH>")
}

Пример BVS JSON конфигурации

{
    "username": "<USERNAME>",
    "password": "<PASSWORD>",
    "appId": "<APP_ID>",
    "appSecret": "<APP_SECRET>",
    "ssoUrl": "https://bvs-delta.qa.loc:8443",
    "decortUrl": "https://delta.qa.loc",
    "domain":    "dynamix",
    "token": {
        "access_token": "string_token",
        "token_type": "bearer",
        "refresh_token": "string_refresh_token",
        "expiry": "2023-11-24T12:40:27.954150524+03:00"
    },
    "retries": 5,
    "sslSkipVerify": true,
    "timeout": "5m",
    "path_cfg": "config",
    "path_token": "token",
    "timeToRefresh": 5
}

Пример BVS YAML конфигурации

    username: <USERNAME>
    password: <PASSWORD>
    appId: <APP_ID>
    appSecret: <APP_SECRET>
    ssoUrl: https://bvs-delta.qa.loc:8443
    decortUrl: https://delta.qa.loc
    domain:    dynamix
    token": 
    access_token: string_token
    token_type: bearer
    refresh_token: string_refresh_token
    expiry: 2023-11-24T12:40:27.954150524+03:00
    retries: 5
    sslSkipVerify: true
    timeout: 5m
    path_cfg: config
    path_token: token
    timeToRefresh: 5

Создание BVS клиента

Создание клиента происходит с помощью функции-строителя NewBVS из основного пакета decort-sdk, для избежания проблем с именами, пакету можно присвоить алиас decort. Функция принимает конфигурацию, возвращает структуру DecortClient, с помощью которой можно взаимодействовать с платформой.

Пример создания BVS клиента

package main

import (
    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
    decort "repository.basistech.ru/BASIS/decort-golang-sdk"
)

func main() {
    // Настройка конфигурации
    BVSCfg := config.BVSConfig{
        Username:  "<USERNAME>",
        Password:  "<PASSWORD>",
        AppID:     "<APPID>",
        AppSecret: "<APPSECRET>",
        SSOURL:    "https://bvs-delta.qa.loc:8443",
        DecortURL: "https://mr4.digitalenergy.online",
        Domain:    "dynamix",
        Retries:   5,
    }

    BVSCfg.SetTimeout(5 * time.Minute)

    // Создание клиента
    BVSClient := decort.NewBVS(BVSCfg)
}

Пример получения BVS токена

В случае указания значения в переменной конфигурации PathCfg токен и конфигурация будут записаны в файл в формате json, переменная PathToken служит для записи токена в файл в формате json

package main

import (
	"fmt"

    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
    decort "repository.basistech.ru/BASIS/decort-golang-sdk"
)

func main() {
    // Настройка конфигурации
    BVSCfg := config.BVSConfig{
        Username:  "<USERNAME>",
        Password:  "<PASSWORD>",
        AppID:     "<APPID>",
        AppSecret: "<APPSECRET>",
        SSOURL:    "https://bvs-delta.qa.loc:8443",
        DecortURL: "https://mr4.digitalenergy.online",
        Domain:    "dynamix",
        PathCfg:   "config",
        Retries:   5,
    }

    // Создание клиента
    BVSClient := decort.NewBVS(BVSCfg)
    
    // Выполнение запроса на получение токена
    token, err := BVSClient.GetToken(context.Background())
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(token)
}

Пример обновления BVS токена

В случае указания значения в переменной конфигурации PathCfg обновленный токен и конфигурация будут записаны в файл в формате json, переменная PathToken служит для записи токена в файл в формате json

package main

import (
	"fmt"

    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
    decort "repository.basistech.ru/BASIS/decort-golang-sdk"
)

func main() {
    // Настройка конфигурации
    BVSCfg := config.BVSConfig{
        Username:  "<USERNAME>",
        Password:  "<PASSWORD>",
        AppID:     "<APPID>",
        AppSecret: "<APPSECRET>",
        SSOURL:    "https://bvs-delta.qa.loc:8443",
        DecortURL: "https://mr4.digitalenergy.online",
        Domain:    "dynamix",
        PathToken: "token",
        Retries:   5,
    }

    // Создание клиента
    BVSClient := decort.NewBVS(BVSCfg)
    
    // Выполнение запроса на обновление токена
    token, err := BVSClient.RefreshToken(context.Background())
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(token)
}

Пример выполнения запроса

package main

import (
	"fmt"

    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
    decort "repository.basistech.ru/BASIS/decort-golang-sdk"
)

func main() {
    // Настройка конфигурации
    BVSCfg := config.BVSConfig{
        Username:  "<USERNAME>",
        Password:  "<PASSWORD>",
        AppID:     "<APPID>",
        AppSecret: "<APPSECRET>",
        SSOURL:    "https://bvs-delta.qa.loc:8443",
        DecortURL: "https://mr4.digitalenergy.online",
        Domain:    "dynamix",
        Retries:   5,
    }

    // Создание клиента
    BVSClient := decort.NewBVS(BVSCfg)
    
    // Создание структуры запроса
    // CreateRequest - реквест на создание виртуальной машины
    req := kvmx86.CreateRequest{
        RGID:    123,
        Name:    "compute",
        CPU:     4,
        RAM:     4096,
        ImageID: 321,
    }

    // Выполнение запроса
    res, err := BVSClient.CloudAPI().KVMX86().Create(context.Background(), req)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(res)
}

Пример валидации запросов, имеющих в своей структуре поле RAM (или MasterRam/WorkerRAM)

Если структура запроса содержит поле RAM (или MasterRam/WorkerRAM), то он может быть проверен на валидность. Для этого запрос должен быть передан в функцию ValidateRAM. Вторым аргументом ValidateRAM ожидает число uint64. Рекомендуется использовать константу constants.RAM_DIVISIBILITY. Функция проверит кратно ли значение поля RAM (или MasterRam/WorkerRAM) этому числу.

Пример выполнения запроса

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	decort "repository.basistech.ru/BASIS/decort-golang-sdk"
	"repository.basistech.ru/BASIS/decort-golang-sdk/config"
	"repository.basistech.ru/BASIS/decort-golang-sdk/internal/constants"
	"repository.basistech.ru/BASIS/decort-golang-sdk/internal/validators"
	"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/kvmx86"
)

func main() {
	// Настройка конфигурации
	cfg := config.Config{
		AppID:         "<APPID>",
		AppSecret:     "<APPSECRET>",
		SSOURL:        "https://sso-delta.qa.loc:8443",
		DecortURL:     "https://delta.qa.loc",
		Retries:       5,
		SSLSkipVerify: true,
	}

	// Создание клиента
	client := decort.New(cfg)

	// Создание структуры запроса
	// CreateRequest - реквест на создание виртуальной машины
	req := kvmx86.CreateRequest{
		Name:    "kvmx86",
		RGID:    907,
		CPU:     2048,
		RAM:     1024,
		ImageID: 161,
	}

    // Валидация запроса
	err := validators.ValidateRAM(req, constants.RAM_DIVISIBILITY)
	if err != nil {
		log.Fatalf("unable to validate request: %v", err)
	}
	//Выполнение запроса с помощью конвейера
	res, err := client.CloudBroker().KVMX86().Create(context.Background(), req)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	log.Println(res)

}

Работа с универсальным клиентом

Работа с универсальным клиентом позволяет использовать любой тип авторизации

Настройка конфигурации универсального клиента

Параметр Тип Обязательный Описание
Decs3oConfig *Config Нет Конфигурация Decs3o
BVSConfig *BVSConfig Нет Конфигурация BVS
LegacyConfig string Нет Конфигурация Legacy

В универсальном клиенте можно использовать только один тип конфигурации одновременно.

Пример конфигурации универсального клиента

import (
    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
)

func main(){
    // Настройка конфигурации
    BVSConfig := config.BVSConfig{
        AppID:     "<APP_ID>",
        AppSecret: "<APP_SECRET>",
        SSOURL:    "https://sso.digitalenergy.online",
        DecortURL: "https://mr4.digitalenergy.online",
        Username:  "<Username>",
        Password:  "<Password>",
        Retries:   5,
    }

    BVSConfig.SetTimeout(5 * time.Minute)

    cfg := config.UniversalConfig{
		BVSConfig: &BVScfg,
	}
}

Создание универсального клиента

Создание клиента происходит с помощью функции-строителя NewUniversal из основного пакета decort-sdk, для избежания проблем с именами, пакету можно присвоить алиас decort. Функция принимает конфигурацию, возвращает структуру ClientInterface, с помощью которой можно взаимодействовать с платформой.

Пример создания универсального клиента

package main

import (
    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
    decort "repository.basistech.ru/BASIS/decort-golang-sdk"
)

func main() {
    // Настройка конфигурации
    legacyCfg := config.LegacyConfig{
        Username:  "<USERNAME>",
        Password:  "<PASSWORD>",
        DecortURL: "https://mr4.digitalenergy.online",
        Retries:   5,
    }

    legacyCfg.SetTimeout(5 * time.Minute)

    cfg := config.UniversalConfig{
        LegacyConfig: &legacyCfg,
	}

    // Создание клиента
    universalClient := decort.NewUniversal(cfg)
}

Пример выполнения запроса

package main

import (
	"fmt"

    "repository.basistech.ru/BASIS/decort-golang-sdk/config"
    decort "repository.basistech.ru/BASIS/decort-golang-sdk"
)

func main() {
    // Настройка конфигурации
    legacyCfg := config.LegacyConfig{
        Username:  "<USERNAME>",
        Password:  "<PASSWORD>",
        Domain:    "dynamix",
        DecortURL: "https://mr4.digitalenergy.online",
        Retries:   5,
    }

    legacyCfg.SetTimeout(5 * time.Minute)

    cfg := config.UniversalConfig{
	    LegacyConfig: &legacyCfg,
	}

    // Создание клиента
    universalClient := decort.NewUniversal(cfg)
    
    // Создание структуры запроса
    // CreateRequest - реквест на создание виртуальной машины
    req := kvmx86.CreateRequest{
        RGID:    123,
        Name:    "compute",
        CPU:     4,
        RAM:     4096,
        ImageID: 321,
    }

    // Выполнение запроса
    res, err := universalClient.CloudAPI().KVMX86().Create(context.Background(), req)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(res)
}