diff --git a/.github/gitops-action-fleets/action.yml b/.github/gitops-action-fleets/action.yml index 9ec6c68..cf7b51e 100644 --- a/.github/gitops-action-fleets/action.yml +++ b/.github/gitops-action-fleets/action.yml @@ -20,7 +20,18 @@ runs: working-directory: ${{ inputs.working-directory }} run: | FLEET_URL="${FLEET_URL%/}" - FLEET_VERSION="$(curl "$FLEET_URL/api/v1/fleet/version" --header "Authorization: Bearer $FLEET_API_TOKEN" --fail --silent | jq --raw-output '.version')" + + # Build optional custom request headers from FLEET_CUSTOM_HEADERS, a comma-separated + # list of "Header:Value" pairs (e.g. a Cloudflare Access service token). Empty by default. + CURL_HEADER_ARGS=() + if [[ -n "${FLEET_CUSTOM_HEADERS:-}" ]]; then + IFS=',' read -ra _CUSTOM_HEADERS <<< "$FLEET_CUSTOM_HEADERS" + for _header in "${_CUSTOM_HEADERS[@]}"; do + CURL_HEADER_ARGS+=(--header "$_header") + done + fi + + FLEET_VERSION="$(curl "$FLEET_URL/api/v1/fleet/version" --header "Authorization: Bearer $FLEET_API_TOKEN" "${CURL_HEADER_ARGS[@]}" --fail --silent | jq --raw-output '.version')" DEFAULT_FLEETCTL_VERSION="4.87.0" # Decide which fleetctl version to install: @@ -48,7 +59,18 @@ runs: - name: Configure fleetctl shell: bash working-directory: ${{ inputs.working-directory }} - run: fleetctl config set --address ${{ env.FLEET_URL }} --token ${{ env.FLEET_API_TOKEN }} + run: | + # Build optional custom request headers from FLEET_CUSTOM_HEADERS, a comma-separated + # list of "Header:Value" pairs. fleetctl persists them and sends them on every request, + # so the gitops commands below use them too. + CUSTOM_HEADER_ARGS=() + if [[ -n "${FLEET_CUSTOM_HEADERS:-}" ]]; then + IFS=',' read -ra _CUSTOM_HEADERS <<< "$FLEET_CUSTOM_HEADERS" + for _header in "${_CUSTOM_HEADERS[@]}"; do + CUSTOM_HEADER_ARGS+=(--custom-header "$_header") + done + fi + fleetctl config set --address "$FLEET_URL" --token "$FLEET_API_TOKEN" "${CUSTOM_HEADER_ARGS[@]}" - name: Run fleetctl gitops commands shell: bash diff --git a/.github/gitops-action-rc/action.yml b/.github/gitops-action-rc/action.yml index cfa560f..e605b70 100644 --- a/.github/gitops-action-rc/action.yml +++ b/.github/gitops-action-rc/action.yml @@ -37,7 +37,18 @@ runs: - name: Configure fleetctl shell: bash working-directory: ${{ inputs.working-directory }} - run: fleetctl config set --address ${{ env.FLEET_URL }} --token ${{ env.FLEET_API_TOKEN }} + run: | + # Build optional custom request headers from FLEET_CUSTOM_HEADERS, a comma-separated + # list of "Header:Value" pairs. fleetctl persists them and sends them on every request, + # so the gitops commands below use them too. + CUSTOM_HEADER_ARGS=() + if [[ -n "${FLEET_CUSTOM_HEADERS:-}" ]]; then + IFS=',' read -ra _CUSTOM_HEADERS <<< "$FLEET_CUSTOM_HEADERS" + for _header in "${_CUSTOM_HEADERS[@]}"; do + CUSTOM_HEADER_ARGS+=(--custom-header "$_header") + done + fi + fleetctl config set --address "$FLEET_URL" --token "$FLEET_API_TOKEN" "${CUSTOM_HEADER_ARGS[@]}" - name: Run fleetctl gitops commands shell: bash diff --git a/.github/gitops-action/action.yml b/.github/gitops-action/action.yml index cbaf8d1..cfb69d0 100644 --- a/.github/gitops-action/action.yml +++ b/.github/gitops-action/action.yml @@ -20,7 +20,18 @@ runs: working-directory: ${{ inputs.working-directory }} run: | FLEET_URL="${FLEET_URL%/}" - FLEET_VERSION="$(curl "$FLEET_URL/api/v1/fleet/version" --header "Authorization: Bearer $FLEET_API_TOKEN" --fail --silent | jq --raw-output '.version')" + + # Build optional custom request headers from FLEET_CUSTOM_HEADERS, a comma-separated + # list of "Header:Value" pairs (e.g. a Cloudflare Access service token). Empty by default. + CURL_HEADER_ARGS=() + if [[ -n "${FLEET_CUSTOM_HEADERS:-}" ]]; then + IFS=',' read -ra _CUSTOM_HEADERS <<< "$FLEET_CUSTOM_HEADERS" + for _header in "${_CUSTOM_HEADERS[@]}"; do + CURL_HEADER_ARGS+=(--header "$_header") + done + fi + + FLEET_VERSION="$(curl "$FLEET_URL/api/v1/fleet/version" --header "Authorization: Bearer $FLEET_API_TOKEN" "${CURL_HEADER_ARGS[@]}" --fail --silent | jq --raw-output '.version')" DEFAULT_FLEETCTL_VERSION="4.87.0" # Decide which fleetctl version to install: @@ -48,7 +59,18 @@ runs: - name: Configure fleetctl shell: bash working-directory: ${{ inputs.working-directory }} - run: fleetctl config set --address ${{ env.FLEET_URL }} --token ${{ env.FLEET_API_TOKEN }} + run: | + # Build optional custom request headers from FLEET_CUSTOM_HEADERS, a comma-separated + # list of "Header:Value" pairs. fleetctl persists them and sends them on every request, + # so the gitops commands below use them too. + CUSTOM_HEADER_ARGS=() + if [[ -n "${FLEET_CUSTOM_HEADERS:-}" ]]; then + IFS=',' read -ra _CUSTOM_HEADERS <<< "$FLEET_CUSTOM_HEADERS" + for _header in "${_CUSTOM_HEADERS[@]}"; do + CUSTOM_HEADER_ARGS+=(--custom-header "$_header") + done + fi + fleetctl config set --address "$FLEET_URL" --token "$FLEET_API_TOKEN" "${CUSTOM_HEADER_ARGS[@]}" - name: Run fleetctl gitops commands shell: bash diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 57a42d6..9f77087 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -40,6 +40,10 @@ jobs: FLEET_API_TOKEN: ${{ secrets.FLEET_API_TOKEN }} FLEET_PERSONAL_MOBILE_DEVICES_ENROLL_SECRET: ${{ secrets.FLEET_PERSONAL_MOBILE_DEVICES_ENROLL_SECRET }} FLEET_URL: ${{ secrets.FLEET_URL }} + # Optional. Comma-separated list of extra HTTP headers ("Header:Value") sent on every + # request to Fleet, e.g. a Cloudflare Access service token. Add it as a repository + # secret to use it; leave the secret unset to send no extra headers. + FLEET_CUSTOM_HEADERS: ${{ secrets.FLEET_CUSTOM_HEADERS }} FLEET_WORKSTATIONS_ENROLL_SECRET: ${{ secrets.FLEET_WORKSTATIONS_ENROLL_SECRET }} FLEET_GLOBAL_ENROLL_SECRET: ${{ secrets.FLEET_GLOBAL_ENROLL_SECRET }} diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 04afa15..e6fd077 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,6 +2,16 @@ fleet-gitops: image: node:22 variables: FLEET_DRY_RUN_ONLY: true + # Optional. Extra HTTP headers to send on every request to Fleet. They are applied to + # both the version check (curl) and all fleetctl commands (config set / gitops). + # + # Format: a comma-separated list of "Header:Value" pairs. Header values cannot contain + # commas. Leave empty to send no extra headers. + # + # Set the real value as a (masked) CI/CD variable in Settings > CI/CD > Variables, which + # overrides this default. Example for a Cloudflare Access service token: + # FLEET_CUSTOM_HEADERS: "CF-Access-Client-Id:,CF-Access-Client-Secret:" + FLEET_CUSTOM_HEADERS: "" rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event' - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH @@ -14,8 +24,19 @@ fleet-gitops: - apt-get -qq update - apt-get install -y 'jq=1.6-2.1*' script: + # Parse FLEET_CUSTOM_HEADERS into argument arrays for curl and fleetctl. + - | + CURL_HEADER_ARGS=() + FLEETCTL_HEADER_ARGS=() + if [[ -n "$FLEET_CUSTOM_HEADERS" ]]; then + IFS=',' read -ra _CUSTOM_HEADERS <<< "$FLEET_CUSTOM_HEADERS" + for _header in "${_CUSTOM_HEADERS[@]}"; do + CURL_HEADER_ARGS+=(--header "$_header") + FLEETCTL_HEADER_ARGS+=(--custom-header "$_header") + done + fi - > - FLEET_VERSION="$(curl "$FLEET_URL/api/v1/fleet/version" --header "Authorization: Bearer $FLEET_API_TOKEN" --fail --silent | jq --raw-output '.version')" + FLEET_VERSION="$(curl "$FLEET_URL/api/v1/fleet/version" --header "Authorization: Bearer $FLEET_API_TOKEN" "${CURL_HEADER_ARGS[@]}" --fail --silent | jq --raw-output '.version')" - > if [[ -n "$FLEET_VERSION" ]] ; then npm install -g "fleetctl@$FLEET_VERSION" || npm install -g fleetctl @@ -23,5 +44,5 @@ fleet-gitops: echo "Failed to get Fleet version from $FLEET_URL, installing latest version of fleetctl" npm install -g fleetctl fi - - fleetctl config set --address $FLEET_URL --token $FLEET_API_TOKEN + - fleetctl config set --address $FLEET_URL --token $FLEET_API_TOKEN "${FLEETCTL_HEADER_ARGS[@]}" - ./gitops.sh