1 package couchctl
2
3 import (
4 "fmt"
5 "testing"
6
7 "github.com/stretchr/testify/require"
8 "gotest.tools/v3/assert"
9 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10 "sigs.k8s.io/controller-runtime/pkg/client"
11
12 "edge-infra.dev/pkg/edge/constants/api/cluster"
13 "edge-infra.dev/pkg/edge/constants/api/fleet"
14 dsapi "edge-infra.dev/pkg/edge/datasync/apis/v1alpha1"
15 "edge-infra.dev/pkg/edge/datasync/couchdb"
16 "edge-infra.dev/test/f2"
17 "edge-infra.dev/test/f2/x/ktest"
18 )
19
20 func TestCouchUserReconciler(t *testing.T) {
21 fin := f2.NewFeature("CouchUserReconciler").
22 WithLabel(_fleetType, fleet.Store, fleet.CouchDB).
23 WithLabel(_clusterType, cluster.Generic, cluster.DSDS, cluster.GKE).
24 Setup("CouchDBUser Created", func(ctx f2.Context, t *testing.T) f2.Context {
25 k := ktest.FromContextT(ctx, t)
26 k.WaitOn(t, k.ObjExists(couchDBServer))
27 assert.NilError(t, client.IgnoreAlreadyExists(k.Client.Create(ctx, couchDBDUser)))
28 return ctx
29 }).
30 Test("CouchDBServer Ready", testReady(couchDBServer)).
31 Test("CouchDBUser Ready", testReady(couchDBDUser)).
32 Test("K8 Secret Created", func(ctx f2.Context, t *testing.T) f2.Context {
33 k := ktest.FromContextT(ctx, t)
34
35 user := &couchdb.UserCredentials{}
36 secret, err := user.FromSecret(ctx, k.Client, couchDBDUser.SecretNamespacedName())
37 require.NoError(t, err)
38 require.NotNil(t, secret)
39 assert.Assert(t, len(user.Username) != 0)
40 assert.Assert(t, len(user.Password) != 0)
41 assert.Assert(t, len(user.URI) != 0)
42 return ctx
43 }).
44 Test("Couchdb User Created", func(ctx f2.Context, t *testing.T) f2.Context {
45 k := ktest.FromContextT(ctx, t)
46
47 cc, err := couchdbServerClient(ctx, k.Client, couchDBServer)
48 require.NoError(t, err)
49
50 exists, err := cc.CheckUserAndRolesExists(ctx, couchDBDUser.Spec.User.Name, couchDBDUser.Spec.User.Roles)
51 require.NoError(t, err)
52 require.True(t, exists, "user: %s, ", couchDBDUser.Spec.User.Name)
53 return ctx
54 }).
55 Test("Couchdb User Security Exist In DB", func(ctx f2.Context, t *testing.T) f2.Context {
56 if couchDBServer.IsCloud() {
57 return ctx
58 }
59 k := ktest.FromContextT(ctx, t)
60
61 cc, err := couchdbServerClient(ctx, k.Client, couchDBServer)
62 require.NoError(t, err)
63
64 replSet := &dsapi.ReplicationSet{}
65 err = cc.GetReplicationSetDoc(ctx, couchCtlConfig.ReplicationDB(), replSet)
66 require.NoError(t, err)
67
68 security := userToSecurity(couchDBDUser, couchDBDUser.Spec.User.Name)
69
70 for _, d := range replSet.Datasets {
71 exists, err := cc.CheckDBUsersAndRoles(ctx, security, d.Name)
72 require.NoError(t, err)
73 require.True(t, exists)
74 }
75 return ctx
76 }).
77 Test("ServerURL Checks", func(ctx f2.Context, t *testing.T) f2.Context {
78 if couchDBServer.IsCloud() {
79 return ctx
80 }
81 couchDBUserURL := getCouchDBUserURL(couchCtlConfig, couchDBServer)
82 serverURL := getServerURL(couchCtlConfig, couchDBServer)
83 name := "data-sync-couchdb"
84 if couchCtlConfig.IsDSDS() {
85 name = "data-sync-couchdb-lane"
86 }
87 require.Equal(t, couchDBUserURL, fmt.Sprintf("%s.data-sync-couchdb.svc.cluster.local", name))
88 require.Equal(t, serverURL, fmt.Sprintf("http://%s:%s", couchDBServer.Spec.URI, couchCtlConfig.CouchDBPort))
89 return ctx
90 }).
91 Feature()
92
93 f.Test(t, fin)
94 }
95
96 func newCouchDBUser(name, userName string, server *dsapi.CouchDBServer) *dsapi.CouchDBUser {
97 return &dsapi.CouchDBUser{
98 TypeMeta: metav1.TypeMeta{
99 APIVersion: dsapi.GroupVersion.String(),
100 Kind: "CouchDBUser",
101 },
102 ObjectMeta: metav1.ObjectMeta{
103 Name: name,
104 Namespace: server.Namespace,
105 },
106 Spec: dsapi.CouchDBUserSpec{
107 Type: dsapi.UserCredentials,
108 ServerRef: server.ServerRef(),
109 User: dsapi.User{
110 Name: userName,
111 Roles: []string{couchdb.ReadOnlyUser},
112 },
113 Provider: &dsapi.Provider{Name: fmt.Sprintf("%s-provider", userName)},
114 },
115 }
116 }
117
View as plain text