[NET-5622] build: consolidate Envoy version management (#21245)

* build: consolidate Envoy version management

Simplify Envoy version management by consolidating all runtime, build,
and CI sources of Envoy versions into a single plaintext file.

The goal of this change is to avoid common mistakes missing an update of
some Envoy versions (both in general and due to release branch
inconsistency), and enable automated Envoy version updates in the
future.

* ci: add missing ref argument for get-go-version

Supports nightly tests.
This commit is contained in:
Michael Zalimeni 2024-07-05 15:19:23 -04:00 committed by GitHub
parent 763cd0bffb
commit 40ca4ad6d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 460 additions and 221 deletions

View File

@ -39,12 +39,20 @@ jobs:
get-go-version: get-go-version:
uses: ./.github/workflows/reusable-get-go-version.yml uses: ./.github/workflows/reusable-get-go-version.yml
with:
ref: ${{ inputs.branch }}
get-envoy-versions:
uses: ./.github/workflows/reusable-get-envoy-versions.yml
with:
ref: ${{ inputs.branch }}
tests: tests:
runs-on: ${{ fromJSON(needs.setup.outputs.compute-xl ) }} runs-on: ${{ fromJSON(needs.setup.outputs.compute-xl ) }}
needs: needs:
- setup - setup
- get-go-version - get-go-version
- get-envoy-versions
permissions: permissions:
id-token: write # NOTE: this permission is explicitly required for Vault auth. id-token: write # NOTE: this permission is explicitly required for Vault auth.
contents: read contents: read
@ -62,7 +70,7 @@ jobs:
name: '${{matrix.test-case}}' name: '${{matrix.test-case}}'
env: env:
ENVOY_VERSION: "1.29.5" ENVOY_VERSION: ${{ needs.get-envoy-versions.outputs.max-envoy-version }}
steps: steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
# NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos.

View File

@ -50,6 +50,14 @@ jobs:
get-go-version: get-go-version:
needs: [check-ent] needs: [check-ent]
uses: ./.github/workflows/reusable-get-go-version.yml uses: ./.github/workflows/reusable-get-go-version.yml
with:
ref: release/1.15.x
get-envoy-versions:
needs: [check-ent]
uses: ./.github/workflows/reusable-get-envoy-versions.yml
with:
ref: release/1.15.x
dev-build: dev-build:
needs: needs:
@ -79,28 +87,25 @@ jobs:
- name: Generate Envoy Job Matrix - name: Generate Envoy Job Matrix
id: set-matrix id: set-matrix
env: env:
# this is further going to multiplied in envoy-integration tests by the # TEST_SPLITS sets the number of test case splits to use in the matrix. This will be
# other dimensions in the matrix. Currently TOTAL_RUNNERS would be # further multiplied in envoy-integration tests by the other dimensions in the matrix
# 14 based on these values: # to determine the total number of runners used.
# envoy-version: ["1.22.11", "1.23.12", "1.24.12", "1.25.11", "1.26.8", "1.27.5", "1.28.3"] TEST_SPLITS: 4
# xds-target: ["server", "client"]
TOTAL_RUNNERS: 7
JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]'
run: | run: |
NUM_RUNNERS=$TOTAL_RUNNERS
NUM_DIRS=$(find ./test/integration/connect/envoy -mindepth 1 -maxdepth 1 -type d | wc -l) NUM_DIRS=$(find ./test/integration/connect/envoy -mindepth 1 -maxdepth 1 -type d | wc -l)
if [ "$NUM_DIRS" -lt "$NUM_RUNNERS" ]; then if [ "$NUM_DIRS" -lt "$TEST_SPLITS" ]; then
echo "TOTAL_RUNNERS is larger than the number of tests/packages to split." echo "TEST_SPLITS is larger than the number of tests/packages to split."
NUM_RUNNERS=$((NUM_DIRS-1)) TEST_SPLITS=$((NUM_DIRS-1))
fi fi
# fix issue where test splitting calculation generates 1 more split than TOTAL_RUNNERS. # fix issue where test splitting calculation generates 1 more split than TEST_SPLITS.
NUM_RUNNERS=$((NUM_RUNNERS-1)) TEST_SPLITS=$((TEST_SPLITS-1))
{ {
echo -n "envoy-matrix=" echo -n "envoy-matrix="
find ./test/integration/connect/envoy -maxdepth 1 -type d -print0 \ find ./test/integration/connect/envoy -maxdepth 1 -type d -print0 \
| xargs -0 -n 1 basename \ | xargs -0 -n 1 basename \
| jq --raw-input --argjson runnercount "$NUM_RUNNERS" "$JQ_SLICER" \ | jq --raw-input --argjson runnercount "$TEST_SPLITS" "$JQ_SLICER" \
| jq --compact-output 'map(join("|"))' | jq --compact-output 'map(join("|"))'
} >> "$GITHUB_OUTPUT" } >> "$GITHUB_OUTPUT"
@ -109,6 +114,7 @@ jobs:
needs: needs:
- setup - setup
- get-go-version - get-go-version
- get-envoy-versions
- generate-envoy-job-matrices - generate-envoy-job-matrices
- dev-build - dev-build
permissions: permissions:
@ -117,7 +123,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
envoy-version: ["1.22.11", "1.23.12", "1.24.12", "1.25.11", "1.26.8", "1.27.6", "1.28.4"] envoy-version: ${{ fromJSON(needs.get-envoy-versions.outputs.envoy-versions-json) }}
xds-target: ["server", "client"] xds-target: ["server", "client"]
test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }}
env: env:
@ -212,7 +218,17 @@ jobs:
consul-version: ["1.14", "1.15"] consul-version: ["1.14", "1.15"]
env: env:
CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} CONSUL_LATEST_VERSION: ${{ matrix.consul-version }}
ENVOY_VERSION: "1.24.6" # ENVOY_VERSION should be the latest version supported by _all_ Consul versions in the
# matrix.consul-version, since we are testing upgrade from an older Consul version.
# In practice, this should be the highest Envoy version supported by the lowest non-LTS
# Consul version in the matrix (LTS versions receive additional Envoy version support).
#
# This value should be kept current in new nightly test workflows, and updated any time
# a new major Envoy release is added to the set supported by Consul versions in
# matrix.consul-version (i.e. whenever the highest common Envoy version across active
# Consul versions changes). The minor Envoy version does not necessarily need to be
# kept current for the purpose of these tests, but the major (1.N) version should be.
ENVOY_VERSION: "1.24.12"
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4

View File

