github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/update/authproxy/authproxy_update_test.go (about)

     1  // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package authproxy
     5  
     6  import (
     7  	"fmt"
     8  	"sigs.k8s.io/yaml"
     9  	"time"
    10  
    11  	. "github.com/onsi/ginkgo/v2"
    12  	"github.com/verrazzano/verrazzano/pkg/constants"
    13  	vzapi "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1alpha1"
    14  	"github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1beta1"
    15  	"github.com/verrazzano/verrazzano/tests/e2e/pkg"
    16  	"github.com/verrazzano/verrazzano/tests/e2e/pkg/test/framework"
    17  	"github.com/verrazzano/verrazzano/tests/e2e/pkg/update"
    18  	corev1 "k8s.io/api/core/v1"
    19  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    20  )
    21  
    22  const (
    23  	authProxyLabelValue = "verrazzano-authproxy"
    24  	authProxyLabelKey   = "app"
    25  	explicitReplicas    = uint32(3)
    26  	waitTimeout         = 20 * time.Minute
    27  	pollingInterval     = 10 * time.Second
    28  )
    29  
    30  type AuthProxyReplicasModifier struct {
    31  	replicas uint32
    32  }
    33  
    34  type AuthProxyReplicasModifierV1beta1 struct {
    35  	replicas uint32
    36  }
    37  
    38  type AuthProxyPodPerNodeAffintyModifierV1beta1 struct {
    39  }
    40  
    41  type AuthProxyPodPerNodeAffintyModifier struct {
    42  }
    43  
    44  type AuthProxyDefaultModifier struct {
    45  }
    46  
    47  type AuthProxyDefaultModifierV1beta1 struct {
    48  }
    49  
    50  func (u AuthProxyReplicasModifier) ModifyCR(cr *vzapi.Verrazzano) {
    51  	if cr.Spec.Components.AuthProxy == nil {
    52  		cr.Spec.Components.AuthProxy = &vzapi.AuthProxyComponent{}
    53  	}
    54  	if cr.Spec.Components.AuthProxy.Kubernetes == nil {
    55  		cr.Spec.Components.AuthProxy.Kubernetes = &vzapi.AuthProxyKubernetesSection{}
    56  	}
    57  	cr.Spec.Components.AuthProxy.Kubernetes.Replicas = u.replicas
    58  	t.Logs.Debugf("AuthProxyReplicasModifier CR: %v", marshalCRToString(cr.Spec))
    59  }
    60  
    61  func (u AuthProxyReplicasModifierV1beta1) ModifyCRV1beta1(cr *v1beta1.Verrazzano) {
    62  	if cr.Spec.Components.AuthProxy == nil {
    63  		cr.Spec.Components.AuthProxy = &v1beta1.AuthProxyComponent{}
    64  	}
    65  	authProxyReplicasOverridesYaml := fmt.Sprintf(`replicas: %v`, u.replicas)
    66  	cr.Spec.Components.AuthProxy.ValueOverrides = pkg.CreateOverridesOrDie(authProxyReplicasOverridesYaml)
    67  	t.Logs.Debugf("AuthProxyReplicasModifierV1beta1 CR: %s", marshalCRToString(cr.Spec))
    68  }
    69  
    70  func (u AuthProxyPodPerNodeAffintyModifierV1beta1) ModifyCRV1beta1(cr *v1beta1.Verrazzano) {
    71  	if cr.Spec.Components.AuthProxy == nil {
    72  		cr.Spec.Components.AuthProxy = &v1beta1.AuthProxyComponent{}
    73  	}
    74  	authProxyAffinityOverridesYaml := fmt.Sprintf(`affinity: |
    75                podAntiAffinity:
    76                  preferredDuringSchedulingIgnoredDuringExecution:
    77                  - podAffinityTerm:
    78                      labelSelector:
    79                        matchExpressions:
    80                        - key: %v
    81                          operator: In
    82                          values:
    83                          - %v
    84                      topologyKey: kubernetes.io/hostname
    85                    weight: 100`, authProxyLabelKey, authProxyLabelValue)
    86  	cr.Spec.Components.AuthProxy.ValueOverrides = pkg.CreateOverridesOrDie(authProxyAffinityOverridesYaml)
    87  	t.Logs.Debugf("AuthProxyPodPerNodeAffintyModifierV1beta1 CR: %v", marshalCRToString(cr.Spec))
    88  }
    89  
    90  func (u AuthProxyPodPerNodeAffintyModifier) ModifyCR(cr *vzapi.Verrazzano) {
    91  	if cr.Spec.Components.AuthProxy == nil {
    92  		cr.Spec.Components.AuthProxy = &vzapi.AuthProxyComponent{}
    93  	}
    94  	if cr.Spec.Components.AuthProxy.Kubernetes == nil {
    95  		cr.Spec.Components.AuthProxy.Kubernetes = &vzapi.AuthProxyKubernetesSection{}
    96  	}
    97  	if cr.Spec.Components.AuthProxy.Kubernetes.Affinity == nil {
    98  		cr.Spec.Components.AuthProxy.Kubernetes.Affinity = &corev1.Affinity{}
    99  	}
   100  	if cr.Spec.Components.AuthProxy.Kubernetes.Affinity.PodAntiAffinity == nil {
   101  		cr.Spec.Components.AuthProxy.Kubernetes.Affinity.PodAntiAffinity = &corev1.PodAntiAffinity{}
   102  	}
   103  	list := cr.Spec.Components.AuthProxy.Kubernetes.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution
   104  	list = append(list, corev1.PodAffinityTerm{
   105  		LabelSelector: &metav1.LabelSelector{
   106  			MatchLabels: nil,
   107  			MatchExpressions: []metav1.LabelSelectorRequirement{
   108  				{
   109  					Key:      authProxyLabelKey,
   110  					Operator: "In",
   111  					Values: []string{
   112  						authProxyLabelValue,
   113  					},
   114  				},
   115  			},
   116  		},
   117  		TopologyKey: "kubernetes.io/hostname",
   118  	})
   119  	cr.Spec.Components.AuthProxy.Kubernetes.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution = list
   120  	t.Logs.Debugf("AuthProxyPodPerNodeAffintyModifier CR: %v", marshalCRToString(cr.Spec))
   121  }
   122  
   123  func (u AuthProxyDefaultModifier) ModifyCR(cr *vzapi.Verrazzano) {
   124  	cr.Spec.Components.AuthProxy = &vzapi.AuthProxyComponent{}
   125  	t.Logs.Debugf("AuthProxyDefaultModifier CR: %v", cr.Spec)
   126  }
   127  
   128  func (u AuthProxyDefaultModifierV1beta1) ModifyCRV1beta1(cr *v1beta1.Verrazzano) {
   129  	cr.Spec.Components.AuthProxy = &v1beta1.AuthProxyComponent{}
   130  	t.Logs.Debugf("AuthProxyDefaultModifierV1beta1 CR: %v", marshalCRToString(cr.Spec))
   131  }
   132  
   133  var t = framework.NewTestFramework("update authproxy")
   134  
   135  var nodeCount uint32
   136  
   137  var beforeSuite = t.BeforeSuiteFunc(func() {
   138  	var err error
   139  	nodeCount, err = pkg.GetSchedulableNodeCount()
   140  	if err != nil {
   141  		Fail(err.Error())
   142  	}
   143  	t.Logs.Infof("Schedulable nodes: %v", nodeCount)
   144  })
   145  
   146  var _ = BeforeSuite(beforeSuite)
   147  
   148  var afterSuite = t.AfterSuiteFunc(func() {
   149  	m := AuthProxyDefaultModifier{}
   150  	update.UpdateCRWithRetries(m, pollingInterval, waitTimeout)
   151  	update.ValidatePods(authProxyLabelValue, authProxyLabelKey, constants.VerrazzanoSystemNamespace, uint32(1), false)
   152  })
   153  
   154  var _ = AfterSuite(afterSuite)
   155  
   156  var _ = t.Describe("Update authProxy", Label("f:platform-lcm.update"), func() {
   157  	t.Describe("verrazzano-authproxy verify", Label("f:platform-lcm.authproxy-verify"), func() {
   158  		t.It("authproxy default replicas", func() {
   159  			update.ValidatePods(authProxyLabelValue, authProxyLabelKey, constants.VerrazzanoSystemNamespace, uint32(1), false)
   160  		})
   161  	})
   162  
   163  	t.Describe("verrazzano-authproxy update replicas", Label("f:platform-lcm.authproxy-update-replicas"), func() {
   164  		t.It("authproxy explicit replicas v1alpha1", func() {
   165  			m := AuthProxyReplicasModifier{replicas: nodeCount}
   166  			update.UpdateCRWithRetries(m, pollingInterval, waitTimeout)
   167  			expectedRunning := nodeCount
   168  			update.ValidatePods(authProxyLabelValue, authProxyLabelKey, constants.VerrazzanoSystemNamespace, expectedRunning, false)
   169  		})
   170  	})
   171  
   172  	t.Describe("verrazzano-authproxy update affinity", Label("f:platform-lcm.authproxy-update-affinity"), func() {
   173  		t.It("authproxy explicit affinity v1alpha1", func() {
   174  			m := AuthProxyPodPerNodeAffintyModifier{}
   175  			update.UpdateCRWithRetries(m, pollingInterval, waitTimeout)
   176  
   177  			// Because the authproxy rollout strategy requires maxUnavailable == 0, k8s tries to spin
   178  			// up a new pod after the edit to the deployment which gets stuck in pending, regardless of the number
   179  			// of nodes
   180  			expectedRunning := nodeCount
   181  			expectedPending := true
   182  			t.Logs.Debugf("Expected running: %v, expected pending %v", expectedRunning, expectedPending)
   183  			update.ValidatePods(authProxyLabelValue, authProxyLabelKey, constants.VerrazzanoSystemNamespace, expectedRunning, expectedPending)
   184  		})
   185  	})
   186  
   187  	t.Describe("verrazzano-authproxy update replicas with v1beta1 client", Label("f:platform-lcm.authproxy-update-replicas"), func() {
   188  		t.It("authproxy explicit replicas v1beta1", func() {
   189  			m := AuthProxyReplicasModifierV1beta1{replicas: explicitReplicas}
   190  			update.UpdateCRV1beta1WithRetries(m, pollingInterval, waitTimeout)
   191  			expectedRunning := explicitReplicas
   192  			update.ValidatePods(authProxyLabelValue, authProxyLabelKey, constants.VerrazzanoSystemNamespace, expectedRunning, false)
   193  		})
   194  	})
   195  
   196  	t.Describe("verrazzano-authproxy update affinity using v1beta1 client", Label("f:platform-lcm.authproxy-update-affinity"), func() {
   197  		t.It("authproxy explicit affinity v1beta1", func() {
   198  			m := AuthProxyPodPerNodeAffintyModifierV1beta1{}
   199  			update.UpdateCRV1beta1WithRetries(m, pollingInterval, waitTimeout)
   200  			expectedRunning := explicitReplicas
   201  			update.ValidatePods(authProxyLabelValue, authProxyLabelKey, constants.VerrazzanoSystemNamespace, expectedRunning, false)
   202  		})
   203  	})
   204  
   205  })
   206  
   207  func marshalCRToString(cr interface{}) string {
   208  	data, err := yaml.Marshal(cr)
   209  	if err != nil {
   210  		t.Logs.Errorf("Error marshalling CR to string")
   211  		return ""
   212  	}
   213  	return string(data)
   214  }