[Яндекс API] Как легко и быстро сделать создание snapshot'ов и их автоматическое удаление
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
История о том, как у меня была задача на решение которой ушло 2 дня. Обнаружилось несоответствие в документации и реальном мире яндекс облака в Яндекс писалось, но ответа не получилось.
Yandex.Cloud
Задача:
По расписанию, создавать SNAPSHOT дисков в используемых instance. При этом должна быть возможность помечать диски, которые нужно подвергать процедуре резервного копирования, а какие нет.
Подзадачи:
- Snapshot’ы старше n дней должны автоматически удаляться из хранилища. При этом должна быть возможность изменять n.
- Snapshot’ы должны иметь человеко-читаемый вид названия. И соответствовать следующему шаблону:
%имя диска оригинала%-дата создания%-%уникальное имя диска%
Для того, чтобы в случае необходимости, человеку было очевидно из чего разворачивать новые машины. (в финальном варианте реализовано отдельным bash скриптом исполняемым со сторонней машины).
Ход выполнения:
В Y.cloud нет штатной функции выполняющей подобную задачу.
Решение — реализовать за счет function внутри самого Y.cloud, для экономии ресурсов. Для создания snapshot’ов была написана функция на NodeJS12
const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID;
async function handler(event, context) {
const snapshotService = new ycsdk.SnapshotService();
const diskService = new ycsdk.DiskService();
const diskList = await diskService.list({
folderId: FOLDER_ID,
});
for (const disk of diskList.disks) {
if ('snapshot' in disk.labels) {
snapshotService.create({
folderId: FOLDER_ID,
diskId: disk.id
});
}
}
}
exports.handler = handler;
*При вызове данной функции, нужно через окружение передать FODLER_ID и указать служебную учетную запись.
Далее добавляется вызов данной функции по расписанию. И задача решена.
Подзадача 1.
Первоначально было решено делать через такую же функцию NodeJS12
Логика работы: анализируем дату создания snapshot’a сравниваем с разницей между текущей датой и n и в случае превышения лимита – удаляем.
Для этого, обращаемся к официальной документации и видим, что параметр CreatedAt должен иметь тип string.
Ок. Пишем функцию, которая удалит snapshot’ы которые моложе 1 часа от рождения (для теста). Запускаем. Получаем ничего. Совсем ничего. Ни ошибки в поле вывода ошибок, но нужного нам действия.
Итерация 1.
const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID;
const date = new Date();
date.setHours( date.getHours() - 1 );
async function handler(event, context) {
const snapshotService = new ycsdk.SnapshotService();
const {snapshots} = await snapshotService.list({folderId: FOLDER_ID});
for ( let snapshot in snapshots ) {
const dateSnapshot = new Date( snapshot.createdAt );
if ( dateSnapshot.getTime() > date.getTime() ) snapshotService.delete({snapshotId: snapshot.id});
}
}
exports.handler = handler;
Итерация 2.
Изменяем функцию так, чтобы она в теле ошибки вывела нам ответное сообщение.
const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID;
const date = new Date();
date.setHours( date.getHours() - 1 );
async function handler(event, context) {
const snapshotService = new ycsdk.SnapshotService();
const {snapshots} = await snapshotService.list({folderId: FOLDER_ID});
throw Error( JSON.stringify( snapshots ) );
}
exports.handler = handler;
Получаем в ответ ошибку:
«"errorMessage": "[{"labels":{},"productIds":[],"id":"fd813o0n3p753lhqphie","folderId":"b1gfub3omefcfvchsd0f","createdAt":{"seconds":{"low":1594137358,"high":0,"unsigned":false}},"diskSize":{"low":1073741824,"high":0,"unsigned":false},"status":2,"sourceDiskId":"ef3ivjn6340h9e8incbq"},…..»
Причесав который, мы видим следующее:
{
"labels": {},
"productIds": [],
"id": "fd813o0n3p753lhqphie",
"folderId": "b1gfub3omefcfvchsd0f",
"createdAt": {
"seconds": {
"low": 1594137358,
"high": 0,
"unsigned": false
}
Отсюда делаем заключение. CreatedAt не строка а, объект.
Итерация3.
Пытаемся работать с CreatedAt. Меняем функцию.
const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID;
const date = new Date();
date.setHours( date.getHours() - 1 );
async function handler(event, context) {
const snapshotService = new ycsdk.SnapshotService();
const {snapshots} = await snapshotService.list({folderId: FOLDER_ID});
for ( let snapshot in snapshots ) {
if ( snapshot.createdAt.seconds.low > date.getTime() / 1000 ) {
snapshotService.delete({snapshotId: snapshot.id});
}
}
}
exports.handler = handler;
Получаем ошибку:
{
"errorMessage": "Cannot read property 'seconds' of undefined",
"errorType": "TypeError",
"stackTrace": [
{
"function": "Runtime.handler",
"file": "/function/code/index.js",
"line": 14,
"column": 29
}
]
Ошибка говорит нам о том, мы пытаемся взять свойство seconds у несуществующего объекта, хотя ранее мы наблюдали вывод свойств объекта ответа "createdAt":{"seconds":{"low":1594137358,"high":0,"unsigned":false}}
Итерация 4.
const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID;
const date = new Date();
date.setHours( date.getHours() - 1 );
async function handler(event, context) {
const snapshotService = new ycsdk.SnapshotService();
const {snapshots} = await snapshotService.list({folderId: FOLDER_ID});
for ( let i = 0; i < 5; i++ ) {
throw Error( JSON.stringify( snapshots[i].createdAt ) );
}
}
exports.handler = handler;
Получаем ошибку:
{
"errorMessage": "{"seconds":{"low":1594137358,"high":0,"unsigned":false}}",
"errorType": "Error",
"stackTrace": [
{
"function": "Runtime.handler",
"file": "/function/code/index.js",
"line": 13,
"column": 11
}
]
}
Сократили цикл до 5 итераций для удобства.
Итерация 5.
const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID;
const date = new Date();
date.setHours( date.getHours() - 1 );
async function handler(event, context) {
const snapshotService = new ycsdk.SnapshotService();
const {snapshots} = await snapshotService.list({folderId: FOLDER_ID});
const list = [];
list.push( date.getTime() / 1000 );
for ( let i in snapshots ) {
const d = new Date( snapshots[i].createdAt );
list.push( d.getTime() / 1000 );
}
throw Error( JSON.stringify( list ) );
}
exports.handler = handler;
;
Получаем ошибку:
{
"errorMessage": "[1594135869.705,null,null,null,null,null,null,null]",
"errorType": "Error",
"stackTrace": [
{
"function": "Runtime.handler",
"file": "/function/code/index.js",
"line": 18,
"column": 9
}
]
}
Этот ответ говорит нам о том, что функция Date не смогла распарсить якобы строку свойства createdAt, которая должна содержать дату и время в виде строки, согласно документации.
Итого — в платформе Яндекс Облако найдено еще одно не соответствие документации и реального положения дел. Если у вас стоит такая же задача как у меня, вы можете теперь не тратить на это целый рабочий день.
===========
Источник:
habr.com
===========
Похожие новости:
- [Ajax, PHP, MySQL, JavaScript, jQuery] Пишем комментарии для сайта на чистом PHP + MySQL + Ajax
- [VueJS, Разработка веб-сайтов] Переключение шаблона страниц во vuejs
- [JavaScript, Node.JS, PostgreSQL, ReactJS] Javascript платформа Objectum
- [Информационная безопасность, Разработка веб-сайтов, ВКонтакте API, Конференции, Дизайн игр] 27 августа приглашаем на онлайн-митап Hot Frontend
- [ReactJS, Разработка веб-сайтов] Улучшаем useReducer
- [JavaScript, Node.JS, VueJS] Как мы проводили офлайн мероприятие в онлайн формате
- [GitHub, Python, SQLite, Алгоритмы, Веб-аналитика] Как проанализировать рынок фотостудий с помощью Python (2/3). База данных
- [Node.JS, TypeScript] Пишем свой dependency free WebSocket сервер на Node.js
- [JavaScript, ReactJS, Программирование, Разработка веб-сайтов] О роли фронтенд-разработчика (перевод)
- [JavaScript, Node.JS, Разработка веб-сайтов] Lock-файлы npm
Теги для поиска: #_jandeks_api (Яндекс API), #_y.cloud, #_js, #_bekap (бэкап), #_snapshot (снапшот), #_jandeks_api (
Яндекс API
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 00:12
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
История о том, как у меня была задача на решение которой ушло 2 дня. Обнаружилось несоответствие в документации и реальном мире яндекс облака в Яндекс писалось, но ответа не получилось. Yandex.Cloud Задача: По расписанию, создавать SNAPSHOT дисков в используемых instance. При этом должна быть возможность помечать диски, которые нужно подвергать процедуре резервного копирования, а какие нет. Подзадачи:
Для того, чтобы в случае необходимости, человеку было очевидно из чего разворачивать новые машины. (в финальном варианте реализовано отдельным bash скриптом исполняемым со сторонней машины). Ход выполнения: В Y.cloud нет штатной функции выполняющей подобную задачу. Решение — реализовать за счет function внутри самого Y.cloud, для экономии ресурсов. Для создания snapshot’ов была написана функция на NodeJS12 const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID; async function handler(event, context) { const snapshotService = new ycsdk.SnapshotService(); const diskService = new ycsdk.DiskService(); const diskList = await diskService.list({ folderId: FOLDER_ID, }); for (const disk of diskList.disks) { if ('snapshot' in disk.labels) { snapshotService.create({ folderId: FOLDER_ID, diskId: disk.id }); } } } exports.handler = handler; *При вызове данной функции, нужно через окружение передать FODLER_ID и указать служебную учетную запись. Далее добавляется вызов данной функции по расписанию. И задача решена. Подзадача 1. Первоначально было решено делать через такую же функцию NodeJS12 Логика работы: анализируем дату создания snapshot’a сравниваем с разницей между текущей датой и n и в случае превышения лимита – удаляем. Для этого, обращаемся к официальной документации и видим, что параметр CreatedAt должен иметь тип string. Ок. Пишем функцию, которая удалит snapshot’ы которые моложе 1 часа от рождения (для теста). Запускаем. Получаем ничего. Совсем ничего. Ни ошибки в поле вывода ошибок, но нужного нам действия. Итерация 1. const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID; const date = new Date(); date.setHours( date.getHours() - 1 ); async function handler(event, context) { const snapshotService = new ycsdk.SnapshotService(); const {snapshots} = await snapshotService.list({folderId: FOLDER_ID}); for ( let snapshot in snapshots ) { const dateSnapshot = new Date( snapshot.createdAt ); if ( dateSnapshot.getTime() > date.getTime() ) snapshotService.delete({snapshotId: snapshot.id}); } } exports.handler = handler; Итерация 2. Изменяем функцию так, чтобы она в теле ошибки вывела нам ответное сообщение. const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID; const date = new Date(); date.setHours( date.getHours() - 1 ); async function handler(event, context) { const snapshotService = new ycsdk.SnapshotService(); const {snapshots} = await snapshotService.list({folderId: FOLDER_ID}); throw Error( JSON.stringify( snapshots ) ); } exports.handler = handler; Получаем в ответ ошибку: «"errorMessage": "[{"labels":{},"productIds":[],"id":"fd813o0n3p753lhqphie","folderId":"b1gfub3omefcfvchsd0f","createdAt":{"seconds":{"low":1594137358,"high":0,"unsigned":false}},"diskSize":{"low":1073741824,"high":0,"unsigned":false},"status":2,"sourceDiskId":"ef3ivjn6340h9e8incbq"},…..» Причесав который, мы видим следующее: {
"labels": {}, "productIds": [], "id": "fd813o0n3p753lhqphie", "folderId": "b1gfub3omefcfvchsd0f", "createdAt": { "seconds": { "low": 1594137358, "high": 0, "unsigned": false } Отсюда делаем заключение. CreatedAt не строка а, объект. Итерация3. Пытаемся работать с CreatedAt. Меняем функцию. const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID; const date = new Date(); date.setHours( date.getHours() - 1 ); async function handler(event, context) { const snapshotService = new ycsdk.SnapshotService(); const {snapshots} = await snapshotService.list({folderId: FOLDER_ID}); for ( let snapshot in snapshots ) { if ( snapshot.createdAt.seconds.low > date.getTime() / 1000 ) { snapshotService.delete({snapshotId: snapshot.id}); } } } exports.handler = handler; Получаем ошибку: {
"errorMessage": "Cannot read property 'seconds' of undefined", "errorType": "TypeError", "stackTrace": [ { "function": "Runtime.handler", "file": "/function/code/index.js", "line": 14, "column": 29 } ] Ошибка говорит нам о том, мы пытаемся взять свойство seconds у несуществующего объекта, хотя ранее мы наблюдали вывод свойств объекта ответа "createdAt":{"seconds":{"low":1594137358,"high":0,"unsigned":false}} Итерация 4. const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID; const date = new Date(); date.setHours( date.getHours() - 1 ); async function handler(event, context) { const snapshotService = new ycsdk.SnapshotService(); const {snapshots} = await snapshotService.list({folderId: FOLDER_ID}); for ( let i = 0; i < 5; i++ ) { throw Error( JSON.stringify( snapshots[i].createdAt ) ); } } exports.handler = handler; Получаем ошибку: {
"errorMessage": "{"seconds":{"low":1594137358,"high":0,"unsigned":false}}", "errorType": "Error", "stackTrace": [ { "function": "Runtime.handler", "file": "/function/code/index.js", "line": 13, "column": 11 } ] } Сократили цикл до 5 итераций для удобства. Итерация 5. const ycsdk = require("yandex-cloud/api/compute/v1");
const FOLDER_ID = process.env.FOLDER_ID; const date = new Date(); date.setHours( date.getHours() - 1 ); async function handler(event, context) { const snapshotService = new ycsdk.SnapshotService(); const {snapshots} = await snapshotService.list({folderId: FOLDER_ID}); const list = []; list.push( date.getTime() / 1000 ); for ( let i in snapshots ) { const d = new Date( snapshots[i].createdAt ); list.push( d.getTime() / 1000 ); } throw Error( JSON.stringify( list ) ); } exports.handler = handler; ; Получаем ошибку: {
"errorMessage": "[1594135869.705,null,null,null,null,null,null,null]", "errorType": "Error", "stackTrace": [ { "function": "Runtime.handler", "file": "/function/code/index.js", "line": 18, "column": 9 } ] } Этот ответ говорит нам о том, что функция Date не смогла распарсить якобы строку свойства createdAt, которая должна содержать дату и время в виде строки, согласно документации. Итого — в платформе Яндекс Облако найдено еще одно не соответствие документации и реального положения дел. Если у вас стоит такая же задача как у меня, вы можете теперь не тратить на это целый рабочий день. =========== Источник: habr.com =========== Похожие новости:
Яндекс API ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 00:12
Часовой пояс: UTC + 5