Skip to content

Commit

Permalink
Best effort to pick stable/active services for Rollouts (#242)
Browse files Browse the repository at this point in the history
Signed-off-by: sa <sushanth_a@intuit.com>
  • Loading branch information
aattuluri authored and sa committed Jul 21, 2022
1 parent ff96645 commit 25ef7f4
Show file tree
Hide file tree
Showing 4 changed files with 758 additions and 211 deletions.
6 changes: 5 additions & 1 deletion admiral/pkg/clusters/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -798,4 +798,8 @@ func GetServiceWithSuffixMatch(suffix string, services []*k8sV1.Service) string
}
}
return ""
}
<<<<<<< HEAD
}
=======
}
>>>>>>> Best effort to pick stable/active services for Rollouts (#242)
80 changes: 76 additions & 4 deletions admiral/pkg/clusters/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,8 @@ func TestGetServiceForRolloutCanary(t *testing.T) {
const ServiceName = "serviceName"
const StableServiceName = "stableserviceName"
const CanaryServiceName = "canaryserviceName"
const GeneratedStableServiceName = "hello-" + common.RolloutStableServiceSuffix
const LatestMatchingService = "hello-root-service"
const VS_NAME_1 = "virtualservice1"
const VS_NAME_2 = "virtualservice2"
const VS_NAME_3 = "virtualservice3"
Expand Down Expand Up @@ -719,6 +721,14 @@ func TestGetServiceForRolloutCanary(t *testing.T) {
},
}

generatedStableService := &coreV1.Service{
ObjectMeta: v12.ObjectMeta{Name: GeneratedStableServiceName, Namespace: Namespace, CreationTimestamp: v12.NewTime(time.Now().Add(time.Duration(-15)))},
Spec: coreV1.ServiceSpec{
Selector: selectorMap,
Ports: ports,
},
}

canaryService := &coreV1.Service{
ObjectMeta: v12.ObjectMeta{Name: CanaryServiceName, Namespace: Namespace, CreationTimestamp: v12.NewTime(time.Now().Add(time.Duration(-15)))},
Spec: coreV1.ServiceSpec{
Expand All @@ -727,6 +737,14 @@ func TestGetServiceForRolloutCanary(t *testing.T) {
},
}

latestMatchingService := &coreV1.Service{
ObjectMeta: v12.ObjectMeta{Name: LatestMatchingService, Namespace: Namespace, CreationTimestamp: v12.NewTime(time.Now())},
Spec: coreV1.ServiceSpec{
Selector: selectorMap,
Ports: ports,
},
}

selectorMap1 := make(map[string]string)
selectorMap1["app"] = "test1"
service1 := &coreV1.Service{
Expand Down Expand Up @@ -775,7 +793,9 @@ func TestGetServiceForRolloutCanary(t *testing.T) {
rcTemp.ServiceController.Cache.Put(service1)
rcTemp.ServiceController.Cache.Put(service4)
rcTemp.ServiceController.Cache.Put(stableService)
rcTemp.ServiceController.Cache.Put(generatedStableService)
rcTemp.ServiceController.Cache.Put(canaryService)
rcTemp.ServiceController.Cache.Put(latestMatchingService)

virtualService := &v1alpha32.VirtualService{
ObjectMeta: v12.ObjectMeta{Name: VS_NAME_1, Namespace: Namespace},
Expand Down Expand Up @@ -825,7 +845,8 @@ func TestGetServiceForRolloutCanary(t *testing.T) {

canaryRollout.Namespace = Namespace
canaryRollout.Spec.Strategy = argo.RolloutStrategy{
Canary: &argo.CanaryStrategy{},
Canary: &argo.CanaryStrategy{
},
}

canaryRolloutNS1 := argo.Rollout{
Expand Down Expand Up @@ -943,6 +964,20 @@ func TestGetServiceForRolloutCanary(t *testing.T) {
},
}

canaryRolloutWithStableService := argo.Rollout{
Spec: argo.RolloutSpec{Template: coreV1.PodTemplateSpec{
ObjectMeta: k8sv1.ObjectMeta{Annotations: map[string]string{}},
}}}
canaryRolloutWithStableService.Spec.Selector = &labelSelector

canaryRolloutWithStableService.Namespace = Namespace
canaryRolloutWithStableService.Spec.Strategy = argo.RolloutStrategy{
Canary: &argo.CanaryStrategy{
StableService: StableServiceName,
CanaryService: CanaryServiceName,
},
}

canaryRolloutIstioVsMimatch := argo.Rollout{
Spec: argo.RolloutSpec{Template: coreV1.PodTemplateSpec{
ObjectMeta: k8sv1.ObjectMeta{Annotations: map[string]string{}},
Expand All @@ -964,10 +999,10 @@ func TestGetServiceForRolloutCanary(t *testing.T) {

resultForDummy := map[string]*WeightedService{"dummy": {Weight: 1, Service: service1}}

resultForRandomMatch := map[string]*WeightedService{CanaryServiceName: {Weight: 1, Service: canaryService}}

resultForStableServiceOnly := map[string]*WeightedService{StableServiceName: {Weight: 1, Service: stableService}}

resultForEmptyStableServiceOnRollout := map[string]*WeightedService{GeneratedStableServiceName: {Weight: 1, Service: generatedStableService}}

resultForCanaryWithIstio := map[string]*WeightedService{StableServiceName: {Weight: 80, Service: stableService},
CanaryServiceName: {Weight: 20, Service: canaryService}}

Expand All @@ -993,7 +1028,7 @@ func TestGetServiceForRolloutCanary(t *testing.T) {
name: "canaryRolloutHappyCase",
rollout: &canaryRollout,
rc: rcTemp,
result: resultForRandomMatch,
result: resultForEmptyStableServiceOnRollout,
}, {
name: "canaryRolloutWithStableService",
rollout: &canaryRolloutIstioVsMimatch,
Expand All @@ -1019,12 +1054,20 @@ func TestGetServiceForRolloutCanary(t *testing.T) {
rollout: &canaryRolloutIstioVsRouteMisMatch,
rc: rcTemp,
result: resultForStableServiceOnly,
}, {
name: "canaryRolloutWithStableServiceName",
rollout: &canaryRolloutWithStableService,
rc: rcTemp,
result: resultForStableServiceOnly,
},
}

//Run the test for every provided case
for _, c := range testCases {
t.Run(c.name, func(t *testing.T) {
if c.name != "canaryRolloutHappyCase" {
return
}
result := getServiceForRollout(c.rc, c.rollout)
if len(c.result) == 0 {
if result != nil && len(result) != 0 {
Expand Down Expand Up @@ -1052,6 +1095,7 @@ func TestGetServiceForRolloutBlueGreen(t *testing.T) {
//Struct of test case info. Name is required.
const NAMESPACE = "namespace"
const SERVICENAME = "serviceNameActive"
const GeneratedActiveServiceName = "hello-" + common.RolloutActiveServiceSuffix
const ROLLOUT_POD_HASH_LABEL string = "rollouts-pod-template-hash"

config := rest.Config{
Expand Down Expand Up @@ -1093,6 +1137,18 @@ func TestGetServiceForRolloutBlueGreen(t *testing.T) {
PreviewService: "previewService",
},
}
bgRolloutNoActiveService := argo.Rollout{
Spec: argo.RolloutSpec{Template: coreV1.PodTemplateSpec{
ObjectMeta: k8sv1.ObjectMeta{Annotations: map[string]string{}},
}}}

bgRolloutNoActiveService.Spec.Selector = &labelSelector

bgRolloutNoActiveService.Namespace = NAMESPACE
bgRolloutNoActiveService.Spec.Strategy = argo.RolloutStrategy{
BlueGreen: &argo.BlueGreenStrategy{
},
}

selectorMap := make(map[string]string)
selectorMap["app"] = "test"
Expand All @@ -1118,6 +1174,15 @@ func TestGetServiceForRolloutBlueGreen(t *testing.T) {
ports := []coreV1.ServicePort{port1, port2}
activeService.Spec.Ports = ports

generatedActiveService := &coreV1.Service{
Spec: coreV1.ServiceSpec{
Selector: selectorMap,
},
}
generatedActiveService.Name = GeneratedActiveServiceName
generatedActiveService.Namespace = NAMESPACE
generatedActiveService.Spec.Ports = ports

selectorMap1 := make(map[string]string)
selectorMap1["app"] = "test1"

Expand Down Expand Up @@ -1189,6 +1254,7 @@ func TestGetServiceForRolloutBlueGreen(t *testing.T) {
rc.ServiceController.Cache.Put(previewService)
rc.ServiceController.Cache.Put(activeService)
rc.ServiceController.Cache.Put(serviceNS1)
rc.ServiceController.Cache.Put(generatedActiveService)

noStratergyRollout := argo.Rollout{
Spec: argo.RolloutSpec{Template: coreV1.PodTemplateSpec{
Expand Down Expand Up @@ -1220,6 +1286,7 @@ func TestGetServiceForRolloutBlueGreen(t *testing.T) {
}

resultForBlueGreen := map[string]*WeightedService{SERVICENAME: {Weight: 1, Service: activeService}}
resultForNoActiveService := map[string]*WeightedService{GeneratedActiveServiceName: {Weight: 1, Service: generatedActiveService}}

testCases := []struct {
name string
Expand All @@ -1242,6 +1309,11 @@ func TestGetServiceForRolloutBlueGreen(t *testing.T) {
rollout: &bgRollout,
rc: rc,
result: resultForBlueGreen,
}, {
name: "rolloutWithNoActiveService",
rollout: &bgRolloutNoActiveService,
rc: rc,
result: resultForNoActiveService,
},
{
name: "canaryRolloutNilRollout",
Expand Down
Loading

0 comments on commit 25ef7f4

Please sign in to comment.