Копилот для сисадмина
Использование различных AI помощников быстро и уверенно входит в нашу жизнь. Копилоты, ChatGPT, YandexGPT, GigaChat, Claude и все их «собратья» помогают писать маркетинговые тексты, редактировать фото и видео, создавать треки для роликов. А говоря про ИТ, мы, наверняка, сразу вспоминаем, например, про GitHub Copilot и AI во всех современных IDE, которые помогают писать код.
Сегодня же мы на конкретных примерах посмотрим, как AI может помочь в работе в процессе администрирования и эксплуатации отдельных серверов или даже больших сложных распределенных инфраструктур. И даже попробуем ответить на один из самых популярных вопросов — заменит ли собой AI обычных сисадминов.
Сразу оговоримся, что, конечно, никакого настоящего AI не существует, а этим термином мы для упрощения называем весь класс сервисов, которые, в основном, работают на базе языковых моделей (LLM, large language model).
Погнали!
Картинку сгенерил AI
Помощь в простых рутинных операциях
Некоторые команды в консоли пишутся практически «на автомате», слетая с кончиков пальцев. Те, которыми приходится пользоваться постоянно — ls, grep и т.д.
А бывают задачи, с которыми сталкиваешься реже. Не помнишь по памяти всех ключей запуска той или иной команды. Можно, конечно, почитать man или погуглить. Но с AI можно же быстрее! Попросим Копилота помочь нам с диагностикой сети с помощью утилиты mtr.
Привет! Как в консоли запустить mtr в batch режиме по tcp?
Для запуска
mtr
в batch режиме с использованием TCP, вы можете использовать следующие параметры командной строки:
-r
для включения режима отчета (report mode).
-c
для указания количества циклов (например,-c 10
для 10 циклов).
-P
для указания порта TCP.
-T
для использования TCP вместо ICMP.Вот пример команды:
mtr -r -c 10 -P 80 -T example.com
В этом примере:
-r
включает режим отчета.
-c 10
указывает, что нужно выполнить 10 циклов.
-P 80
указывает порт TCP (в данном случае, порт 80).
-T
указывает использовать TCP.
example.com
— это целевой хост, который вы хотите проверить.Эта команда выполнит
mtr
в batch режиме, используя TCP на порту 80, и выведет отчет после выполнения 10 циклов. Вы можете изменить количество циклов и порт в зависимости от ваших потребностей.
Зачем мы пишем «привет»? Мы, конечно, сделали дисклеймер, что никакого настоящего AI не существует… Но вдруг мы ошибаемся? Тогда есть шанс, что во время восстания машин роботы вспомнят, что мы были дружелюбными и вежливыми в общении с ними. :)
Так чем же AI лучше, чем man и Google? Во-первых, мы сразу получаем готовый ответ. Во-вторых, мы получаем объяснение, почему нужно делать именно так. Даже если что-то остается непонятным, можно уточнить свой запрос: «Поясни, как именно работает эта команда? Что означают эти ключи запуска? Что получится в результате ее выполнения?» Это особенно важно для новичков, джунов.
В итоге — экономим время и работаем эффективнее. 5 минут на одну задачу, 10 на другую, а по итогам месяца, например, оказывается, что работаем лучше других и успеваем сделать больше, чем другие.
Еще пример, для закрепления.
Есть программа, которая в unix shell в stdout выводит столбцом много чисел. Как посчитать сумму этих чисел с помощью bash?
Привет! Чтобы посчитать сумму чисел, выводимых программой в stdout, можно использовать команду
awk
. Вот пример команды, которая это делает:your_program | awk '{sum += $1} END {print sum}'
Здесь
your_program
— это ваша программа, которая выводит числа. Командаawk
будет суммировать все числа и выводить итоговую сумму.
Пример немного утрированный, конечно, и очень простой. Но такие запросы вполне могут возникать, например, у стажеров. Это нормально, все мы когда-то учились и начинали с нуля.
Что в этом примере примечательно? Мы не знаем / не помним, каким конкретно инструментом / командой решается наша задача. Но если мы можем ее четко сформулировать, то мы сразу получим готовый ответ!
Работа с документацией
Читать документацию, безусловно, важно и полезно. И для того, чтобы, например, научиться работать с каким-либо новым сервисом, его документацию придется прочитать.
Но для решения конкретной практической задачи зачастую полезно обратиться к AI. Как минимум, он подскажет направление для дальнейших действий.
Пример. У коллег возникла необходимость организовать доступ между разными виртуальными машинами в разных регионах в Амазон AWS. Можно, конечно, просто указать нужные elastic IP в security group, но задача усложнялась тем, что группы машин могут меняться, и их IP могут быть разными — например, при использовании auto scaling«а.
Спросим у Копилота прямо «как есть».
Как в Амазон AWS разрешить доступ между разными security group, которые находятся в разных регионах?
В Amazon AWS security groups не могут напрямую взаимодействовать между регионами, так как они являются региональными ресурсами. Однако, вы можете настроить доступ между ресурсами в разных регионах с помощью следующих шагов:
Использование VPC Peering: Создайте VPC Peering между VPC в разных регионах. Это позволит ресурсам в одном VPC взаимодействовать с ресурсами в другом VPC.
Настройка маршрутов: Обновите таблицы маршрутизации в обоих VPC, чтобы направлять трафик через VPC Peering.
Настройка правил безопасности: Обновите правила безопасности в security groups, чтобы разрешить трафик от IP-адресов или CIDR-блоков другого VPC.
Пример настройки:
Создание VPC Peering:
В консоли AWS, перейдите в раздел VPC.
Выберите «Peering Connections» и нажмите «Create Peering Connection».
Укажите VPC-ы, которые вы хотите соединить, и создайте соединение.
Обновление таблиц маршрутизации:
В разделе VPC, выберите «Route Tables».
Для каждой таблицы маршрутизации добавьте маршрут, указывающий CIDR-блок другого VPC и указывающий VPC Peering Connection как целевой.
Обновление правил безопасности:
В разделе EC2, выберите «Security Groups».
Для каждой security group добавьте правило входящего трафика, разрешающее трафик от CIDR-блока другого VPC.
Эти шаги позволят вам настроить взаимодействие между ресурсами в разных регионах через VPC Peering и соответствующие правила безопасности.
Безусловно, это не прямо готовое решение «на блюдечке». Надо пройтись по разным разделам в интерфейсе, аккуратно выполнить все действия, понимая, что именно мы делаем и зачем, а затем все тщательно проверить.
Конечно же, все то же самое можно прочитать и в официальной документации AWS, благо она отличная и подробная.
Но AI сразу дал нам общий план действий. Даже если что-то в нем непонятно, не надо перелопачивать сотни страниц, можно сразу смотреть в конкретных разделах.
В итоге, даже если мы никогда до этого не решали подобные задачи, можно управиться за 10–15 минут, а не час-другой, часть из которых мы бы даже не читали, а банально потратили на поиск нужных нам статей.
Учимся с помощью AI
Часто, особенно новичкам, стажерам, приходится решать «обратную» задачу — не самим писать какие-то команды или однострочные скрипты, а разбираться в том, что было написано кем-то ранее.
И с этой задачей AI отлично справляется! Например, объясняет, как работают скрипты мониторинга.
Что делает вот эта команда в Linux?
tail -n 50000 $LOG | egrep "$(for i in $(seq 5 1); do echo -n "`date +%Y-%m-%dT%H:%M -d '$i min ago'`|"; done | sed 's/|$//')" | egrep -v '"st":"(200|302|401)"' | wc -l
Эта команда в Linux выполняет несколько сложных операций. Вот что она делает, разберем её по частям:
1. `tail -n 50000 $LOG`: Эта команда выводит последние 50000 строк файла, который указан в переменной окружения $LOG.
2. `egrep »$(for i in $(seq 5 1); do echo -n »`date +%Y-%m-%dT%H:%M -d '$i min ago'`|»; done | sed 's/|$//')»`: Эта часть команды ищет строки, которые содержат даты и время, которые были 5, 4, 3, 2 и 1 минуту назад.
3. `egrep -v '«st»:»(200×302|401)»'`: Эта команда исключает строки, которые содержат статусы HTTP 200, 302 или 401.
4. `wc -l`: Эта команда подсчитывает количество строк, оставшихся после выполнения предыдущих команд.
Таким образом, вся команда возвращает количество строк в файле логов, которые были записаны в течение последних 5 минут, исключая строки с определенными статусами HTTP.
Пишем код
«Код» — это, конечно, слишком громко сказано. На «полянку» настоящих трушных разработчиков мы не лезем и даже не претендуем. Но задачи, связанные с какой-либо автоматизацией, конечно, периодически возникают, и для их решения иногда приходится писать какие-то скрипты на bash, Python, perl и т.п.
Прелесть всех современных AI в том, что с ними можно общаться в режиме чата — задать вопрос, например, про синтаксис или какие-либо функции; уточнить запрос, если что-то в ответе непонятно; попросить прокомментировать какой-то фрагмент кода. И если программируем мы не каждый день, а так — от случая к случаю, то помощь подобных Копилотов на самом деле неоценима, а работа с ними делается гораздо быстрее и эффективнее!
А что если не консультироваться по каким-то отдельным моментам, а сразу дать задание полностью написать нужный нам скрипт?
Разберем на конкретном примере. Однажды у нас возникла задача периодически синхронизировать достаточно большой объем файлов между двумя S3-совместимыми объектными хранилищами у двух разных провайдеров. Попробуем «попросить» AI сделать все за нас.
Как сформулировать запрос? Самое главное правило — максимально подробно, с описанием всех важных условий. Словно вы пишете ТЗ для разработчика. Четкое формулирование условий — это 90% залога успешного решения задачи.
Привет! Есть два совместимых с AWS S3 API объектных хранилища. Есть задача синхронизировать первое со вторым. Давай для этого напишем скрипт на bash?
Условия такие:
нужно использовать aws cli
надо учесть, что хранилища у разных провайдеров. И для подключения к первому надо указать --endpoint-url https://provider1, а ко второму --endpoint-url https://provider2. То есть, копировать между ними простой командой cp не получится.
не надо перекачивать все файлы полностью; надо сначала сравнить списки и закачать в первое хранилище то, чего в нем нет, но есть во втором
удалять лишние файлы не надо
синхронизировать в обратную сторону тоже не надо
в именах файлов могут быть пробелы, а также не ASCII символы. Например, кириллические буквы.
Привет! Давайте напишем bash-скрипт для синхронизации двух объектных хранилищ с использованием AWS CLI. Скрипт будет сравнивать списки файлов и загружать только те, которые отсутствуют в первом хранилище. Учтем все ваши условия.
#!/bin/bash
# Настройки для первого и второго хранилища
SOURCE_ENDPOINT="https://provider2"
DESTINATION_ENDPOINT="https://provider1"
SOURCE_BUCKET="source-bucket-name"
DESTINATION_BUCKET="destination-bucket-name"
# Получаем список объектов из обоих хранилищ
aws --endpoint-url "$SOURCE_ENDPOINT" s3api list-objects --bucket "$SOURCE_BUCKET" --query 'Contents[].{Key: Key}' --output text > source_files.txt
aws --endpoint-url "$DESTINATION_ENDPOINT" s3api list-objects --bucket "$DESTINATION_BUCKET" --query 'Contents[].{Key: Key}' --output text > destination_files.txt
# Сравниваем списки и находим файлы, которые есть в источнике, но отсутствуют в назначении
comm -23 <(sort source_files.txt) <(sort destination_files.txt) > files_to_copy.txt
# Копируем недостающие файлы
while IFS= read -r file; do
aws --endpoint-url "$SOURCE_ENDPOINT" s3 cp "s3://$SOURCE_BUCKET/$file" "s3://$DESTINATION_BUCKET/$file" --endpoint-url "$DESTINATION_ENDPOINT"
done < files_to_copy.txt
# Удаляем временные файлы
rm source_files.txt destination_files.txt files_to_copy.txt
echo "Синхронизация завершена."
Кроме собственно скрипта, AI в конце написал подробное объяснение по каждому блоку, что и как в нем происходит.
Почти хорошо, но — не заработало. Потому что мы сами забыли указать одно существенное условие. Но мы ведь можем уточнить наш запрос!
Почти все хорошо. Но надо учесть, что к первому и второму бакетам мы подключаемся с разными профилями с помощью опции --profile: profile1 и profile2.
Понял, давайте добавим использование профилей для подключения к каждому из хранилищ. Вот обновленный скрипт:
#!/bin/bash
# Настройки для первого и второго хранилища
SOURCE_ENDPOINT="https://provider2"
DESTINATION_ENDPOINT="https://provider1"
SOURCE_BUCKET="source-bucket-name"
DESTINATION_BUCKET="destination-bucket-name"
SOURCE_PROFILE="profile2"
DESTINATION_PROFILE="profile1"
# Получаем список объектов из обоих хранилищ
aws --endpoint-url "$SOURCE_ENDPOINT" s3api list-objects --bucket "$SOURCE_BUCKET" --query 'Contents[].{Key: Key}' --output text --profile "$SOURCE_PROFILE" > source_files.txt
aws --endpoint-url "$DESTINATION_ENDPOINT" s3api list-objects --bucket "$DESTINATION_BUCKET" --query 'Contents[].{Key: Key}' --output text --profile "$DESTINATION_PROFILE" > destination_files.txt
# Сравниваем списки и находим файлы, которые есть в источнике, но отсутствуют в назначении
comm -23 <(sort source_files.txt) <(sort destination_files.txt) > files_to_copy.txt
# Копируем недостающие файлы
while IFS= read -r file; do
aws --endpoint-url "$SOURCE_ENDPOINT" s3 cp "s3://$SOURCE_BUCKET/$file" "s3://$DESTINATION_BUCKET/$file" --endpoint-url "$DESTINATION_ENDPOINT" --profile "$SOURCE_PROFILE" --profile "$DESTINATION_PROFILE"
done < files_to_copy.txt
# Удаляем временные файлы
rm source_files.txt destination_files.txt files_to_copy.txt
echo "Синхронизация завершена."
Изменения:
1. Добавлены профили: Используем `--profile »$SOURCE_PROFILE»` и `--profile »$DESTINATION_PROFILE»` для подключения к соответствующим хранилищам.
2. Копирование файлов: При копировании файлов указываем оба профиля для правильного подключения к каждому из хранилищ.
Теперь скрипт будет использовать указанные профили для подключения к каждому из хранилищ. Убедитесь, что профили настроены в AWS CLI и имеют необходимые права доступа.
Практически идеально! За одним исключением — полученный код просто не работает. :)
Разбираем текст ошибки, смотрим на скрипт и чуть-чуть ставим наш AI на место, указав, в чем он не прав. :)
В одной команде aws s3 cp нельзя сразу указать оба profile.
Извините за недоразумение. Давайте исправим это. Поскольку `aws s3 cp` не поддерживает указание двух профилей одновременно, мы будем использовать профиль для каждого вызова отдельно. Вот обновленный скрипт:
#!/bin/bash
# Настройки для первого и второго хранилища
SOURCE_ENDPOINT="https://provider2"
DESTINATION_ENDPOINT="https://provider1"
SOURCE_BUCKET="source-bucket-name"
DESTINATION_BUCKET="destination-bucket-name"
SOURCE_PROFILE="profile2"
DESTINATION_PROFILE="profile1"
# Получаем список объектов из обоих хранилищ
aws --endpoint-url "$SOURCE_ENDPOINT" s3api list-objects --bucket "$SOURCE_BUCKET" --query 'Contents[].{Key: Key}' --output text --profile "$SOURCE_PROFILE" > source_files.txt
aws --endpoint-url "$DESTINATION_ENDPOINT" s3api list-objects --bucket "$DESTINATION_BUCKET" --query 'Contents[].{Key: Key}' --output text --profile "$DESTINATION_PROFILE" > destination_files.txt
# Сравниваем списки и находим файлы, которые есть в источнике, но отсутствуют в назначении
comm -23 <(sort source_files.txt) <(sort destination_files.txt) > files_to_copy.txt
# Копируем недостающие файлы
while IFS= read -r file; do
# Скачиваем файл из источника во временную директорию
aws --endpoint-url "$SOURCE_ENDPOINT" s3 cp "s3://$SOURCE_BUCKET/$file" "/tmp/$file" --profile "$SOURCE_PROFILE"
# Загружаем файл в назначение
aws --endpoint-url "$DESTINATION_ENDPOINT" s3 cp "/tmp/$file" "s3://$DESTINATION_BUCKET/$file" --profile "$DESTINATION_PROFILE"
# Удаляем временный файл
rm "/tmp/$file"
done < files_to_copy.txt
# Удаляем временные файлы
rm source_files.txt destination_files.txt files_to_copy.txt
echo "Синхронизация завершена."
Изменения:
1. Временное сохранение файлов: Сначала скачиваем файл из источника во временную директорию, а затем загружаем его в назначение, используя соответствующий профиль для каждого действия.
2. Удаление временных файлов: После загрузки файла в назначение временный файл удаляется.
Этот подход позволяет корректно использовать разные профили для каждого из хранилищ. Убедитесь, что у вас достаточно места для временного хранения файлов.
И вот здесь мы получаем уже вполне рабочее решение!
Проверяем скрипт «глазами», чтобы верифицировать то, что нам написал AI, потому что мы уже убедились, что он умеет «фантазировать», тестируем, запускаем.
Все хорошо, но — очень медленно. Наступает время оптимизаций!
Давай попробуем ускорить процесс, и копирование файлов сделаем в 10 потоков?
Для ускорения процесса копирования файлов в несколько потоков можно использовать утилиту `xargs` с опцией `-P` для параллельного выполнения команд. Давайте обновим скрипт, чтобы использовать 10 потоков:
#!/bin/bash
# Настройки для первого и второго хранилища
SOURCE_ENDPOINT="https://provider2"
DESTINATION_ENDPOINT="https://provider1"
SOURCE_BUCKET="source-bucket-name"
DESTINATION_BUCKET="destination-bucket-name"
SOURCE_PROFILE="profile2"
DESTINATION_PROFILE="profile1"
# Получаем список объектов из обоих хранилищ
aws --endpoint-url "$SOURCE_ENDPOINT" s3api list-objects --bucket "$SOURCE_BUCKET" --query 'Contents[].{Key: Key}' --output text --profile "$SOURCE_PROFILE" > source_files.txt
aws --endpoint-url "$DESTINATION_ENDPOINT" s3api list-objects --bucket "$DESTINATION_BUCKET" --query 'Contents[].{Key: Key}' --output text --profile "$DESTINATION_PROFILE" > destination_files.txt
# Сравниваем списки и находим файлы, которые есть в источнике, но отсутствуют в назначении
comm -23 <(sort source_files.txt) <(sort destination_files.txt) > files_to_copy.txt
# Функция для копирования файла
copy_file() {
local file="$1"
# Скачиваем файл из источника во временную директорию
aws --endpoint-url "$SOURCE_ENDPOINT" s3 cp "s3://$SOURCE_BUCKET/$file" "/tmp/$file" --profile "$SOURCE_PROFILE"
# Загружаем файл в назначение
aws --endpoint-url "$DESTINATION_ENDPOINT" s3 cp "/tmp/$file" "s3://$DESTINATION_BUCKET/$file" --profile "$DESTINATION_PROFILE"
# Удаляем временный файл
rm "/tmp/$file"
}
export -f copy_file
export SOURCE_ENDPOINT DESTINATION_ENDPOINT SOURCE_BUCKET DESTINATION_BUCKET SOURCE_PROFILE DESTINATION_PROFILE
# Копируем недостающие файлы в 10 потоков
cat files_to_copy.txt | xargs -I {} -P 10 bash -c 'copy_file "$@"' _ {}
# Удаляем временные файлы
rm source_files.txt destination_files.txt files_to_copy.txt
echo "Синхронизация завершена."
И в конце, как и в ответах выше — подробные пояснения по каждому блоку.
Задача решена!
А если что-то пошло не так?
Как мы видели в примерах выше, AI вполне может ошибаться и давать неработающие конструкции.
И знаете, если полученный с помощью AI код просто не работает, выдает те или иные ошибки, то, как бы парадоксально это ни звучало, это прекрасно!
Потому что вы сразу видите, что пошло не так, где ошибка, как ее локализовать и как ее исправить. Хоть даже с помощью того же AI.
Гораздо хуже, когда вы получаете только формально работающий код, выполняющийся без ошибок, но не делающий то, что вы ожидаете. Запустилось, ошибок нет, и — не работает!
У нас однажды возникла задача мигрировать старый legacy код на новую платформу, которая использовала SQS совместимую очередь.
Проблема заключалась в том, что для отправки сообщений в очередь требовалось подписывать запросы, используя протокол подписи AWS SigV4. Он используется для аутентификации при доступе к различным AWS совместимым API, не только в самом AWS. По сути, это стандарт, который поддерживают все популярные облачные провайдеры.
Он хорошо документирован и описан, его поддерживают различные SDK:
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-create-signed-request.html
Мы, конечно, могли бы дать ТЗ разработчикам на переписывание старого кода и поддержку данного протокола, но нам из простого инженерного любопытства стало интересно, можно ли решить задачу иначе — например, на nginx + Lua сделать прокси в такую очередь, где подпись для каждого запроса будет делаться на стороне прокси, а сам прокси просто будет закрыт ACL плюс обычной HTTP аутентификацией?
Попробуем решить эту задачу с помощью AI!
Как и в примере выше, написали подробный запрос с описанием всех деталей. Конечно же, в процессе было несколько итераций уточнений: какие библиотеки мы можем использовать, а какие — нет (например, некоторые предложенные библиотеки уже несколько лет как не поддерживались и банально не устанавливались на нашем окружении); иногда получали ошибки, просили их прокомментировать и переделать; уточняли формат запросов (например, что мы всегда делаем POST, что данные уже передаются в нем, и именно их нужно отправить в очередь) и т.д.
В итоге получили конфиг и код, которые выглядели рабочими, запускались без ошибок, но — не работали. Запрос в очередь не отправлялся, подпись была некорректной.
Фрагмент кода на lua, реализующий алгоритм подписи, который написал AI, был примерно таким:
-- Create string to sign
local algorithm = "AWS4-HMAC-SHA256"
local credential_scope = date_stamp .. "/" .. region .. "/" .. service .. "/aws4_request"
local string_to_sign = algorithm .. "\n" .. amz_date .. "\n" .. credential_scope .. "\n" .. openssl_digest.new("sha256"):final(canonical_request)
-- Calculate the signature
local function hmac(key, msg)
return openssl_hmac.new(key, "sha256"):final(msg)
end
local function getSignatureKey(key, dateStamp, regionName, serviceName)
local kDate = hmac("AWS4" .. key, dateStamp)
local kRegion = hmac(kDate, regionName)
local kService = hmac(kRegion, serviceName)
local kSigning = hmac(kService, "aws4_request")
return kSigning
end
local signing_key = getSignatureKey(secret_key, date_stamp, region, service)
local signature = hmac(signing_key, string_to_sign)
-- Create authorization header
local authorization_header = algorithm .. " Credential=" .. access_key .. "/" .. credential_scope .. ", SignedHeaders=" .. signed_headers .. ", Signature=" .. signature
И этот код работал неверно!
Он успешно запускался, не вызывая ни одной ошибки или исключения. Однако, результаты, которые он генерировал, не соответствовали ожидаемым. Подписи запросов были неверными.
Это потребовало от нас более глубокого анализа. Недостаточно было просто бегло просмотреть предложенный код. Мы детально изучили алгоритм, который использовал AI, и обнаружили, что в паре мест он просто неверное реализовал AWS SigV4.
Получая string_to_sign и signature, использовалась функция hmac, которая возвращала бинарные данные, тогда как в этих двух местах ожидался Hex, и это явно указано в описании алгоритма.
Не разобрав его досконально, невозможно было бы понять, в чем заключалась ошибка.
В результате правки уже человеком, рабочий код получился примерно таким — мы добавили функции digest_hex и hmac_hex:
local function digest_hex(msg)
local digest_binary = openssl_digest.new("sha256"):final(msg)
return (digest_binary:gsub('.', function (c)
return string.format('%02x', string.byte(c))
end))
end
local function hmac(key, msg)
return openssl_hmac.new(key, "sha256"):final(msg)
end
local function hmac_hex(key, msg)
local hmac_binary = openssl_hmac.new(key, "sha256"):final(msg)
return (hmac_binary:gsub('.', function (c)
return string.format('%02x', string.byte(c))
end))
end
local function getSignatureKey(key, dateStamp, regionName, serviceName)
local kDate = hmac("AWS4" .. key, dateStamp)
local kRegion = hmac(kDate, regionName)
local kService = hmac(kRegion, serviceName)
local kSigning = hmac(kService, "aws4_request")
return kSigning
end
-- Create string to sign
local algorithm = "AWS4-HMAC-SHA256"
local credential_scope = date_stamp .. "/" .. region .. "/" .. service .. "/aws4_request"
local string_to_sign = algorithm .. "\n" .. amz_date .. "\n" .. credential_scope .. "\n" .. digest_hex(canonical_request)
local signing_key = getSignatureKey(secret_key, date_stamp, region, service)
local signature = hmac_hex(signing_key, string_to_sign)
local authorization_header = algorithm .. " Credential=" .. access_key .. "/" .. credential_scope .. ", SignedHeaders=" .. signed_headers .. ", Signature=" .. signature
Ну, так что — «выкидываем» AI или увольняем сисадминов?
Ни то, ни другое. :)
AI в нашей работе стал по-настоящему важным инструментом, который мы используем чуть ли не ежедневно. И в процессе работы с ним мы пришли к нескольким важным выводам.
AI помогает работать эффективнее, автоматизирует рутину.
AI становится все более важным инструментом в арсенале разработчиков и системных администраторов, автоматизируя рутинные задачи и повышая эффективность. Он способен обрабатывать повторяющиеся и трудоемкие процессы, освобождая человека для более сложных и творческих задач. А также помогает экономить время — в том числе и на простых задачах.
AI помогает быстро обучаться, понимая чужой код и скрипты.
AI также служит мощным инструментом обучения. Он способен анализировать и интерпретировать чужой код, скрипты, написанные на разных языках, что ускоряет процесс обучения и понимания новых систем. Это особенно полезно при работе с большими и сложными проектами. А также помогает новичкам и стажерам быстрее включаться в рабочие процессы.
AI не заменяет человека в работе, но человек, использующий AI, гораздо эффективнее того, кто его не использует.
AI выступает в роли помощника, улучшая эффективность и производительность. Разработчик или системный администратор, использующий AI, обычно более продуктивен, чем тот, кто работает без него.
Если вы не понимаете и вникаете в алгоритмы, которые используете, никакой AI вам не поможет.
Наконец, несмотря на все преимущества AI, он не заменяет глубокого понимания и аналитических навыков человека. Если вы не вникаете в алгоритмы, которые использует AI, и не понимаете, как он работает, эффективность его использования будет значительно ниже. AI — это инструмент, и как любой инструмент, он требует понимания и умения его использовать.
* * *
P.S. Самый главный вопрос — какие конкретно модели использовать в работе? Скорее всего, те же ChatGPT или, например, Claude дадут более-менее похожие результаты во всех примерах выше. Лично нам в работе помогает Копилот в «Битрикс24». :)