@ -50,6 +50,14 @@ jobs:
get-go-version: get-go-version:
needs: [check-ent] needs: [check-ent]
uses: ./.github/workflows/reusable-get-go-version.yml uses: ./.github/workflows/reusable-get-go-version.yml
with:
ref: release/1.17.x
get-envoy-versions:
needs: [check-ent]
uses: ./.github/workflows/reusable-get-envoy-versions.yml
with:
ref: release/1.17.x
dev-build: dev-build:
needs: needs:
@ -79,28 +87,25 @@ jobs:
- name: Generate Envoy Job Matrix - name: Generate Envoy Job Matrix
id: set-matrix id: set-matrix
env: env:
# this is further going to multiplied in envoy-integration tests by the # TEST_SPLITS sets the number of test case splits to use in the matrix. This will be
# other dimensions in the matrix. Currently TOTAL_RUNNERS would be # further multiplied in envoy-integration tests by the other dimensions in the matrix
# multiplied by 8 based on these values: # to determine the total number of runners used.
# envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.5"] TEST_SPLITS: 4
# xds-target: ["server", "client"]
TOTAL_RUNNERS: 4
JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]'
run: | run: |
NUM_RUNNERS=$TOTAL_RUNNERS
NUM_DIRS=$(find ./test/integration/connect/envoy -mindepth 1 -maxdepth 1 -type d | wc -l) NUM_DIRS=$(find ./test/integration/connect/envoy -mindepth 1 -maxdepth 1 -type d | wc -l)
if [ "$NUM_DIRS" -lt "$NUM_RUNNERS" ]; then if [ "$NUM_DIRS" -lt "$TEST_SPLITS" ]; then
echo "TOTAL_RUNNERS is larger than the number of tests/packages to split." echo "TEST_SPLITS is larger than the number of tests/packages to split."
NUM_RUNNERS=$((NUM_DIRS-1)) TEST_SPLITS=$((NUM_DIRS-1))
fi fi
# fix issue where test splitting calculation generates 1 more split than TOTAL_RUNNERS. # fix issue where test splitting calculation generates 1 more split than TEST_SPLITS.
NUM_RUNNERS=$((NUM_RUNNERS-1)) TEST_SPLITS=$((TEST_SPLITS-1))
{ {
echo -n "envoy-matrix=" echo -n "envoy-matrix="
find ./test/integration/connect/envoy -maxdepth 1 -type d -print0 \ find ./test/integration/connect/envoy -maxdepth 1 -type d -print0 \
| xargs -0 -n 1 basename \ | xargs -0 -n 1 basename \
| jq --raw-input --argjson runnercount "$NUM_RUNNERS" "$JQ_SLICER" \ | jq --raw-input --argjson runnercount "$TEST_SPLITS" "$JQ_SLICER" \
| jq --compact-output 'map(join("|"))' | jq --compact-output 'map(join("|"))'
} >> "$GITHUB_OUTPUT" } >> "$GITHUB_OUTPUT"
@ -109,6 +114,7 @@ jobs:
needs: needs:
- setup - setup
- get-go-version - get-go-version
- get-envoy-versions
- generate-envoy-job-matrices - generate-envoy-job-matrices
- dev-build - dev-build
permissions: permissions:
@ -117,7 +123,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.6"] envoy-version: ${{ fromJSON(needs.get-envoy-versions.outputs.envoy-versions-json) }}
xds-target: ["server", "client"] xds-target: ["server", "client"]
test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }}
env: env:
@ -215,7 +221,17 @@ jobs:
consul-version: ["1.15", "1.16", "1.17"] consul-version: ["1.15", "1.16", "1.17"]
env: env:
CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} CONSUL_LATEST_VERSION: ${{ matrix.consul-version }}
ENVOY_VERSION: "1.24.6" # ENVOY_VERSION should be the latest version supported by _all_ Consul versions in the
# matrix.consul-version, since we are testing upgrade from an older Consul version.
# In practice, this should be the highest Envoy version supported by the lowest non-LTS
# Consul version in the matrix (LTS versions receive additional Envoy version support).
#
# This value should be kept current in new nightly test workflows, and updated any time
# a new major Envoy release is added to the set supported by Consul versions in
# matrix.consul-version (i.e. whenever the highest common Envoy version across active
# Consul versions changes). The minor Envoy version does not necessarily need to be
# kept current for the purpose of these tests, but the major (1.N) version should be.
ENVOY_VERSION: 1.27.6
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4

View File

@ -50,6 +50,13 @@ jobs:
get-go-version: get-go-version:
needs: [check-ent] needs: [check-ent]
uses: ./.github/workflows/reusable-get-go-version.yml uses: ./.github/workflows/reusable-get-go-version.yml
with:
ref: release/1.18.x
get-envoy-versions:
uses: ./.github/workflows/reusable-get-envoy-versions.yml
with:
ref: release/1.18.x
dev-build: dev-build:
needs: needs:
@ -79,28 +86,25 @@ jobs:
- name: Generate Envoy Job Matrix - name: Generate Envoy Job Matrix
id: set-matrix id: set-matrix
env: env:
# this is further going to multiplied in envoy-integration tests by the # TEST_SPLITS sets the number of test case splits to use in the matrix. This will be
# other dimensions in the matrix. Currently TOTAL_RUNNERS would be # further multiplied in envoy-integration tests by the other dimensions in the matrix
# multiplied by 8 based on these values: # to determine the total number of runners used.
# envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.6"] TEST_SPLITS: 4
# xds-target: ["server", "client"]
TOTAL_RUNNERS: 4
JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]'
run: | run: |
NUM_RUNNERS=$TOTAL_RUNNERS
NUM_DIRS=$(find ./test/integration/connect/envoy -mindepth 1 -maxdepth 1 -type d | wc -l) NUM_DIRS=$(find ./test/integration/connect/envoy -mindepth 1 -maxdepth 1 -type d | wc -l)
if [ "$NUM_DIRS" -lt "$NUM_RUNNERS" ]; then if [ "$NUM_DIRS" -lt "$TEST_SPLITS" ]; then
echo "TOTAL_RUNNERS is larger than the number of tests/packages to split." echo "TEST_SPLITS is larger than the number of tests/packages to split."
NUM_RUNNERS=$((NUM_DIRS-1)) TEST_SPLITS=$((NUM_DIRS-1))
fi fi
# fix issue where test splitting calculation generates 1 more split than TOTAL_RUNNERS. # fix issue where test splitting calculation generates 1 more split than TEST_SPLITS.
NUM_RUNNERS=$((NUM_RUNNERS-1)) TEST_SPLITS=$((TEST_SPLITS-1))
{ {
echo -n "envoy-matrix=" echo -n "envoy-matrix="
find ./test/integration/connect/envoy -maxdepth 1 -type d -print0 \ find ./test/integration/connect/envoy -maxdepth 1 -type d -print0 \
| xargs -0 -n 1 basename \ | xargs -0 -n 1 basename \
| jq --raw-input --argjson runnercount "$NUM_RUNNERS" "$JQ_SLICER" \ | jq --raw-input --argjson runnercount "$TEST_SPLITS" "$JQ_SLICER" \
| jq --compact-output 'map(join("|"))' | jq --compact-output 'map(join("|"))'
} >> "$GITHUB_OUTPUT" } >> "$GITHUB_OUTPUT"
@ -109,6 +113,7 @@ jobs:
needs: needs:
- setup - setup
- get-go-version - get-go-version
- get-envoy-versions
- generate-envoy-job-matrices - generate-envoy-job-matrices
- dev-build - dev-build
permissions: permissions:
@ -117,7 +122,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.6"] envoy-version: ${{ fromJSON(needs.get-envoy-versions.outputs.envoy-versions-json) }}
xds-target: ["server", "client"] xds-target: ["server", "client"]
test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }}
env: env:
@ -212,10 +217,20 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
consul-version: ["1.15", "1.16", "1.17"] consul-version: ["1.15", "1.16", "1.17", "1.18"]
env: env:
CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} CONSUL_LATEST_VERSION: ${{ matrix.consul-version }}
ENVOY_VERSION: "1.24.6" # ENVOY_VERSION should be the latest version supported by _all_ Consul versions in the
# matrix.consul-version, since we are testing upgrade from an older Consul version.
# In practice, this should be the highest Envoy version supported by the lowest non-LTS
# Consul version in the matrix (LTS versions receive additional Envoy version support).
#
# This value should be kept current in new nightly test workflows, and updated any time
# a new major Envoy release is added to the set supported by Consul versions in
# matrix.consul-version (i.e. whenever the highest common Envoy version across active
# Consul versions changes). The minor Envoy version does not necessarily need to be
# kept current for the purpose of these tests, but the major (1.N) version should be.
ENVOY_VERSION: 1.27.6
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4

