Conformance Ingress (ci-ingress) #5756
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Conformance Ingress (ci-ingress) | |
# Any change in triggers needs to be reflected in the concurrency group. | |
on: | |
workflow_dispatch: | |
inputs: | |
PR-number: | |
description: "Pull request number." | |
required: true | |
context-ref: | |
description: "Context in which the workflow runs. If PR is from a fork, will be the PR target branch (general case). If PR is NOT from a fork, will be the PR branch itself (this allows committers to test changes to workflows directly from PRs)." | |
required: true | |
SHA: | |
description: "SHA under test (head of the PR branch)." | |
required: true | |
extra-args: | |
description: "[JSON object] Arbitrary arguments passed from the trigger comment via regex capture group. Parse with 'fromJson(inputs.extra-args).argName' in workflow." | |
required: false | |
default: '{}' | |
push: | |
branches: | |
- v1.14 | |
- ft/v1.14/** | |
- 'renovate/v1.14-**' | |
paths-ignore: | |
- 'Documentation/**' | |
- 'test/**' | |
# By specifying the access of one of the scopes, all of those that are not | |
# specified are set to 'none'. | |
permissions: | |
# To be able to access the repository with actions/checkout | |
contents: read | |
# To allow retrieving information from the PR API | |
pull-requests: read | |
# To be able to set commit status | |
statuses: write | |
concurrency: | |
# Structure: | |
# - Workflow name | |
# - Event type | |
# - A unique identifier depending on event type: | |
# - schedule: SHA | |
# - workflow_dispatch: PR number | |
# | |
# This structure ensures a unique concurrency group name is generated for each | |
# type of testing, such that re-runs will cancel the previous run. | |
group: | | |
${{ github.workflow }} | |
${{ github.event_name }} | |
${{ | |
(github.event_name == 'push' && github.sha) || | |
(github.event_name == 'workflow_dispatch' && github.event.inputs.PR-number) | |
}} | |
cancel-in-progress: true | |
env: | |
cilium_cli_ci_version: | |
CILIUM_CLI_MODE: helm | |
kind_config: .github/kind-config.yaml | |
metallb_version: 0.12.1 | |
timeout: 5m | |
jobs: | |
echo-inputs: | |
if: ${{ github.event_name == 'workflow_dispatch' }} | |
name: Echo Workflow Dispatch Inputs | |
runs-on: ubuntu-24.04 | |
steps: | |
- name: Echo Workflow Dispatch Inputs | |
run: | | |
echo '${{ tojson(inputs) }}' | |
commit-status-start: | |
name: Commit Status Start | |
runs-on: ubuntu-latest | |
steps: | |
- name: Set initial commit status | |
uses: myrotvorets/set-commit-status-action@3730c0a348a2ace3c110851bed53331bc6406e9f # v2.0.1 | |
with: | |
sha: ${{ inputs.SHA || github.sha }} | |
wait-for-images: | |
name: Wait for images | |
runs-on: ubuntu-latest | |
timeout-minutes: 30 | |
steps: | |
- name: Checkout context ref (trusted) | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
ref: ${{ inputs.context-ref || github.sha }} | |
persist-credentials: false | |
- name: Wait for images | |
uses: ./.github/actions/wait-for-images | |
with: | |
SHA: ${{ inputs.SHA }} | |
images: cilium-ci operator-generic-ci | |
ingress-conformance-test: | |
name: Ingress Conformance Test | |
needs: [wait-for-images] | |
runs-on: ubuntu-latest | |
timeout-minutes: 120 | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- name: Without XDP | |
bpf-lb-acceleration: disabled | |
loadbalancer-mode: dedicated | |
default-ingress-controller: false | |
- name: With XDP | |
bpf-lb-acceleration: native | |
loadbalancer-mode: dedicated | |
default-ingress-controller: false | |
- name: With Shared LB | |
bpf-lb-acceleration: disabled | |
loadbalancer-mode: shared | |
default-ingress-controller: false | |
- name: With Default Ingress Controller | |
bpf-lb-acceleration: disabled | |
loadbalancer-mode: dedicated | |
default-ingress-controller: true | |
steps: | |
- name: Checkout context ref (trusted) | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
ref: ${{ inputs.context-ref || github.sha }} | |
persist-credentials: false | |
- name: Set Environment Variables | |
uses: ./.github/actions/set-env-variables | |
- name: Install Cilium CLI | |
uses: cilium/cilium-cli@6977c4a640ad45da3a95eb12054497f2bdd22c48 # v0.16.19 | |
with: | |
release-version: ${{ env.CILIUM_CLI_VERSION }} | |
ci-version: ${{ env.cilium_cli_ci_version }} | |
- name: Set image tag | |
id: vars | |
run: | | |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
SHA="${{ inputs.SHA }}" | |
else | |
SHA="${{ github.sha }}" | |
fi | |
echo sha=${SHA} >> $GITHUB_OUTPUT | |
CILIUM_INSTALL_DEFAULTS="--chart-directory=./untrusted/install/kubernetes/cilium \ | |
--helm-set=debug.enabled=true \ | |
--helm-set=debug.verbose=envoy \ | |
--helm-set=image.repository=quay.io/${{ env.QUAY_ORGANIZATION_DEV }}/cilium-ci \ | |
--helm-set=image.useDigest=false \ | |
--helm-set=image.tag=${SHA} \ | |
--helm-set=operator.image.repository=quay.io/${{ env.QUAY_ORGANIZATION_DEV }}/operator \ | |
--helm-set=operator.image.suffix=-ci \ | |
--helm-set=operator.image.tag=${SHA} \ | |
--helm-set=operator.image.useDigest=false \ | |
--helm-set=securityContext.privileged=true \ | |
--helm-set kubeProxyReplacement=true \ | |
--helm-set=ingressController.enabled=true \ | |
--helm-set=ingressController.loadbalancerMode=${{ matrix.loadbalancer-mode }} \ | |
--helm-set=ingressController.default=${{ matrix.default-ingress-controller }} \ | |
--helm-set=extraConfig.bpf-lb-acceleration=${{ matrix.bpf-lb-acceleration }}" | |
echo cilium_install_defaults=${CILIUM_INSTALL_DEFAULTS} >> $GITHUB_OUTPUT | |
# Warning: since this is a privileged workflow, subsequent workflow job | |
# steps must take care not to execute untrusted code. | |
- name: Checkout pull request branch (NOT TRUSTED) | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
ref: ${{ steps.vars.outputs.sha }} | |
persist-credentials: false | |
path: untrusted | |
sparse-checkout: | | |
install/kubernetes/cilium | |
examples | |
- name: Create kind cluster | |
uses: helm/kind-action@0025e74a8c7512023d06dc019c617aa3cf561fde # v1.10.0 | |
with: | |
version: ${{ env.KIND_VERSION }} | |
node_image: ${{ env.KIND_K8S_IMAGE }} | |
kubectl_version: ${{ env.KIND_K8S_VERSION }} | |
config: ${{ env.kind_config }} | |
wait: 0 # The control-plane never becomes ready, since no CNI is present | |
- name: Checkout ingress-controller-conformance | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
# Use the forked repo with retry mechanism | |
# Please refer to https://github.com/kubernetes-sigs/ingress-controller-conformance/pull/101 for more details. | |
repository: cilium/ingress-controller-conformance | |
path: ingress-controller-conformance | |
ref: 6a193b3f73d8b1201a818bb7c8f204059b064857 | |
persist-credentials: false | |
- name: Install Ingress conformance test tool | |
timeout-minutes: 10 | |
run: | | |
cd ingress-controller-conformance | |
make build | |
- name: Install Cilium | |
run: | | |
cilium install ${{ steps.vars.outputs.cilium_install_defaults }} | |
- name: Wait for Cilium to be ready | |
run: | | |
cilium status --wait | |
kubectl get pods -n kube-system | |
- name: Install metallb for LB service | |
timeout-minutes: 10 | |
run: | | |
KIND_NET_CIDR=$(docker network inspect kind -f '{{json .IPAM.Config}}' | jq -r '.[] | select(.Subnet | test("^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+")) | .Subnet') | |
echo "KIND_NET_CIDR: $KIND_NET_CIDR" | |
METALLB_IP_START=$(echo ${KIND_NET_CIDR} | sed "[email protected]/[email protected]@") | |
METALLB_IP_END=$(echo ${KIND_NET_CIDR} | sed "[email protected]/[email protected]@") | |
METALLB_IP_RANGE="${METALLB_IP_START}-${METALLB_IP_END}" | |
cat << EOF > metallb_values.yaml | |
configInline: | |
address-pools: | |
- name: default | |
protocol: layer2 | |
addresses: | |
- ${METALLB_IP_RANGE} | |
psp: | |
create: false | |
EOF | |
cat metallb_values.yaml | |
helm install --namespace metallb-system \ | |
--create-namespace \ | |
--repo https://metallb.github.io/metallb metallb metallb \ | |
--version ${{ env.metallb_version }} \ | |
--values metallb_values.yaml \ | |
--wait | |
- name: Create sample workload | |
timeout-minutes: 5 | |
run: | | |
kubectl apply -n default -f https://raw.githubusercontent.com/istio/istio/release-1.11/samples/bookinfo/platform/kube/bookinfo.yaml | |
if [ ${{ matrix.default-ingress-controller }} = "true" ]; then | |
# remove ingressClassName line from basic-ingress.yaml | |
sed -i '/ingressClassName/d' untrusted/examples/kubernetes/servicemesh/basic-ingress.yaml | |
kubectl apply -n default -f untrusted/examples/kubernetes/servicemesh/basic-ingress.yaml | |
kubectl wait -n default --for=condition=Ready --all pod --timeout=${{ env.timeout }} | |
fi | |
kubectl apply -n default -f untrusted/examples/kubernetes/servicemesh/basic-ingress.yaml | |
kubectl wait -n default --for=condition=Ready --all pod --timeout=${{ env.timeout }} | |
- name: Run Sanity check (external) | |
timeout-minutes: 5 | |
run: | | |
lb=$(kubectl get ingress basic-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}') | |
curl -s -v --connect-timeout 5 --max-time 20 --retry 3 --fail -- http://"$lb" | |
curl -s -v --connect-timeout 5 --max-time 20 --retry 3 --fail -- http://"$lb"/details/1 | |
- name: Run Sanity check (internal to NodePort) | |
timeout-minutes: 5 | |
run: | | |
if [ ${{ matrix.loadbalancer-mode }} = "dedicated" ]; then | |
node_port=$(kubectl get svc cilium-ingress-basic-ingress -o jsonpath='{.spec.ports[?(@.port==80)].nodePort}') | |
else | |
node_port=$(kubectl get -n kube-system svc cilium-ingress -o jsonpath='{.spec.ports[?(@.port==80)].nodePort}') | |
fi | |
docker exec -i chart-testing-control-plane curl -s -v --connect-timeout 5 --max-time 20 --retry 3 --fail http://localhost:$node_port/details/1 | |
- name: Cleanup Sanity check | |
timeout-minutes: 5 | |
run: | | |
# Clean up after sanity check to avoid any conflicts with the conformance test | |
kubectl delete -n default -f untrusted/examples/kubernetes/servicemesh/basic-ingress.yaml | |
kubectl delete -n default -f https://raw.githubusercontent.com/istio/istio/release-1.11/samples/bookinfo/platform/kube/bookinfo.yaml | |
kubectl wait ingress basic-ingress --for=delete | |
- name: Run Ingress conformance test | |
timeout-minutes: 30 | |
run: | | |
cd ingress-controller-conformance | |
./ingress-controller-conformance -ingress-class cilium -wait-time-for-ingress-status 60s -wait-time-for-ready 60s -http-client-timeout 60s | |
- name: Post-test information gathering | |
if: ${{ !success() }} | |
run: | | |
kubectl get pods --all-namespaces -o wide | |
cilium status | |
cilium sysdump --output-filename cilium-sysdump-out | |
shell: bash {0} # Disable default fail-fast behaviour so that all commands run independently | |
- name: Upload artifacts | |
if: ${{ !success() }} | |
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 | |
with: | |
name: cilium-sysdump-out-${{ matrix.name }} | |
path: cilium-sysdump-out-*.zip | |
retention-days: 5 | |
commit-status-final: | |
if: ${{ always() }} | |
name: Commit Status Final | |
needs: ingress-conformance-test | |
runs-on: ubuntu-latest | |
steps: | |
- name: Set final commit status | |
uses: myrotvorets/set-commit-status-action@3730c0a348a2ace3c110851bed53331bc6406e9f # v2.0.1 | |
with: | |
sha: ${{ inputs.SHA || github.sha }} | |
status: ${{ needs.ingress-conformance-test.result }} |