Привет 👋 На связи команда PaaS СберМаркета. Меня зовут Роман, и уже больше 2-х лет моя группа занимается разработкой инструментов для разработчиков, в том числе утилитой sbm-cli, о которой хочу рассказать сегодня. Вероятно вы каждый день пользуетесь консольными утилитами, такими как git, homebrew, ssh, grep, find, etc. Мы сделали command line interface приложение, запуск которого на локальной машине разработчика может превышать количество запусков команды git (спойлер: статистика в конце статьи).  О том как так получилось, почему этот инструмент так важен для разработчика и что он умеет, а что нет, расскажем в этой статье. Обо всем по порядку: Как мы пришли к созданию такого инструмента? Почему этот cli настолько важен для наших разработчиков? 27 команд sbm-cli (управление шаблонами, локальная среда разработки и др) Планы на будущее и результаты Это третья статья из цикла о разработке IT-платформы. В предыдущих сериях: С чего мы начинали разработку PaaS 2 года назад. Как подступиться к созданию платформы? PaaS два года спустя. Обзор инструментов и какие задачи они решают Классическая проблема, с которой вы можете столкнуться во время разработки — это использование разных версий инструментов для обслуживания ваших сервисов.  В примере ниже это cli-приложение oapi-codegen — утилита для генерации Go-кода на основе openapi спецификации. Каждый разработчик ставит себе @latest и скоро версии oapi-codegen расходятся даже у членов одной команды. Вероятно, вы сталкивались с тем, что в соседних проектах для <чего-либо> (http client'а, авторизации, генерации кода, ORM и т.д.) используются разные библиотеки. На первый взгляд это не является проблемой, но со временем точно ей становится — когда приходится тратить много время на получение экспертизы N технических компонентов, реализующих смежные технологии. Еще одна типичная боль для разработчика — выбор инструментов для локального запуска сервиса и его зависимостей: кто-то запускает приложение и зависимости нативно (go run, python *.py runserver, systemctl start postgresql, etc); кому-то ближе история с docker-compose; есть любители minikube.  Список подобных разногласий может быть достаточно объемным. Чтобы минимизировать количество таких болей мы и сделали sbm-cli. Давайте представим крутую команду инженеров (скорее всего вы в такой работаете), которая разрабатывает и обслуживает N микросервисов. Перед вами встаёт задача написать новый сервис, например, промокодов. Он будет ходить в сервис заказов. Забирать некоторую информацию. Агрегировать ее и отправлять в кафку. Спецификации API в сервисе заказов не оказалось или она просто устарела. Поэтому разработчик курит изучает код, чтобы получить возможные варианты входных и выходных параметров API. В итоге, для решения задачи он потратил на 2 дня больше, чем планировал.  Может показаться, что это не так много. Но представьте, что подобная проблема встречается в каждом сервисе, и каждая новая интеграция требует еще больше времени. Ситуация усугубляется, когда с подобной проблемой сталкивается не только один инженер, но и вся команда. При создании sbm-cli у нас была одна основная цель: ускорить процесс доставки ценности. И мы руководствовались простым принципом: если что-то можно автоматизировать, то это нужно сделать. На сегодняшний день sbm-cli содержит команды из шести доменных областей. Далее  подробнее поговорим о каждой.  управление шаблонами сервиса локальная среда разработки работа с API работа с БД валидация системные команды Управление шаблоном сервиса sbm-cli service create sbm-cli service upgrade Локальная среда разработки (Playground) sbm-cli service up sbm-cli service down sbm-cli service debug sbm-cli service reset sbm-cli service purge sbm-cli service status sbm-cli service env Работа с API sbm-cli dependency add sbm-cli dependency upgrade sbm-cli contract list sbm-cli codegen Работа с БД sbm-cli database create sbm-cli migration create sbm-cli migration apply sbm-cli migration rollback Валидация sbm-cli code lint sbm-cli contract verify sbm-cli dependency check sbm-cli manifest check sbm-cli inframanifest check sbm-cli setup system-check Системные команды sbm-cli setup self-upgrade sbm-cli setup autoupgrade sbm-cli setup token-set sbm-cli version  Для каждой команды соблюдаются следующие правила интерфейса: Help: Понятная помощь на старте с примером запуска команды. Next steps: Рекомендации по выполнению дальнейших действий после успешного завершения команды. What to do: Ответ на вопрос «Что надо сделать, что бы команда успешно прошла?» Exit codes: 0 — успех, 1 — ошибка, 3 — предупреждение. Экосистема PaaS построена вокруг главной сущности — сервиса. Для обеспечения корректной работы платформы мы приняли ряд конвенций. Поэтому наше типичное приложение имеет следующую структуру каталогов в сервисе, вне зависимости от выбранного engine (языка или фреймворка): Engine — основная технология на которой построен сервис. В СберМаркете это Golang, Rails, Python и NodeJS. Для обеспечения такого соглашения мы сделали свой механизм создания сервиса. Именно с него началась разработка sbm-cli. Мы вдохновились лучшими практиками шаблонизации сервисов: project-layout для Golang;  rails application template для Ruby; aiohttp-demo для Python.  И объединили их с конвенциями принятыми в платформе. Пример создания сервиса: sbm-cli service create https://git.sbermarket.tech/paas/test-python-service --engine=python В статье Как подступиться к созданию PaaS мой коллега подчеркивал важность стандартного набора библиотек для разработки сервисов. Поэтому для каждого engine была разработана своя God-библиотека <engine>-libs (go-libs, ruby-libs, etc), которая предоставляет API для использования библиотеки следующего уровня.  Например, вы хотите использовать ruby http client faraday. ruby-libs предоставляет инстанс faraday с базовой конфигурацией, миддлварами, единым форматом логов и метрик, которые общеприняты в платформе. С течением времени наши базовые шаблоны менялись, и мы решили добавить функцию обновления в sbm-cli с командой sbm-cli service upgrade, чтобы упростить процесс перехода на новые версии библиотек. Docker-compose является достаточно эффективным инструментом для локального запуска приложения и его зависимостей. Но писать новый docker-compose.yaml каждый раз для нового сервиса — весьма утомительно. Наша команда поставила себе цель, сделать так, чтобы для локального старта любого сервиса разработчик выполнил как можно меньше действий. Так появилась команда sbm-cli service up. Playground — это docker-compose-based компонент sbm-cli, который управляет жизненным циклом сервиса на локальной машине разработчика. sbm-cli service up разворачивает приложение и все его инфраструктурные зависимости. Список зависимостей определяется в configs/values.yaml и используется как при деплое приложения, так и при локальном развертывании. сonfigs/values.yaml — манифест инфраструктуры, в котором декларируется поведение сервиса и его зависимостей в staging, production и playground среде. При необходимости, разработчик может указать точную версию образа, который необходим для развертывания зависимости. В противном случае будет выбрана версия по умолчанию. Playground предоставляет возможность запустить docker-контейнеры только с инфраструктурными зависимостями. При этом запуск самого приложения может оставаться на локальной машине.  Остальные команды playground: sbm-cli service debug — запускает приложение в режиме debug (например с использованием delve для golang). sbm-cli service down — останавливает приложение. sbm-cli service status — отображает состояние приложения. sbm-cli service reset — down & up. sbm-cli service purge — полный сброс (останавливает приложение и удаляет все образы, контейнеры, вольюмы, сети). sbm-cli service env — вызов команды в контексте playground (например sbm-cli service env -- go test -v ./… запустит тесты в окружении env переменных для подключения к ресурсам, развернутым в playground). Наша tech-команда выбирает API-first подход при разработке. Подробнее можно прочитать в статье: Трудности перевода. Как научить микросервисы общаться и не ссориться. Этот метод предоставляет ряд ключевых преимуществ: улучшение качества проектирования приложения; всегда актуальные контракты для разработки; разработчики могут одновременно работать над клиентской и серверной частями приложения.  Как это работает на практике? Разработчик сервиса-продьюсера формирует контракт в директории api. Затем он может применить инструмент кодогенерации sbm-cli codegen –servers для автоматической генерации серверного кода на основе этого контракта. Мы используем openapi и proto спецификации. Кодогенерация доступна для каждого вида контракта. Разработчик сервиса-консьюмера использует команду sbm-cli dependency add перед реализацией интеграции. Она выполняет несколько функций: Декларирует интеграцию в манифесте приложения app.toml. Скачивает контракты сервиса в директорию deps/services/<service-name>/<contract-name>. Генерирует клиентский код (как команда sbm-cli codegen –clients). В манифесте инфраструктуры values.yaml прописывает сетевой доступ для межсервисного взаимодействия в kubernetes. Одна команда закрывает большую часть вопросов и разработчик может сфокусироваться на написании кода. Что делать если в контракте добавилось новое поле и необходимо его поддержать со стороны консьюмера? Для этого есть команда sbm-cli dependency upgrade, которая актуализирует контракт и клиентский код. Для просмотра всех контрактов сервиса используется команда sbm-cli contract list. Что необходимо сделать, чтобы создать БД postgres локально? Базовый сценарий такой: Подготовить, если еще нет, dsn для будущего подключения приложения к БД. (Опционально) Подключиться к хосту, на котором располагается сервер БД (например docker-контейнер). Подключиться к psql. CREATE DATABASE … Для разработчика, который использует платформу это одна команда sbm-cli database create. При проектировании PaaS нам необходимо было выбрать один инструмент управления миграциями, чтобы он использовался как при локальной разработке так и в среде kubernetes. Команды sbm-cli migration up и sbm-cli migration rollback применяют или откатывают миграцию с использованием goose, а также сохраняют дамп structure.sql. sbm-cli позволяет снизить человеческий фактор при разработке вашего приложения в части изменения контрактов. Вероятно вы встречали случаи, когда в response body удалили одно поле, после чего пострадали сервисы-консумеры. sbm-cli contract verify проверяет контракты на обратную совместимость с master веткой, а также на соответствие REST API стандарту (только для openapi). В платформе мы выработали ряд базовых линтов golang кода, которые используются в большинстве проектов и общеприняты go-сообществом. Такие линты проверяются командой sbm-cli code lint. Линты, которые не являются базовыми, могут быть настроены в каждом проекте по решению команды.  Системные проверки в sbm-cli: sbm-cli dependency check — проверяет корректность декларированных зависимостей. sbm-cli manifest check — проверяет корректность заполнения  configs/app.toml. sbm-cli inframanifest check — проверяет корректность заполнения  configs/values.yaml. sbm-cli setup system-check — проверяет наличие дистрибутива engine, docker и других зависимостей на хосте. Большая часть команд из этой категории используется в CI/CD пайплайнах, тем самым обеспечивается гарантия вызова этих валидаций. Наша команда планирует дальнейшее развитие sbm-cli. Вот основные фичи, которые запланированы на будущий год: Поддержка ruby проектов в Playground (пока доступно только для go и python). Локальный запуск backend и frontend приложений одновременно в Playground среде. Использование локального docker-контейнера в удаленной среде kubernetes. Уровень зрелости инструмента достигает своего максимума, поэтому еще одно из направлений развития sbm-cli, которые рассматривает наша команда, — open source. Вероятно, не все проблемы необходимо решать здесь и сейчас. Но с ростом инженерной команды компании исправление их задним числом может оказаться достаточно дорогими.  После двух с половиной лет разработки sbm-cli стал повседневным инструментом инженера в СберМаркете. Количество ежедневных вызовов sbm-cli может превышать 2400, а количество уникальных пользователей ежедневно более 210 — это около 30% нашей tech команды. Я надеюсь эта статья помогла вам взглянуть на стандартизацию и автоматизацию процессов разработки с новой стороны. Пишите в комментариях какая часть sbm-cli вам наиболее интересна и мы постараемся раскрыть технические детали этого компонента в одной из следующих статей цикла. Tech-команда СберМаркета ведет соцсети с новостями и анонсами. Если хочешь узнать, что под капотом высоконагруженного e-commerce, следи за нами в Telegram и на  YouTube. А также слушай подкаст «Для tech и этих» от наших it-менеджеров.  Решаю проблемы бизнеса.