auth-proxy: reusable ingress with auth proxy object for cue configs (#113)

affects: #110

Creates reusable auth proxy object in base cue config, and migrates rpuppy, url-shortener, pihole and memberships app to it.

Memberships app always requires authentication.
url-shortener now supports non-auth based interactions.
diff --git a/core/installer/app_test.go b/core/installer/app_test.go
index 6162299..6b84005 100644
--- a/core/installer/app_test.go
+++ b/core/installer/app_test.go
@@ -4,13 +4,128 @@
 	"testing"
 )
 
-func TestHeadscaleUser(t *testing.T) {
+func TestAuthProxyEnabled(t *testing.T) {
 	r := NewInMemoryAppRepository(CreateAllApps())
-	a, err := r.Find("headscale-user")
+	for _, app := range []string{"rpuppy", "Pi-hole", "url-shortener"} {
+		a, err := r.Find(app)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if a == nil {
+			t.Fatal("returned app is nil")
+		}
+		d := Derived{
+			Release: Release{
+				Namespace: "foo",
+			},
+			Global: Values{
+				PCloudEnvName:   "dodo",
+				Id:              "id",
+				ContactEmail:    "foo@bar.ge",
+				Domain:          "bar.ge",
+				PrivateDomain:   "p.bar.ge",
+				PublicIP:        "1.2.3.4",
+				NamespacePrefix: "id-",
+			},
+			Values: map[string]any{
+				"network": map[string]any{
+					"name":              "Public",
+					"ingressClass":      "dodo-ingress-public",
+					"certificateIssuer": "id-public",
+					"domain":            "bar.ge",
+				},
+				"subdomain": "woof",
+				"auth": map[string]any{
+					"enabled": true,
+					"groups":  "a,b",
+				},
+			},
+		}
+		rendered, err := a.Render(d)
+		if err != nil {
+			t.Fatal(err)
+		}
+		for _, r := range rendered.Resources {
+			t.Log(string(r))
+		}
+	}
+}
+
+func TestAuthProxyDisabled(t *testing.T) {
+	r := NewInMemoryAppRepository(CreateAllApps())
+	for _, app := range []string{"rpuppy", "Pi-hole", "url-shortener"} {
+		a, err := r.Find(app)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if a == nil {
+			t.Fatal("returned app is nil")
+		}
+		d := Derived{
+			Release: Release{
+				Namespace: "foo",
+			},
+			Global: Values{
+				PCloudEnvName:   "dodo",
+				Id:              "id",
+				ContactEmail:    "foo@bar.ge",
+				Domain:          "bar.ge",
+				PrivateDomain:   "p.bar.ge",
+				PublicIP:        "1.2.3.4",
+				NamespacePrefix: "id-",
+			},
+			Values: map[string]any{
+				"network": map[string]any{
+					"name":              "Public",
+					"ingressClass":      "dodo-ingress-public",
+					"certificateIssuer": "id-public",
+					"domain":            "bar.ge",
+				},
+				"subdomain": "woof",
+				"auth": map[string]any{
+					"enabled": false,
+				},
+			},
+		}
+		rendered, err := a.Render(d)
+		if err != nil {
+			t.Fatal(err)
+		}
+		for _, r := range rendered.Resources {
+			t.Log(string(r))
+		}
+	}
+}
+
+func TestGroupMemberships(t *testing.T) {
+	r := NewInMemoryAppRepository(CreateAllApps())
+	a, err := r.Find("memberships")
 	if err != nil {
 		t.Fatal(err)
 	}
 	if a == nil {
 		t.Fatal("returned app is nil")
 	}
+	d := Derived{
+		Release: Release{
+			Namespace: "foo",
+		},
+		Global: Values{
+			PCloudEnvName:   "dodo",
+			Id:              "id",
+			ContactEmail:    "foo@bar.ge",
+			Domain:          "bar.ge",
+			PrivateDomain:   "p.bar.ge",
+			PublicIP:        "1.2.3.4",
+			NamespacePrefix: "id-",
+		},
+		Values: map[string]any{},
+	}
+	rendered, err := a.Render(d)
+	if err != nil {
+		t.Fatal(err)
+	}
+	for _, r := range rendered.Resources {
+		t.Log(string(r))
+	}
 }