Skip to content

Commit

Permalink
Merge pull request #34 from globis-org/feat/analyzer
Browse files Browse the repository at this point in the history
feat: add manifest-analyzer action
  • Loading branch information
yukin01 authored Sep 15, 2023
2 parents 9a2ef9c + 508c00e commit 68ee9a4
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 0 deletions.
56 changes: 56 additions & 0 deletions manifest-analyzer/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: sre-actions/manifest-analyzer
description: Analyze kubernetes manifests
author: sys-gdp
inputs:
base-dir:
description: Base directory to analyze
required: true
head-dir:
description: Head directory to analyze
required: true
k8s-version:
description: Kubernetes version
required: true

runs:
using: composite
steps:
- uses: asdf-vm/actions/install@6a442392015fbbdd8b48696d41e0051b2698b2e4 # v2.2.0
with:
tool_versions: |
kustomize 5.0.1 # Argo CD v2.7.0
kube-score 1.16.1
kubeconform 0.6.1
pluto 5.16.1
dyff 1.5.8
- id: kustomize
run: ${{ github.action_path }}/kustomize.sh
shell: bash
env:
BASE_DIR: ${{ inputs.base-dir }}
HEAD_DIR: ${{ inputs.head-dir }}

- id: dyff
run: ${{ github.action_path }}/dyff.sh
shell: bash
env:
BASE_DIR: ${{ inputs.base-dir }}
HEAD_DIR: ${{ inputs.head-dir }}

- id: lint
run: ${{ github.action_path }}/lint.sh
shell: bash
env:
BASE_DIR: ${{ inputs.base-dir }}
HEAD_DIR: ${{ inputs.head-dir }}
K8S_VERSION: ${{ inputs.k8s-version }}

- uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1
with:
script: |
const { promises: fs } = require('fs');
const dyff = await fs.readFile('${{ steps.dyff.outputs.file }}', 'utf8');
const lint = await fs.readFile('${{ steps.lint.outputs.file }}', 'utf8');
await core.summary.addRaw(dyff).addEOL().addRaw(lint).write();
if: always()
63 changes: 63 additions & 0 deletions manifest-analyzer/dyff.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/bin/bash
set -u

base_dir="$BASE_DIR"
head_dir="$HEAD_DIR"

base_manifest=base.yaml
head_manifest=head.yaml
output_file=dyff.md

function get_emoji() {
if [[ $1 -eq 0 || $1 -eq 1 ]]; then
echo
else
echo 💥
fi
}

function get_message() {
if [[ $1 -eq 0 ]]; then
echo "no changes detected 🎉"
elif [[ $1 -eq 1 ]]; then
echo "some changes detected 👀"
else
echo "dyff failed"
fi
}

diff_output=""
if [[ -s "$base_manifest" ]]; then
diff_output=$(dyff between "$base_manifest" "$head_manifest" --color off --set-exit-code 2>&1)
else
echo "base manifest not found or empty."
touch "$base_manifest"
diff_output=$(diff "$base_manifest" "$head_manifest" --unified 2>&1)
fi
rc=$?

tee "$output_file" << EOS
### $(get_emoji $rc) dyff [$head_dir]
\`\`\`
$(get_message $rc)
\`\`\`
<details><summary>show outputs</summary>
\`\`\`diff
$diff_output
\`\`\`
</details>
EOS

echo "file=$output_file" >> "$GITHUB_OUTPUT"
echo "rc_emoji=$(get_emoji $rc)" >> "$GITHUB_OUTPUT"

if [[ $rc -ne 0 && $rc -ne 1 ]]; then
echo "dyff failed."
exit 1
fi

echo "dyff passed."
29 changes: 29 additions & 0 deletions manifest-analyzer/kustomize.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash
set -eu

base_dir="$BASE_DIR"
head_dir="$HEAD_DIR"

base_manifest=base.yaml
head_manifest=head.yaml

echo "kustomize base directory: $base_dir"
echo "kustomize head directory: $head_dir"
echo "working directory: $(pwd)"

if [[ -d "$base_dir" ]]; then
echo "kustomize build $base_dir"
kustomize build "$base_dir" -o "$base_manifest"
else
touch "$base_manifest"
fi

if [[ -d "$head_dir" ]]; then
echo "kustomize build $head_dir"
kustomize build "$head_dir" -o "$head_manifest"
else
echo "head directory not found: $head_dir"
exit 1
fi

echo "build manifests successfully."
90 changes: 90 additions & 0 deletions manifest-analyzer/lint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/bin/bash
set -u

base_dir="$BASE_DIR"
head_dir="$HEAD_DIR"
version="$K8S_VERSION"

base_manifest=base.yaml
head_manifest=head.yaml
output_file=lint.md

function get_emoji() {
if [[ $1 -eq 0 ]]; then
echo
else
echo 💥
fi
}

format="v[0-9]+.[0-9]+.[0-9]+"

if [[ ! $version =~ $format ]]; then
echo "Invalid version format: $version"
exit 1
fi

minor_version=$(echo "$version" | cut -d. -f1-2)

kubeconform=$(cat "$head_manifest" | kubeconform -strict -output tap \
-ignore-missing-schemas \
-kubernetes-version "${version#v}" 2>&1) # remove prefix "v" from version
rc1=$?

kube_score=$(cat "$head_manifest" | kube-score score -o ci - \
--ignore-test container-security-context-user-group-id \
--ignore-test container-security-context-privileged \
--ignore-test container-security-context-readonlyrootfilesystem \
--ignore-test container-ephemeral-storage-request-and-limit \
--ignore-test pod-probes \
--kubernetes-version "$minor_version" 2>&1)
rc2=$?

pluto=$(cat "$head_manifest" | pluto detect - -o custom \
--columns 'name,kind,version,replacement,deprecated in,removed in' \
--target-versions k8s="$version" 2>&1)
rc3=$?

tee "$output_file" << EOS
### $(get_emoji $rc1) kubeconform [$head_dir]
<details><summary>show outputs</summary>
\`\`\`
$kubeconform
\`\`\`
</details>
### $(get_emoji $rc2) kube-score [$head_dir]
<details><summary>show outputs</summary>
\`\`\`
$kube_score
\`\`\`
</details>
### $(get_emoji $rc3) pluto [$head_dir]
<details><summary>show outputs</summary>
\`\`\`
$pluto
\`\`\`
</details>
EOS

echo "file=$output_file" >> "$GITHUB_OUTPUT"
echo "rc1_emoji=$(get_emoji $rc1)" >> "$GITHUB_OUTPUT"
echo "rc2_emoji=$(get_emoji $rc2)" >> "$GITHUB_OUTPUT"
echo "rc3_emoji=$(get_emoji $rc3)" >> "$GITHUB_OUTPUT"

if [[ $rc1 -ne 0 || $rc2 -ne 0 || $rc3 -ne 0 ]]; then
echo "kubeconform, kube-score or pluto failed."
exit 1
fi

echo "kubeconform, kube-score and pluto passed."

0 comments on commit 68ee9a4

Please sign in to comment.