-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Add integration test for outboundTrafficPolicy #13099
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
Changes from all commits
00e4ed4
1dfafa4
670b624
9543e70
e85c36b
61734b1
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 |
|---|---|---|
|
|
@@ -322,9 +322,11 @@ func newKube(ctx resource.Context, cfg Config) (Instance, error) { | |
|
|
||
| var err error | ||
|
|
||
| // Wait for the pods to transition to running. | ||
| if c.namespace, err = namespace.New(ctx, "apps", true); err != nil { | ||
| return nil, err | ||
| c.namespace = cfg.Namespace | ||
| if c.namespace == nil { | ||
| if c.namespace, err = namespace.New(ctx, "apps", true); err != nil { | ||
| return nil, err | ||
| } | ||
| } | ||
|
|
||
| params := cfg.AppParams | ||
|
|
@@ -663,19 +665,9 @@ func (a *kubeApp) Call(e AppEndpoint, opts AppCallOptions) ([]*echo.ParsedRespon | |
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| if len(resp) != 1 { | ||
|
Contributor
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 think we should leave the check for len here. Everything else we can remove completely. |
||
| if len(resp) != opts.Count { | ||
| return nil, fmt.Errorf("unexpected number of responses: %d", len(resp)) | ||
| } | ||
| if !resp[0].IsOK() { | ||
| return nil, fmt.Errorf("unexpected response status code: %s", resp[0].Code) | ||
| } | ||
| if resp[0].Host != dstServiceName { | ||
| return nil, fmt.Errorf("unexpected host: %s", resp[0].Host) | ||
| } | ||
| if resp[0].Port != strconv.Itoa(dst.networkEndpoint.ServicePort.Port) { | ||
| return nil, fmt.Errorf("unexpected port: %s", resp[0].Port) | ||
| } | ||
|
|
||
| return resp, nil | ||
| } | ||
|
|
@@ -685,6 +677,7 @@ func (a *kubeApp) CallOrFail(e AppEndpoint, opts AppCallOptions, t testing.TB) [ | |
| if err != nil { | ||
| t.Fatal(err) | ||
| } | ||
|
|
||
| return r | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -388,18 +388,9 @@ func (a *nativeApp) Call(e AppEndpoint, opts AppCallOptions) ([]*echo.ParsedResp | |
| return nil, err | ||
| } | ||
|
|
||
| if len(resp) != 1 { | ||
| if len(resp) != opts.Count { | ||
| return nil, fmt.Errorf("unexpected number of responses: %d", len(resp)) | ||
| } | ||
| if !resp[0].IsOK() { | ||
| return nil, fmt.Errorf("unexpected response status code: %s", resp[0].Code) | ||
| } | ||
| if resp[0].Host != dstHost { | ||
| return nil, fmt.Errorf("unexpected host: %s", resp[0].Host) | ||
| } | ||
| if resp[0].Port != strconv.Itoa(dst.port.ApplicationPort) { | ||
| return nil, fmt.Errorf("unexpected port: %s", resp[0].Port) | ||
| } | ||
|
|
||
| return resp, nil | ||
| } | ||
|
|
@@ -409,6 +400,7 @@ func (a *nativeApp) CallOrFail(e AppEndpoint, opts AppCallOptions, t testing.TB) | |
| if err != nil { | ||
| t.Fatal(err) | ||
|
Member
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'd imagine there could be a test where if a request fails due to some reason, e.g. network, then the test may want to try again, so maybe let the caller decide to stop the test if they want to, and change the function name to something like |
||
| } | ||
|
|
||
| return r | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| // Copyright 2019 Istio Authors | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| package allowany | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "istio.io/istio/pkg/test/framework" | ||
| "istio.io/istio/pkg/test/framework/components/environment" | ||
| "istio.io/istio/pkg/test/framework/components/istio" | ||
| "istio.io/istio/tests/integration/pilot/outboundtrafficpolicy" | ||
| ) | ||
|
|
||
| func TestMain(m *testing.M) { | ||
| var ist istio.Instance | ||
| framework.NewSuite("outbound_traffic_policy_allow_any", m). | ||
| RequireEnvironment(environment.Kube). | ||
| Setup(istio.SetupOnKube(&ist, setupConfig)). | ||
| Run() | ||
| } | ||
|
|
||
| func setupConfig(cfg *istio.Config) { | ||
| if cfg == nil { | ||
| return | ||
| } | ||
| cfg.Values["global.outboundTrafficPolicy.mode"] = "ALLOW_ANY" | ||
| cfg.Values["pilot.env.PILOT_ENABLE_FALLTHROUGH_ROUTE"] = "true" | ||
| } | ||
|
|
||
| func TestOutboundTrafficPolicyAllowAny(t *testing.T) { | ||
| expected := map[string][]string{ | ||
| "http": {"200"}, | ||
| "https": {"200"}, | ||
| } | ||
| outboundtrafficpolicy.RunExternalRequestTest(expected, t) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| package outboundtrafficpolicy | ||
|
|
||
| import ( | ||
| "bytes" | ||
| "html/template" | ||
| "reflect" | ||
| "testing" | ||
|
|
||
| "istio.io/istio/pkg/test/framework" | ||
| "istio.io/istio/pkg/test/framework/components/apps" | ||
| "istio.io/istio/pkg/test/framework/components/environment" | ||
| "istio.io/istio/pkg/test/framework/components/galley" | ||
| "istio.io/istio/pkg/test/framework/components/namespace" | ||
| "istio.io/istio/pkg/test/framework/components/pilot" | ||
| ) | ||
|
|
||
| const ( | ||
| IstioSystemScope = ` | ||
| ` | ||
| ServiceEntry = ` | ||
| apiVersion: networking.istio.io/v1alpha3 | ||
| kind: ServiceEntry | ||
| metadata: | ||
| name: https-service | ||
| spec: | ||
| hosts: | ||
| - istio.io | ||
| location: MESH_EXTERNAL | ||
| ports: | ||
| - name: https | ||
| number: 90 | ||
| protocol: HTTPS | ||
| resolution: DNS | ||
| --- | ||
| apiVersion: networking.istio.io/v1alpha3 | ||
| kind: ServiceEntry | ||
| metadata: | ||
| name: http | ||
| spec: | ||
| hosts: | ||
| - istio.io | ||
| location: MESH_EXTERNAL | ||
| ports: | ||
| - name: http | ||
| number: 80 | ||
| protocol: HTTP | ||
| resolution: DNS | ||
| ` | ||
| SidecarScope = ` | ||
| apiVersion: networking.istio.io/v1alpha3 | ||
| kind: Sidecar | ||
| metadata: | ||
| name: restrict-to-service-entry-namespace | ||
| spec: | ||
| egress: | ||
| - hosts: | ||
| - "{{.ImportNamespace}}/*" | ||
| - "istio-system/*" | ||
| ` | ||
| ) | ||
|
|
||
| // We want to test "external" traffic. To do this without actually hitting an external endpoint, | ||
| // we can import only the service namespace, so the apps are not known | ||
| func createSidecarScope(t *testing.T, appsNamespace namespace.Instance, serviceNamespace namespace.Instance, g galley.Instance) { | ||
| tmpl, err := template.New("SidecarScope").Parse(SidecarScope) | ||
| if err != nil { | ||
| t.Errorf("failed to create template: %v", err) | ||
| } | ||
|
|
||
| var buf bytes.Buffer | ||
| if err := tmpl.Execute(&buf, map[string]string{"ImportNamespace": serviceNamespace.Name()}); err != nil { | ||
| t.Errorf("failed to create template: %v", err) | ||
| } | ||
| if err := g.ApplyConfig(appsNamespace, buf.String()); err != nil { | ||
| t.Errorf("failed to apply service entries: %v", err) | ||
| } | ||
| } | ||
|
|
||
| // TODO support native environment. Blocked by #13177 because the listeners for native use static | ||
| // routes and this test relies on the dynamic routes sent through pilot to allow external traffic. | ||
|
|
||
| // Expected is a map of protocol -> expected response codes | ||
| func RunExternalRequestTest(expected map[string][]string, t *testing.T) { | ||
| framework. | ||
| NewTest(t). | ||
| RequiresEnvironment(environment.Kube). | ||
| Run(func(ctx framework.TestContext) { | ||
| g := galley.NewOrFail(t, ctx, galley.Config{}) | ||
| p := pilot.NewOrFail(t, ctx, pilot.Config{Galley: g}) | ||
|
|
||
| appsNamespace := namespace.NewOrFail(t, ctx, "app", true) | ||
| serviceNamespace := namespace.NewOrFail(t, ctx, "service", true) | ||
|
|
||
| createSidecarScope(t, appsNamespace, serviceNamespace, g) | ||
|
|
||
| // External traffic should work even if we have service entries on the same ports | ||
| if err := g.ApplyConfig(serviceNamespace, ServiceEntry); err != nil { | ||
| t.Errorf("failed to apply service entries: %v", err) | ||
| } | ||
|
|
||
| instance := apps.NewOrFail(t, ctx, apps.Config{ | ||
| Namespace: appsNamespace, | ||
| Pilot: p, | ||
| Galley: g, | ||
| AppParams: []apps.AppParam{ | ||
| {Name: "client"}, | ||
| {Name: "destination"}, | ||
| }, | ||
| }) | ||
|
|
||
| client := instance.GetAppOrFail("client", t).(apps.KubeApp) | ||
| dest := instance.GetAppOrFail("destination", t).(apps.KubeApp) | ||
|
|
||
| cases := []struct { | ||
| name string | ||
| protocol string | ||
| port int | ||
| }{ | ||
| { | ||
| "HTTP Traffic", | ||
| "http", | ||
| 80, | ||
| }, | ||
| { | ||
| "HTTPS Traffic", | ||
| "https", | ||
| 90, | ||
| }, | ||
| } | ||
| for _, tc := range cases { | ||
| t.Run(tc.name, func(t *testing.T) { | ||
| if tc.protocol == "https" { | ||
| t.Skip("https is currently not supported until #13386 is fixed") | ||
| } | ||
| ep := dest.EndpointForPort(tc.port) | ||
| resp, err := client.Call(ep, apps.AppCallOptions{}) | ||
| if err != nil { | ||
| t.Errorf("call failed: %v", err) | ||
| } | ||
| codes := make([]string, 0, len(resp)) | ||
| for _, r := range resp { | ||
| codes = append(codes, r.Code) | ||
| } | ||
| if !reflect.DeepEqual(codes, expected[tc.protocol]) { | ||
| t.Errorf("got codes %v, expected %v", codes, expected[tc.protocol]) | ||
| } | ||
| }) | ||
| } | ||
| }) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| // Copyright 2019 Istio Authors | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| package registryonly | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "istio.io/istio/pkg/test/framework" | ||
| "istio.io/istio/pkg/test/framework/components/environment" | ||
| "istio.io/istio/pkg/test/framework/components/istio" | ||
| "istio.io/istio/tests/integration/pilot/outboundtrafficpolicy" | ||
| ) | ||
|
|
||
| func TestMain(m *testing.M) { | ||
| var ist istio.Instance | ||
| framework.NewSuite("outbound_traffic_policy_registry_only", m). | ||
| RequireEnvironment(environment.Kube). | ||
| Setup(istio.SetupOnKube(&ist, setupConfig)). | ||
| Run() | ||
| } | ||
|
|
||
| func setupConfig(cfg *istio.Config) { | ||
| if cfg == nil { | ||
| return | ||
| } | ||
| cfg.Values["global.outboundTrafficPolicy.mode"] = "REGISTRY_ONLY" | ||
| cfg.Values["pilot.env.PILOT_ENABLE_FALLTHROUGH_ROUTE"] = "true" | ||
| } | ||
|
|
||
| func TestOutboundTrafficPolicyRegistryOnly(t *testing.T) { | ||
| expected := map[string][]string{ | ||
| "http": {"502"}, // HTTP will return an error code | ||
| "https": {}, // HTTPS will direct to blackhole cluster, giving no response | ||
| } | ||
| outboundtrafficpolicy.RunExternalRequestTest(expected, t) | ||
| } |
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.
probably don't worry about changing this file. I believe it's going away anyway.
@ozevren?