View File

@ -42,6 +42,13 @@ jobs:
get-go-version: get-go-version:
uses: ./.github/workflows/reusable-get-go-version.yml uses: ./.github/workflows/reusable-get-go-version.yml
with:
ref: release/1.19.x
get-envoy-versions:
uses: ./.github/workflows/reusable-get-envoy-versions.yml
with:
ref: release/1.19.x
dev-build: dev-build:
needs: needs:
@ -71,28 +78,25 @@ jobs:
- name: Generate Envoy Job Matrix - name: Generate Envoy Job Matrix
id: set-matrix id: set-matrix
env: env:
# this is further going to multiplied in envoy-integration tests by the # TEST_SPLITS sets the number of test case splits to use in the matrix. This will be
# other dimensions in the matrix. Currently TOTAL_RUNNERS would be # further multiplied in envoy-integration tests by the other dimensions in the matrix
# multiplied by 8 based on these values: # to determine the total number of runners used.
# envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.6"] TEST_SPLITS: 4
# xds-target: ["server", "client"]
TOTAL_RUNNERS: 4
JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]'
run: | run: |
NUM_RUNNERS=$TOTAL_RUNNERS
NUM_DIRS=$(find ./test/integration/connect/envoy -mindepth 1 -maxdepth 1 -type d | wc -l) NUM_DIRS=$(find ./test/integration/connect/envoy -mindepth 1 -maxdepth 1 -type d | wc -l)
if [ "$NUM_DIRS" -lt "$NUM_RUNNERS" ]; then if [ "$NUM_DIRS" -lt "$TEST_SPLITS" ]; then
echo "TOTAL_RUNNERS is larger than the number of tests/packages to split." echo "TEST_SPLITS is larger than the number of tests/packages to split."
NUM_RUNNERS=$((NUM_DIRS-1)) TEST_SPLITS=$((NUM_DIRS-1))
fi fi
# fix issue where test splitting calculation generates 1 more split than TOTAL_RUNNERS. # fix issue where test splitting calculation generates 1 more split than TEST_SPLITS.
NUM_RUNNERS=$((NUM_RUNNERS-1)) TEST_SPLITS=$((TEST_SPLITS-1))
{ {
echo -n "envoy-matrix=" echo -n "envoy-matrix="
find ./test/integration/connect/envoy -maxdepth 1 -type d -print0 \ find ./test/integration/connect/envoy -maxdepth 1 -type d -print0 \
| xargs -0 -n 1 basename \ | xargs -0 -n 1 basename \
| jq --raw-input --argjson runnercount "$NUM_RUNNERS" "$JQ_SLICER" \ | jq --raw-input --argjson runnercount "$TEST_SPLITS" "$JQ_SLICER" \
| jq --compact-output 'map(join("|"))' | jq --compact-output 'map(join("|"))'
} >> "$GITHUB_OUTPUT" } >> "$GITHUB_OUTPUT"
@ -101,6 +105,7 @@ jobs:
needs: needs:
- setup - setup
- get-go-version - get-go-version
- get-envoy-versions
- generate-envoy-job-matrices - generate-envoy-job-matrices
- dev-build - dev-build
permissions: permissions:
@ -109,7 +114,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
envoy-version: ["1.26.8", "1.27.6", "1.28.4", "1.29.5"] envoy-version: ${{ fromJSON(needs.get-envoy-versions.outputs.envoy-versions-json) }}
xds-target: ["server", "client"] xds-target: ["server", "client"]
test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }}
env: env:
@ -197,6 +202,7 @@ jobs:
needs: needs:
- setup - setup
- get-go-version - get-go-version
- get-envoy-versions
- dev-build - dev-build
permissions: permissions:
id-token: write # NOTE: this permission is explicitly required for Vault auth. id-token: write # NOTE: this permission is explicitly required for Vault auth.
@ -204,10 +210,20 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
consul-version: ["1.15", "1.17", "1.18"] consul-version: ["1.15", "1.17", "1.18", "1.19"]
env: env:
CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} CONSUL_LATEST_VERSION: ${{ matrix.consul-version }}
ENVOY_VERSION: "1.24.6" # ENVOY_VERSION should be the latest version supported by _all_ Consul versions in the
# matrix.consul-version, since we are testing upgrade from an older Consul version.
# In practice, this should be the highest Envoy version supported by the lowest non-LTS
# Consul version in the matrix (LTS versions receive additional Envoy version support).
#
# This value should be kept current in new nightly test workflows, and updated any time
# a new major Envoy release is added to the set supported by Consul versions in
# matrix.consul-version (i.e. whenever the highest common Envoy version across active
# Consul versions changes). The minor Envoy version does not necessarily need to be
# kept current for the purpose of these tests, but the major (1.N) version should be.
ENVOY_VERSION: 1.27.6
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4

View File

