# 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 версии платформы ## Оглавление - [Decort SDK](#decort-sdk) - [Версии](#версии) - [Оглавление](#оглавление) - [Установка](#установка) - [Список API](#список-api) - [Cloudapi](#cloudapi) - [Cloudbroker](#cloudbroker) - [Работа с библиотекой](#работа-с-библиотекой) - [Настройка конфигурации клиента](#настройка-конфигурации-клиента) - [Пример конфигурации клиента](#пример-конфигурации-клиента) - [Парсинг конфигурации из файла](#парсинг-конфигурации-из-файла) - [Пример JSON конфигурации](#пример-json-конфигурации) - [Пример YAML конфигурации](#пример-yaml-конфигурации) - [Создание клиента](#создание-клиента) - [Пример](#пример) - [Создание структуры запроса](#создание-структуры-запроса) - [Пример комментариев структуры](#пример-комментариев-структуры) - [Пример создания запроса для развертывания виртуальной машины:](#пример-создания-запроса-для-развертывания-виртуальной-машины) - [Выполнение запроса](#выполнение-запроса) - [Пример выполнения запроса](#пример-выполнения-запроса) - [Пример выполнения GetRaw и ListRaw запросов](#пример-выполнения-getraw-и-listraw-запросов) - [Фильтрация](#фильтрация) - [Использование на примере `compute.FilterByK8SID`:](#использование-на-примере-computefilterbyk8sid) - [Сортировка](#сортировка) - [Сериализация](#сериализация) - [Комплексный пример](#комплексный-пример) - [Получение списка уникальных идентификаторов ID объекта](#получение-списка-уникальных-идентификаторов-id-объекта) - [Методы поля Result для группы tasks](#методы-поля-result-для-группы-tasks) - [Работа с legacy клиентом](#работа-с-legacy-клиентом) - [Настройка конфигурации legacy клиента](#настройка-конфигурации-legacy-клиента) - [Пример конфигурации legacy клиента](#пример-конфигурации-legacy-клиента) - [Парсинг legacy конфигурации из файла](#парсинг-legacy-конфигурации-из-файла) - [Пример legacy JSON конфигурации](#пример-legacy-json-конфигурации) - [Пример legacy YAML конфигурации](#пример-legacy-yaml-конфигурации) - [Создание legacy клиента](#создание-legacy-клиента) - [Пример создания legacy клиента](#пример-создания-legacy-клиента) - [Пример выполнения запроса](#пример-выполнения-запроса-1) - [Работа с BVS клиентом](#работа-с-bvs-клиентом) - [Настройка параметров BVS в кабинете администратора](#настройка-параметров-bvs-в-кабинете-администратора) - [Настройка конфигурации BVS клиента](#настройка-конфигурации-bvs-клиента) - [Описание структуры token](#описание-структуры-token) - [Пример конфигурации BVS клиента](#пример-конфигурации-bvs-клиента) - [Парсинг BVS конфигурации из файла](#парсинг-bvs-конфигурации-из-файла) - [Парсинг BVS токена из файла](#парсинг-bvs-токена-из-файла) - [Пример BVS JSON конфигурации](#пример-bvs-json-конфигурации) - [Пример BVS YAML конфигурации](#пример-bvs-yaml-конфигурации) - [Создание BVS клиента](#создание-bvs-клиента) - [Пример создания BVS клиента](#пример-создания-bvs-клиента) - [Пример получения BVS токена](#пример-получения-bvs-токена) - [Пример обновления BVS токена](#пример-обновления-bvs-токена) - [Пример выполнения запроса](#пример-выполнения-запроса-2) - [Пример валидации запросов, имеющих в своей структуре поле RAM (или MasterRam/WorkerRAM)](#пример-валидации-запросов-имеющих-в-своей-структуре-поле-ram-или-masterramworkerram) - [Пример выполнения запроса](#пример-выполнения-запроса-3) - [Работа с универсальным клиентом](#работа-с-универсальным-клиентом) - [Настройка конфигурации универсального клиента](#настройка-конфигурации-универсального-клиента) - [Пример конфигурации универсального клиента](#пример-конфигурации-универсального-клиента) - [Парсинг универсальной конфигурации из файла](#парсинг-универсальной-конфигурации-из-файла) - [Создание универсального клиента](#создание-универсального-клиента) - [Пример создания универсального клиента](#пример-создания-универсального-клиента) - [Пример выполнения запроса](#пример-выполнения-запроса-4) ## Установка Выполните команду в терминале: ```bash 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. Выполнение одного из действий: - настройка конфигурации клиента; - парсинг конфигурации из файла. 2. Создание клиента. 3. Создание структуры запроса. 4. Выполнение запроса. ### Настройка конфигурации клиента Сначала, необходимо создать переменную конфигурации клиента. Конфигурация состоит как из обязательных, так и необязательных полей. | Поле | Тип | Обязательный | Описание | | --- | --- | --- | --- | | 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 токен | ##### Пример конфигурации клиента ```go import ( "repository.basistech.ru/BASIS/decort-golang-sdk/config" ) func main(){ // Настройка конфигурации cfg := config.Config{ AppID: "", AppSecret: "", SSOURL: "https://sso.digitalenergy.online", DecortURL: "https://mr4.digitalenergy.online", Retries: 5, } cfg.SetTimeout(5 * time.Minute) } ``` #### Парсинг конфигурации из файла Также возможно создать переменную конфигурации из JSON или YAML файла, используя функцию `ParseConfigJSON` (или `ParseConfigYAML`) из пакета config.
*См. пример файлов конфигурации ниже и в директории `samples/`.* ```go import ( "repository.basistech.ru/BASIS/decort-golang-sdk/config" ) func main() { // Парсинг конфигурации из JSON-файла cfg, _ := config.ParseConfigJSON("") } ``` #### Пример JSON конфигурации ```json { "appId": "", "appSecret": "", "ssoUrl": "https://sso.digitalenergy.online", "decortUrl": "https://mr4.digitalenergy.online", "retries": 5, "timeout": "5m", "sslSkipVerify": false } ``` #### Пример YAML конфигурации ```yaml appId: appSecret: ssoUrl: https://sso.digitalenergy.online decortUrl: https://mr4.digitalenergy.online retries: 5 timeout: 5m sslSkipVerify: false ``` ### Создание клиента Создание клиента происходит с помощью функции-строителя `New` из основного пакета `decort-sdk`, для избежания проблем с именами, пакету можно присвоить алиас `decort`. Функция принимает конфигурацию, возвращает структуру `DecortClient`, с помощью которой можно взаимодействовать с платформой. ### Пример ```go 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: "", 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 в комментариях; - Доп. информация (допустимые значения, значения по умолчанию). #### Пример комментариев структуры ```go 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"` } ``` #### Пример создания запроса для развертывания виртуальной машины: ```go 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: "", 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 имеются свои доступные методы, которые определяются платформой. 4. Обработать результат и ошибки. Т.к. все вызовы методов идут последовательно, можно их объеденить в конвейер: Общий вид конвейера будет выглядеть так: ```go client..<группа>.<метод> ``` #### Пример выполнения запроса ```go 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: "", 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 запросов ```go 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: "", 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()`, например: ```go // Создание запроса 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 == "" { // Фильтр по ACL/UgroupID return true } } return false }) ``` Для удобства пользователей, особенно важные фильтры вынесены в отдельные функции, что облегчает фильтрацию сразу по нескольким полям: ```go // Создание запроса account/list req := account.ListRequest{} resp, err := client.CloudAPI().Account().List(context.Background(), req) if err != nil { log.Fatal(err) } // Несколько фильтров объединены в конвейер filtered := resp. FilterByName(""). FilterByStatus("") // .... ``` Также у `compute`, `disks`, и `lb` присутствуют специфические функции фильтрации, отправляющие дополнительные запросы. В качестве параметров принимают: - context.Context - контекст для доп. запроса - id (или другое поле, по которому производится фильтрация) - interfaces.Caller - DECORT-клиент для запроса Так как эти функции возвращают не только результирующий слайс, но и возможную ошибку - конвейер придется прервать для обработки ошибки. #### Использование на примере `compute.FilterByK8SID`: ```go func main() { // Чтение конфигурации из файла cfg, _ := config.ParseConfigJSON("") // Создание клиента 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(), , client) if err != nil { log.Fatal(err) // Возможная ошибка запроса } // Доп. фильтрация и сортировка результата - worker ноды кластера workers := filtered.FilterByK8SWorkers().SortByCreatedTime(false) // Доп. фильтрация и сортировка результата - master ноды кластера masters := filtered.FilterByK8SMasters().SortByCreatedTime(true) // .... } ``` ### Сортировка Функции сортировки так же могут быть объединены в конвейер: ```go // Создание запроса 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). В случае если функция вызывается без аргументов, то маршализация пройдет успешно, но без отступов и префиксов. ```go // Сериализация данных с префиксом "" и отступом "\t" serialized, err := filtered.Serialize("", "\t") if err != nil { log.Fatal(err) } // Запись сериализованных данных в файл err = serialized.WriteToFile("") if err != nil { log.Fatal(err) } ``` #### Комплексный пример ```go 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: "", AppSecret: "", SSOURL: "", DecortURL: "", 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(""). // Фильтр по имени SortByCPU(false). // Сортировка по кол-ву ядер CPU по возрастанию SortByCreatedTime(true). // Сортировка по времени создания по убыванию Serialize("", "\t") // Сериализация с префиксом "" и отступом "\t" // Serialize - терминальная функция, возвращает Serialized (обертку над []byte) // Запись данных в файл err = filtered.WriteToFile("") if err != nil { log.Fatal(err) } } ``` ### Получение списка уникальных идентификаторов ID объекта Для всех структур, имеющих поля со списками объектов с уникальными числовыми идентификаторами (ID), добавлены методы IDs(), возвращающие массивы уникальных идентификаторов объектов в этих списках. ```go 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: "", 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 нельзя получить информацию, которую предоставляет метод. ```go 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: "", 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 клиента ```go import ( "repository.basistech.ru/BASIS/decort-golang-sdk/config" ) func main(){ // Настройка конфигурации legacyCfg := config.LegacyConfig{ Username: "", Password: "", DecortURL: "https://mr4.digitalenergy.online", Retries: 5, } legacyCfg.SetTimeout(5 * time.Minute) } ``` #### Парсинг legacy конфигурации из файла Также возможно создать переменную конфигурации из JSON или YAML файла, используя функцию `ParseLegacyConfigJSON` (или `ParseLegacyConfigYAML`) из пакета config.
*См. пример файлов конфигурации ниже и в директории `samples/`.* ```go import ( "repository.basistech.ru/BASIS/decort-golang-sdk/config" ) func main() { // Парсинг конфигурации из YAML-файла legacyCfg, _ := config.ParseLegacyConfigYAML("") } ``` #### Пример legacy JSON конфигурации ```json { "username": "", "password": "", "decortUrl": "https://mr4.digitalenergy.online", "retries": 5, "timeout": "5m", "sslSkipVerify": true } ``` #### Пример legacy YAML конфигурации ```yaml username: password: decortUrl: https://mr4.digitalenergy.online retries: 5 timeout: 5m sslSkipVerify: true ``` ### Создание legacy клиента Создание клиента происходит с помощью функции-строителя `NewLegacy` из основного пакета `decort-sdk`, для избежания проблем с именами, пакету можно присвоить алиас `decort`. Функция принимает конфигурацию, возвращает структуру `DecortClient`, с помощью которой можно взаимодействовать с платформой. #### Пример создания legacy клиента ```go 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: "", Password: "", DecortURL: "https://mr4.digitalenergy.online", Retries: 5, } legacyCfg.SetTimeout(5 * time.Minute) // Создание клиента legacyClient := decort.NewLegacy(legacyCfg) } ``` #### Пример выполнения запроса ```go 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: "", 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{} [см. ниже](#описание-структуры-token)| Нет | JWT токен | | PathCfg | string | Нет | Путь записи конфигурации в файл | | PathToken | string | Нет | Путь записи токена в файл | | TimeToRefresh | uint | Нет | Количество минут, за сколько до истечения срока действия токена выполнится его обновление, по умолчанию - 1 минута | ### Описание структуры token | Параметр | Тип | Описание | | ------------ | ------ | ------------------------------- | | AccessToken | string | Токен | | TokenType | string | Тип токена | | RefreshToken | string | Токен для запроса на обновление | | Expiry | time | Время жизни токена | #### Пример конфигурации BVS клиента ```go import ( "repository.basistech.ru/BASIS/decort-golang-sdk/config" ) func main(){ // Настройка конфигурации BvsCfg := config.BVSConfig{ AppID: "", AppSecret: "", Username: "", 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/`.* ```go import ( "repository.basistech.ru/BASIS/decort-golang-sdk/config" ) func main() { // Парсинг конфигурации из YAML-файла BVSCfg, _ := config.ParseConfigBVSYAML("") } ``` #### Парсинг BVS токена из файла Также возможно создать переменную токена из JSON или YAML файла, используя функцию `ParseTokenBVSJSON` (или `ParseTokenBVSYAML`) из пакета config.
*См. пример файлов конфигурации ниже и в директории `samples/`.* ```go import ( "repository.basistech.ru/BASIS/decort-golang-sdk/config" ) func main() { // Парсинг токена из json-файла BVSToken, _ := config.ParseTokenBVSJSON("") } ``` #### Пример BVS JSON конфигурации ```json { "username": "", "password": "", "appId": "", "appSecret": "", "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 конфигурации ```yaml username: password: appId: appSecret: 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 клиента ```go 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: "", Password: "", AppID: "", 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` ```go 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: "", Password: "", AppID: "", 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` ```go 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: "", Password: "", AppID: "", 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) } ``` #### Пример выполнения запроса ```go 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: "", Password: "", AppID: "", 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) этому числу. #### Пример выполнения запроса ```go 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: "", 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 | В универсальном клиенте можно использовать только один тип конфигурации одновременно. #### Пример конфигурации универсального клиента ```go import ( "repository.basistech.ru/BASIS/decort-golang-sdk/config" ) func main(){ // Настройка конфигурации BVSConfig := config.BVSConfig{ AppID: "", AppSecret: "", SSOURL: "https://sso.digitalenergy.online", DecortURL: "https://mr4.digitalenergy.online", Username: "", Password: "", Retries: 5, } BVSConfig.SetTimeout(5 * time.Minute) cfg := config.UniversalConfig{ BVSConfig: &BVScfg, } } ``` #### Создание универсального клиента Создание клиента происходит с помощью функции-строителя `NewUniversal` из основного пакета `decort-sdk`, для избежания проблем с именами, пакету можно присвоить алиас `decort`. Функция принимает конфигурацию, возвращает структуру `ClientInterface`, с помощью которой можно взаимодействовать с платформой. #### Пример создания универсального клиента ```go 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: "", Password: "", DecortURL: "https://mr4.digitalenergy.online", Retries: 5, } legacyCfg.SetTimeout(5 * time.Minute) cfg := config.UniversalConfig{ LegacyConfig: &legacyCfg, } // Создание клиента universalClient := decort.NewUniversal(cfg) } ``` #### Пример выполнения запроса ```go 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: "", 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) } ```