diff --git a/bash/containers/falcon-container-sensor-pull/README.md b/bash/containers/falcon-container-sensor-pull/README.md index 690b9d3..dba7984 100644 --- a/bash/containers/falcon-container-sensor-pull/README.md +++ b/bash/containers/falcon-container-sensor-pull/README.md @@ -101,6 +101,16 @@ Optional Flags: By default, the image name and tag are appended. Use --copy-omit-image-name and/or --copy-custom-tag to change that behavior. -v, --version Specify sensor version to retrieve from the registry + + Accepts version strings or channel keywords: + ------------------------------------------- + latest Latest sensor version (default) + N-1 Previous major.minor release + N-2 Two major.minor releases back + LTS Latest LTS release + LTS-1 Previous LTS release + 7.33 Latest build of version 7.33.x + 7.33.0-18606 Specific sensor build -p, --platform Specify sensor platform to retrieve, e.g., x86_64, aarch64 -t, --type Specify which sensor to download (Default: falcon-container) @@ -144,7 +154,7 @@ Help Options: | `-s`, `--client-secret ` | `$FALCON_CLIENT_SECRET` | `None` (Required) | CrowdStrike API Client Secret | | `-r`, `--region ` | `$FALCON_CLOUD` | `us-1` (Optional) | CrowdStrike Region.
\**Auto-discovery is only available for [`us-1, us-2, eu-1`] regions.* | | `-c`, `--copy ` | `$COPY` | `None` (Optional) | Registry you want to copy the sensor image to. Example: `myregistry.com/mynamespace`.
*\*By default, the image name and tag are appended. Use `--copy-omit-image-name` and/or `--copy-custom-tag` to change that behavior.* | -| `-v`, `--version ` | `$SENSOR_VERSION` | `None` (Optional) | Specify sensor version to retrieve from the registry | +| `-v`, `--version ` | `$SENSOR_VERSION` | `None` (Optional) | Specify sensor version to retrieve from the registry. Accepts version strings (e.g., `7.33`, `7.33.0`) or channel keywords: `latest`, `N-1`, `N-2`, `LTS`, `LTS-1` | | `-p`, `--platform ` | `$SENSOR_PLATFORM` | `None` (Optional) | Specify sensor platform to retrieve from the registry | | `-t`, `--type ` | `$SENSOR_TYPE` | `falcon-container` (Optional) | Specify which sensor to download [`falcon-container`, `falcon-sensor`, `falcon-sensor-regional`, `falcon-kac`, `falcon-snapshot`, `falcon-imageanalyzer`, `fcs`, `falcon-jobcontroller`, `falcon-registryassessmentexecutor`] ([see more details below](#sensor-types)) | | `--runtime` | `$CONTAINER_TOOL` | `docker` (Optional) | Use a different container runtime [docker, podman, skopeo]. **Default is Docker**. | @@ -183,6 +193,45 @@ The following sensor types are available to download: | `falcon-jobcontroller` | The Self Hosted Registry Assessment Jobs Controller | | `falcon-registryassessmentexecutor` | The Self Hosted Registry Assessment Executor | +### Version Channels + +The `-v, --version` flag accepts channel keywords for policy-driven deployments without needing to know exact version numbers: + +| Keyword | Description | +| :------- | :---------------------------------- | +| `latest` | Latest sensor version (default) | +| `N-1` | Previous major.minor release | +| `N-2` | Two major.minor releases back | +| `LTS` | Latest LTS release | +| `LTS-1` | Previous LTS release | + +Channel keywords are case-insensitive (`n-1`, `N-1`, `lts`, `LTS` all work). N-1/N-2 exclude LTS tags from consideration. No additional API scopes are required — channels are resolved entirely from existing registry tag data. + +```shell +# Pull latest (default behavior) +./falcon-container-sensor-pull.sh \ +--client-id \ +--client-secret + +# Pull the previous major.minor release (N-1) +./falcon-container-sensor-pull.sh \ +--client-id \ +--client-secret \ +--version N-1 + +# Pull the latest LTS release +./falcon-container-sensor-pull.sh \ +--client-id \ +--client-secret \ +--version LTS + +# Pull the previous LTS release +./falcon-container-sensor-pull.sh \ +--client-id \ +--client-secret \ +--version LTS-1 +``` + ### Examples #### Example downloading the Falcon Kubernetes Admission Controller diff --git a/bash/containers/falcon-container-sensor-pull/falcon-container-sensor-pull.sh b/bash/containers/falcon-container-sensor-pull/falcon-container-sensor-pull.sh index 9e601bb..c9e0c41 100755 --- a/bash/containers/falcon-container-sensor-pull/falcon-container-sensor-pull.sh +++ b/bash/containers/falcon-container-sensor-pull/falcon-container-sensor-pull.sh @@ -23,6 +23,17 @@ Optional Flags: By default, the image name and tag are appended. Use --copy-omit-image-name and/or --copy-custom-tag to change that behavior. -v, --version Specify sensor version to retrieve from the registry + + Accepts version strings or channel keywords: + ------------------------------------------- + latest Latest sensor version (default) + N-1 Previous major.minor release + N-2 Two major.minor releases back + LTS Latest LTS release + LTS-1 Previous LTS release + 7.33 Latest build of version 7.33.x + 7.33.0-18606 Specific sensor build + -p, --platform Specify sensor platform to retrieve, e.g., x86_64, aarch64 -t, --type Specify which sensor to download (Default: falcon-container) @@ -454,6 +465,88 @@ display_api_scopes() { esac } +# Extract clean tag strings from list_tags JSON output +extract_raw_tags() { + list_tags | awk ' + /^[[:space:]]*"[0-9]/ { + gsub(/^[[:space:]]*"/, "") + gsub(/"[[:space:]]*,?[[:space:]]*$/, "") + if (length($0) > 0) print $0 + } + ' +} + +# Resolve version channel keywords (latest, N-1, N-2, LTS, LTS-1) to version prefixes +resolve_version_channel() { + local input="$1" + local normalized all_tags major_minor_versions lts_tags lts_versions target_version + + normalized=$(echo "$input" | tr '[:upper:]' '[:lower:]') + + case "$normalized" in + latest) + echo "" + return 0 + ;; + n-1 | n-2 | lts | lts-1) + all_tags=$(extract_raw_tags) + if [ -z "$all_tags" ]; then + die "No tags found for sensor type: ${SENSOR_TYPE}" + fi + ;; + *) + # Not a channel keyword — pass through as-is + echo "$input" + return 0 + ;; + esac + + case "$normalized" in + n-1) + major_minor_versions=$(echo "$all_tags" | grep -v "\-LTS" | + awk -F'.' '{ print $1"."$2 }' | sort -u -V) + if [ "$(echo "$major_minor_versions" | wc -l)" -lt 2 ]; then + die "Not enough versions available for N-1. Only $(echo "$major_minor_versions" | wc -l | tr -d ' ') major.minor version(s) found." + fi + target_version=$(echo "$major_minor_versions" | tail -2 | head -1) + ;; + n-2) + major_minor_versions=$(echo "$all_tags" | grep -v "\-LTS" | + awk -F'.' '{ print $1"."$2 }' | sort -u -V) + if [ "$(echo "$major_minor_versions" | wc -l)" -lt 3 ]; then + die "Not enough versions available for N-2. Only $(echo "$major_minor_versions" | wc -l | tr -d ' ') major.minor version(s) found." + fi + target_version=$(echo "$major_minor_versions" | tail -3 | head -1) + ;; + lts) + lts_tags=$(echo "$all_tags" | grep "\-LTS") + if [ -z "$lts_tags" ]; then + die "No LTS versions found for sensor type: ${SENSOR_TYPE}" + fi + lts_versions=$(echo "$lts_tags" | awk -F'.' '{ print $1"."$2 }' | sort -u -V) + target_version=$(echo "$lts_versions" | tail -1) + ;; + lts-1) + lts_tags=$(echo "$all_tags" | grep "\-LTS") + if [ -z "$lts_tags" ]; then + die "No LTS versions found for sensor type: ${SENSOR_TYPE}" + fi + lts_versions=$(echo "$lts_tags" | awk -F'.' '{ print $1"."$2 }' | sort -u -V) + if [ "$(echo "$lts_versions" | wc -l)" -lt 2 ]; then + die "Not enough LTS versions available for LTS-1. Only $(echo "$lts_versions" | wc -l | tr -d ' ') LTS version(s) found." + fi + target_version=$(echo "$lts_versions" | tail -2 | head -1) + ;; + esac + + if [ -z "$target_version" ]; then + return 1 + fi + + echo "$target_version" + return 0 +} + # Smart version matching function match_sensor_version() { local requested_version="$1" @@ -462,14 +555,7 @@ match_sensor_version() { local version_pattern # Get all available tags by properly parsing JSON output from list_tags - all_tags=$(list_tags | awk ' - /^[[:space:]]*"[0-9]/ { - # Extract quoted tag (lines starting with version numbers), remove surrounding quotes and whitespace - gsub(/^[[:space:]]*"/, "") - gsub(/"[[:space:]]*,?[[:space:]]*$/, "") - if (length($0) > 0) print $0 - } - ') + all_tags=$(extract_raw_tags) if [ -z "$requested_version" ]; then # If no version specified, get the latest version @@ -835,10 +921,14 @@ if [ "${ERROR}" = "true" ]; then die "ERROR: ${CONTAINER_TOOL} login failed. Error message: ${error_message}" fi -#Get latest sensor version -set +e # Temporarily disable exit-on-error for version matching -LATESTSENSOR=$(match_sensor_version "$SENSOR_VERSION") -set -e # Re-enable exit-on-error +# Resolve channel keywords (latest, N-1, N-2, LTS, LTS-1) to version prefixes. +RESOLVED_VERSION=$(resolve_version_channel "$SENSOR_VERSION") + +# Get latest sensor version +# match_sensor_version returns 1 for "no match" — a soft failure we handle below. +set +e +LATESTSENSOR=$(match_sensor_version "$RESOLVED_VERSION") +set -e # Re-enable exit-on-error # Check if version matching was successful if [ -z "$LATESTSENSOR" ]; then @@ -847,6 +937,7 @@ if [ -z "$LATESTSENSOR" ]; then Available versions can be listed with: $0 --list-tags -t ${SENSOR_TYPE} Tips for version matching: + - Use channel keywords: -v latest, -v N-1, -v N-2, -v LTS, -v LTS-1 - Use exact version: -v 7.31.0 - Use partial version: -v 7.31 (matches latest 7.31.x) - Use major version: -v 7 (matches latest 7.x.x)