@ -41,6 +41,9 @@ jobs:
get-go-version: get-go-version:
uses: ./.github/workflows/reusable-get-go-version.yml uses: ./.github/workflows/reusable-get-go-version.yml
get-envoy-versions:
uses: ./.github/workflows/reusable-get-envoy-versions.yml
dev-build: dev-build:
needs: needs:
- setup - setup
@ -55,7 +58,9 @@ jobs:
elevated-github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} elevated-github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
generate-envoy-job-matrices: generate-envoy-job-matrices:
needs: [setup] needs:
- setup
- get-envoy-versions
runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }}
name: Generate Envoy Job Matrices name: Generate Envoy Job Matrices
outputs: outputs:
@ -68,28 +73,25 @@ jobs:
- name: Generate Envoy Job Matrix - name: Generate Envoy Job Matrix
id: set-matrix id: set-matrix
env: env:
# this is further going to multiplied in envoy-integration tests by the # TEST_SPLITS sets the number of test case splits to use in the matrix. This will be
# other dimensions in the matrix. Currently TOTAL_RUNNERS would be # further multiplied in envoy-integration tests by the other dimensions in the matrix
# multiplied by 8 based on these values: # to determine the total number of runners used.
# envoy-version: ["1.26.8", "1.27.5", "1.28.3", "1.29.4"] TEST_SPLITS: 4
# xds-target: ["server", "client"]
TOTAL_RUNNERS: 8
JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]'
run: | run: |
NUM_RUNNERS=$TOTAL_RUNNERS
NUM_DIRS=$(find ./test/integration/connect/envoy -mindepth 1 -maxdepth 1 -type d | wc -l) NUM_DIRS=$(find ./test/integration/connect/envoy -mindepth 1 -maxdepth 1 -type d | wc -l)
if [ "$NUM_DIRS" -lt "$NUM_RUNNERS" ]; then if [ "$NUM_DIRS" -lt "$TEST_SPLITS" ]; then
echo "TOTAL_RUNNERS is larger than the number of tests/packages to split." echo "TEST_SPLITS is larger than the number of tests/packages to split."
NUM_RUNNERS=$((NUM_DIRS-1)) TEST_SPLITS=$((NUM_DIRS-1))
fi fi
# fix issue where test splitting calculation generates 1 more split than TOTAL_RUNNERS. # fix issue where test splitting calculation generates 1 more split than TEST_SPLITS.
NUM_RUNNERS=$((NUM_RUNNERS-1)) TEST_SPLITS=$((TEST_SPLITS-1))
{ {
echo -n "envoy-matrix=" echo -n "envoy-matrix="
find ./test/integration/connect/envoy -maxdepth 1 -type d -print0 \ find ./test/integration/connect/envoy -maxdepth 1 -type d -print0 \
| xargs -0 -n 1 basename \ | xargs -0 -n 1 basename \
| jq --raw-input --argjson runnercount "$NUM_RUNNERS" "$JQ_SLICER" \ | jq --raw-input --argjson runnercount "$TEST_SPLITS" "$JQ_SLICER" \
| jq --compact-output 'map(join("|"))' | jq --compact-output 'map(join("|"))'
} >> "$GITHUB_OUTPUT" } >> "$GITHUB_OUTPUT"
@ -98,6 +100,7 @@ jobs:
needs: needs:
- setup - setup
- get-go-version - get-go-version
- get-envoy-versions
- generate-envoy-job-matrices - generate-envoy-job-matrices
- dev-build - dev-build
permissions: permissions:
@ -106,7 +109,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
envoy-version: ["1.26.8", "1.27.6", "1.28.4", "1.29.5"] envoy-version: ${{ fromJSON(needs.get-envoy-versions.outputs.envoy-versions-json) }}
xds-target: ["server", "client"] xds-target: ["server", "client"]
test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }}
env: env:
@ -201,13 +204,20 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
consul-version: [ "1.17", "1.18"] consul-version: ["1.17", "1.18", "1.19"]
env: env:
CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} CONSUL_LATEST_VERSION: ${{ matrix.consul-version }}
# ENVOY_VERSION should be the latest version upported by all # ENVOY_VERSION should be the latest version supported by _all_ Consul versions in the
# consul versions in the matrix.consul-version, since we are testing upgrade from # matrix.consul-version, since we are testing upgrade from an older Consul version.
# an older consul version, e.g., 1.27.x is supported by both 1.17 and 1.18. # In practice, this should be the highest Envoy version supported by the lowest non-LTS
ENVOY_VERSION: "1.27.6" # Consul version in the matrix (LTS versions receive additional Envoy version support).
#
# This value should be kept current in new nightly test workflows, and updated any time
# a new major Envoy release is added to the set supported by Consul versions in
# matrix.consul-version (i.e. whenever the highest common Envoy version across active
# Consul versions changes). The minor Envoy version does not necessarily need to be
# kept current for the purpose of these tests, but the major (1.N) version should be.
ENVOY_VERSION: 1.27.6
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4

View File

