Skip to content

Commit 2409cb0

Browse files
committed
feat: enhance Argo CD version check with improved validation logic
Refactor the Argo CD version check in the pre-install hook to include additional validation functions. This change introduces a more robust method for fetching and validating the Argo CD service information and version, ensuring compliance with specified version constraints. The configuration options for the version check have also been streamlined in the values.yaml file.
1 parent bf6573f commit 2409cb0

File tree

2 files changed

+124
-82
lines changed

2 files changed

+124
-82
lines changed

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

Lines changed: 124 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -31,92 +31,142 @@ spec:
3131
image: "{{ .Values.installer.image.repository }}:{{ .Values.installer.image.tag | default .Chart.Version }}"
3232
imagePullPolicy: {{ .Values.installer.image.pullPolicy }}
3333
env:
34-
- name: ARGOCD_LABELS
35-
value: "{{ range $k, $v := .Values.installer.argoCdVersionCheck.argoServerLabels }}{{ $k }}={{ $v }},{{ end }}"
36-
- name: ARGOCD_VERSION_PATH
37-
value: {{ .Values.installer.argoCdVersionCheck.versionPath | default "/api/version" }}
38-
- name: ARGOCD_SCHEME
39-
value: {{ .Values.installer.argoCdVersionCheck.scheme | default "http" }}
40-
- name: ARGOCD_INSECURE
41-
value: {{ .Values.installer.argoCdVersionCheck.insecureSkipVerify | default false | quote }}
42-
- name: REQUIRED_VERSION_CONSTRAINT
43-
value: ">=2.12 <3"
4434
- name: NAMESPACE
4535
valueFrom:
4636
fieldRef:
4737
fieldPath: metadata.namespace
4838
- name: CHART_VERSION
4939
value: {{ .Chart.Version }}
40+
{{- if not (get .Values "argo-cd").enabled }}
41+
- name: ARGOCD_LABELS
42+
value: "{{ range $k, $v := .Values.installer.argoCdVersionCheck.argoServerLabels }}{{ $k }}={{ $v }},{{ end }}"
43+
- name: ARGOCD_VERSION_PATH
44+
value: "/api/version"
45+
- name: REQUIRED_VERSION_CONSTRAINT
46+
value: ">=2.12 <3"
47+
{{- end }}
5048
command: ["sh", "-c"]
5149
args:
5250
- | # shell
53-
# --- Service Discovery and Version Fetching ---
54-
# (This part remains the same as the previous version)
55-
CLEAN_LABELS=$(echo "$ARGOCD_LABELS" | sed 's/,$//')
56-
echo "Searching for Argo CD service in namespace '$NAMESPACE' with labels '$CLEAN_LABELS'"
57-
SERVICE_INFO=$(kubectl get svc -n "$NAMESPACE" -l "$CLEAN_LABELS" -o json)
58-
SERVICE_COUNT=$(echo "$SERVICE_INFO" | jq '.items | length')
59-
60-
if [ "$SERVICE_COUNT" -eq 0 ]; then
61-
echo "Error: No Argo CD service found matching labels '$CLEAN_LABELS' in namespace '$NAMESPACE'."
62-
exit 1
63-
elif [ "$SERVICE_COUNT" -gt 1 ]; then
64-
echo "Warning: Found multiple services matching labels '$CLEAN_LABELS'. Using the first one found."
65-
fi
66-
67-
SERVICE_NAME=$(echo "$SERVICE_INFO" | jq -r '.items[0].metadata.name')
68-
SERVICE_PORT=$(echo "$SERVICE_INFO" | jq -r '.items[0].spec.ports[0].port')
69-
70-
if [ -z "$SERVICE_NAME" ] || [ "$SERVICE_NAME" = "null" ] || [ -z "$SERVICE_PORT" ] || [ "$SERVICE_PORT" = "null" ]; then
71-
echo "Error: Could not extract service name or port from the found service."
72-
exit 1
73-
fi
74-
75-
echo "Found Argo CD service '$SERVICE_NAME' on port '$SERVICE_PORT'"
76-
TARGET_URL="${ARGOCD_SCHEME}://${SERVICE_NAME}.${NAMESPACE}.svc.cluster.local:${SERVICE_PORT}${ARGOCD_VERSION_PATH}"
77-
echo "Checking Argo CD version via API: $TARGET_URL"
78-
79-
CURL_OPTS="-sS --fail --connect-timeout 10"
80-
if [ "$ARGOCD_SCHEME" = "https" ] && [ "$ARGOCD_INSECURE" = "true" ]; then
81-
CURL_OPTS="$CURL_OPTS -k"
82-
fi
83-
84-
VERSION_JSON=$(curl $CURL_OPTS "$TARGET_URL")
85-
CURL_EXIT_CODE=$?
86-
87-
if [ $CURL_EXIT_CODE -ne 0 ]; then
88-
echo "Error: Failed to connect to Argo CD API at $TARGET_URL (curl exit code: $CURL_EXIT_CODE)."
89-
exit 1
90-
fi
91-
92-
VERSION_STRING=$(echo "$VERSION_JSON" | jq -r '.Version')
93-
94-
if [ -z "$VERSION_STRING" ] || [ "$VERSION_STRING" = "null" ]; then
95-
echo "Error: Could not parse '.Version' field from API response using jq."
96-
echo "Response JSON: $VERSION_JSON"
97-
exit 1
98-
fi
99-
100-
# Clean potential 'v' prefix for semver tool
101-
CLEAN_VERSION_STRING=${VERSION_STRING#v}
102-
103-
echo "Found Argo CD version string: $VERSION_STRING (using $CLEAN_VERSION_STRING for check)"
104-
echo "Required version constraint: $REQUIRED_VERSION_CONSTRAINT"
105-
106-
# --- Semver Check (using semver CLI) ---
107-
echo "Performing semver check using 'semver' CLI..."
108-
# The semver command will exit non-zero if the version doesn't satisfy the range.
109-
# 'set -e' will cause the script to exit immediately if semver fails.
110-
if semver-cli satisfies "$CLEAN_VERSION_STRING" "$REQUIRED_VERSION_CONSTRAINT"; then
111-
echo "Argo CD version $VERSION_STRING satisfies range '$REQUIRED_VERSION_CONSTRAINT'."
112-
else
113-
echo "Error: Argo CD version $VERSION_STRING does not satisfy required range '$REQUIRED_VERSION_CONSTRAINT'."
114-
exit 1 # Explicitly exit 1 for clarity, though 'set -e' would handle it
115-
fi
51+
{{- if not (get .Values "argo-cd").enabled }}
52+
# Function to find Argo CD service and export its name and port
53+
get_argocd_service_info() {
54+
local service_info
55+
local service_count
56+
57+
# Clean labels
58+
CLEAN_LABELS=$(echo "$ARGOCD_LABELS" | sed 's/,$//')
59+
60+
echo "Searching for Argo CD service in namespace '$NAMESPACE' with labels '$CLEAN_LABELS'"
61+
service_info=$(kubectl get svc -n "$NAMESPACE" -l "$CLEAN_LABELS" -o json)
62+
service_count=$(echo "$service_info" | jq '.items | length')
63+
64+
if [ "$service_count" -eq 0 ]; then
65+
echo "Error: No Argo CD service found matching labels '$CLEAN_LABELS' in namespace '$NAMESPACE'."
66+
exit 1
67+
elif [ "$service_count" -gt 1 ]; then
68+
echo "Warning: Found multiple services matching labels '$CLEAN_LABELS'. Using the first one found."
69+
fi
70+
71+
# Set global variables
72+
SERVICE_NAME=$(echo "$service_info" | jq -r '.items[0].metadata.name')
73+
SERVICE_PORT=$(echo "$service_info" | jq -r '.items[0].spec.ports[0].port')
74+
75+
if [ -z "$SERVICE_NAME" ] || [ "$SERVICE_NAME" = "null" ] || [ -z "$SERVICE_PORT" ] || [ "$SERVICE_PORT" = "null" ]; then
76+
echo "Error: Could not extract service name or port from the found service."
77+
exit 1
78+
fi
79+
80+
echo "Found Argo CD service '$SERVICE_NAME' on port '$SERVICE_PORT'"
81+
}
82+
83+
# Function to get and normalize the Argo CD root path
84+
get_argocd_root_path() {
85+
local root_path
86+
87+
echo "Fetching Argo CD root path from ConfigMap '$ARGOCD_CM_PARAMS_NAME' in namespace '$NAMESPACE'..."
88+
root_path=$(kubectl get configmap "$ARGOCD_CM_PARAMS_NAME" -n "$NAMESPACE" -o jsonpath='{.data.server\.rootpath}' 2>/dev/null || echo "")
89+
90+
if [ -n "$root_path" ] && [ "$root_path" != "/" ]; then
91+
root_path=$(echo "$root_path" | sed 's:/*$::') # Remove trailing slash
92+
[ "${root_path#\/}" = "$root_path" ] && root_path="/$root_path" # Add leading slash if missing
93+
elif [ "$root_path" = "/" ]; then
94+
root_path="" # Treat as empty for URL construction
95+
else
96+
echo "Warning: 'server.rootpath' not found in ConfigMap '$ARGOCD_CM_PARAMS_NAME' or ConfigMap not found. Assuming default root path '/'. "
97+
root_path="" # Default to empty string
98+
fi
99+
100+
# Set global variable
101+
ARGOCD_ROOT_PATH="$root_path"
102+
echo "Using Argo CD root path: '${ARGOCD_ROOT_PATH:-/}'"
103+
}
104+
105+
# Function to get the Argo CD version string via API
106+
get_argocd_version_string() {
107+
# Local variables for values obtained internally
108+
local api_full_path
109+
local target_url
110+
local curl_opts
111+
local version_json
112+
local curl_exit_code
113+
114+
# Call functions to get required info - they set global vars
115+
# We'll use the global vars directly after calling
116+
get_argocd_service_info
117+
get_argocd_root_path
118+
119+
# Construct Target URL using the globally set variables
120+
api_full_path=$(echo "${ARGOCD_ROOT_PATH}${ARGOCD_VERSION_PATH}" | sed 's://:/:g')
121+
target_url="http://${SERVICE_NAME}.${NAMESPACE}.svc.cluster.local:${SERVICE_PORT}${api_full_path}"
122+
echo "Checking Argo CD version via API: $target_url"
123+
124+
# Curl Execution
125+
curl_opts="-sS --fail --connect-timeout 10 -L -k" # Base options, follow redirects
126+
version_json=$(curl $curl_opts "$target_url")
127+
curl_exit_code=$?
128+
129+
if [ $curl_exit_code -ne 0 ]; then
130+
echo "Error: Failed to connect to Argo CD API at $target_url (curl exit code: $curl_exit_code)."
131+
exit 1
132+
fi
133+
134+
# Version Parsing - Set global variable
135+
VERSION_STRING=$(echo "$version_json" | jq -r '.Version')
136+
if [ -z "$VERSION_STRING" ] || [ "$VERSION_STRING" = "null" ]; then
137+
echo "Error: Could not parse '.Version' field from API response using jq."
138+
echo "Response JSON: $version_json"
139+
exit 1
140+
fi
141+
}
142+
143+
# Function to validate Argo CD version and perform semver check
144+
validate_argocd_version() {
145+
# Call function to get version string (sets VERSION_STRING)
146+
# This function now internally calls get_argocd_service_info and get_argocd_root_path
147+
get_argocd_version_string
148+
149+
# Clean potential 'v' prefix for semver tool
150+
CLEAN_VERSION_STRING=${VERSION_STRING#v}
151+
152+
echo "Found Argo CD version string: $VERSION_STRING (using $CLEAN_VERSION_STRING for check)"
153+
echo "Required version constraint: $REQUIRED_VERSION_CONSTRAINT"
154+
155+
# --- Semver Check (using semver CLI) ---
156+
echo "Performing semver check using 'semver-cli'..."
157+
if semver-cli satisfies "$CLEAN_VERSION_STRING" "$REQUIRED_VERSION_CONSTRAINT"; then
158+
echo "Argo CD version $VERSION_STRING satisfies range '$REQUIRED_VERSION_CONSTRAINT'."
159+
else
160+
echo "Error: Argo CD version $VERSION_STRING does not satisfy required range '$REQUIRED_VERSION_CONSTRAINT'."
161+
exit 1
162+
fi
163+
}
164+
165+
validate_argocd_version
116166

117167
# --- Helm Values Validation (cf cli) ---
118-
# This part only runs if the semver check passes
119168
echo "Argo CD version check passed. Validating helm values using cf cli..."
169+
{{- end }}
120170
cf helm validate --values /job_tmp/values.yaml --namespace ${NAMESPACE} --version ${CHART_VERSION} --hook --log-level debug
121171
volumeMounts:
122172
- name: customized-values

charts/gitops-runtime/values.yaml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -183,18 +183,10 @@ installer:
183183
pullPolicy: IfNotPresent
184184

185185
argoCdVersionCheck:
186-
enabled: true
187186
# Labels to find the Argo CD API server service
188-
# Note: Typically the 'server' component provides the API, not 'repo-server'. Adjust if needed.
189187
argoServerLabels:
190188
app.kubernetes.io/component: server
191189
app.kubernetes.io/part-of: argocd
192-
# API path to get version info
193-
versionPath: /api/version
194-
# Scheme to use (http or https). Dynamic detection is complex, assuming http.
195-
scheme: http
196-
# Set to true if using https with self-signed certs and want to skip verification
197-
insecureSkipVerify: false
198190

199191
# -----------------------------------------------------------------------------------------------------------------------
200192
# Sealed secrets

0 commit comments

Comments
 (0)