Skip to content

Commit b678492

Browse files
author
Venkata Subramani Renduchintala
committed
feat(sre): add Ansible, Jsonnet and Python LSP, linting and formatting
- after/lsp/ansiblels.lua: ansiblels with validation and ansible-lint - after/lsp/jsonnet_ls.lua: jsonnet_ls with -t flag and formatting settings - mason.lua: add jsonnet_ls to lspconfig, ruff to nvim-lint; wire python linting - conform.lua: add python ruff_format formatter - treesitter.lua: add jsonnet parser to SRE section - test fixtures: dashboard.jsonnet (Grafonnet), script.py (kubectl health checker) - CI: install jsonnet+python parsers, validate ansiblels+jsonnet_ls settings
1 parent 19457f8 commit b678492

10 files changed

Lines changed: 131 additions & 3 deletions

File tree

after/lsp/ansiblels.lua

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
vim.lsp.config('ansiblels', {
2+
settings = {
3+
ansible = {
4+
ansible = {
5+
path = "ansible",
6+
},
7+
executionEnvironment = {
8+
enabled = false,
9+
},
10+
python = {
11+
interpreterPath = "python3",
12+
},
13+
validation = {
14+
enabled = true,
15+
lint = {
16+
enabled = true,
17+
path = "ansible-lint",
18+
},
19+
},
20+
},
21+
},
22+
})

after/lsp/jsonnet_ls.lua

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
vim.lsp.config('jsonnet_ls', {
2+
cmd = { "jsonnet-language-server", "-t" },
3+
settings = {
4+
ext_vars = {},
5+
formatting = {
6+
Indent = 2,
7+
MaxBlankLines = 2,
8+
StringStyle = "s",
9+
CommentStyle = "s",
10+
PrettyFieldNames = true,
11+
SortImports = true,
12+
},
13+
},
14+
})

