@@ -189,6 +189,8 @@ jobs:
189189 storageType: ${{ inputs.storage_type }}
190190 storageClass: ${defaultStorageClass}
191191 sa: dkp-sa
192+ enabledModules:
193+ - console
192194 deckhouse:
193195 channel: ${{ env.DECKHOUSE_CHANNEL }}
194196 podSubnetCIDR: ${{ inputs.pod_subnet_cidr }}
@@ -515,10 +517,171 @@ jobs:
515517 ```
516518 EOF
517519
520+ configure-sdn :
521+ name : Configure SDN
522+ runs-on : ubuntu-latest
523+ needs : bootstrap
524+ steps :
525+ - uses : actions/checkout@v4
526+
527+ - name : Install Task
528+ uses : go-task/setup-task@v2
529+ with :
530+ version : 3.x
531+ repo-token : ${{ secrets.GITHUB_TOKEN }}
532+
533+ - name : Setup d8
534+ uses : ./.github/actions/install-d8
535+ env :
536+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
537+
538+ - name : Install kubectl CLI
539+ uses : azure/setup-kubectl@v4
540+
541+ - name : Check nested kube-api via generated kubeconfig
542+ run : |
543+ mkdir -p ~/.kube
544+ echo "[INFO] Configure kubeconfig for nested cluster"
545+ echo "${{ needs.bootstrap.outputs.kubeconfig }}" | base64 -d | base64 -d > ~/.kube/config
546+
547+ echo "[INFO] Show paths and files content"
548+ ls -la ~/.kube
549+ echo "[INFO] Set permissions for kubeconfig"
550+ chmod 600 ~/.kube/config
551+
552+ echo "[INFO] Show current kubeconfig context"
553+ kubectl config get-contexts
554+
555+ echo "[INFO] Show nodes in cluster"
556+ # `kubectl get nodes` may return error, so we need to retry.
557+ count=30
558+ success=false
559+ for i in $(seq 1 $count); do
560+ echo "[INFO] Attempt $i/$count..."
561+ if kubectl get nodes; then
562+ echo "[SUCCESS] Successfully retrieved nodes."
563+ success=true
564+ break
565+ fi
566+
567+ if [ $i -lt $count ]; then
568+ echo "[INFO] Retrying in 10 seconds..."
569+ sleep 10
570+ fi
571+ done
572+
573+ if [ "$success" = false ]; then
574+ echo "[ERROR] Failed to retrieve nodes after $count attempts."
575+ exit 1
576+ fi
577+ - name : Enable SDN
578+ run : |
579+ echo "[INFO] Enable SDN"
580+ d8 system module enable sdn
581+ echo "[INFO] Wait for sdn modules to be ready, timeout: 300s"
582+ kubectl wait --for=jsonpath='{.status.phase}'=Ready modules sdn --timeout=300s
583+ echo "[INFO] Wait for sdn deployments to be ready, timeout: 300s"
584+ kubectl -n d8-sdn wait --for=condition=Available deploy --all --timeout 300s
585+ echo "[INFO] Wait for sdn daemonset agent to be ready, timeout: 300s"
586+ kubectl -n d8-sdn rollout status daemonset agent --timeout=300s
587+ echo "[SUCCESS] Done"
588+
589+ - name : Wait for nodenetworkinterfaces to be ready
590+ run : |
591+ count=60
592+ success=false
593+ wait_time_seconds=5
594+
595+ for i in $(seq 1 $count); do
596+ nodes=$(kubectl get nodes -o name | wc -l)
597+ actual=$(kubectl get nodenetworkinterfaces -o json | jq -r '.items[] | select(.status.operationalState == "Up") | .metadata.name' | wc -l) || true
598+ expected=$((nodes * 2))
599+
600+ echo "[INFO] Attempt $i/$count: expected=$expected, actual=$actual"
601+
602+ if [ "$actual" -ge "$expected" ]; then
603+ echo "[SUCCESS] All nodenetworkinterfaces are present (expected=$expected, actual=$actual)"
604+ kubectl get nodenetworkinterfaces
605+ success=true
606+ break
607+ fi
608+
609+ if (( i % 5 == 0 )) ; then
610+ echo "::group::[DEBUG] show namespaces d8-sdn"
611+ kubectl -n d8-sdn get pods || true
612+ echo "::endgroup::"
613+
614+ echo "::group::[DEBUG] show nodenetworkinterfaces d8-sdn"
615+ kubectl get nodenetworkinterfaces || true
616+ echo "::endgroup::"
617+
618+ echo "[INFO] Retrying in 10 seconds..."
619+ sleep $wait_time_seconds
620+ elif [ $i -lt $count ]; then
621+ echo "[INFO] Retrying in 10 seconds..."
622+ sleep $wait_time_seconds
623+ fi
624+ done
625+
626+ if [ "$success" = false ]; then
627+ echo "[ERROR] Failed to get all nodenetworkinterfaces after $count attempts (expected=$expected)"
628+ echo "[DEBUG] Show namespaces d8-sdn"
629+ kubectl -n d8-sdn get pods || true
630+ echo "[DEBUG] Show nodenetworkinterfaces d8-sdn"
631+ kubectl get nodenetworkinterfaces || true
632+ exit 1
633+ fi
634+
635+ - name : Configure ClusterNetwork
636+ run : |
637+ extraNic=$(kubectl get nodenetworkinterfaces -l network.deckhouse.io/interface-type=NIC -o json | jq -r '.items[] | select(.status.operationalState == "Up") | select(.status.ifName != "eno1" and .status.ifName != "enp1s0") | .metadata.name')
638+
639+ for nic in $extraNic; do
640+ echo "[INFO] Label nodenetworkinterface $nic nic-group=extra"
641+ kubectl label nodenetworkinterfaces $nic nic-group=extra
642+ done
643+
644+ kubectl get nodenetworkinterface -l nic-group=extra
645+
646+ cat <<'EOF' | kubectl apply -f -
647+ ---
648+ apiVersion: network.deckhouse.io/v1alpha1
649+ kind: ClusterNetwork
650+ metadata:
651+ name: cn-4006-for-e2e-test
652+ spec:
653+ parentNodeNetworkInterfaces:
654+ labelSelector:
655+ matchLabels:
656+ nic-group: extra
657+ type: Access
658+ ---
659+ apiVersion: network.deckhouse.io/v1alpha1
660+ kind: ClusterNetwork
661+ metadata:
662+ name: cn-4007-for-e2e-test
663+ spec:
664+ parentNodeNetworkInterfaces:
665+ labelSelector:
666+ matchLabels:
667+ nic-group: extra
668+ type: VLAN
669+ vlan:
670+ id: 4007
671+ EOF
672+
673+ echo "[INFO] Wait for ClusterNetwork cn-4006-for-e2e-test to be ready"
674+ kubectl wait clusternetworks.network.deckhouse.io --for=condition=Ready cn-4006-for-e2e-test --timeout=120s
675+
676+ echo "[INFO] Wait for ClusterNetwork cn-4007-for-e2e-test to be ready"
677+ kubectl wait clusternetworks.network.deckhouse.io --for=condition=Ready cn-4007-for-e2e-test --timeout=120s
678+
518679 configure-storage :
519680 name : Configure storage
520681 runs-on : ubuntu-latest
521- needs : bootstrap
682+ needs :
683+ - configure-sdn
684+ - bootstrap
522685 steps :
523686 - uses : actions/checkout@v4
524687
0 commit comments