@ -0,0 +1,71 @@
name: get-envoy-versions
# Reads the canonical ENVOY_VERSIONS file for either the current branch or a specified version of Consul,
# and returns both the max and all supported Envoy versions.
on:
workflow_call:
inputs:
ref:
description: |
The Consul ref/branch (e.g. release/1.18.x) for which to determine supported Envoy versions.
If not provided, the default actions/checkout value (current ref) is used.
type: string
outputs:
max-envoy-version:
description: The max supported Envoy version for the specified Consul version
value: ${{ jobs.get-envoy-versions.outputs.max-envoy-version }}
envoy-versions:
description: |
All supported Envoy versions for the specified Consul version (formatted as multiline string with one version
per line, in descending order)
value: ${{ jobs.get-envoy-versions.outputs.envoy-versions }}
envoy-versions-json:
description: |
All supported Envoy versions for the specified Consul version (formatted as JSON array)
value: ${{ jobs.get-envoy-versions.outputs.envoy-versions-json }}
jobs:
get-envoy-versions:
name: "Determine supported Envoy versions"
runs-on: ubuntu-latest
outputs:
max-envoy-version: ${{ steps.get-envoy-versions.outputs.max-envoy-version }}
envoy-versions: ${{ steps.get-envoy-versions.outputs.envoy-versions }}
envoy-versions-json: ${{ steps.get-envoy-versions.outputs.envoy-versions-json }}
steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
with:
# If not set, will default to current branch.
ref: ${{ inputs.ref }}
- name: Determine Envoy versions
id: get-envoy-versions
# Note that this script assumes that the ENVOY_VERSIONS file is in the envoyextensions/xdscommon directory.
# If in the future this file moves between branches, we could introduce a workflow input for the path that
# defaults to the new value, and manually configure the old value as needed.
run: |
MAX_ENVOY_VERSION=$(cat envoyextensions/xdscommon/ENVOY_VERSIONS | grep '^[[:digit:]]' | sort -nr | head -n 1)
ENVOY_VERSIONS=$(cat envoyextensions/xdscommon/ENVOY_VERSIONS | grep '^[[:digit:]]' | sort -nr)
ENVOY_VERSIONS_JSON=$(echo -n '[' && echo "${ENVOY_VERSIONS}" | awk '{printf "\"%s\",", $0}' | sed 's/,$//' && echo -n ']')
# Loop through each line of ENVOY_VERSIONS and compare it to the regex
while IFS= read -r version; do
if ! [[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo 'Invalid version in ENVOY_VERSIONS: '$version' does not match the pattern ^[0-9]+\.[0-9]+\.[0-9]+$'
exit 1
fi
done <<< "$ENVOY_VERSIONS"
if ! [[ $MAX_ENVOY_VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo 'Invalid MAX_ENVOY_VERSION: '$MAX_ENVOY_VERSION' does not match the pattern ^[0-9]+\.[0-9]+\.[0-9]+$'
exit 1
fi
echo "Supported Envoy versions:"
echo "${ENVOY_VERSIONS}"
echo "envoy-versions<<EOF" >> $GITHUB_OUTPUT
echo "${ENVOY_VERSIONS}" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "Supported Envoy versions JSON: ${ENVOY_VERSIONS_JSON}"
echo "envoy-versions-json=${ENVOY_VERSIONS_JSON}" >> $GITHUB_OUTPUT
echo "Max supported Envoy version: ${MAX_ENVOY_VERSION}"
echo "max-envoy-version=${MAX_ENVOY_VERSION}" >> $GITHUB_OUTPUT

View File

@ -2,6 +2,12 @@ name: get-go-version
on: on:
workflow_call: workflow_call:
inputs:
ref:
description: |
The Consul ref/branch (e.g. release/1.18.x) for which to determine the Go version.
If not provided, the default actions/checkout value (current ref) is used.
type: string
outputs: outputs:
go-version: go-version:
description: "The Go version detected by this workflow" description: "The Go version detected by this workflow"
@ -19,6 +25,9 @@ jobs:
go-version-previous: ${{ steps.get-go-version.outputs.go-version-previous }} go-version-previous: ${{ steps.get-go-version.outputs.go-version-previous }}
steps: steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
with:
# If not set, will default to current branch.
ref: ${{ inputs.ref }}
- name: Determine Go version - name: Determine Go version
id: get-go-version id: get-go-version
# We use .go-version as our source of truth for current Go # We use .go-version as our source of truth for current Go

View File

@ -63,6 +63,9 @@ jobs:
get-go-version: get-go-version:
uses: ./.github/workflows/reusable-get-go-version.yml uses: ./.github/workflows/reusable-get-go-version.yml
get-envoy-versions:
uses: ./.github/workflows/reusable-get-envoy-versions.yml
dev-build: dev-build:
needs: needs:
- setup - setup
@ -269,28 +272,25 @@ jobs:
- name: Generate Envoy Job Matrix - name: Generate Envoy Job Matrix
id: set-matrix id: set-matrix
env: env:
# this is further going to multiplied in envoy-integration tests by the # TEST_SPLITS sets the number of test case splits to use in the matrix. This will be
# other dimensions in the matrix. Currently TOTAL_RUNNERS would be # further multiplied in envoy-integration tests by the other dimensions in the matrix
# multiplied by 2 based on these values: # to determine the total number of runners used.
# envoy-version: ["1.29.5"] TEST_SPLITS: 4
# xds-target: ["server", "client"]
TOTAL_RUNNERS: 2
JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]'
run: | run: |
NUM_RUNNERS=$TOTAL_RUNNERS
NUM_DIRS=$(find ./test/integration/connect/envoy -mindepth 1 -maxdepth 1 -type d | wc -l) NUM_DIRS=$(find ./test/integration/connect/envoy -mindepth 1 -maxdepth 1 -type d | wc -l)
if [ "$NUM_DIRS" -lt "$NUM_RUNNERS" ]; then if [ "$NUM_DIRS" -lt "$TEST_SPLITS" ]; then
echo "TOTAL_RUNNERS is larger than the number of tests/packages to split." echo "TEST_SPLITS is larger than the number of tests/packages to split."
NUM_RUNNERS=$((NUM_DIRS-1)) TEST_SPLITS=$((NUM_DIRS-1))
fi fi
# fix issue where test splitting calculation generates 1 more split than TOTAL_RUNNERS. # fix issue where test splitting calculation generates 1 more split than TEST_SPLITS.
NUM_RUNNERS=$((NUM_RUNNERS-1)) TEST_SPLITS=$((TEST_SPLITS-1))
{ {
echo -n "envoy-matrix=" echo -n "envoy-matrix="
find ./test/integration/connect/envoy -maxdepth 1 -type d -print0 \ find ./test/integration/connect/envoy -maxdepth 1 -type d -print0 \
| xargs -0 -n 1 basename \ | xargs -0 -n 1 basename \
| jq --raw-input --argjson runnercount "$NUM_RUNNERS" "$JQ_SLICER" \ | jq --raw-input --argjson runnercount "$TEST_SPLITS" "$JQ_SLICER" \
| jq --compact-output 'map(join("|"))' | jq --compact-output 'map(join("|"))'
} >> "$GITHUB_OUTPUT" } >> "$GITHUB_OUTPUT"
@ -299,6 +299,7 @@ jobs:
needs: needs:
- setup - setup
- get-go-version - get-go-version
- get-envoy-versions
- generate-envoy-job-matrices - generate-envoy-job-matrices
- dev-build - dev-build
permissions: permissions:
@ -307,11 +308,10 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
envoy-version: ["1.29.5"]
xds-target: ["server", "client"] xds-target: ["server", "client"]
test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }}
env: env:
ENVOY_VERSION: ${{ matrix.envoy-version }} ENVOY_VERSION: ${{ needs.get-envoy-versions.outputs.max-envoy-version }}
XDS_TARGET: ${{ matrix.xds-target }} XDS_TARGET: ${{ matrix.xds-target }}
AWS_LAMBDA_REGION: us-west-2 AWS_LAMBDA_REGION: us-west-2
steps: steps:
@ -392,13 +392,14 @@ jobs:
needs: needs:
- setup - setup
- get-go-version - get-go-version
- get-envoy-versions
- dev-build - dev-build
permissions: permissions:
id-token: write # NOTE: this permission is explicitly required for Vault auth. id-token: write # NOTE: this permission is explicitly required for Vault auth.
contents: read contents: read
env: env:
ENVOY_VERSION: "1.29.5" ENVOY_VERSION: ${{ needs.get-envoy-versions.outputs.max-envoy-version }}
CONSUL_DATAPLANE_IMAGE: "docker.io/hashicorppreview/consul-dataplane:1.3-dev-ubi" CONSUL_DATAPLANE_IMAGE: "docker.io/hashicorppreview/consul-dataplane:1.5-dev-ubi"
steps: steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
# NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos.

View File

@ -71,7 +71,8 @@ CONSUL_IMAGE_VERSION?=latest
# When changing the method of Go version detection, also update # When changing the method of Go version detection, also update
# version detection in CI workflows (reusable-get-go-version.yml). # version detection in CI workflows (reusable-get-go-version.yml).
GOLANG_VERSION?=$(shell head -n 1 .go-version) GOLANG_VERSION?=$(shell head -n 1 .go-version)
ENVOY_VERSION?='1.29.5' # Takes the highest version from the ENVOY_VERSIONS file.
ENVOY_VERSION?=$(shell cat envoyextensions/xdscommon/ENVOY_VERSIONS | grep '^[[:digit:]]' | sort -nr | head -n 1)
CONSUL_DATAPLANE_IMAGE := $(or $(CONSUL_DATAPLANE_IMAGE),"docker.io/hashicorppreview/consul-dataplane:1.3-dev-ubi") CONSUL_DATAPLANE_IMAGE := $(or $(CONSUL_DATAPLANE_IMAGE),"docker.io/hashicorppreview/consul-dataplane:1.3-dev-ubi")
DEPLOYER_CONSUL_DATAPLANE_IMAGE := $(or $(DEPLOYER_CONSUL_DATAPLANE_IMAGE), "docker.io/hashicorppreview/consul-dataplane:1.3-dev") DEPLOYER_CONSUL_DATAPLANE_IMAGE := $(or $(DEPLOYER_CONSUL_DATAPLANE_IMAGE), "docker.io/hashicorppreview/consul-dataplane:1.3-dev")

View File

@ -1052,7 +1052,7 @@ func checkEnvoyVersionCompatibility(envoyVersion string, unsupportedList []strin
// Next build the constraint string using the bounds, make sure that we are less than but not equal to // Next build the constraint string using the bounds, make sure that we are less than but not equal to
// maxSupported since we will add 1. Need to add one to the max minor version so that we accept all patches // maxSupported since we will add 1. Need to add one to the max minor version so that we accept all patches
splitS := strings.Split(xdscommon.GetMaxEnvoyMinorVersion(), ".") splitS := strings.Split(xdscommon.GetMaxEnvoyMajorVersion(), ".")
minor, err := strconv.Atoi(splitS[1]) minor, err := strconv.Atoi(splitS[1])
if err != nil { if err != nil {
return envoyCompat{}, err return envoyCompat{}, err
@ -1061,7 +1061,7 @@ func checkEnvoyVersionCompatibility(envoyVersion string, unsupportedList []strin
maxSupported := fmt.Sprintf("%s.%d", splitS[0], minor) maxSupported := fmt.Sprintf("%s.%d", splitS[0], minor)
cs.Reset() cs.Reset()
cs.WriteString(fmt.Sprintf(">= %s, < %s", xdscommon.GetMinEnvoyMinorVersion(), maxSupported)) cs.WriteString(fmt.Sprintf(">= %s, < %s", xdscommon.GetMinEnvoyMajorVersion(), maxSupported))
constraints, err := version.NewConstraint(cs.String()) constraints, err := version.NewConstraint(cs.String())
if err != nil { if err != nil {
return envoyCompat{}, err return envoyCompat{}, err

View File

@ -1850,7 +1850,7 @@ func TestCheckEnvoyVersionCompatibility(t *testing.T) {
}, },
{ {
name: "supported-at-max", name: "supported-at-max",
envoyVersion: xdscommon.GetMaxEnvoyMinorVersion(), envoyVersion: xdscommon.GetMaxEnvoyMajorVersion(),
unsupportedList: xdscommon.UnsupportedEnvoyVersions, unsupportedList: xdscommon.UnsupportedEnvoyVersions,
expectedCompat: envoyCompat{ expectedCompat: envoyCompat{
isCompatible: true, isCompatible: true,

View File

@ -0,0 +1,14 @@
# This file represents the canonical list of supported Envoy versions for this version of Consul.
#
# Every line must contain a valid version number in the format "x.y.z" where x, y, and z are integers.
# All other lines must be comments beginning with a "#", or a blank line.
#
# Every prior "minor" version for a given "major" (x.y) version is implicitly supported unless excluded by
# `xdscommon.UnsupportedEnvoyVersions`. For example, 1.28.3 implies support for 1.28.0, 1.28.1, and 1.28.2.
#
# See https://www.consul.io/docs/connect/proxies/envoy#supported-versions for more information on Consul's Envoy
# version support.
1.29.5
1.28.4
1.27.6
1.26.8

View File

@ -13,7 +13,7 @@ import (
var ( var (
// minSupportedVersion is the oldest mainline version we support. This should always be // minSupportedVersion is the oldest mainline version we support. This should always be
// the zero'th point release of the last element of xdscommon.EnvoyVersions. // the zero'th point release of the last element of xdscommon.EnvoyVersions.
minSupportedVersion = version.Must(version.NewVersion(GetMinEnvoyMinorVersion())) minSupportedVersion = version.Must(version.NewVersion(GetMinEnvoyMajorVersion()))
specificUnsupportedVersions = []unsupportedVersion{} specificUnsupportedVersions = []unsupportedVersion{}
) )

View File

@ -4,6 +4,8 @@
package xdscommon package xdscommon
import ( import (
"fmt"
"slices"
"testing" "testing"
envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
@ -70,99 +72,53 @@ func TestDetermineEnvoyVersionFromNode(t *testing.T) {
} }
func TestDetermineSupportedProxyFeaturesFromString(t *testing.T) { func TestDetermineSupportedProxyFeaturesFromString(t *testing.T) {
const ( const errTooOld = "is too old and is not supported by Consul"
errTooOld = "is too old and is not supported by Consul"
)
type testcase struct { type testcase struct {
name string
expect SupportedProxyFeatures expect SupportedProxyFeatures
expectErr string expectErr string
} }
var cases []testcase
// Just the bad versions // Bad versions.
cases := map[string]testcase{ minMajorVersion := version.Must(version.NewVersion(getMinEnvoyVersion()))
"1.9.0": {expectErr: "Envoy 1.9.0 " + errTooOld}, minMajorVersionMajorPart := minMajorVersion.Segments()[len(minMajorVersion.Segments())-2]
"1.10.0": {expectErr: "Envoy 1.10.0 " + errTooOld}, for major := 9; major < minMajorVersionMajorPart; major++ {
"1.11.0": {expectErr: "Envoy 1.11.0 " + errTooOld}, for minor := 0; minor < 10; minor++ {
"1.12.0": {expectErr: "Envoy 1.12.0 " + errTooOld}, cases = append(cases, testcase{
"1.12.1": {expectErr: "Envoy 1.12.1 " + errTooOld}, name: version.Must(version.NewVersion(fmt.Sprintf("1.%d.%d", major, minor))).String(),
"1.12.2": {expectErr: "Envoy 1.12.2 " + errTooOld}, expectErr: errTooOld,
"1.12.3": {expectErr: "Envoy 1.12.3 " + errTooOld}, })
"1.12.4": {expectErr: "Envoy 1.12.4 " + errTooOld}, }
"1.12.5": {expectErr: "Envoy 1.12.5 " + errTooOld},
"1.12.6": {expectErr: "Envoy 1.12.6 " + errTooOld},
"1.12.7": {expectErr: "Envoy 1.12.7 " + errTooOld},
"1.13.0": {expectErr: "Envoy 1.13.0 " + errTooOld},
"1.13.1": {expectErr: "Envoy 1.13.1 " + errTooOld},
"1.13.2": {expectErr: "Envoy 1.13.2 " + errTooOld},
"1.13.3": {expectErr: "Envoy 1.13.3 " + errTooOld},
"1.13.4": {expectErr: "Envoy 1.13.4 " + errTooOld},
"1.13.5": {expectErr: "Envoy 1.13.5 " + errTooOld},
"1.13.6": {expectErr: "Envoy 1.13.6 " + errTooOld},
"1.13.7": {expectErr: "Envoy 1.13.7 " + errTooOld},
"1.14.0": {expectErr: "Envoy 1.14.0 " + errTooOld},
"1.14.1": {expectErr: "Envoy 1.14.1 " + errTooOld},
"1.14.2": {expectErr: "Envoy 1.14.2 " + errTooOld},
"1.14.3": {expectErr: "Envoy 1.14.3 " + errTooOld},
"1.14.4": {expectErr: "Envoy 1.14.4 " + errTooOld},
"1.14.5": {expectErr: "Envoy 1.14.5 " + errTooOld},
"1.14.6": {expectErr: "Envoy 1.14.6 " + errTooOld},
"1.14.7": {expectErr: "Envoy 1.14.7 " + errTooOld},
"1.15.0": {expectErr: "Envoy 1.15.0 " + errTooOld},
"1.15.1": {expectErr: "Envoy 1.15.1 " + errTooOld},
"1.15.2": {expectErr: "Envoy 1.15.2 " + errTooOld},
"1.15.3": {expectErr: "Envoy 1.15.3 " + errTooOld},
"1.15.4": {expectErr: "Envoy 1.15.4 " + errTooOld},
"1.15.5": {expectErr: "Envoy 1.15.5 " + errTooOld},
"1.16.1": {expectErr: "Envoy 1.16.1 " + errTooOld},
"1.16.2": {expectErr: "Envoy 1.16.2 " + errTooOld},
"1.16.3": {expectErr: "Envoy 1.16.3 " + errTooOld},
"1.16.4": {expectErr: "Envoy 1.16.4 " + errTooOld},
"1.16.5": {expectErr: "Envoy 1.16.5 " + errTooOld},
"1.16.6": {expectErr: "Envoy 1.16.6 " + errTooOld},
"1.17.4": {expectErr: "Envoy 1.17.4 " + errTooOld},
"1.18.6": {expectErr: "Envoy 1.18.6 " + errTooOld},
"1.19.5": {expectErr: "Envoy 1.19.5 " + errTooOld},
"1.20.7": {expectErr: "Envoy 1.20.7 " + errTooOld},
"1.21.5": {expectErr: "Envoy 1.21.5 " + errTooOld},
"1.22.0": {expectErr: "Envoy 1.22.0 " + errTooOld},
"1.22.1": {expectErr: "Envoy 1.22.1 " + errTooOld},
"1.22.2": {expectErr: "Envoy 1.22.2 " + errTooOld},
"1.22.3": {expectErr: "Envoy 1.22.3 " + errTooOld},
"1.22.4": {expectErr: "Envoy 1.22.4 " + errTooOld},
"1.22.5": {expectErr: "Envoy 1.22.5 " + errTooOld},
"1.22.6": {expectErr: "Envoy 1.22.6 " + errTooOld},
"1.22.7": {expectErr: "Envoy 1.22.7 " + errTooOld},
"1.22.8": {expectErr: "Envoy 1.22.8 " + errTooOld},
"1.22.9": {expectErr: "Envoy 1.22.9 " + errTooOld},
"1.22.10": {expectErr: "Envoy 1.22.10 " + errTooOld},
"1.22.11": {expectErr: "Envoy 1.22.11 " + errTooOld},
} }
// Insert a bunch of valid versions. // Good versions.
// Populate feature flags here when appropriate. See consul 1.10.x for reference. // Sort ascending so test output is ordered like bad cases above.
/* Example from 1.18 var supportedVersionsAscending []string
for _, v := range []string{ supportedVersionsAscending = append(supportedVersionsAscending, EnvoyVersions...)
"1.18.0", "1.18.1", "1.18.2", "1.18.3", "1.18.4", "1.18.5", "1.18.6", slices.Reverse(supportedVersionsAscending)
} { for _, v := range supportedVersionsAscending {
cases[v] = testcase{expect: SupportedProxyFeatures{ envoyVersion := version.Must(version.NewVersion(v))
ForceLDSandCDSToAlwaysUseWildcardsOnReconnect: true, // e.g. this is 27 in 1.27.4
}} versionMajorPart := envoyVersion.Segments()[len(envoyVersion.Segments())-2]
// e.g. this is 4 in 1.27.4
versionMinorPart := envoyVersion.Segments()[len(envoyVersion.Segments())-1]
// Create synthetic minor versions from .0 through the actual configured version.
for minor := 0; minor <= versionMinorPart; minor++ {
minorVersion := version.Must(version.NewVersion(fmt.Sprintf("1.%d.%d", versionMajorPart, minor)))
cases = append(cases, testcase{
name: minorVersion.String(),
expect: SupportedProxyFeatures{},
})
} }
*/
for _, v := range []string{
"1.26.0", "1.26.1", "1.26.2", "1.26.3", "1.26.4", "1.26.5", "1.26.6", "1.26.7", "1.26.8",
"1.27.0", "1.27.1", "1.27.2", "1.27.3", "1.27.4", "1.27.5", "1.27.6",
"1.28.0", "1.28.1", "1.28.2", "1.28.3", "1.28.4",
"1.29.0", "1.29.1", "1.29.2", "1.29.3", "1.29.4", "1.29.5",
} {
cases[v] = testcase{expect: SupportedProxyFeatures{}}
} }
for name, tc := range cases { for _, tc := range cases {
tc := tc tc := tc
t.Run(name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
sf, err := DetermineSupportedProxyFeaturesFromString(name) sf, err := DetermineSupportedProxyFeaturesFromString(tc.name)
if tc.expectErr == "" { if tc.expectErr == "" {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, tc.expect, sf) require.Equal(t, tc.expect, sf)

View File

@ -3,7 +3,64 @@
package xdscommon package xdscommon
import "strings" import (
_ "embed"
"fmt"
"slices"
"strconv"
"strings"
)
// File containing the canonical range of supported Envoy versions for this version of Consul.
// This file should contain exactly one point release for each major release of Envoy, per line.
// All other contents must be blank lines or comments. Comments must be on their own line starting with '#'.
//
//go:embed ENVOY_VERSIONS
var envoyVersionsRaw string
// initEnvoyVersions calls parseEnvoyVersions and panics if it returns an error. Used to set EnvoyVersions.
func initEnvoyVersions() []string {
versions, err := parseEnvoyVersions(envoyVersionsRaw)
if err != nil {
panic(err)
}
return versions
}
// parseEnvoyVersions parses the ENVOY_VERSIONS file and returns a list of supported Envoy versions.
func parseEnvoyVersions(raw string) ([]string, error) {
lines := strings.Split(raw, "\n")
var versionLines []string
for _, line := range lines {
trimmed := strings.TrimSpace(line)
if trimmed == "" || strings.HasPrefix(trimmed, "#") {
continue // skip empty lines and comments
}
// Assume all remaining lines are valid Envoy versions in the format "X.Y.Z".
versionParts := strings.Split(trimmed, ".")
if len(versionParts) != 3 {
return nil, fmt.Errorf("invalid version in ENVOY_VERSIONS: %s", line)
}
for _, v := range versionParts {
if _, err := strconv.Atoi(v); err != nil {
return nil, fmt.Errorf("invalid version in ENVOY_VERSIONS: %s", line)
}
}
versionLines = append(versionLines, trimmed)
}
// Ensure sorted in descending order.
// We do this here as well as tests because other code (e.g. Makefile) may depend on the order
// of these values, so we want early detection in case tests are not run before compilation.
if !slices.IsSortedFunc(versionLines, func(v1, v2 string) int {
return strings.Compare(v2, v1)
}) {
return nil, fmt.Errorf("ENVOY_VERSIONS must be sorted in descending order")
}
return versionLines, nil
}
// EnvoyVersions lists the latest officially supported versions of envoy. // EnvoyVersions lists the latest officially supported versions of envoy.
// //
@ -11,12 +68,7 @@ import "strings"
// each major release should be present. // each major release should be present.
// //
// see: https://www.consul.io/docs/connect/proxies/envoy#supported-versions // see: https://www.consul.io/docs/connect/proxies/envoy#supported-versions
var EnvoyVersions = []string{ var EnvoyVersions = initEnvoyVersions()
"1.29.5",
"1.28.4",
"1.27.6",
"1.26.8",
}
// UnsupportedEnvoyVersions lists any unsupported Envoy versions (mainly minor versions) that fall // UnsupportedEnvoyVersions lists any unsupported Envoy versions (mainly minor versions) that fall
// within the range of EnvoyVersions above. // within the range of EnvoyVersions above.
@ -27,18 +79,28 @@ var EnvoyVersions = []string{
// see: https://www.consul.io/docs/connect/proxies/envoy#supported-versions // see: https://www.consul.io/docs/connect/proxies/envoy#supported-versions
var UnsupportedEnvoyVersions = []string{} var UnsupportedEnvoyVersions = []string{}
// GetMaxEnvoyMinorVersion grabs the first value in EnvoyVersions and strips the patch number off in order // GetMaxEnvoyMajorVersion grabs the first value in EnvoyVersions and strips the last number off in order
// to return the maximum supported Envoy minor version // to return the maximum supported Envoy "major" version.
// For example, if the input string is "1.14.1", the function would return "1.14". // For example, if the input string is "1.14.1", the function would return "1.14".
func GetMaxEnvoyMinorVersion() string { func GetMaxEnvoyMajorVersion() string {
s := strings.Split(EnvoyVersions[0], ".") s := strings.Split(getMaxEnvoyVersion(), ".")
return s[0] + "." + s[1] return s[0] + "." + s[1]
} }
// GetMinEnvoyMinorVersion grabs the last value in EnvoyVersions and strips the patch number off in order // GetMinEnvoyMajorVersion grabs the last value in EnvoyVersions and strips the patch number off in order
// to return the minimum supported Envoy minor version // to return the minimum supported Envoy "major" version.
// For example, if the input string is "1.12.1", the function would return "1.12". // For example, if the input string is "1.12.1", the function would return "1.12".
func GetMinEnvoyMinorVersion() string { func GetMinEnvoyMajorVersion() string {
s := strings.Split(EnvoyVersions[len(EnvoyVersions)-1], ".") s := strings.Split(getMinEnvoyVersion(), ".")
return s[0] + "." + s[1] return s[0] + "." + s[1]
} }
// getMaxEnvoyVersion returns the first (highest) value in EnvoyVersions.
func getMaxEnvoyVersion() string {
return EnvoyVersions[0]
}
// getMinEnvoyVersion returns the last (lowest) value in EnvoyVersions.
func getMinEnvoyVersion() string {
return EnvoyVersions[len(EnvoyVersions)-1]
}

View File

@ -4,6 +4,7 @@
package xdscommon package xdscommon
import ( import (
"slices"
"sort" "sort"
"testing" "testing"
@ -11,11 +12,17 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
// TestProxySupportOrder tests that the values in EnvoyVersions are valid (X.Y.Z), contiguous by "major" (X.Y) version,
// and sorted in descending order.
func TestProxySupportOrder(t *testing.T) { func TestProxySupportOrder(t *testing.T) {
versions := make([]*version.Version, len(EnvoyVersions)) versions := make([]*version.Version, len(EnvoyVersions))
beforeSort := make([]*version.Version, len(EnvoyVersions)) beforeSort := make([]*version.Version, len(EnvoyVersions))
for i, raw := range EnvoyVersions { for i, raw := range EnvoyVersions {
v, _ := version.NewVersion(raw) v, _ := version.NewVersion(raw)
if v.Segments()[0] != 1 {
// If this fails, we need to add support for a new semver-major (x in x.y.z) version of Envoy
t.Fatalf("Expected major version to be 1, got: %v", v.Segments()[0])
}
versions[i] = v versions[i] = v
beforeSort[i] = v beforeSort[i] = v
} }
@ -30,4 +37,48 @@ func TestProxySupportOrder(t *testing.T) {
for i := range EnvoyVersions { for i := range EnvoyVersions {
assert.True(t, versions[i].Equal(beforeSort[i])) assert.True(t, versions[i].Equal(beforeSort[i]))
} }
// Check that we have a continues set of versions
for i := 1; i < len(versions); i++ {
previousMajorVersion := getMajorVersion(versions[i-1])
majorVersion := getMajorVersion(versions[i])
assert.True(t, majorVersion == previousMajorVersion-1,
"Expected Envoy major version following %d.%d to be %d.%d, got %d.%d",
versions[i-1].Segments()[0],
previousMajorVersion,
versions[i-1].Segments()[0],
previousMajorVersion-1,
versions[i].Segments()[0],
majorVersion)
}
}
func TestParseEnvoyVersions(t *testing.T) {
// Test with valid versions, comments, and blank lines
raw := "# Comment\n1.29.4\n\n# More\n# comments\n1.28.3\n\n1.27.5\n1.26.8\n\n"
expected := []string{"1.29.4", "1.28.3", "1.27.5", "1.26.8"}
versions, err := parseEnvoyVersions(raw)
assert.NoError(t, err)
if !slices.Equal(versions, expected) {
t.Fatalf("Expected %v, got: %v", expected, versions)
}
// Test with invalid version
raw = "1.29.4\n1.26.8\nfoo"
_, err = parseEnvoyVersions(raw)
assert.EqualError(t, err, "invalid version in ENVOY_VERSIONS: foo")
// Test with out-of-order values
raw = "1.29.4\n1.26.8\n1.27.5"
_, err = parseEnvoyVersions(raw)
assert.EqualError(t, err, "ENVOY_VERSIONS must be sorted in descending order")
}
// getMajorVersion returns the "major" (Y in X.Y.Z) version of the given Envoy version.
func getMajorVersion(version *version.Version) int {
return version.Segments()[1]
} }

View File

@ -182,16 +182,6 @@ function assert_envoy_version {
echo "Got version=$VERSION" echo "Got version=$VERSION"
echo "Want version=$ENVOY_VERSION" echo "Want version=$ENVOY_VERSION"
# 1.20.2, 1.19.3 and 1.18.6 are special snowflakes in that the version for
# the release is reported with a '-dev' suffix (eg 1.20.2-dev).
if [ "$ENVOY_VERSION" = "1.20.2" ]; then
ENVOY_VERSION="1.20.2-dev"
elif [ "$ENVOY_VERSION" = "1.19.3" ]; then
ENVOY_VERSION="1.19.3-dev"
elif [ "$ENVOY_VERSION" = "1.18.6" ]; then
ENVOY_VERSION="1.18.6-dev"
fi
echo $VERSION | grep "/$ENVOY_VERSION/" echo $VERSION | grep "/$ENVOY_VERSION/"
} }

View File

@ -15,7 +15,10 @@ DEBUG=${DEBUG:-}
XDS_TARGET=${XDS_TARGET:-server} XDS_TARGET=${XDS_TARGET:-server}
# ENVOY_VERSION to run each test against # ENVOY_VERSION to run each test against
ENVOY_VERSION=${ENVOY_VERSION:-"1.29.5"} if [[ -z "${ENVOY_VERSION:-}" ]]; then
echo "please set Envoy version via ENVOY_VERSION"
exit 1
fi
export ENVOY_VERSION export ENVOY_VERSION
export DOCKER_BUILDKIT=1 export DOCKER_BUILDKIT=1