-
Notifications
You must be signed in to change notification settings - Fork 867
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: ping pong support for istio #3371
Changes from 9 commits
1a22777
2368234
7b6714d
2a4e7a1
81c27d5
040462c
9f7f806
9b68249
7b2f694
1546fc7
4abea33
f9bc1d9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,6 +64,31 @@ func rollout(stableSvc, canarySvc string, istioVirtualService *v1alpha1.IstioVir | |
} | ||
} | ||
|
||
func rolloutPingPong(istioVirtualService *v1alpha1.IstioVirtualService) *v1alpha1.Rollout { | ||
return &v1alpha1.Rollout{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "rollout", | ||
Namespace: "default", | ||
}, | ||
Spec: v1alpha1.RolloutSpec{ | ||
Strategy: v1alpha1.RolloutStrategy{ | ||
Canary: &v1alpha1.CanaryStrategy{ | ||
PingPong: &v1alpha1.PingPongSpec{ | ||
PingService: "ping", | ||
PongService: "pong", | ||
}, | ||
TrafficRouting: &v1alpha1.RolloutTrafficRouting{ | ||
Istio: &v1alpha1.IstioTrafficRouting{ | ||
VirtualService: istioVirtualService, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
Status: v1alpha1.RolloutStatus{Canary: v1alpha1.CanaryStatus{StablePingPong: "ping"}}, | ||
} | ||
} | ||
|
||
func rolloutWithHttpRoutes(stableSvc, canarySvc, vsvc string, httpRoutes []string) *v1alpha1.Rollout { | ||
istioVirtualService := &v1alpha1.IstioVirtualService{ | ||
Name: vsvc, | ||
|
@@ -98,6 +123,16 @@ func rolloutWithHttpAndTlsAndTcpRoutes(stableSvc, canarySvc, vsvc string, httpRo | |
return rollout(stableSvc, canarySvc, istioVirtualService) | ||
} | ||
|
||
func rolloutWithHttpAndTlsAndTcpRoutesPingPong(vsvc string, httpRoutes []string, tlsRoutes []v1alpha1.TLSRoute, tcpRoutes []v1alpha1.TCPRoute) *v1alpha1.Rollout { | ||
istioVirtualService := &v1alpha1.IstioVirtualService{ | ||
Name: vsvc, | ||
Routes: httpRoutes, | ||
TLSRoutes: tlsRoutes, | ||
TCPRoutes: tcpRoutes, | ||
} | ||
return rolloutPingPong(istioVirtualService) | ||
} | ||
|
||
func checkDestination(t *testing.T, destinations []VirtualServiceRouteDestination, svc string, expectWeight int) { | ||
for _, destination := range destinations { | ||
if destination.Destination.Host == svc { | ||
|
@@ -263,6 +298,72 @@ spec: | |
host: canary | ||
weight: 0` | ||
|
||
const regularMixedVsvcPingPong = `apiVersion: networking.istio.io/v1alpha3 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer using See the following PR as an example: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea, I kept it the way it is because it is consistent with all the other tests for istio There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure.. but we have to start somewhere ¯\_(ツ)_/¯ |
||
kind: VirtualService | ||
metadata: | ||
name: vsvc | ||
namespace: default | ||
spec: | ||
gateways: | ||
- istio-rollout-gateway | ||
hosts: | ||
- istio-rollout.dev.argoproj.io | ||
http: | ||
- name: primary | ||
route: | ||
- destination: | ||
host: 'ping' | ||
weight: 100 | ||
- destination: | ||
host: pong | ||
weight: 0 | ||
- name: secondary | ||
route: | ||
- destination: | ||
host: 'ping' | ||
weight: 100 | ||
- destination: | ||
host: pong | ||
weight: 0 | ||
tls: | ||
- match: | ||
- port: 3000 | ||
route: | ||
- destination: | ||
host: 'ping' | ||
weight: 100 | ||
- destination: | ||
host: pong | ||
weight: 0 | ||
- match: | ||
- port: 3001 | ||
route: | ||
- destination: | ||
host: 'ping' | ||
weight: 100 | ||
- destination: | ||
host: pong | ||
weight: 0 | ||
tcp: | ||
- match: | ||
- port: 3000 | ||
route: | ||
- destination: | ||
host: 'ping' | ||
weight: 100 | ||
- destination: | ||
host: pong | ||
weight: 0 | ||
- match: | ||
- port: 3001 | ||
route: | ||
- destination: | ||
host: 'ping' | ||
weight: 100 | ||
- destination: | ||
host: pong | ||
weight: 0` | ||
|
||
const regularMixedVsvcTwoHttpRoutes = `apiVersion: networking.istio.io/v1alpha3 | ||
kind: VirtualService | ||
metadata: | ||
|
@@ -597,6 +698,14 @@ func extractTcpRoutes(t *testing.T, modifiedObj *unstructured.Unstructured) []Vi | |
} | ||
|
||
func assertTcpRouteWeightChanges(t *testing.T, tcpRoute VirtualServiceTCPRoute, portNum, canaryWeight, stableWeight int) { | ||
assertTcpRouteWeightChangesBase(t, tcpRoute, portNum, canaryWeight, stableWeight, "stable", "canary") | ||
} | ||
|
||
func assertTcpRouteWeightChangesPingPong(t *testing.T, tcpRoute VirtualServiceTCPRoute, portNum, canaryWeight, stableWeight int) { | ||
assertTcpRouteWeightChangesBase(t, tcpRoute, portNum, canaryWeight, stableWeight, "ping", "pong") | ||
} | ||
|
||
func assertTcpRouteWeightChangesBase(t *testing.T, tcpRoute VirtualServiceTCPRoute, portNum, canaryWeight, stableWeight int, stableSvc, canarySvc string) { | ||
portsMap := make(map[int64]bool) | ||
for _, routeMatch := range tcpRoute.Match { | ||
if routeMatch.Port != 0 { | ||
|
@@ -610,8 +719,8 @@ func assertTcpRouteWeightChanges(t *testing.T, tcpRoute VirtualServiceTCPRoute, | |
if portNum != 0 { | ||
assert.Equal(t, portNum, port) | ||
} | ||
checkDestination(t, tcpRoute.Route, "stable", stableWeight) | ||
checkDestination(t, tcpRoute.Route, "canary", canaryWeight) | ||
checkDestination(t, tcpRoute.Route, stableSvc, stableWeight) | ||
checkDestination(t, tcpRoute.Route, canarySvc, canaryWeight) | ||
} | ||
|
||
func extractHttpRoutes(t *testing.T, modifiedObj *unstructured.Unstructured) []VirtualServiceHTTPRoute { | ||
|
@@ -643,6 +752,14 @@ func extractTlsRoutes(t *testing.T, modifiedObj *unstructured.Unstructured) []Vi | |
} | ||
|
||
func assertTlsRouteWeightChanges(t *testing.T, tlsRoute VirtualServiceTLSRoute, snis []string, portNum, canaryWeight, stableWeight int) { | ||
assertTlsRouteWeightChangesBase(t, tlsRoute, snis, portNum, canaryWeight, stableWeight, "stable", "canary") | ||
} | ||
|
||
func assertTlsRouteWeightChangesPingPong(t *testing.T, tlsRoute VirtualServiceTLSRoute, snis []string, portNum, canaryWeight, stableWeight int) { | ||
assertTlsRouteWeightChangesBase(t, tlsRoute, snis, portNum, canaryWeight, stableWeight, "ping", "pong") | ||
} | ||
|
||
func assertTlsRouteWeightChangesBase(t *testing.T, tlsRoute VirtualServiceTLSRoute, snis []string, portNum, canaryWeight, stableWeight int, stableSvc, canarySvc string) { | ||
portsMap := make(map[int64]bool) | ||
sniHostsMap := make(map[string]bool) | ||
for _, routeMatch := range tlsRoute.Match { | ||
|
@@ -667,8 +784,8 @@ func assertTlsRouteWeightChanges(t *testing.T, tlsRoute VirtualServiceTLSRoute, | |
if len(snis) != 0 { | ||
assert.Equal(t, evalUtils.Equal(snis, sniHosts), true) | ||
} | ||
checkDestination(t, tlsRoute.Route, "stable", stableWeight) | ||
checkDestination(t, tlsRoute.Route, "canary", canaryWeight) | ||
checkDestination(t, tlsRoute.Route, stableSvc, stableWeight) | ||
checkDestination(t, tlsRoute.Route, canarySvc, canaryWeight) | ||
} | ||
|
||
func TestHttpReconcileWeightsBaseCase(t *testing.T) { | ||
|
@@ -1104,6 +1221,57 @@ func TestReconcileWeightsBaseCase(t *testing.T) { | |
assertTcpRouteWeightChanges(t, tcpRoutes[1], 3001, 0, 100) | ||
} | ||
|
||
func TestReconcileWeightsPingPongBaseCase(t *testing.T) { | ||
r := &Reconciler{ | ||
rollout: rolloutWithHttpAndTlsAndTcpRoutesPingPong("vsvc", []string{"primary"}, | ||
[]v1alpha1.TLSRoute{ | ||
{ | ||
Port: 3000, | ||
}, | ||
}, | ||
[]v1alpha1.TCPRoute{ | ||
{ | ||
Port: 3000, | ||
}, | ||
}, | ||
), | ||
} | ||
obj := unstructuredutil.StrToUnstructuredUnsafe(regularMixedVsvcPingPong) | ||
vsvcRoutes := r.rollout.Spec.Strategy.Canary.TrafficRouting.Istio.VirtualService.Routes | ||
vsvcTLSRoutes := r.rollout.Spec.Strategy.Canary.TrafficRouting.Istio.VirtualService.TLSRoutes | ||
vsvcTCPRoutes := r.rollout.Spec.Strategy.Canary.TrafficRouting.Istio.VirtualService.TCPRoutes | ||
modifiedObj, _, err := r.reconcileVirtualService(obj, vsvcRoutes, vsvcTLSRoutes, vsvcTCPRoutes, 20) | ||
assert.Nil(t, err) | ||
assert.NotNil(t, modifiedObj) | ||
|
||
// HTTP Routes | ||
httpRoutes := extractHttpRoutes(t, modifiedObj) | ||
|
||
// Assertions | ||
assert.Equal(t, httpRoutes[0].Name, "primary") | ||
checkDestination(t, httpRoutes[0].Route, "ping", 80) | ||
checkDestination(t, httpRoutes[0].Route, "pong", 20) | ||
|
||
//assertHttpRouteWeightChanges(t, httpRoutes[1], "secondary", 0, 100) | ||
assert.Equal(t, httpRoutes[1].Name, "secondary") | ||
checkDestination(t, httpRoutes[1].Route, "ping", 100) | ||
checkDestination(t, httpRoutes[1].Route, "pong", 0) | ||
|
||
// TLS Routes | ||
tlsRoutes := extractTlsRoutes(t, modifiedObj) | ||
// | ||
// Assestions | ||
assertTlsRouteWeightChangesPingPong(t, tlsRoutes[0], nil, 3000, 20, 80) | ||
assertTlsRouteWeightChangesPingPong(t, tlsRoutes[1], nil, 3001, 0, 100) | ||
// | ||
// TCP Routes | ||
tcpRoutes := extractTcpRoutes(t, modifiedObj) | ||
|
||
// Assestions | ||
assertTcpRouteWeightChangesPingPong(t, tcpRoutes[0], 3000, 20, 80) | ||
assertTcpRouteWeightChangesPingPong(t, tcpRoutes[1], 3001, 0, 100) | ||
} | ||
|
||
func TestReconcileUpdateVirtualService(t *testing.T) { | ||
ro := rolloutWithHttpRoutes("stable", "canary", "vsvc", []string{"primary"}) | ||
AssertReconcileUpdateVirtualService(t, regularVsvc, ro) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we add a new testcase for istio?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added new test instead of piggy backing off one