feat(): increased test coverage and added simple workflow to build OCI image
This commit is contained in:
79
.gitea/workflows/main.yaml
Normal file
79
.gitea/workflows/main.yaml
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
name: Build and Test
|
||||||
|
run-name: Reference Branch Build 🚀
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
- name: Setup Go
|
||||||
|
uses: actions/setup-go@v6
|
||||||
|
with:
|
||||||
|
go-version: '1.25.x'
|
||||||
|
- name: golangci-lint
|
||||||
|
uses: golangci/golangci-lint-action@v8
|
||||||
|
with:
|
||||||
|
version: v2.1
|
||||||
|
- name: Test with the Go CLI
|
||||||
|
run: go test ./... -v
|
||||||
|
- name: Run Gosec Security Scanner
|
||||||
|
uses: securego/gosec@master
|
||||||
|
with:
|
||||||
|
args: ./...
|
||||||
|
Build_Image_amd64:
|
||||||
|
runs-on: ubuntu-latest-amd64
|
||||||
|
steps:
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
with:
|
||||||
|
driver: remote
|
||||||
|
endpoint: tcp://buildkit-service.buildkit-service.svc:1234
|
||||||
|
- name: Log in to Gitea OCI
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: git.uploadfilter24.eu
|
||||||
|
username: ${{ vars.GA_USER }}
|
||||||
|
password: ${{ secrets.GA_PAT }}
|
||||||
|
- name: Build and Push the Docker Image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
id: build-and-push
|
||||||
|
with:
|
||||||
|
platforms: linux/amd64
|
||||||
|
context: .
|
||||||
|
file: ./Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
git.uploadfilter24.eu/covidnetes/${{ github.event.repository.name }}:${{ github.sha }}
|
||||||
|
Build_Image_arm64:
|
||||||
|
runs-on: ubuntu-latest-arm64
|
||||||
|
steps:
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
with:
|
||||||
|
driver: remote
|
||||||
|
endpoint: tcp://buildkit-service.buildkit-service.svc:1234
|
||||||
|
- name: Log in to Gitea OCI
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: git.uploadfilter24.eu
|
||||||
|
username: ${{ vars.GA_USER }}
|
||||||
|
password: ${{ secrets.GA_PAT }}
|
||||||
|
- name: Build and Push the Docker Image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
id: build-and-push
|
||||||
|
with:
|
||||||
|
platforms: linux/arm64
|
||||||
|
context: .
|
||||||
|
file: ./Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
git.uploadfilter24.eu/covidnetes/${{ github.event.repository.name }}:${{ github.sha }}
|
||||||
@@ -83,13 +83,6 @@ roleRef:
|
|||||||
go test ./...
|
go test ./...
|
||||||
```
|
```
|
||||||
|
|
||||||
## Next steps / TODOs
|
|
||||||
|
|
||||||
- Add CI/CD gitea workflows.
|
|
||||||
- Add Helm Chart for easy deployment.
|
|
||||||
- Add integration tests that run against a kind cluster to validate in-cluster behaviour.
|
|
||||||
- Add a long-running informer with event handlers to react to lease changes instead of polling.
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
- See the `LICENSE` file in this repository.
|
- See the `LICENSE` file in this repository.
|
||||||
|
|||||||
35
internal/informer_test.go
Normal file
35
internal/informer_test.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
coordv1 "k8s.io/api/coordination/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHandleLease_DryRun(t *testing.T) {
|
||||||
|
l := &coordv1.Lease{}
|
||||||
|
l.Name = "cilium-l2announce-abc"
|
||||||
|
hi := "xx-yy-node-a"
|
||||||
|
l.Spec.HolderIdentity = &hi
|
||||||
|
|
||||||
|
cfg := &Config{CiliumLabel: "lbl", DryRun: true}
|
||||||
|
|
||||||
|
handleLease(l, cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleLease_NonCilium(t *testing.T) {
|
||||||
|
l := &coordv1.Lease{}
|
||||||
|
l.Name = "other-lease"
|
||||||
|
hi := "xx-yy-node-a"
|
||||||
|
l.Spec.HolderIdentity = &hi
|
||||||
|
|
||||||
|
cfg := &Config{CiliumLabel: "lbl", DryRun: true}
|
||||||
|
handleLease(l, cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleLease_NoHolderIdentity(t *testing.T) {
|
||||||
|
l := &coordv1.Lease{}
|
||||||
|
l.Name = "cilium-l2announce-123"
|
||||||
|
cfg := &Config{CiliumLabel: "lbl", DryRun: true}
|
||||||
|
handleLease(l, cfg)
|
||||||
|
}
|
||||||
@@ -28,14 +28,18 @@ func generateClient() (kubernetes.Clientset, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func LabelNode(nodeName string, leaseName string, cfg *Config) error {
|
func LabelNode(nodeName string, leaseName string, cfg *Config) error {
|
||||||
|
|
||||||
client, err := generateClient()
|
client, err := generateClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Could not generate client: %s", err.Error())
|
return fmt.Errorf("Could not generate client: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ApplyLabelToNode(&client, nodeName, leaseName, cfg)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func ApplyLabelToNode(client kubernetes.Interface, nodeName string, leaseName string, cfg *Config) error {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"Caller": "LabelNode",
|
"Caller": "ApplyLabelToNode",
|
||||||
}).Info(fmt.Sprintf("Trying to label node %s", nodeName))
|
}).Info(fmt.Sprintf("Trying to label node %s", nodeName))
|
||||||
|
|
||||||
node, err := client.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{})
|
node, err := client.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{})
|
||||||
@@ -56,11 +60,10 @@ func LabelNode(nodeName string, leaseName string, cfg *Config) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"Caller": "LabelNode",
|
"Caller": "ApplyLabelToNode",
|
||||||
}).Info(fmt.Sprintf("Node %s labeled with %s=%s\n", nodeName, cfg.CiliumLabel, "true"))
|
}).Info(fmt.Sprintf("Node %s labeled with %s=%s\n", nodeName, cfg.CiliumLabel, "true"))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func RemoveLabelFromNode(nodeName string) error {
|
func RemoveLabelFromNode(nodeName string) error {
|
||||||
@@ -92,37 +95,6 @@ func RemoveLabelFromNode(nodeName string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// func GetCiliumL2Leases() ([]v1.Lease, error) {
|
|
||||||
// client, err := generateClient()
|
|
||||||
// if err != nil {
|
|
||||||
// log.WithFields(log.Fields{"Caller": "GetCiliumL2Leases"}).Errorf("Could not generate client: %s", err.Error())
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// leases, err := client.CoordinationV1().Leases("kube-system").List(context.TODO(), metav1.ListOptions{})
|
|
||||||
// if err != nil {
|
|
||||||
// log.WithFields(log.Fields{"Caller": "GetCiliumL2Leases"}).Errorf("Could not list leases: %s", err.Error())
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ciliumLeases := []v1.Lease{}
|
|
||||||
|
|
||||||
// for _, l := range leases.Items {
|
|
||||||
// if strings.HasPrefix(l.Name, "cilium-l2announce") {
|
|
||||||
// log.WithFields(log.Fields{
|
|
||||||
// "Caller": "GetCiliumL2Leases",
|
|
||||||
// "Lease": l.Name,
|
|
||||||
// }).Info("Found Cilium L2 lease")
|
|
||||||
// // Pretty-print a couple of fields for debugging
|
|
||||||
// if l.Spec.HolderIdentity != nil {
|
|
||||||
// log.WithFields(log.Fields{"HolderIdentity": *l.Spec.HolderIdentity}).Debug("HolderIdentity")
|
|
||||||
// }
|
|
||||||
// ciliumLeases = append(ciliumLeases, l)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return ciliumLeases, nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
func GetNodeNameFromLease(lease v1.Lease) (string, error) {
|
func GetNodeNameFromLease(lease v1.Lease) (string, error) {
|
||||||
if lease.Spec.HolderIdentity == nil {
|
if lease.Spec.HolderIdentity == nil {
|
||||||
return "", fmt.Errorf("Lease %s has no HolderIdentity", lease.Name)
|
return "", fmt.Errorf("Lease %s has no HolderIdentity", lease.Name)
|
||||||
|
|||||||
73
internal/kube_test.go
Normal file
73
internal/kube_test.go
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
coordv1 "k8s.io/api/coordination/v1"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetNodeNameFromLease_Valid(t *testing.T) {
|
||||||
|
l := coordv1.Lease{}
|
||||||
|
l.Name = "cilium-l2announce-1"
|
||||||
|
hi := "aa-bb-node1"
|
||||||
|
l.Spec.HolderIdentity = &hi
|
||||||
|
|
||||||
|
node, err := GetNodeNameFromLease(l)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if node != "node1" {
|
||||||
|
t.Fatalf("unexpected node name: got %s", node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetNodeNameFromLease_Invalid(t *testing.T) {
|
||||||
|
l := coordv1.Lease{}
|
||||||
|
l.Name = "cilium-l2announce-2"
|
||||||
|
hi := "too-short"
|
||||||
|
l.Spec.HolderIdentity = &hi
|
||||||
|
|
||||||
|
_, err := GetNodeNameFromLease(l)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected error for invalid holder identity")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestApplyLabelToNode_WithFakeClient(t *testing.T) {
|
||||||
|
client := fake.NewSimpleClientset()
|
||||||
|
|
||||||
|
node := &corev1.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test-node",
|
||||||
|
Labels: map[string]string{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_, err := client.CoreV1().Nodes().Create(context.TODO(), node, metav1.CreateOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create fake node: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := &Config{CiliumLabel: "mylabel", DryRun: false}
|
||||||
|
|
||||||
|
err = ApplyLabelToNode(client, "test-node", "lease-1", cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ApplyLabelToNode failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
updated, err := client.CoreV1().Nodes().Get(context.TODO(), "test-node", metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to get node: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if updated.Labels["mylabel"] != "true" {
|
||||||
|
t.Fatalf("expected label set on node, got: %v", updated.Labels)
|
||||||
|
}
|
||||||
|
|
||||||
|
if updated.Labels["cilium.uploadfilter24.eu/lease"] != "lease-1" {
|
||||||
|
t.Fatalf("expected lease label set on node, got: %v", updated.Labels)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user