From fea8cd481e151a61e4be9b09da97a31b1fa64bb7 Mon Sep 17 00:00:00 2001 From: Kristian-ZH Date: Thu, 19 Oct 2023 16:34:48 +0300 Subject: [PATCH] Define MetalLB Github action --- .github/workflows/test-metallb-helm-chart.yml | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 .github/workflows/test-metallb-helm-chart.yml diff --git a/.github/workflows/test-metallb-helm-chart.yml b/.github/workflows/test-metallb-helm-chart.yml new file mode 100644 index 00000000..c31db783 --- /dev/null +++ b/.github/workflows/test-metallb-helm-chart.yml @@ -0,0 +1,165 @@ +name: Test MetalLB Helm Chart + +on: + pull_request: + paths: + - '**/assets/metallb/**' # Adjust the path based on your Helm chart structure + +jobs: + test-metallb-helm-chart: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Get changed files + id: changed-files + uses: tj-actions/changed-files@v39 + + - name: Verify and copy metallb assets + run: | + archive=$(echo "${{ steps.changed-files.outputs.all_changed_files }}" | tr -s " " "\012" | grep assets/metallb/) + + # Count the number of files in the array + num_files=$(echo "${archive}" | wc -l) + # Check if there is only one file + if [ "${num_files}" -gt 1 ]; then + echo "Multiple archives modified - please modify only a single chart release per PR:" + for file in "$archive"; do + echo "${file}" + done + exit 1 # Fail the workflow + fi + + mkdir helm-charts + tar xvzf "${archive}" -C helm-charts/ + + - name: Install K3s + run: | + curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --cluster-init --write-kubeconfig-mode=644 --disable=servicelb --disable=traefik" K3S_TOKEN=foobar sh - + + - name: Install Helm + run: | + curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 + chmod +x get_helm.sh + ./get_helm.sh + + - name: Deploy metallb Helm chart + run: | + export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + helm install metallb helm-charts/metallb + + - name: Wait for all metallb pods to become ready + run: | + export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + + # Set a timeout of 5 minutes + timeout=$((SECONDS + 300)) + + while [ $SECONDS -lt $timeout ]; do + # Run the kubectl command to get pod information + kubectl_output=$(kubectl -n default get po | tail -n +2) + + # Flag to track whether all pods are ready + all_pods_ready=true + + # Iterate over each line in the kubectl output + while IFS= read -r line; do + # Extract the pod name and the readiness status + pod_name=$(echo "$line" | awk '{print $1}') + readiness_status=$(echo "$line" | awk '{print $2}') + + # Extract the desired and running replicas from the readiness status + desired_replicas=$(echo "$readiness_status" | awk -F'/' '{print $1}') + running_replicas=$(echo "$readiness_status" | awk -F'/' '{print $2}') + + # Check if the digit before / is the same as the one after / + if [ "$desired_replicas" -eq "$running_replicas" ]; then + echo "$pod_name is ready" + else + echo "$pod_name is not ready" + all_pods_ready=false + fi + done <<< "$kubectl_output" + + # Check if all pods are ready + if [ "$all_pods_ready" = true ]; then + echo "All pods are ready" + exit 0 + fi + + # Wait for a moment before checking again + sleep 5 + done + + # If the loop completes, it means the timeout occurred + echo "Timeout: Not all pods are ready in 5 minutes." + exit 1 + + - name: Define IPAddressPool + run: | + export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + + cat <<-EOF | kubectl apply -f - + apiVersion: metallb.io/v1beta1 + kind: IPAddressPool + metadata: + name: ip-pool + spec: + addresses: + - 1.1.1.1/32 + EOF + + cat <<-EOF | kubectl apply -f - + apiVersion: metallb.io/v1beta1 + kind: L2Advertisement + metadata: + name: ip-pool-l2-adv + spec: + ipAddressPools: + - ip-pool + EOF + + - name: Define Kubernetes Service + run: | + export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + + cat <<-EOF | kubectl apply -f - + apiVersion: v1 + kind: Service + metadata: + name: example-service + spec: + selector: + app: example-app + ports: + - protocol: TCP + port: 80 + targetPort: 8080 + type: LoadBalancer + EOF + + - name: Verify externalIP of the Service + run: | + export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + + # Sleep for 30 seconds in order to give enough time to the operator + sleep 30 + + expected_service_ip="1.1.1.1" + actual_service_ip=$(kubectl get svc example-service -o yaml -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + + if [ "$expected_service_ip" != "$actual_service_ip" ]; then + echo "Error: The external IP addresses of the Service do not match. expected_service_ip: $expected_service_ip, actual_service_ip: $actual_service_ip" + exit 1 + fi + + - name: Uninstall Helm chart + run: | + export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + helm uninstall metallb + + - name: Uninstall K3s + run: | + /usr/local/bin/k3s-uninstall.sh