feat: add pre-commit configuration (#9)
- add pre-commit-config - add yamllint config - add ci/validate-* custom scripts - verify no secrets added - verify clusters with kustomize and kubeconform - verify apps with kustomize and kubeconform Reviewed-on: #9
This commit is contained in:
parent
ebb47348fe
commit
72a892eb14
53
.pre-commit-config.yaml
Normal file
53
.pre-commit-config.yaml
Normal file
@ -0,0 +1,53 @@
|
||||
repos:
|
||||
# General file checks
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.5.0
|
||||
hooks:
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-json
|
||||
- id: check-added-large-files
|
||||
args: ['--maxkb=500']
|
||||
- id: check-merge-conflict
|
||||
- id: check-shebang-scripts-are-executable
|
||||
- id: check-symlinks
|
||||
- id: check-toml
|
||||
- id: check-yaml
|
||||
args: [--allow-multiple-documents]
|
||||
- id: detect-aws-credentials
|
||||
args: [--allow-missing-credentials]
|
||||
- id: detect-private-key
|
||||
- id: end-of-file-fixer
|
||||
- id: forbid-new-submodules
|
||||
- id: no-commit-to-branch
|
||||
- id: pretty-format-json
|
||||
- id: trailing-whitespace
|
||||
|
||||
# YAML linting
|
||||
- repo: https://github.com/adrienverge/yamllint.git
|
||||
rev: v1.37.1
|
||||
hooks:
|
||||
- id: yamllint
|
||||
args:
|
||||
[
|
||||
"-d {extends: relaxed, rules: {line-length: disable}, ignore: chart}",
|
||||
"-s",
|
||||
]
|
||||
|
||||
# Kubernetes manifest validation
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: kubeconform_validate_apps
|
||||
name: kubeconform validate apps
|
||||
entry: ci/validate-apps.sh
|
||||
language: system
|
||||
pass_filenames: false
|
||||
- id: kubeconform_validate_clusters
|
||||
name: kubeconform validate clusters
|
||||
entry: ci/validate-clusters.sh
|
||||
language: system
|
||||
pass_filenames: false
|
||||
- id: no_plain_secrets
|
||||
name: prevent plain kubernetes secrets
|
||||
entry: ci/validate-no-secrets.sh
|
||||
language: system
|
||||
pass_filenames: false
|
||||
29
.yamllint.yaml
Normal file
29
.yamllint.yaml
Normal file
@ -0,0 +1,29 @@
|
||||
# .yamllint.yaml
|
||||
extends: default
|
||||
|
||||
rules:
|
||||
# Allow long lines for base64 encoded values and URLs
|
||||
line-length:
|
||||
max: 200
|
||||
allow-non-breakable-words: true
|
||||
allow-non-breakable-inline-mappings: true
|
||||
|
||||
# Kubernetes manifests use 2-space indentation
|
||||
indentation:
|
||||
spaces: 2
|
||||
indent-sequences: consistent
|
||||
|
||||
# Allow multiple documents (---) in a single file
|
||||
document-start: enable
|
||||
|
||||
# Be lenient with comments
|
||||
comments:
|
||||
require-starting-space: true
|
||||
min-spaces-from-content: 1
|
||||
|
||||
# Allow empty values (common in Kustomize patches)
|
||||
empty-values: enable
|
||||
|
||||
truthy:
|
||||
# Allow 'on' and 'yes' values (common in Kubernetes)
|
||||
allowed-values: ['true', 'false', 'yes', 'no', 'on', 'off']
|
||||
23
ci/validate-apps.sh
Executable file
23
ci/validate-apps.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
KUBE_VERSION="1.33.7"
|
||||
|
||||
schema_args=(
|
||||
-schema-location "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/{{.NormalizedKubernetesVersion}}-standalone{{.StrictSuffix}}/{{.ResourceKind}}{{.KindSuffix}}.json"
|
||||
-schema-location "https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json"
|
||||
)
|
||||
|
||||
while IFS= read -r -d "" k; do
|
||||
dir="$(dirname "$k")"
|
||||
echo "==> kubeconform: $dir" >&2
|
||||
|
||||
kustomize build --enable-helm "$dir" \
|
||||
| kubeconform \
|
||||
-kubernetes-version "$KUBE_VERSION" \
|
||||
-summary \
|
||||
-output pretty \
|
||||
-verbose \
|
||||
-skip CustomResourceDefinition \
|
||||
"${schema_args[@]}"
|
||||
done < <(find apps/overlays -name kustomization.yaml -print0)
|
||||
23
ci/validate-clusters.sh
Executable file
23
ci/validate-clusters.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
KUBE_VERSION="1.33.7"
|
||||
|
||||
schema_args=(
|
||||
-schema-location "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/{{.NormalizedKubernetesVersion}}-standalone{{.StrictSuffix}}/{{.ResourceKind}}{{.KindSuffix}}.json"
|
||||
-schema-location "https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json"
|
||||
)
|
||||
|
||||
while IFS= read -r -d "" k; do
|
||||
dir="$(dirname "$k")"
|
||||
echo "==> kubeconform: $dir" >&2
|
||||
|
||||
kustomize build --enable-helm "$dir" \
|
||||
| kubeconform \
|
||||
-kubernetes-version "$KUBE_VERSION" \
|
||||
-summary \
|
||||
-output pretty \
|
||||
-verbose \
|
||||
-skip CustomResourceDefinition \
|
||||
"${schema_args[@]}"
|
||||
done < <(find clusters -name kustomization.yaml -print0)
|
||||
22
ci/validate-no-secrets.sh
Executable file
22
ci/validate-no-secrets.sh
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Check staged files for plain Kubernetes Secrets
|
||||
ERRORS=0
|
||||
|
||||
while IFS= read -r -d '' file; do
|
||||
# Skip if file doesn't exist (e.g., deleted files)
|
||||
[[ -f "$file" ]] || continue
|
||||
|
||||
# Check if the file contains a plain Kubernetes Secret
|
||||
if grep -q "^kind: Secret" "$file"; then
|
||||
# Allow secure secret types
|
||||
if ! grep -q -E "^kind: (SealedSecret|ExternalSecret|VaultStaticSecret|VaultDynamicSecret)" "$file"; then
|
||||
echo "BLOCKED: $file contains a plain Kubernetes Secret" >&2
|
||||
echo " Use VaultStaticSecret or VaultDynamicSecret instead" >&2
|
||||
((ERRORS++))
|
||||
fi
|
||||
fi
|
||||
done < <(git diff --cached --name-only --diff-filter=ACM -z | grep -zE '\.(yaml|yml)$')
|
||||
|
||||
exit $ERRORS
|
||||
Loading…
Reference in New Issue
Block a user