mirror of https://github.com/istio/istio.io.git
Generate test snippets from md files POC (#7044)
* Generate test snippets from md POC * fixes * fix python lint * fix snip source * improvements * update snip calls * add copyright header * lint errors * lint error in md instructions * better default snip_id * run test without snippet gen * gofmt * fixes * fix path * fixes * fix verify
This commit is contained in:
parent
83dbc79145
commit
3b59501872
|
@ -5,6 +5,7 @@ weight: 40
|
|||
keywords: [security,authentication,migration]
|
||||
aliases:
|
||||
- /docs/tasks/security/mtls-migration/
|
||||
test: true
|
||||
---
|
||||
|
||||
This task shows how to ensure your workloads only communicate using mutual TLS as they are migrated to
|
||||
|
@ -55,7 +56,7 @@ the policies to enforce STRICT mutual TLS between the workloads.
|
|||
* Verify setup by sending an http request (using curl command) from any sleep pod (among those in namespace `foo`, `bar` or `legacy`) to `httpbin.foo`. All requests should success with HTTP code 200.
|
||||
|
||||
{{< text bash >}}
|
||||
$ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
|
||||
$ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
|
||||
sleep.foo to httpbin.foo: 200
|
||||
sleep.foo to httpbin.bar: 200
|
||||
sleep.bar to httpbin.foo: 200
|
||||
|
@ -96,7 +97,7 @@ EOF
|
|||
Now, you should see the request from `sleep.legacy` to `httpbin.foo` failing.
|
||||
|
||||
{{< text bash >}}
|
||||
$ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
|
||||
$ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
|
||||
sleep.foo to httpbin.foo: 200
|
||||
sleep.foo to httpbin.bar: 200
|
||||
sleep.bar to httpbin.foo: 200
|
||||
|
@ -110,7 +111,7 @@ If you installed Istio with `values.global.proxy.privileged=true`, you can use `
|
|||
traffic is encrypted or not.
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl exec -nfoo $(kubectl get pod -nfoo -lapp=httpbin -ojsonpath={.items..metadata.name}) -c istio-proxy -it -- sudo tcpdump dst port 80 -A
|
||||
$ kubectl exec -nfoo "$(kubectl get pod -nfoo -lapp=httpbin -ojsonpath={.items..metadata.name})" -c istio-proxy -it -- sudo tcpdump dst port 80 -A
|
||||
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
|
||||
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
|
||||
{{< /text >}}
|
||||
|
@ -140,7 +141,7 @@ Now, both the `foo` and `bar` namespaces enforce mutual TLS only traffic, so you
|
|||
failing for both.
|
||||
|
||||
{{< text bash >}}
|
||||
$ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
|
||||
$ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
|
||||
{{< /text >}}
|
||||
|
||||
## Clean up the example
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright Istio Authors. All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
####################################################################################################
|
||||
# WARNING: THIS IS AN AUTO-GENERATED FILE, DO NOT EDIT. PLEASE MODIFY THE ORIGINAL MARKDOWN FILE:
|
||||
# docs/tasks/security/authentication/mtls-migration/index.md
|
||||
####################################################################################################
|
||||
|
||||
snip_set_up_the_cluster_1() {
|
||||
kubectl create ns foo
|
||||
kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n foo
|
||||
kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n foo
|
||||
kubectl create ns bar
|
||||
kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n bar
|
||||
kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n bar
|
||||
}
|
||||
|
||||
snip_set_up_the_cluster_2() {
|
||||
kubectl create ns legacy
|
||||
kubectl apply -f samples/sleep/sleep.yaml -n legacy
|
||||
}
|
||||
|
||||
snip_set_up_the_cluster_3() {
|
||||
for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
! read -r -d '' snip_set_up_the_cluster_3_out <<ENDSNIP
|
||||
sleep.foo to httpbin.foo: 200
|
||||
sleep.foo to httpbin.bar: 200
|
||||
sleep.bar to httpbin.foo: 200
|
||||
sleep.bar to httpbin.bar: 200
|
||||
sleep.legacy to httpbin.foo: 200
|
||||
sleep.legacy to httpbin.bar: 200
|
||||
ENDSNIP
|
||||
|
||||
snip_set_up_the_cluster_4() {
|
||||
kubectl get peerauthentication --all-namespaces
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
! read -r -d '' snip_set_up_the_cluster_4_out <<ENDSNIP
|
||||
No resources found
|
||||
ENDSNIP
|
||||
|
||||
snip_set_up_the_cluster_5() {
|
||||
kubectl get destinationrule --all-namespaces
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
! read -r -d '' snip_set_up_the_cluster_5_out <<ENDSNIP
|
||||
No resources found
|
||||
ENDSNIP
|
||||
|
||||
snip_lock_down_to_mutual_tls_by_namespace_1() {
|
||||
kubectl apply -n foo -f - <<EOF
|
||||
apiVersion: "security.istio.io/v1beta1"
|
||||
kind: "PeerAuthentication"
|
||||
metadata:
|
||||
name: "default"
|
||||
spec:
|
||||
mtls:
|
||||
mode: STRICT
|
||||
EOF
|
||||
}
|
||||
|
||||
snip_lock_down_to_mutual_tls_by_namespace_2() {
|
||||
for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
! read -r -d '' snip_lock_down_to_mutual_tls_by_namespace_2_out <<ENDSNIP
|
||||
sleep.foo to httpbin.foo: 200
|
||||
sleep.foo to httpbin.bar: 200
|
||||
sleep.bar to httpbin.foo: 200
|
||||
sleep.bar to httpbin.bar: 200
|
||||
sleep.legacy to httpbin.foo: 000
|
||||
command terminated with exit code 56
|
||||
sleep.legacy to httpbin.bar: 200
|
||||
ENDSNIP
|
||||
|
||||
snip_lock_down_to_mutual_tls_by_namespace_3() {
|
||||
kubectl exec -nfoo "$(kubectl get pod -nfoo -lapp=httpbin -ojsonpath={.items..metadata.name})" -c istio-proxy -it -- sudo tcpdump dst port 80 -A
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
! read -r -d '' snip_lock_down_to_mutual_tls_by_namespace_3_out <<ENDSNIP
|
||||
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
|
||||
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
|
||||
ENDSNIP
|
||||
|
||||
snip_lock_down_mutual_tls_for_the_entire_mesh_1() {
|
||||
kubectl apply -n istio-system -f - <<EOF
|
||||
apiVersion: "security.istio.io/v1beta1"
|
||||
kind: "PeerAuthentication"
|
||||
metadata:
|
||||
name: "default"
|
||||
spec:
|
||||
mtls:
|
||||
mode: STRICT
|
||||
EOF
|
||||
}
|
||||
|
||||
snip_lock_down_mutual_tls_for_the_entire_mesh_2() {
|
||||
for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
|
||||
}
|
||||
|
||||
snip_clean_up_the_example_1() {
|
||||
kubectl delete peerauthentication --all-namespaces --all
|
||||
}
|
||||
|
||||
snip_clean_up_the_example_2() {
|
||||
kubectl delete ns foo bar legacy
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
! read -r -d '' snip_clean_up_the_example_2_out <<ENDSNIP
|
||||
Namespaces foo bar legacy deleted.
|
||||
ENDSNIP
|
|
@ -5,6 +5,7 @@ weight: 30
|
|||
keywords: [traffic-management,traffic-shifting]
|
||||
aliases:
|
||||
- /docs/tasks/traffic-management/version-migration.html
|
||||
test: true
|
||||
---
|
||||
|
||||
This task shows you how to gradually migrate traffic from one version of a
|
||||
|
@ -35,7 +36,7 @@ If you haven't already applied destination rules, follow the instructions in [Ap
|
|||
1. To get started, run this command to route all traffic to the `v1` version of
|
||||
each microservice.
|
||||
|
||||
{{< text bash >}}
|
||||
{{< text syntax=bash snip_id=config_all_v1 >}}
|
||||
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
|
||||
{{< /text >}}
|
||||
|
||||
|
@ -49,7 +50,7 @@ the [Bookinfo](/docs/examples/bookinfo/#determine-the-ingress-ip-and-port) doc.
|
|||
|
||||
1. Transfer 50% of the traffic from `reviews:v1` to `reviews:v3` with the following command:
|
||||
|
||||
{{< text bash >}}
|
||||
{{< text syntax=bash snip_id=config_50_v3 >}}
|
||||
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml@
|
||||
{{< /text >}}
|
||||
|
||||
|
@ -57,7 +58,7 @@ the [Bookinfo](/docs/examples/bookinfo/#determine-the-ingress-ip-and-port) doc.
|
|||
|
||||
1. Confirm the rule was replaced:
|
||||
|
||||
{{< text bash yaml >}}
|
||||
{{< text syntax=bash outputis=yaml snip_id=verify_config_50_v3 >}}
|
||||
$ kubectl get virtualservice reviews -o yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
|
@ -92,7 +93,7 @@ the star ratings service, but the `v1` version does not.
|
|||
1. Assuming you decide that the `reviews:v3` microservice is stable, you can
|
||||
route 100% of the traffic to `reviews:v3` by applying this virtual service:
|
||||
|
||||
{{< text bash >}}
|
||||
{{< text syntax=bash snip_id=config_100_v3 >}}
|
||||
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-v3.yaml@
|
||||
{{< /text >}}
|
||||
|
||||
|
@ -112,7 +113,7 @@ article [Canary Deployments using Istio](/blog/2017/0.1-canary/).
|
|||
|
||||
1. Remove the application routing rules:
|
||||
|
||||
{{< text bash >}}
|
||||
{{< text syntax=bash snip_id=cleanup >}}
|
||||
$ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
|
||||
{{< /text >}}
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright Istio Authors. All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
####################################################################################################
|
||||
# WARNING: THIS IS AN AUTO-GENERATED FILE, DO NOT EDIT. PLEASE MODIFY THE ORIGINAL MARKDOWN FILE:
|
||||
# docs/tasks/traffic-management/traffic-shifting/index.md
|
||||
####################################################################################################
|
||||
|
||||
snip_config_all_v1() {
|
||||
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
|
||||
}
|
||||
|
||||
snip_config_50_v3() {
|
||||
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml
|
||||
}
|
||||
|
||||
snip_verify_config_50_v3() {
|
||||
kubectl get virtualservice reviews -o yaml
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
! read -r -d '' snip_verify_config_50_v3_out <<ENDSNIP
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: reviews
|
||||
...
|
||||
spec:
|
||||
hosts:
|
||||
- reviews
|
||||
http:
|
||||
- route:
|
||||
- destination:
|
||||
host: reviews
|
||||
subset: v1
|
||||
weight: 50
|
||||
- destination:
|
||||
host: reviews
|
||||
subset: v3
|
||||
weight: 50
|
||||
ENDSNIP
|
||||
|
||||
snip_config_100_v3() {
|
||||
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-v3.yaml
|
||||
}
|
||||
|
||||
snip_cleanup() {
|
||||
kubectl delete -f samples/bookinfo/networking/virtual-service-all-v1.yaml
|
||||
}
|
|
@ -319,10 +319,15 @@ func (s Script) runCommand(ctx Context) {
|
|||
|
||||
// Copy the commands from the snippet.
|
||||
for _, snippetCommand := range snippetCommands {
|
||||
commandLines = append(commandLines, filterCommandLine(snippetCommand))
|
||||
if sinfo.name != "" {
|
||||
snippetCommand = filterCommandLine(snippetCommand)
|
||||
}
|
||||
commandLines = append(commandLines, snippetCommand)
|
||||
}
|
||||
} else {
|
||||
// Not a snippet, just copy the line directly to the command.
|
||||
// TODO commandLines = append(commandLines, line) // Commands outside of snippets should be proper bash
|
||||
// TODO Need to fix some tests that are incorrectly annotating commands outside of snippets.
|
||||
commandLines = append(commandLines, filterCommandLine(line))
|
||||
}
|
||||
}
|
||||
|
@ -390,6 +395,11 @@ func (s Script) createSnippets(ctx Context) {
|
|||
// Verify the output for this snippet.
|
||||
sinfo.verify()
|
||||
|
||||
if strings.HasPrefix(sinfo.name, "_NOGEN_") {
|
||||
// No snippet to generate, just verifying output.
|
||||
continue
|
||||
}
|
||||
|
||||
// Verify the output, if configured to do so.
|
||||
snippetOutput := ""
|
||||
if sinfo.outputIs != "" {
|
||||
|
@ -530,7 +540,8 @@ func parseSnippet(ctx Context, lineIndex *int, lines []string) snippetInfo {
|
|||
}
|
||||
|
||||
if info.name == "" {
|
||||
ctx.Fatalf("snippet missing name")
|
||||
// If no snippet name is set, the framework will run the commands/verifiers without generating snippets.
|
||||
info.name = fmt.Sprintf("_NOGEN_%d", *lineIndex)
|
||||
}
|
||||
|
||||
if info.outputIs == "" && info.outputSnippet {
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright 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.
|
||||
|
||||
set -e
|
||||
|
||||
find content/en -name '*.md' -exec grep --quiet 'test: true' {} \; -exec python scripts/snip.py {} \;
|
|
@ -0,0 +1,138 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# Copyright Istio Authors. All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
|
||||
linenum = 0
|
||||
snipnum = 0
|
||||
section = ""
|
||||
|
||||
current_snip = None
|
||||
multiline_cmd = False
|
||||
output_started = False
|
||||
snippets = []
|
||||
|
||||
HEADER = """#!/bin/bash
|
||||
|
||||
# Copyright Istio Authors. All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
####################################################################################################
|
||||
# WARNING: THIS IS AN AUTO-GENERATED FILE, DO NOT EDIT. PLEASE MODIFY THE ORIGINAL MARKDOWN FILE:
|
||||
# %s
|
||||
####################################################################################################
|
||||
"""
|
||||
|
||||
startsnip = re.compile(r"^(\s*){{< text (syntax=)?\"?(\w+)\"? .*>}}$")
|
||||
snippetid = re.compile(r"snip_id=(\w+)")
|
||||
githubfile = re.compile(r"^([^@]*)@([\w\.\-_/]+)@([^@]*)$")
|
||||
sectionhead = re.compile(r"^##+ (.*)$")
|
||||
invalidchar = re.compile(r"[^0-9a-zA-Z_]")
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print("usage: python snip.py mdfile [ snipdir ]")
|
||||
sys.exit(1)
|
||||
|
||||
markdown = sys.argv[1]
|
||||
|
||||
if len(sys.argv) > 2:
|
||||
snipdir = sys.argv[2]
|
||||
else:
|
||||
snipdir = os.path.dirname(markdown)
|
||||
|
||||
snipfile = "snips.sh" if markdown.split('/')[-1] == "index.md" else markdown.split('/')[-1] + "_snips.sh"
|
||||
|
||||
print("generating snips: " + os.path.join(snipdir, snipfile))
|
||||
|
||||
with open(markdown, 'rt') as mdfile:
|
||||
for line in mdfile:
|
||||
linenum += 1
|
||||
|
||||
match = sectionhead.match(line)
|
||||
if match:
|
||||
snipnum = 0
|
||||
section = invalidchar.sub('', match.group(1).replace(" ", "_")).lower()
|
||||
continue
|
||||
|
||||
match = startsnip.match(line)
|
||||
if match:
|
||||
snipnum += 1
|
||||
indent = match.group(1)
|
||||
kind = match.group(3)
|
||||
match = snippetid.search(line)
|
||||
if match:
|
||||
id = "snip_" + match.group(1)
|
||||
else:
|
||||
id = "snip_%s_%d" % (section, snipnum)
|
||||
if kind == "bash":
|
||||
script = "\n%s() {\n" % id
|
||||
else:
|
||||
script = "\n# shellcheck disable=SC2034\n! read -r -d '' %s <<ENDSNIP\n" % id
|
||||
current_snip = {"start": linenum, "id": id, "kind": kind, "indent": indent, "script": ["", script]}
|
||||
snippets.append(current_snip)
|
||||
continue
|
||||
|
||||
if current_snip != None:
|
||||
if current_snip["indent"]:
|
||||
_, line = line.split(current_snip["indent"], 1)
|
||||
if "{{< /text >}}" in line:
|
||||
if current_snip["kind"] == "bash" and not output_started:
|
||||
script = "}\n"
|
||||
else:
|
||||
script = "ENDSNIP\n"
|
||||
current_snip["script"].append(script)
|
||||
current_snip = None
|
||||
multiline_cmd = False
|
||||
output_started = False
|
||||
else:
|
||||
if current_snip["kind"] == "bash":
|
||||
if line.startswith("$ "):
|
||||
line = line[2:]
|
||||
else:
|
||||
if multiline_cmd:
|
||||
if line == "EOF\n":
|
||||
multiline_cmd = False
|
||||
elif not current_snip["script"][-1].endswith("\\\n"):
|
||||
# command output
|
||||
if not output_started:
|
||||
current_snip["script"].append("}\n\n# shellcheck disable=SC2034\n! read -r -d '' %s_out <<ENDSNIP\n" % id)
|
||||
output_started = True
|
||||
match = githubfile.match(line)
|
||||
if match:
|
||||
line = match.group(1) + match.group(2) + match.group(3)
|
||||
if "<<EOF" in line:
|
||||
multiline_cmd = True
|
||||
current_snip["script"].append(line)
|
||||
|
||||
with open(os.path.join(snipdir, snipfile), 'w') as f:
|
||||
f.write(HEADER % markdown.split("content/en/")[1] if "content/en/" in markdown else markdown)
|
||||
for snippet in snippets:
|
||||
lines = snippet["script"]
|
||||
for line in lines:
|
||||
f.write(line)
|
|
@ -18,6 +18,8 @@ set -e
|
|||
set -u
|
||||
set -o pipefail
|
||||
|
||||
source ${REPO_ROOT}/content/en/docs/tasks/traffic-management/traffic-shifting/snips.sh
|
||||
|
||||
# setup bookinfo & sleep pods
|
||||
kubectl label namespace default istio-injection=enabled --overwrite || true
|
||||
|
||||
|
@ -78,8 +80,8 @@ function verify_traffic_shift() {
|
|||
|
||||
# Step 1
|
||||
|
||||
# $snippet route_all_v1 syntax="bash" outputis="text" outputsnippet="true"
|
||||
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
|
||||
# $snippet
|
||||
snip_config_all_v1
|
||||
# $verify
|
||||
virtualservice.networking.istio.io/productpage created
|
||||
virtualservice.networking.istio.io/reviews created
|
||||
|
@ -92,29 +94,33 @@ verify_traffic_shift 0
|
|||
|
||||
# Step 3: switch 50% traffic to v3
|
||||
|
||||
# $snippet route_50_percent_v3 syntax="bash" outputis="text" outputsnippet="true"
|
||||
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml@
|
||||
# $snippet
|
||||
snip_config_50_v3
|
||||
# $verify
|
||||
virtualservice.networking.istio.io/reviews configured
|
||||
# $endsnippet
|
||||
istioctl experimental wait --for=distribution VirtualService reviews.default
|
||||
|
||||
istioctl experimental wait --for=distribution VirtualService reviews.default
|
||||
|
||||
# Step 4: Confirm the rule was replaced
|
||||
|
||||
# $snippet verify_review_virtualservice syntax="bash" outputis="text" outputsnippet="true"
|
||||
$ kubectl get virtualservice reviews -o yaml
|
||||
# $snippet
|
||||
snip_verify_config_50_v3
|
||||
# $verify verifier="contains"
|
||||
subset: v3
|
||||
# $endsnippet
|
||||
|
||||
#TODO The above verify could instead test the doc output snippet if we add a suitable yaml verifier
|
||||
#TODO # $verify verifier="yaml-subset"
|
||||
#TODO echo "$verify_config_50_v3_out"
|
||||
|
||||
# Step 5: verify rating stars visible 50% of the time
|
||||
verify_traffic_shift 50
|
||||
|
||||
# Step 6: route 100% traffic to v3
|
||||
|
||||
# $snippet route_100_percent_v3 syntax="bash" outputis="text" outputsnippet="true"
|
||||
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-v3.yaml@
|
||||
# $snippet
|
||||
snip_config_100_v3
|
||||
# $endsnippet
|
||||
|
||||
verify_traffic_shift 100
|
||||
|
|
Loading…
Reference in New Issue