@@ -28,18 +28,24 @@ import (
28
28
gs "github.com/onsi/gomega/gstruct"
29
29
appsv1 "k8s.io/api/apps/v1"
30
30
corev1 "k8s.io/api/core/v1"
31
+ policyv1 "k8s.io/api/policy/v1"
31
32
storagev1 "k8s.io/api/storage/v1"
32
33
k8serrors "k8s.io/apimachinery/pkg/api/errors"
33
34
"k8s.io/apimachinery/pkg/api/resource"
34
35
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
35
36
"k8s.io/apimachinery/pkg/labels"
36
37
"k8s.io/apimachinery/pkg/types"
38
+ "k8s.io/apimachinery/pkg/util/intstr"
37
39
ctrl "sigs.k8s.io/controller-runtime"
38
40
"sigs.k8s.io/controller-runtime/pkg/client"
39
41
42
+ apiv1alpha1 "github.com/percona/percona-server-mysql-operator/api/v1alpha1"
40
43
psv1alpha1 "github.com/percona/percona-server-mysql-operator/api/v1alpha1"
44
+ "github.com/percona/percona-server-mysql-operator/pkg/haproxy"
45
+ "github.com/percona/percona-server-mysql-operator/pkg/innodbcluster"
41
46
"github.com/percona/percona-server-mysql-operator/pkg/mysql"
42
47
"github.com/percona/percona-server-mysql-operator/pkg/naming"
48
+ "github.com/percona/percona-server-mysql-operator/pkg/orchestrator"
43
49
)
44
50
45
51
var _ = Describe ("Sidecars" , Ordered , func () {
@@ -306,6 +312,162 @@ var _ = Describe("Unsafe configurations", Ordered, func() {
306
312
})
307
313
})
308
314
315
+ var _ = Describe ("PodDisruptionBudget" , Ordered , func () {
316
+ ctx := context .Background ()
317
+
318
+ crName := "pdb"
319
+ ns := crName
320
+ crNamespacedName := types.NamespacedName {Name : crName , Namespace : ns }
321
+
322
+ namespace := & corev1.Namespace {
323
+ ObjectMeta : metav1.ObjectMeta {
324
+ Name : crName ,
325
+ Namespace : ns ,
326
+ },
327
+ }
328
+
329
+ var r * PerconaServerMySQLReconciler
330
+
331
+ BeforeAll (func () {
332
+ By ("Creating the Namespace to perform the tests" )
333
+ err := k8sClient .Create (ctx , namespace )
334
+ Expect (err ).To (Not (HaveOccurred ()))
335
+ })
336
+
337
+ AfterAll (func () {
338
+ By ("Deleting the Namespace to perform the tests" )
339
+ _ = k8sClient .Delete (ctx , namespace )
340
+ })
341
+
342
+ Context ("Check default cluster" , Ordered , func () {
343
+ cr , err := readDefaultCR (crName , ns )
344
+ It ("should prepare reconciler" , func () {
345
+ r = reconciler ()
346
+ Expect (err ).To (Succeed ())
347
+ cliCmd , err := getFakeClient (cr , innodbcluster .ClusterStatusOK , []innodbcluster.MemberState {
348
+ innodbcluster .MemberStateOnline ,
349
+ innodbcluster .MemberStateOnline ,
350
+ innodbcluster .MemberStateOnline ,
351
+ }, false , true )
352
+ Expect (err ).To (Succeed ())
353
+ r .ClientCmd = cliCmd
354
+ const operatorPass = "test"
355
+ secret := & corev1.Secret {
356
+ ObjectMeta : metav1.ObjectMeta {
357
+ Name : cr .InternalSecretName (),
358
+ Namespace : cr .Namespace ,
359
+ },
360
+ Data : map [string ][]byte {
361
+ string (apiv1alpha1 .UserOperator ): []byte (operatorPass ),
362
+ },
363
+ }
364
+ Expect (k8sClient .Create (ctx , secret )).Should (Succeed ())
365
+ })
366
+
367
+ It ("should create cr.yaml" , func () {
368
+ cr .Spec .MySQL .ClusterType = psv1alpha1 .ClusterTypeAsync
369
+ cr .Spec .Unsafe .Orchestrator = true
370
+ cr .Spec .Unsafe .Proxy = true
371
+ cr .Spec .MySQL .PodDisruptionBudget = & psv1alpha1.PodDisruptionBudgetSpec {
372
+ MaxUnavailable : & intstr.IntOrString {
373
+ Type : intstr .Int ,
374
+ IntVal : 20 ,
375
+ },
376
+ }
377
+ cr .Spec .Proxy .Router .Enabled = false
378
+ cr .Spec .Proxy .HAProxy .Enabled = true
379
+ cr .Spec .Proxy .HAProxy .PodDisruptionBudget = & psv1alpha1.PodDisruptionBudgetSpec {
380
+ MinAvailable : & intstr.IntOrString {
381
+ Type : intstr .Int ,
382
+ IntVal : 12 ,
383
+ },
384
+ }
385
+ cr .Spec .Orchestrator .Enabled = true
386
+ cr .Spec .Orchestrator .PodDisruptionBudget = & psv1alpha1.PodDisruptionBudgetSpec {
387
+ MaxUnavailable : & intstr.IntOrString {
388
+ Type : intstr .Int ,
389
+ IntVal : 11 ,
390
+ },
391
+ }
392
+ Expect (k8sClient .Create (ctx , cr )).Should (Succeed ())
393
+ })
394
+
395
+ It ("should create MySQL pods" , func () {
396
+ for _ , pod := range makeFakeReadyPods (cr , 3 , "mysql" ) {
397
+ status := pod .(* corev1.Pod ).Status
398
+ Expect (k8sClient .Create (ctx , pod )).Should (Succeed ())
399
+ p := new (corev1.Pod )
400
+ Expect (k8sClient .Get (ctx , client .ObjectKeyFromObject (pod ), p )).Should (Succeed ())
401
+ p .Status = status
402
+ Expect (k8sClient .Status ().Update (ctx , p )).Should (Succeed ())
403
+ }
404
+ })
405
+
406
+ When ("HAProxy is enabled" , Ordered , func () {
407
+ It ("should reconcile" , func () {
408
+ _ , err := r .Reconcile (ctx , ctrl.Request {NamespacedName : crNamespacedName })
409
+ Expect (err ).NotTo (HaveOccurred ())
410
+ })
411
+ It ("should check PodDisruptionBudget for MySQL" , func () {
412
+ pdb := & policyv1.PodDisruptionBudget {
413
+ ObjectMeta : metav1.ObjectMeta {
414
+ Name : cr .Name + "-mysql" ,
415
+ Namespace : cr .Namespace ,
416
+ },
417
+ }
418
+
419
+ Eventually (func () bool {
420
+ err := k8sClient .Get (ctx , client .ObjectKeyFromObject (pdb ), pdb )
421
+ return err == nil
422
+ }, time .Second * 15 , time .Millisecond * 250 ).Should (BeTrue ())
423
+
424
+ Expect (pdb .Labels ).To (Equal (mysql .MatchLabels (cr )))
425
+ Expect (pdb .Spec .Selector .MatchLabels ).To (Equal (mysql .MatchLabels (cr )))
426
+
427
+ Expect (pdb .Spec .MaxUnavailable .IntVal ).To (Equal (int32 (20 )))
428
+ })
429
+
430
+ It ("should check PodDisruptionBudget for HAProxy" , func () {
431
+ pdb := & policyv1.PodDisruptionBudget {
432
+ ObjectMeta : metav1.ObjectMeta {
433
+ Name : cr .Name + "-haproxy" ,
434
+ Namespace : cr .Namespace ,
435
+ },
436
+ }
437
+
438
+ Eventually (func () bool {
439
+ err := k8sClient .Get (ctx , client .ObjectKeyFromObject (pdb ), pdb )
440
+ return err == nil
441
+ }, time .Second * 15 , time .Millisecond * 250 ).Should (BeTrue ())
442
+
443
+ Expect (pdb .Labels ).To (Equal (haproxy .MatchLabels (cr )))
444
+ Expect (pdb .Spec .Selector .MatchLabels ).To (Equal (haproxy .MatchLabels (cr )))
445
+
446
+ Expect (pdb .Spec .MinAvailable .IntVal ).To (Equal (int32 (12 )))
447
+ })
448
+
449
+ It ("should check PodDisruptionBudget for Orchestrator" , func () {
450
+ pdb := & policyv1.PodDisruptionBudget {
451
+ ObjectMeta : metav1.ObjectMeta {
452
+ Name : cr .Name + "-orchestrator" ,
453
+ Namespace : cr .Namespace ,
454
+ },
455
+ }
456
+
457
+ Eventually (func () bool {
458
+ err := k8sClient .Get (ctx , client .ObjectKeyFromObject (pdb ), pdb )
459
+ return err == nil
460
+ }, time .Second * 15 , time .Millisecond * 250 ).Should (BeTrue ())
461
+
462
+ Expect (pdb .Labels ).To (Equal (orchestrator .MatchLabels (cr )))
463
+ Expect (pdb .Spec .Selector .MatchLabels ).To (Equal (orchestrator .MatchLabels (cr )))
464
+
465
+ Expect (pdb .Spec .MaxUnavailable .IntVal ).To (Equal (int32 (11 )))
466
+ })
467
+ })
468
+ })
469
+ })
470
+
309
471
var _ = Describe ("Reconcile HAProxy when async cluster type" , Ordered , func () {
310
472
ctx := context .Background ()
311
473
0 commit comments