@@ -25,16 +25,171 @@ package tests
2525import (
2626 "context"
2727 "fmt"
28+ "strings"
2829 "testing"
30+ "time"
31+
32+ "github.com/ghodss/yaml"
2933
3034 "github.com/dchest/uniuri"
35+ "k8s.io/api/core/v1"
36+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
37+ "k8s.io/client-go/kubernetes"
3138
3239 driver "github.com/arangodb/go-driver"
3340 api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1alpha"
3441 "github.com/arangodb/kube-arangodb/pkg/client"
42+ "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned"
3543 "github.com/arangodb/kube-arangodb/pkg/util"
44+ "github.com/arangodb/kube-arangodb/pkg/util/constants"
45+ "github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
46+ "github.com/arangodb/kube-arangodb/pkg/util/retry"
3647)
3748
49+ // deployAccessPackage unpacks the secrets from an access package and deploys them
50+ func deployAccessPackage (ap * v1.Secret , kube kubernetes.Interface ) error {
51+ if allyaml , ok := ap .Data [constants .SecretAccessPackageYaml ]; ok {
52+ secrets := strings .Split (string (allyaml ), "---" )
53+ for _ , secretyaml := range secrets {
54+ var secret v1.Secret
55+ if err := yaml .Unmarshal ([]byte (secretyaml ), & secret ); err != nil {
56+ return err
57+ }
58+
59+ if _ , err := kube .Core ().Secrets (ap .GetNamespace ()).Create (& secret ); err != nil {
60+ return err
61+ }
62+ }
63+
64+ return nil
65+ }
66+ return fmt .Errorf ("Failed to read access package" )
67+ }
68+
69+ // removeAccessPackage fire and forget deletes secrets related to a access package
70+ func removeAccessPackage (name , ns string , kube kubernetes.Interface ) {
71+ kube .Core ().Secrets (ns ).Delete (name + "-auth" , & metav1.DeleteOptions {})
72+ kube .Core ().Secrets (ns ).Delete (name + "-ca" , & metav1.DeleteOptions {})
73+ }
74+
75+ // waitUntilReplicationNotFound waits until a replication resource is deleted
76+ func waitUntilReplicationNotFound (ns , name string , cli versioned.Interface ) error {
77+ return retry .Retry (func () error {
78+ if _ , err := cli .Replication ().ArangoDeploymentReplications (ns ).Get (name , metav1.GetOptions {}); k8sutil .IsNotFound (err ) {
79+ return nil
80+ } else if err != nil {
81+ return err
82+ }
83+ return fmt .Errorf ("Resource not yet gone" )
84+ }, time .Minute )
85+ }
86+
87+ // TestSyncSameDC create two clusters and configures sync between them.
88+ // Then it creates a test collection in source and waits for it to appear in dest.
89+ func TestSyncSameDC (t * testing.T ) {
90+ longOrSkip (t )
91+ img := getEnterpriseImageOrSkip (t )
92+ c := client .MustNewInCluster ()
93+ kubecli := mustNewKubeClient (t )
94+ ns := getNamespace (t )
95+
96+ apname := "test-sync-sdc-a-access-package"
97+
98+ depla := newDeployment ("test-sync-sdc-a-" + uniuri .NewLen (4 ))
99+ depla .Spec .Mode = api .NewMode (api .DeploymentModeCluster )
100+ depla .Spec .Image = util .NewString (img )
101+ depla .Spec .Sync .Enabled = util .NewBool (true )
102+ depla .Spec .Sync .ExternalAccess .Type = api .NewExternalAccessType (api .ExternalAccessTypeNone )
103+ depla .Spec .Sync .ExternalAccess .AccessPackageSecretNames = []string {apname }
104+
105+ // Create deployment
106+ _ , err := c .DatabaseV1alpha ().ArangoDeployments (ns ).Create (depla )
107+ if err != nil {
108+ t .Fatalf ("Create deployment a failed: %v" , err )
109+ }
110+ // Prepare cleanup
111+ defer deferedCleanupDeployment (c , depla .GetName (), ns )
112+
113+ deplb := newDeployment ("test-sync-sdc-b-" + uniuri .NewLen (4 ))
114+ deplb .Spec .Mode = api .NewMode (api .DeploymentModeCluster )
115+ deplb .Spec .Image = util .NewString (img )
116+ deplb .Spec .Sync .Enabled = util .NewBool (true )
117+ deplb .Spec .Sync .ExternalAccess .Type = api .NewExternalAccessType (api .ExternalAccessTypeNone )
118+
119+ // Create deployment
120+ _ , err = c .DatabaseV1alpha ().ArangoDeployments (ns ).Create (deplb )
121+ if err != nil {
122+ t .Fatalf ("Create deployment b failed: %v" , err )
123+ }
124+ // Prepare cleanup
125+ defer deferedCleanupDeployment (c , deplb .GetName (), ns )
126+
127+ // Wait for deployments to be ready
128+ // Wait for access package
129+ // Deploy access package
130+ ap , err := waitUntilSecret (kubecli , apname , ns , nil , deploymentReadyTimeout )
131+ if err != nil {
132+ t .Fatalf ("Failed to get access package: %v" , err )
133+ }
134+ if err := deployAccessPackage (ap , kubecli ); err != nil {
135+ t .Fatalf ("Failed to deploy access package: %v" , err )
136+ }
137+ defer removeAccessPackage (apname , ns , kubecli )
138+
139+ // Deploy Replication Resource
140+ repl := newReplication ("test-sync-sdc-repl" )
141+ repl .Spec .Source .DeploymentName = util .NewString (depla .GetName ())
142+ repl .Spec .Source .Authentication .KeyfileSecretName = util .NewString ("test-syn-sdc-a-access-package-auth" )
143+ repl .Spec .Source .TLS .CASecretName = util .NewString ("test-syn-sdc-a-access-package-ca" )
144+ repl .Spec .Destination .DeploymentName = util .NewString (deplb .GetName ())
145+ _ , err = c .ReplicationV1alpha ().ArangoDeploymentReplications (ns ).Create (repl )
146+ if err != nil {
147+ t .Fatalf ("Create replication resource failed: %v" , err )
148+ }
149+ defer deferedCleanupReplication (c , repl .GetName (), ns )
150+
151+ deplaobj , err := waitUntilDeployment (c , depla .GetName (), ns , deploymentIsReady ())
152+ if err != nil {
153+ t .Fatalf ("Deployment A not running in time: %v" , err )
154+ }
155+
156+ deplbobj , err := waitUntilDeployment (c , deplb .GetName (), ns , deploymentIsReady ())
157+ if err != nil {
158+ t .Fatalf ("Deployment B not running in time: %v" , err )
159+ }
160+
161+ // Create a database in DC-A
162+ // Wait for database in DC-B
163+ time .Sleep (10 * time .Second )
164+ testdbname := "replicated-db"
165+
166+ ctx := context .Background ()
167+ clienta := mustNewArangodDatabaseClient (ctx , kubecli , deplaobj , t , nil )
168+ if _ , err := clienta .CreateDatabase (ctx , testdbname , nil ); err != nil {
169+ t .Fatalf ("Failed to create database in a: %v" , err )
170+ }
171+
172+ clientb := mustNewArangodDatabaseClient (ctx , kubecli , deplbobj , t , nil )
173+ retry .Retry (func () error {
174+ if ok , err := clientb .DatabaseExists (ctx , testdbname ); err != nil {
175+ return err
176+ } else if ! ok {
177+ return fmt .Errorf ("Database does not exist" )
178+ }
179+ return nil
180+ }, time .Minute )
181+
182+ // Disable replication
183+ removeReplication (c , repl .GetName (), ns )
184+ if err := waitUntilReplicationNotFound (ns , repl .GetName (), c ); err != nil {
185+ t .Errorf ("Could not remove replication resource: %v" , err )
186+ }
187+
188+ // Cleanup
189+ removeDeployment (c , deplb .GetName (), ns )
190+ removeDeployment (c , depla .GetName (), ns )
191+ }
192+
38193// TestSyncToggleEnabled tests a normal cluster and enables sync later.
39194// Once sync is active, it is disabled again.
40195func TestSyncToggleEnabled (t * testing.T ) {
0 commit comments