Skip to content

Commit 2db91c7

Browse files
ATGardnerilia-medvedev-codefresh
authored andcommitted
feat: add Argo CD version check and validation in pre-install hook (#462)
* feat: add Argo CD version check and validation in pre-install hook Enhance the pre-install hook to include a version check for Argo CD. This change introduces environment variables for Argo CD service discovery and version validation, ensuring compatibility with the required version constraint. Additionally, update the Dockerfile to install necessary dependencies for the validation process.
1 parent efa1873 commit 2db91c7

File tree

3 files changed

+144
-4
lines changed

3 files changed

+144
-4
lines changed

charts/gitops-runtime/templates/hooks/pre-install/validate-values.yaml

+131-3
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,139 @@ spec:
3535
valueFrom:
3636
fieldRef:
3737
fieldPath: metadata.namespace
38-
- name: VERSION
38+
- name: CHART_VERSION
3939
value: {{ .Chart.Version }}
40+
- name: ARGOCD_CHECK_VERSION
41+
value: {{ not (get .Values "argo-cd").enabled | quote }}
42+
- name: ARGOCD_LABELS
43+
value: "{{ range $k, $v := .Values.installer.argoCdVersionCheck.argoServerLabels }}{{ $k }}={{ $v }},{{ end }}"
44+
- name: ARGOCD_VERSION_PATH
45+
value: "/api/version"
46+
- name: REQUIRED_VERSION_CONSTRAINT
47+
value: ">=2.12 <3"
4048
command: ["sh", "-c"]
41-
args:
42-
- cf helm validate --values /job_tmp/values.yaml --namespace ${NAMESPACE} --version ${VERSION} --hook --log-level debug
49+
args:
50+
- | # shell
51+
# Function to find Argo CD service and export its name and port
52+
get_argocd_service_info() {
53+
local service_info
54+
local service_count
55+
56+
# Clean labels
57+
CLEAN_LABELS=$(echo "$ARGOCD_LABELS" | sed 's/,$//')
58+
59+
echo "Searching for Argo CD service in namespace '$NAMESPACE' with labels '$CLEAN_LABELS'"
60+
service_info=$(kubectl get svc -n "$NAMESPACE" -l "$CLEAN_LABELS" -o json)
61+
service_count=$(echo "$service_info" | jq '.items | length')
62+
63+
if [ "$service_count" -eq 0 ]; then
64+
echo "Error: No Argo CD service found matching labels '$CLEAN_LABELS' in namespace '$NAMESPACE'."
65+
exit 1
66+
elif [ "$service_count" -gt 1 ]; then
67+
echo "Warning: Found multiple services matching labels '$CLEAN_LABELS'. Using the first one found."
68+
fi
69+
70+
# Set global variables
71+
SERVICE_NAME=$(echo "$service_info" | jq -r '.items[0].metadata.name')
72+
SERVICE_PORT=$(echo "$service_info" | jq -r '.items[0].spec.ports[0].port')
73+
74+
if [ -z "$SERVICE_NAME" ] || [ "$SERVICE_NAME" = "null" ] || [ -z "$SERVICE_PORT" ] || [ "$SERVICE_PORT" = "null" ]; then
75+
echo "Error: Could not extract service name or port from the found service."
76+
exit 1
77+
fi
78+
79+
echo "Found Argo CD service '$SERVICE_NAME' on port '$SERVICE_PORT'"
80+
}
81+
82+
# Function to get and normalize the Argo CD root path
83+
get_argocd_root_path() {
84+
local root_path
85+
86+
echo "Fetching Argo CD root path from ConfigMap '$ARGOCD_CM_PARAMS_NAME' in namespace '$NAMESPACE'..."
87+
root_path=$(kubectl get configmap "$ARGOCD_CM_PARAMS_NAME" -n "$NAMESPACE" -o jsonpath='{.data.server\.rootpath}' 2>/dev/null || echo "")
88+
89+
if [ -n "$root_path" ] && [ "$root_path" != "/" ]; then
90+
root_path=$(echo "$root_path" | sed 's:/*$::') # Remove trailing slash
91+
[ "${root_path#\/}" = "$root_path" ] && root_path="/$root_path" # Add leading slash if missing
92+
elif [ "$root_path" = "/" ]; then
93+
root_path="" # Treat as empty for URL construction
94+
else
95+
echo "Warning: 'server.rootpath' not found in ConfigMap '$ARGOCD_CM_PARAMS_NAME' or ConfigMap not found. Assuming default root path '/'. "
96+
root_path="" # Default to empty string
97+
fi
98+
99+
# Set global variable
100+
ARGOCD_ROOT_PATH="$root_path"
101+
echo "Using Argo CD root path: '${ARGOCD_ROOT_PATH:-/}'"
102+
}
103+
104+
# Function to get the Argo CD version string via API
105+
get_argocd_version_string() {
106+
# Local variables for values obtained internally
107+
local api_full_path
108+
local target_url
109+
local curl_opts
110+
local version_json
111+
local curl_exit_code
112+
113+
# Call functions to get required info - they set global vars
114+
# We'll use the global vars directly after calling
115+
get_argocd_service_info
116+
get_argocd_root_path
117+
118+
# Construct Target URL using the globally set variables
119+
api_full_path=$(echo "${ARGOCD_ROOT_PATH}${ARGOCD_VERSION_PATH}" | sed 's://:/:g')
120+
target_url="http://${SERVICE_NAME}.${NAMESPACE}.svc.cluster.local:${SERVICE_PORT}${api_full_path}"
121+
echo "Checking Argo CD version via API: $target_url"
122+
123+
# Curl Execution
124+
curl_opts="-sS --fail --connect-timeout 10 -L -k" # Base options, follow redirects
125+
version_json=$(curl $curl_opts "$target_url")
126+
curl_exit_code=$?
127+
128+
if [ $curl_exit_code -ne 0 ]; then
129+
echo "Error: Failed to connect to Argo CD API at $target_url (curl exit code: $curl_exit_code)."
130+
exit 1
131+
fi
132+
133+
# Version Parsing - Set global variable
134+
VERSION_STRING=$(echo "$version_json" | jq -r '.Version')
135+
if [ -z "$VERSION_STRING" ] || [ "$VERSION_STRING" = "null" ]; then
136+
echo "Error: Could not parse '.Version' field from API response using jq."
137+
echo "Response JSON: $version_json"
138+
exit 1
139+
fi
140+
}
141+
142+
# Function to validate Argo CD version and perform semver check
143+
validate_argocd_version() {
144+
# Call function to get version string (sets VERSION_STRING)
145+
# This function now internally calls get_argocd_service_info and get_argocd_root_path
146+
get_argocd_version_string
147+
148+
# Clean potential 'v' prefix for semver tool
149+
CLEAN_VERSION_STRING=${VERSION_STRING#v}
150+
151+
echo "Found Argo CD version string: $VERSION_STRING (using $CLEAN_VERSION_STRING for check)"
152+
echo "Required version constraint: $REQUIRED_VERSION_CONSTRAINT"
153+
154+
# --- Semver Check (using semver CLI) ---
155+
echo "Performing semver check using 'semver-cli'..."
156+
if semver-cli satisfies "$CLEAN_VERSION_STRING" "$REQUIRED_VERSION_CONSTRAINT"; then
157+
echo "Argo CD version $VERSION_STRING satisfies range '$REQUIRED_VERSION_CONSTRAINT'."
158+
else
159+
echo "Error: Argo CD version $VERSION_STRING does not satisfy required range '$REQUIRED_VERSION_CONSTRAINT'."
160+
exit 1
161+
fi
162+
}
163+
164+
if [ "$ARGOCD_CHECK_VERSION" = "true" ]; then
165+
validate_argocd_version
166+
fi
167+
168+
# --- Helm Values Validation (cf cli) ---
169+
echo "Argo CD version check passed. Validating helm values using cf cli..."
170+
cf helm validate --values /job_tmp/values.yaml --namespace ${NAMESPACE} --version ${CHART_VERSION} --hook --log-level debug
43171
volumeMounts:
44172
- name: customized-values
45173
mountPath: "/job_tmp"

charts/gitops-runtime/values.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,12 @@ installer:
182182
tag: ""
183183
pullPolicy: IfNotPresent
184184

185+
argoCdVersionCheck:
186+
# Labels to find the Argo CD API server service
187+
argoServerLabels:
188+
app.kubernetes.io/component: server
189+
app.kubernetes.io/part-of: argocd
190+
185191
# -----------------------------------------------------------------------------------------------------------------------
186192
# Sealed secrets
187193
# -----------------------------------------------------------------------------------------------------------------------

installer-image/Dockerfile

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
FROM golang:1.24.2 AS go-build
2+
3+
RUN go install github.com/davidrjonas/semver-cli@latest \
4+
&& cp $GOPATH/bin/semver-cli /usr/local/bin/
5+
16
#bookworm-slim
27
FROM debian:12.10-slim
38

@@ -6,8 +11,9 @@ RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selectio
611
ARG CF_CLI_VERSION=v0.2.6
712
ARG TARGETARCH
813

9-
RUN apt-get update && apt-get install curl -y
14+
RUN apt-get update && apt-get install curl jq -y
1015
RUN curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/${CF_CLI_VERSION}/cf-linux-${TARGETARCH}.tar.gz | tar zx && mv ./cf-linux-${TARGETARCH} /usr/local/bin/cf
16+
COPY --from=go-build /usr/local/bin/semver-cli /usr/local/bin/semver-cli
1117
COPY --from=bitnami/kubectl:1.32.3 /opt/bitnami/kubectl/bin/kubectl /usr/local/bin/
1218

1319
RUN adduser --shell /bin/bash codefresh

0 commit comments

Comments
 (0)