Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0d80215207 | |||
| e0e7018a55 | |||
| 3676ccf990 |
Executable
+5
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
repo_root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
||||||
|
"${repo_root}/scripts/check-chart.sh"
|
||||||
@@ -44,18 +44,30 @@ The rendered reference reflects the default values in `helm/values.yaml`, so opt
|
|||||||
|
|
||||||
For fast validation while wiring up infrastructure, use these tools together:
|
For fast validation while wiring up infrastructure, use these tools together:
|
||||||
|
|
||||||
- `helm lint ./helm`
|
- `./scripts/check-chart.sh`
|
||||||
- `helm template agentguard-ci ./helm`
|
- `RUN_KUBECTL_CLIENT_CHECK=1 ./scripts/check-chart.sh`
|
||||||
- `helm template agentguard-ci ./helm | kubectl apply --dry-run=client -f -`
|
- `RUN_KUBECTL_SERVER_CHECK=1 ./scripts/check-chart.sh`
|
||||||
- `helm template agentguard-ci ./helm | kubectl apply --dry-run=server -f -`
|
|
||||||
- `argo lint rendered.yaml`
|
What each mode does:
|
||||||
|
|
||||||
|
- `./scripts/check-chart.sh` runs the fast offline checks used by the repo-managed pre-commit hook: `helm lint`, `helm template`, and `argo lint --offline`.
|
||||||
|
- `RUN_KUBECTL_CLIENT_CHECK=1 ./scripts/check-chart.sh` adds a client-side `kubectl` dry-run. This is optional because CRD-heavy manifests can still be environment-sensitive here.
|
||||||
|
- `RUN_KUBECTL_SERVER_CHECK=1 ./scripts/check-chart.sh` adds a server-side dry-run against your current cluster context, which is the strongest validation once the Argo and Infisical CRDs are installed.
|
||||||
|
|
||||||
|
Install the shared git hook once per clone:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git config core.hooksPath .githooks
|
||||||
|
```
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
- `helm lint` catches Helm chart problems.
|
- `helm lint` catches Helm chart problems.
|
||||||
- `kubectl --dry-run=client` catches basic Kubernetes schema issues without talking to the cluster.
|
- `helm template` proves the chart renders successfully with the current values.
|
||||||
- `kubectl --dry-run=server` is better once the cluster already has the Argo and Infisical CRDs installed.
|
- `argo lint --offline` is the most useful Argo-specific local check because it validates the rendered `ClusterWorkflowTemplate` without needing cluster access.
|
||||||
- `argo lint` is the most useful Argo-specific check once you have the Argo CLI installed.
|
- `kubectl --dry-run=client` is weaker for CRDs than Argo lint, so it is included as an optional extra check instead of the default hook behavior.
|
||||||
|
- `kubectl --dry-run=server` is best once the cluster already has the Argo and Infisical CRDs installed.
|
||||||
|
- CI should still rerun the same baseline checks even if pre-commit already passed, because hooks are local and bypassable. The usual CI extra is the server-side `kubectl` dry-run once a cluster with the needed CRDs is available.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,268 @@
|
|||||||
|
# Rendered reference for the default chart values in helm/values.yaml.
|
||||||
|
# This is intended for reading and review, so you can inspect the final Argo object
|
||||||
|
# without also mentally evaluating Helm templates.
|
||||||
|
#
|
||||||
|
# Notes:
|
||||||
|
# - Optional storage, DefectDojo, and Infisical resources are omitted because they are
|
||||||
|
# disabled by default.
|
||||||
|
# - Argo placeholders such as {{workflow.parameters.repo-url}} are expected and remain
|
||||||
|
# in the rendered object because Argo resolves them at workflow runtime.
|
||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: ClusterWorkflowTemplate
|
||||||
|
metadata:
|
||||||
|
name: amp-security-pipeline-v1.0.0
|
||||||
|
spec:
|
||||||
|
serviceAccountName: default
|
||||||
|
entrypoint: security-pipeline
|
||||||
|
onExit: pipeline-exit-hook
|
||||||
|
volumeClaimTemplates:
|
||||||
|
- metadata:
|
||||||
|
name: workspace
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 1Gi
|
||||||
|
arguments:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
value: "."
|
||||||
|
- name: fail-on-cvss
|
||||||
|
value: "7.0"
|
||||||
|
- name: repo-url
|
||||||
|
- name: git-revision
|
||||||
|
value: "main"
|
||||||
|
templates:
|
||||||
|
- name: security-pipeline
|
||||||
|
dag:
|
||||||
|
tasks:
|
||||||
|
- name: clone
|
||||||
|
template: clone-repo
|
||||||
|
arguments:
|
||||||
|
parameters:
|
||||||
|
- name: repo-url
|
||||||
|
value: "{{workflow.parameters.repo-url}}"
|
||||||
|
- name: git-revision
|
||||||
|
value: "{{workflow.parameters.git-revision}}"
|
||||||
|
- name: scanners
|
||||||
|
dependencies:
|
||||||
|
- clone
|
||||||
|
template: parallel-scanners
|
||||||
|
arguments:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
value: "{{workflow.parameters.working-dir}}"
|
||||||
|
- name: enforce-policy
|
||||||
|
dependencies:
|
||||||
|
- scanners
|
||||||
|
template: enforce-policy
|
||||||
|
arguments:
|
||||||
|
parameters:
|
||||||
|
- name: fail-on-cvss
|
||||||
|
value: "{{workflow.parameters.fail-on-cvss}}"
|
||||||
|
- name: clone-repo
|
||||||
|
inputs:
|
||||||
|
parameters:
|
||||||
|
- name: repo-url
|
||||||
|
- name: git-revision
|
||||||
|
container:
|
||||||
|
image: alpine/git:2.45.2
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
args:
|
||||||
|
- git clone --branch "{{inputs.parameters.git-revision}}" --single-branch "{{inputs.parameters.repo-url}}" /workspace
|
||||||
|
volumeMounts:
|
||||||
|
- name: workspace
|
||||||
|
mountPath: /workspace
|
||||||
|
- name: parallel-scanners
|
||||||
|
inputs:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
dag:
|
||||||
|
tasks:
|
||||||
|
- name: trufflehog
|
||||||
|
template: scan-trufflehog
|
||||||
|
arguments:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
value: "{{inputs.parameters.working-dir}}"
|
||||||
|
- name: semgrep
|
||||||
|
template: scan-semgrep
|
||||||
|
arguments:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
value: "{{inputs.parameters.working-dir}}"
|
||||||
|
- name: kics
|
||||||
|
template: scan-kics
|
||||||
|
arguments:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
value: "{{inputs.parameters.working-dir}}"
|
||||||
|
- name: socketdev
|
||||||
|
template: scan-socketdev
|
||||||
|
arguments:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
value: "{{inputs.parameters.working-dir}}"
|
||||||
|
- name: syft-grype
|
||||||
|
template: scan-syft-grype
|
||||||
|
arguments:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
value: "{{inputs.parameters.working-dir}}"
|
||||||
|
- name: pulumi-crossguard
|
||||||
|
template: scan-pulumi-crossguard
|
||||||
|
arguments:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
value: "{{inputs.parameters.working-dir}}"
|
||||||
|
- name: pipeline-exit-hook
|
||||||
|
container:
|
||||||
|
image: curlimages/curl:8.8.0
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
set -eu
|
||||||
|
echo "Pipeline completed with status: {{workflow.status}}"
|
||||||
|
- name: scan-trufflehog
|
||||||
|
inputs:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
container:
|
||||||
|
image: trufflesecurity/trufflehog:latest
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
set -eu
|
||||||
|
mkdir -p /workspace/reports
|
||||||
|
trufflehog filesystem "/workspace/{{inputs.parameters.working-dir}}" --json > /workspace/reports/trufflehog.json || true
|
||||||
|
volumeMounts:
|
||||||
|
- name: workspace
|
||||||
|
mountPath: /workspace
|
||||||
|
- name: scan-semgrep
|
||||||
|
inputs:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
container:
|
||||||
|
image: returntocorp/semgrep:1.85.0
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
set -eu
|
||||||
|
mkdir -p /workspace/reports
|
||||||
|
semgrep scan --config auto --sarif --output /workspace/reports/semgrep.sarif "/workspace/{{inputs.parameters.working-dir}}" || true
|
||||||
|
volumeMounts:
|
||||||
|
- name: workspace
|
||||||
|
mountPath: /workspace
|
||||||
|
- name: scan-kics
|
||||||
|
inputs:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
container:
|
||||||
|
image: checkmarx/kics:1.7.14
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
set -eu
|
||||||
|
mkdir -p /workspace/reports
|
||||||
|
kics scan -p "/workspace/{{inputs.parameters.working-dir}}" -o /workspace/reports --report-formats sarif,json --output-name kics || true
|
||||||
|
if [ -f /workspace/reports/kics.sarif ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
if [ -f /workspace/reports/kics.json ]; then
|
||||||
|
cp /workspace/reports/kics.json /workspace/reports/kics.sarif
|
||||||
|
fi
|
||||||
|
volumeMounts:
|
||||||
|
- name: workspace
|
||||||
|
mountPath: /workspace
|
||||||
|
- name: scan-socketdev
|
||||||
|
inputs:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
container:
|
||||||
|
image: socketdev/socketcli:latest
|
||||||
|
env:
|
||||||
|
- name: SOCKET_DEV_API_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: amp-security-pipeline-secrets
|
||||||
|
key: SOCKET_DEV_API_KEY
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
set -eu
|
||||||
|
mkdir -p /workspace/reports
|
||||||
|
socketdev scan "/workspace/{{inputs.parameters.working-dir}}" --format json --output /workspace/reports/socketdev.json || true
|
||||||
|
volumeMounts:
|
||||||
|
- name: workspace
|
||||||
|
mountPath: /workspace
|
||||||
|
- name: scan-syft-grype
|
||||||
|
inputs:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
container:
|
||||||
|
image: anchore/syft:latest
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
set -eu
|
||||||
|
mkdir -p /workspace/reports
|
||||||
|
syft scan dir:/workspace/{{inputs.parameters.working-dir}} -o cyclonedx-json=/workspace/reports/sbom.json || true
|
||||||
|
grype sbom:/workspace/reports/sbom.json -o sarif=/workspace/reports/grype.sarif || true
|
||||||
|
volumeMounts:
|
||||||
|
- name: workspace
|
||||||
|
mountPath: /workspace
|
||||||
|
- name: scan-pulumi-crossguard
|
||||||
|
inputs:
|
||||||
|
parameters:
|
||||||
|
- name: working-dir
|
||||||
|
container:
|
||||||
|
image: pulumi/pulumi:3.154.0
|
||||||
|
env:
|
||||||
|
- name: PULUMI_ACCESS_TOKEN
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: amp-security-pipeline-secrets
|
||||||
|
key: PULUMI_ACCESS_TOKEN
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
args:
|
||||||
|
- |
|
||||||
|
set -eu
|
||||||
|
mkdir -p /workspace/reports
|
||||||
|
cd "/workspace/{{inputs.parameters.working-dir}}"
|
||||||
|
pulumi preview --policy-pack "policy-pack" > /workspace/reports/pulumi-crossguard.json 2>&1 || true
|
||||||
|
volumeMounts:
|
||||||
|
- name: workspace
|
||||||
|
mountPath: /workspace
|
||||||
|
- name: enforce-policy
|
||||||
|
inputs:
|
||||||
|
parameters:
|
||||||
|
- name: fail-on-cvss
|
||||||
|
container:
|
||||||
|
image: agentguard-tools:latest
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
command:
|
||||||
|
- node
|
||||||
|
- /app/dist/enforce-policy.js
|
||||||
|
env:
|
||||||
|
- name: FAIL_ON_CVSS
|
||||||
|
value: "{{inputs.parameters.fail-on-cvss}}"
|
||||||
|
volumeMounts:
|
||||||
|
- name: workspace
|
||||||
|
mountPath: /workspace
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json-schema.org/draft-07/schema#",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"pipeline": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"description": "Core Argo workflow settings.",
|
||||||
|
"properties": {
|
||||||
|
"enabled": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Render the ClusterWorkflowTemplate when true."
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Name of the ClusterWorkflowTemplate resource.",
|
||||||
|
"minLength": 1
|
||||||
|
},
|
||||||
|
"serviceAccountName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Service account used by workflow pods.",
|
||||||
|
"minLength": 1
|
||||||
|
},
|
||||||
|
"workingDir": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Repository path scanned inside the cloned workspace.",
|
||||||
|
"minLength": 1
|
||||||
|
},
|
||||||
|
"gitRevision": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Default git revision to clone when the workflow caller does not override it.",
|
||||||
|
"minLength": 1
|
||||||
|
},
|
||||||
|
"failOnCvss": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "CVSS threshold passed to the policy enforcement utility.",
|
||||||
|
"pattern": "^[0-9]+(\\.[0-9]+)?$"
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"description": "PVC configuration for the shared workspace volume.",
|
||||||
|
"properties": {
|
||||||
|
"storage": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Requested workspace PVC size, for example 1Gi.",
|
||||||
|
"minLength": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"storage"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"repoName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Repository name used in storage upload paths.",
|
||||||
|
"minLength": 1
|
||||||
|
},
|
||||||
|
"scanners": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Ordered list of scanner templates wired into the scanner fan-out DAG.",
|
||||||
|
"minItems": 1,
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"trufflehog",
|
||||||
|
"semgrep",
|
||||||
|
"kics",
|
||||||
|
"socketdev",
|
||||||
|
"syft-grype",
|
||||||
|
"pulumi-crossguard"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"uniqueItems": true
|
||||||
|
},
|
||||||
|
"toolsImage": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"description": "Custom image that packages the Node utilities used by the workflow.",
|
||||||
|
"properties": {
|
||||||
|
"repository": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1
|
||||||
|
},
|
||||||
|
"tag": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1
|
||||||
|
},
|
||||||
|
"pullPolicy": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Always",
|
||||||
|
"IfNotPresent",
|
||||||
|
"Never"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"repository",
|
||||||
|
"tag",
|
||||||
|
"pullPolicy"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"enabled",
|
||||||
|
"name",
|
||||||
|
"serviceAccountName",
|
||||||
|
"workingDir",
|
||||||
|
"gitRevision",
|
||||||
|
"failOnCvss",
|
||||||
|
"workspace",
|
||||||
|
"repoName",
|
||||||
|
"scanners",
|
||||||
|
"toolsImage"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"images": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"description": "Container images used by each workflow step.",
|
||||||
|
"properties": {
|
||||||
|
"git": { "type": "string", "minLength": 1 },
|
||||||
|
"trufflehog": { "type": "string", "minLength": 1 },
|
||||||
|
"semgrep": { "type": "string", "minLength": 1 },
|
||||||
|
"kics": { "type": "string", "minLength": 1 },
|
||||||
|
"socketdev": { "type": "string", "minLength": 1 },
|
||||||
|
"syftGrype": { "type": "string", "minLength": 1 },
|
||||||
|
"pulumiCrossguard": { "type": "string", "minLength": 1 },
|
||||||
|
"awsCli": { "type": "string", "minLength": 1 },
|
||||||
|
"curl": { "type": "string", "minLength": 1 }
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"git",
|
||||||
|
"trufflehog",
|
||||||
|
"semgrep",
|
||||||
|
"kics",
|
||||||
|
"socketdev",
|
||||||
|
"syftGrype",
|
||||||
|
"pulumiCrossguard",
|
||||||
|
"awsCli",
|
||||||
|
"curl"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"description": "Optional raw report upload configuration.",
|
||||||
|
"properties": {
|
||||||
|
"enabled": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"reportsBucket": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1
|
||||||
|
},
|
||||||
|
"endpoint": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Optional custom S3 endpoint for MinIO or another compatible store."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"enabled",
|
||||||
|
"reportsBucket",
|
||||||
|
"endpoint"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"pulumi": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"description": "Pulumi CrossGuard scanner settings.",
|
||||||
|
"properties": {
|
||||||
|
"policyPackPath": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"policyPackPath"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"defectdojo": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"description": "Optional DefectDojo upload step configuration.",
|
||||||
|
"properties": {
|
||||||
|
"enabled": { "type": "boolean" },
|
||||||
|
"productTypeName": { "type": "string", "minLength": 1 },
|
||||||
|
"productName": { "type": "string", "minLength": 1 },
|
||||||
|
"engagementName": { "type": "string", "minLength": 1 },
|
||||||
|
"minimumSeverity": { "type": "string", "minLength": 1 },
|
||||||
|
"active": { "type": "boolean" },
|
||||||
|
"verified": { "type": "boolean" },
|
||||||
|
"closeOldFindings": { "type": "boolean" },
|
||||||
|
"autoCreateContext": { "type": "boolean" }
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"enabled",
|
||||||
|
"productTypeName",
|
||||||
|
"productName",
|
||||||
|
"engagementName",
|
||||||
|
"minimumSeverity",
|
||||||
|
"active",
|
||||||
|
"verified",
|
||||||
|
"closeOldFindings",
|
||||||
|
"autoCreateContext"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"infisical": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"description": "Optional Infisical operator integration.",
|
||||||
|
"properties": {
|
||||||
|
"enabled": { "type": "boolean" },
|
||||||
|
"workspaceSlug": { "type": "string" },
|
||||||
|
"projectSlug": { "type": "string" }
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"enabled",
|
||||||
|
"workspaceSlug",
|
||||||
|
"projectSlug"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"pipeline",
|
||||||
|
"images",
|
||||||
|
"storage",
|
||||||
|
"pulumi",
|
||||||
|
"defectdojo",
|
||||||
|
"infisical"
|
||||||
|
]
|
||||||
|
}
|
||||||
Executable
+59
@@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
repo_root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
||||||
|
chart_dir="${repo_root}/helm"
|
||||||
|
rendered_manifest="$(mktemp --suffix=.yaml)"
|
||||||
|
release_name="${RELEASE_NAME:-agentguard-ci}"
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
rm -f "${rendered_manifest}"
|
||||||
|
}
|
||||||
|
|
||||||
|
require_command() {
|
||||||
|
if ! command -v "$1" >/dev/null 2>&1; then
|
||||||
|
printf 'Missing required command: %s\n' "$1" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
run_kubectl_client_check() {
|
||||||
|
require_command kubectl
|
||||||
|
if ! kubectl apply --dry-run=client --validate=false -f "${rendered_manifest}" >/dev/null 2>&1; then
|
||||||
|
cat <<'EOF' >&2
|
||||||
|
kubectl client dry-run failed.
|
||||||
|
For Argo CRDs, this check can still be environment-sensitive and is optional here.
|
||||||
|
Re-run without RUN_KUBECTL_CLIENT_CHECK=1, or use RUN_KUBECTL_SERVER_CHECK=1 against a cluster with the CRDs installed.
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
run_kubectl_server_check() {
|
||||||
|
require_command kubectl
|
||||||
|
kubectl apply --dry-run=server -f "${rendered_manifest}" >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
require_command helm
|
||||||
|
require_command argo
|
||||||
|
|
||||||
|
printf '==> helm lint\n'
|
||||||
|
helm lint "${chart_dir}"
|
||||||
|
|
||||||
|
printf '==> helm template\n'
|
||||||
|
helm template "${release_name}" "${chart_dir}" > "${rendered_manifest}"
|
||||||
|
|
||||||
|
printf '==> argo lint --offline\n'
|
||||||
|
argo lint --offline --kinds=clusterworkflowtemplates "${rendered_manifest}"
|
||||||
|
|
||||||
|
if [[ "${RUN_KUBECTL_CLIENT_CHECK:-0}" == "1" ]]; then
|
||||||
|
printf '==> kubectl apply --dry-run=client\n'
|
||||||
|
run_kubectl_client_check
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${RUN_KUBECTL_SERVER_CHECK:-0}" == "1" ]]; then
|
||||||
|
printf '==> kubectl apply --dry-run=server\n'
|
||||||
|
run_kubectl_server_check
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user