lua/plugins/configs/conform.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ return {
2525
formatters_by_ft = {
2626
lua = { "stylua" },
2727
sh = { "shfmt" },
28+
python = { "ruff_format" },
2829
json = { "jq" },
2930
html = { "prettierd", "prettier", "tidy", stop_after_first = true },
3031
css = { "prettierd", "prettier", "tidy", stop_after_first = true },

lua/plugins/configs/mason.lua

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ return {
2828
"terraformls",
2929
"helm_ls",
3030
"ansiblels",
31+
"jsonnet_ls",
3132
"bashls",
3233
"dockerls",
3334
"docker_compose_language_service",
@@ -60,6 +61,7 @@ return {
6061
"shellcheck",
6162
"shfmt",
6263
"hadolint",
64+
"ruff",
6365
"actionlint",
6466
"ansible-lint",
6567
"api-linter",
@@ -93,9 +95,10 @@ return {
9395
sh = { "shellcheck" },
9496
bash = { "shellcheck" },
9597
dockerfile = { "hadolint" },
98+
python = { "ruff" },
9699
}
97100
vim.api.nvim_create_autocmd({ "BufWritePost", "BufEnter" }, {
98-
pattern = { "*.yaml", "*.yml", "*.sh", "Dockerfile", "dockerfile" },
101+
pattern = { "*.yaml", "*.yml", "*.sh", "Dockerfile", "dockerfile", "*.py" },
99102
callback = function()
100103
lint.try_lint()
101104
end,

lua/plugins/configs/treesitter.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ return {
4343
"hcl",
4444
"bash",
4545
"gotmpl",
46+
"jsonnet",
4647
},
4748
refactor = {
4849
highlight_definitions = {

test/ci_validate_lsp.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ if not global_cfg or not global_cfg.capabilities then
1313
end
1414

1515
-- Spot-check that server-specific after/lsp overrides are present
16-
local servers_with_settings = { "gopls", "lua_ls", "rust_analyzer", "yamlls", "helm_ls", "eslint" }
16+
local servers_with_settings = { "gopls", "lua_ls", "rust_analyzer", "yamlls", "helm_ls", "eslint", "ansiblels", "jsonnet_ls" }
1717
for _, name in ipairs(servers_with_settings) do
1818
local cfg = vim.lsp.config[name]
1919
if not cfg or not cfg.settings then

test/fixtures/dashboard.jsonnet

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
local grafana = import 'grafonnet/grafana.libsonnet';
2+
local dashboard = grafana.dashboard;
3+
local row = grafana.row;
4+
local prometheus = grafana.target.prometheus;
5+
local graphPanel = grafana.graphPanel;
6+
7+
dashboard.new(
8+
'SRE Overview',
9+
schemaVersion=26,
10+
tags=['sre', 'platform'],
11+
timezone='browser',
12+
refresh='1m',
13+
)
14+
.addRow(
15+
row.new(title='HTTP Traffic')
16+
.addPanel(
17+
graphPanel.new(
18+
'Request Rate',
19+
datasource='Prometheus',
20+
span=6,
21+
)
22+
.addTarget(
23+
prometheus.target(
24+
'sum(rate(http_requests_total[5m])) by (status_code)',
25+
legendFormat='{{status_code}}',
26+
)
27+
)
28+
)
29+
)

test/fixtures/script.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env python3
2+
"""Check pod health across a Kubernetes namespace."""
3+
4+
import argparse
5+
import subprocess
6+
import sys
7+
from dataclasses import dataclass
8+
9+
10+
@dataclass
11+
class Pod:
12+
name: str
13+
namespace: str
14+
status: str
15+
16+
@property
17+
def healthy(self) -> bool:
18+
return self.status == "Running"
19+
20+
21+
def get_pods(namespace: str) -> list[Pod]:
22+
result = subprocess.run(
23+
["kubectl", "get", "pods", "-n", namespace, "--no-headers",
24+
"-o", "custom-columns=NAME:.metadata.name,STATUS:.status.phase"],
25+
capture_output=True,
26+
text=True,
27+
check=True,
28+
)
29+
pods = []
30+
for line in result.stdout.strip().splitlines():
31+
parts = line.split()
32+
if len(parts) == 2:
33+
pods.append(Pod(name=parts[0], namespace=namespace, status=parts[1]))
34+
return pods
35+
36+
37+
def main() -> int:
38+
parser = argparse.ArgumentParser(description=__doc__)
39+
parser.add_argument("namespace", default="default", nargs="?")
40+
args = parser.parse_args()
41+
42+
pods = get_pods(args.namespace)
43+
if not pods:
44+
print(f"No pods found in {args.namespace}", file=sys.stderr)
45+
return 1
46+
47+
failed = [p for p in pods if not p.healthy]
48+
for pod in pods:
49+
status = "OK" if pod.healthy else "FAIL"
50+
print(f" [{status}] {pod.name}: {pod.status}")
51+
52+
return len(failed)
53+
54+
55+
if __name__ == "__main__":
56+
sys.exit(main())

test/install_parsers.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-- Headless treesitter parser installer for CI.
22
-- Uses TSInstall! + vim.wait() polling parser .so files on disk.
33
-- Exit code 1 on timeout so the CI step fails visibly.
4-
local langs = { 'go', 'terraform', 'hcl', 'yaml', 'bash', 'gotmpl', 'dockerfile' }
4+
local langs = { 'go', 'terraform', 'hcl', 'yaml', 'bash', 'gotmpl', 'dockerfile', 'jsonnet', 'python' }
55
local parser_dir = vim.fn.stdpath('data') .. '/lazy/nvim-treesitter/parser/'
66

77
local function installed(lang)

test/validate_treesitter.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ test_parser('yaml', cfg .. '/test/fixtures/deployment.yaml')
4343
test_parser('bash', cfg .. '/test/fixtures/script.sh')
4444
test_parser('gotmpl', cfg .. '/test/fixtures/helm_deployment.yaml')
4545
test_parser('dockerfile', cfg .. '/test/fixtures/Dockerfile')
46+
test_parser('jsonnet', cfg .. '/test/fixtures/dashboard.jsonnet')
47+
test_parser('python', cfg .. '/test/fixtures/script.py')
4648

4749
if #errors > 0 then
4850
for _, err in ipairs(errors) do

0 commit comments

Comments
 (0)