Прим. перев.: оригинальную статью написал Josh Rosso — архитектор из VMware, ранее работавший в таких компаниях, как CoreOS и Heptio, а также являющийся соавтором Kubernetes alb-ingress-controller. Автор делится небольшим рецептом, который может оказаться очень полезным для инженеров по эксплуатации «старой школы», предпочитающих vim даже в эпоху победившего cloud native.



Пишете YAML-манифесты для Kubernetes в vim? Провели бесчисленные часы в попытках понять, где в этой спецификации должно быть очередное поле? А может быть, будете рады быстрому напоминанию о разнице args и command? Есть хорошие новости! Vim легко привязать к yaml-language-server, чтобы получить автоматическое дополнение, валидацию и другие удобства. В статье поговорим о том, как для этого настроить клиента языкового сервера.

(У оригинальной статьи также есть видео, где автор рассказывает и демонстрирует содержимое материала.)

Языковой сервер


Языковые серверы (language servers) рассказывают о возможностях языков программирования редакторам и IDE, для чего они взаимодействуют между собой по специальному протоколу — Language Server Protocol (LSP). Это замечательный подход: ведь он позволяет одной реализации обеспечивать данными сразу множество редакторов/IDE. Я уже писал про gopls — языковой сервер для Golang — и как его можно использовать в vim. Действия для получения автодополнения в YAML для Kubernetes аналогичны.



Чтобы vim заработал описанным способом, понадобится установить клиента языкового сервера. Два известных мне способа — это LanguageClient-neovim и coc.vim. В статье буду рассматривать coc.vim — это самый популярный плагин на настоящий момент. Установить его можно через vim-plug:

" Use release branch (Recommend)
Plug 'neoclide/coc.nvim', {'branch': 'release'}

" Or build from source code by use yarn: https://yarnpkg.com
Plug 'neoclide/coc.nvim', {'do': 'yarn install --frozen-lockfile'}

Для запуска coc (и, таким образом, сервера yaml-language-server) потребуется наличие установленного node.js:

curl -sL install-node.now.sh/lts | bash

Когда coc.vim настроен, установите серверное расширение coc-yaml из vim'а:

:CocInstall coc-yaml



Наконец, вы скорее всего захотите начать с конфигурации coc-vim, представленной как пример. В частности, она активирует комбинацию <Ctrl>+пробел для вызова автодополнения.

Настройка обнаружения yaml-language-server


Чтобы coc мог воспользоваться yaml-language-server, его нужно попросить загружать схему от Kubernetes при редактировании YAML-файлов. Это делается редактированием coc-config:

:CocConfig

В конфигурации потребуется добавить kubernetes для всех файлов yaml. Я дополнительно использую языковой сервер для golang, поэтому мой общий конфиг выглядит так:

{
  "languageserver": {
      "golang": {
        "command": "gopls",
        "rootPatterns": ["go.mod"],
        "filetypes": ["go"]
      }
  },

  "yaml.schemas": {
      "kubernetes": "/*.yaml"
  }
}

kubernetes — зарезервированное поле, сообщающее языковому серверу о необходимости загрузить Kubernetes-схему по URL, определённому в этой константе. yaml.schemas можно расширить поддержкой дополнительных схем — подробнее см. в соответствующей документации.

Теперь можно создать YAML-файл и начать пользоваться автодополнением. Нажатие <Ctrl>+пробел (или другой комбинации, настроенной в vim) должно показать доступные поля и документацию в соответствии с текущим контекстом:


Здесь работает <Ctrl>+пробел, потому что я настроил inoremap <silent><expr> <c-space> coc#refresh(). Если вы этого не сделали — см. coc.nvim README для примера конфигурации.

Выбор версии Kubernetes API


К моменту написания этой статьи yaml-language-server поставляется со схемами Kubernetes 1.14.0. Я не нашёл способа динамически выбирать схему, поэтому открыл соответствующий GitHub issue. К счастью, поскольку языковой сервер написан на typescript, весьма легко вручную изменить версию. Для этого достаточно найти файл server.ts.

Чтобы обнаружить его на своей машине, просто откройте YAML-файл с помощью vim и найдите процесс с yaml-language-server.

ps aux | grep -i yaml-language-server

joshrosso         2380  45.9  0.2  5586084  69324   ??  S     9:32PM   0:00.43 /usr/local/Cellar/node/13.5.0/bin/node /Users/joshrosso/.config/coc/extensions/node_modules/coc-yaml/node_modules/yaml-language-server/out/server/src/server.js --node-ipc --node-ipc --clientProcessId=2379
joshrosso         2382   0.0  0.0  4399352    788 s001  S+    9:32PM   0:00.00 grep -i yaml-language-server

Для нас актуален процесс 2380: именно его использует vim во время редактирования YAML-файла.

Как легко увидеть, файл расположен в /Users/joshrosso/.config/coc/extensions/node_modules/coc-yaml/node_modules/yaml-language-server/out/server/src/server.js. Достаточно отредактировать его, изменив значение KUBERNETES_SCHEMA_URL, например, на версию 1.17.0:

// old 1.14.0 schema
//exports.KUBERNETES_SCHEMA_URL = "https://raw.githubusercontent.com/garethr/kubernetes-json-schema/master/v1.14.0-standalone-strict/all.json";
// new 1.17.0 schema in instrumenta repo
exports.KUBERNETES_SCHEMA_URL = "https://raw.githubusercontent.com/instrumenta/kubernetes-json-schema/master/v1.17.0-standalone-strict/all.json";

В зависимости от версии используемого coc-yaml расположение переменной в коде может быть различным. Обратите также внимание, что я изменил репозиторий с garethr на instrumenta. Похоже, что garethr перешёл на поддержку схем именно там.

Чтобы проверить, что изменение вступило в силу, посмотрите, появляется ли поле, которого раньше [в прошлых версиях Kubernetes] не было. Например, в схеме для K8s 1.14 не было startupProbe:



Резюме


Надеюсь, такая возможность порадовала вас не меньше, чем меня. Счастливого YAML'инга! Не забудьте ознакомиться с этими репозиториями, чтобы получше разобраться с утилитами, упомянутыми в статье:


P.S. от переводчика


А ещё есть vikube, vim-kubernetes и vimkubectl.

Читайте также в нашем блоге: