Skip to content

Commit

Permalink
Merge pull request #6 from jodevsa/tests
Browse files Browse the repository at this point in the history
add tests
  • Loading branch information
jodevsa committed Mar 12, 2022
2 parents 9786078 + f8c8918 commit 64582ac
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 11 deletions.
30 changes: 28 additions & 2 deletions controllers/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ package controllers
import (
"path/filepath"
"testing"
"time"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
"sigs.k8s.io/controller-runtime/pkg/envtest/printer"
Expand Down Expand Up @@ -54,8 +56,9 @@ var _ = BeforeSuite(func() {

By("bootstrapping test environment")
testEnv = &envtest.Environment{
CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")},
ErrorIfCRDPathMissing: true,
CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")},
ErrorIfCRDPathMissing: true,
ControlPlaneStopTimeout: time.Second * 120,
}

cfg, err := testEnv.Start()
Expand All @@ -71,6 +74,29 @@ var _ = BeforeSuite(func() {
Expect(err).NotTo(HaveOccurred())
Expect(k8sClient).NotTo(BeNil())

k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: scheme.Scheme,
})
Expect(err).ToNot(HaveOccurred())

err = (&WireguardReconciler{
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
}).SetupWithManager(k8sManager)
Expect(err).ToNot(HaveOccurred())

err = (&WireguardPeerReconciler{
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
}).SetupWithManager(k8sManager)
Expect(err).ToNot(HaveOccurred())

go func() {
defer GinkgoRecover()
err = k8sManager.Start(ctrl.SetupSignalHandler())
Expect(err).ToNot(HaveOccurred(), "failed to run manager")
}()

}, 60)

var _ = AfterSuite(func() {
Expand Down
14 changes: 5 additions & 9 deletions controllers/wireguard_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ type WireguardReconciler struct {
}

func labelsForWireguard(name string) map[string]string {
return map[string]string{"wireguard_cr": name}
return map[string]string{"app": "wireguard", "instance": name}
}

func (r *WireguardReconciler) ConfigmapForWireguard(m *vpnv1alpha1.Wireguard, hostname string) *corev1.ConfigMap {
Expand Down Expand Up @@ -252,7 +252,7 @@ func (r *WireguardReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
return ctrl.Result{}, err
}

return ctrl.Result{Requeue: true}, nil
return ctrl.Result{}, nil
}

wgConfig := ""
Expand Down Expand Up @@ -322,9 +322,6 @@ ListenPort = 51820

}

wireguard.Annotations["wgConfigLastUpdated"] = time.Now().Format("2006-01-02T15-04-05")
r.Update(ctx, wireguard)

}
if err != nil && errors.IsNotFound(err) {

Expand Down Expand Up @@ -424,6 +421,7 @@ ListenPort = 51820
err = r.updateStatus(ctx, req, wireguard, vpnv1alpha1.WgStatusReport{Status: vpnv1alpha1.Pending, Message: "Waiting for service to be created"})

if err != nil {
log.Error(err, "Failed to update wireguard status", "service.Namespace", svc.Namespace, "service.Name", svc.Name)
return ctrl.Result{}, err
}

Expand Down Expand Up @@ -486,6 +484,8 @@ ListenPort = 51820
log.Error(err, "Failed to update wireguard manifest host and port")
return ctrl.Result{}, err
}

return ctrl.Result{}, nil
}

// configmap
Expand All @@ -503,10 +503,6 @@ ListenPort = 51820

err = r.updateStatus(ctx, req, wireguard, vpnv1alpha1.WgStatusReport{Status: vpnv1alpha1.Pending, Message: "Waiting for configmap to be created"})

if err != nil {
return ctrl.Result{}, err
}

return ctrl.Result{}, err
} else if err != nil {
log.Error(err, "Failed to get config")
Expand Down
164 changes: 164 additions & 0 deletions controllers/wireguard_controller_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package controllers

import (
"context"
"fmt"
"time"

vpnv1alpha1 "github.com/jodevsa/wireguard-operator/api/v1alpha1"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)

var _ = Describe("wireguard controller", func() {

// Define utility constants for object names and testing timeouts/durations and intervals.
const (
wgName = "vpn"
wgNamespace = "default"
Timeout = time.Second * 2
Interval = time.Second * 1
dnsServiceIp = "10.0.0.42"
)

Context("Wireguard", func() {

It("Should create succesfully", func() {
// create kube-dns service
dnsService := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "kube-dns",
Namespace: "kube-system",
},
Spec: corev1.ServiceSpec{
ClusterIP: dnsServiceIp,
Ports: []corev1.ServicePort{{Name: "dns", Protocol: corev1.ProtocolUDP, Port: 53}},
},
}

Expect(k8sClient.Create(context.Background(), dnsService)).Should(Succeed())

wgKey := types.NamespacedName{
Name: wgName,
Namespace: wgNamespace,
}
created := &vpnv1alpha1.Wireguard{
ObjectMeta: metav1.ObjectMeta{
Name: wgKey.Name,
Namespace: wgKey.Namespace,
},
}
expectedLabels := map[string]string{"app": "wireguard", "instance": wgKey.Name}

Expect(k8sClient.Create(context.Background(), created)).Should(Succeed())

// service created
expectedExternalHostName := "test-host-name"
serviceName := wgKey.Name + "-svc"
serviceKey := types.NamespacedName{
Namespace: wgKey.Namespace,
Name: serviceName,
}

// match labels
Eventually(func() map[string]string {
svc := &corev1.Service{}
k8sClient.Get(context.Background(), serviceKey, svc)
return svc.Spec.Selector
}, Timeout, Interval).Should(BeEquivalentTo(expectedLabels))

// match service type
Eventually(func() corev1.ServiceType {
svc := &corev1.Service{}
k8sClient.Get(context.Background(), serviceKey, svc)
return svc.Spec.Type
}, Timeout, Interval).Should(Equal(corev1.ServiceTypeLoadBalancer))

Eventually(func() vpnv1alpha1.WireguardStatus {
wg := &vpnv1alpha1.Wireguard{}
k8sClient.Get(context.Background(), wgKey, wg)
return wg.Status
}, Timeout, Interval).Should(Equal(vpnv1alpha1.WireguardStatus{
Hostname: "",
Port: "",
Status: "pending",
Message: "Waiting for service to be ready",
}))

// update service external hostname
svc := &corev1.Service{}
k8sClient.Get(context.Background(), serviceKey, svc)
svc.Status.LoadBalancer.Ingress = []corev1.LoadBalancerIngress{{Hostname: expectedExternalHostName}}
Expect(k8sClient.Status().Update(context.Background(), svc)).Should(Succeed())

// check that wireguard resource got the right status after the service is ready
wg := &vpnv1alpha1.Wireguard{}
Eventually(func() vpnv1alpha1.WireguardStatus {
Expect(k8sClient.Get(context.Background(), wgKey, wg)).Should(Succeed())
return wg.Status
}, Timeout, Interval).Should(Equal(vpnv1alpha1.WireguardStatus{
Hostname: expectedExternalHostName,
Port: "51820",
Status: "ready",
Message: "VPN is active!",
}))

// create peer
peerKey := types.NamespacedName{
Name: wgKey.Name + "peer",
Namespace: wgKey.Namespace,
}
peer := &vpnv1alpha1.WireguardPeer{
ObjectMeta: metav1.ObjectMeta{
Name: peerKey.Name,
Namespace: peerKey.Namespace,
},
Spec: vpnv1alpha1.WireguardPeerSpec{
WireguardRef: wgKey.Name,
},
}
Expect(k8sClient.Create(context.Background(), peer)).Should(Succeed())

//get peer secret
wgSecretKeyName := types.NamespacedName{
Name: wgKey.Name,
Namespace: wgKey.Namespace,
}
wgSecret := &corev1.Secret{}
Eventually(func() error {
return k8sClient.Get(context.Background(), wgSecretKeyName, wgSecret)
}, Timeout, Interval).Should(Succeed())
wgPublicKey := string(wgSecret.Data["publicKey"])

Eventually(func() string {
Expect(k8sClient.Get(context.Background(), peerKey, peer)).Should(Succeed())
return peer.Spec.Address
}, Timeout, Interval).Should(Equal("10.8.0.2"))

Eventually(func() vpnv1alpha1.WireguardPeerStatus {
Expect(k8sClient.Get(context.Background(), peerKey, peer)).Should(Succeed())
return peer.Status
}, Timeout, Interval).Should(Equal(vpnv1alpha1.WireguardPeerStatus{
Config: fmt.Sprintf(`
echo "
[Interface]
PrivateKey = $(kubectl get secret %s-peer --template={{.data.privateKey}} -n default | base64 -d)
Address = %s
DNS = %s, %s.svc.cluster.local
[Peer]
PublicKey = %s
AllowedIPs = 0.0.0.0/0
Endpoint = %s:%s"`, peerKey.Name, peer.Spec.Address, dnsServiceIp, peer.Namespace, wgPublicKey, expectedExternalHostName, wg.Status.Port),
Status: "ready",
Message: "Peer configured",
}))

})

})

})

0 comments on commit 64582ac

Please sign in to comment.