diff --git a/external/skewer-main/README.md b/external/skewer-main/README.md index 2306ca6..ed01e76 100644 --- a/external/skewer-main/README.md +++ b/external/skewer-main/README.md @@ -10,9 +10,9 @@ and produces two outputs: a `README.md` file and a test routine. ## An example example -[Example `skewer.yaml` file](test-example/skewer.yaml) +[Example `skewer.yaml` file](example/skewer.yaml) -[Example `README.md` output](test-example/README.md) +[Example `README.md` output](example/README.md) ## Setting up Skewer for your own example diff --git a/external/skewer-main/test-example/.gitignore b/external/skewer-main/example/.gitignore similarity index 100% rename from external/skewer-main/test-example/.gitignore rename to external/skewer-main/example/.gitignore diff --git a/external/skewer-main/test-example/.plano.py b/external/skewer-main/example/.plano.py similarity index 100% rename from external/skewer-main/test-example/.plano.py rename to external/skewer-main/example/.plano.py diff --git a/external/skewer-main/test-example/README.md b/external/skewer-main/example/README.md similarity index 81% rename from external/skewer-main/test-example/README.md rename to external/skewer-main/example/README.md index 1dea610..3e24940 100644 --- a/external/skewer-main/test-example/README.md +++ b/external/skewer-main/example/README.md @@ -23,10 +23,9 @@ across cloud providers, data centers, and edge sites. * [Step 6: Check the status of your namespaces](#step-6-check-the-status-of-your-namespaces) * [Step 7: Link your namespaces](#step-7-link-your-namespaces) * [Step 8: Fail on demand](#step-8-fail-on-demand) -* [Step 9: Deploy the frontend and backend services](#step-9-deploy-the-frontend-and-backend-services) -* [Step 10: Expose the backend service](#step-10-expose-the-backend-service) -* [Step 11: Expose the frontend service](#step-11-expose-the-frontend-service) -* [Step 12: Test the application](#step-12-test-the-application) +* [Step 9: Deploy and expose the frontend](#step-9-deploy-and-expose-the-frontend) +* [Step 10: Deploy and expose the backend](#step-10-deploy-and-expose-the-backend) +* [Step 11: Test the application](#step-11-test-the-application) * [Accessing the web console](#accessing-the-web-console) * [Cleaning up](#cleaning-up) * [Summary](#summary) @@ -35,27 +34,11 @@ across cloud providers, data centers, and edge sites. ## Overview -This example is a very simple multi-service HTTP application that can -be deployed across multiple Kubernetes clusters using Skupper. - -It contains two services: - -* A backend service that exposes an `/api/hello` endpoint. It - returns greetings of the form `Hi, . I am - ()`. - -* A frontend service that sends greetings to the backend and - fetches new greetings in response. - -With Skupper, you can place the backend in one cluster and the -frontend in another and maintain connectivity between the two -services without exposing the backend to the public internet. - - +An overview ## Prerequisites -Custom prerequisites +Some prerequisites ## Step 1: Install the Skupper command-line tool @@ -193,6 +176,7 @@ skupper status _Sample output:_ ~~~ console +$ skupper status Skupper is enabled for namespace "" in interior mode. It is connected to 1 other site. It has 1 exposed service. The site console url is: The credentials for internal console-auth mode are held in secret: 'skupper-console-users' @@ -261,15 +245,22 @@ if [ -n "${SKEWER_FAIL}" ]; then expr 1 / 0; fi ~~~ -## Step 9: Deploy the frontend and backend services +## Step 9: Deploy and expose the frontend -Use `kubectl create deployment` to deploy the frontend service -in `west` and the backend service in `east`. +We have established connectivity between the two namespaces and +made the backend in `east` available to the frontend in `west`. +Before we can test the application, we need external access to the +frontend. + +Use `kubectl create deployment` to deploy the frontend service in +West. Use `kubectl expose` with `--type LoadBalancer` to open +network access to the frontend service. _**Console for West:**_ ~~~ shell kubectl create deployment frontend --image quay.io/skupper/hello-world-frontend +kubectl expose deployment/frontend --port 8080 --type LoadBalancer ~~~ _Sample output:_ @@ -277,68 +268,40 @@ _Sample output:_ ~~~ console $ kubectl create deployment frontend --image quay.io/skupper/hello-world-frontend deployment.apps/frontend created -~~~ - -_**Console for East:**_ -~~~ shell -kubectl create deployment backend --image quay.io/skupper/hello-world-backend --replicas 3 -~~~ - -_Sample output:_ - -~~~ console -$ kubectl create deployment backend --image quay.io/skupper/hello-world-backend --replicas 3 -deployment.apps/backend created +$ kubectl expose deployment/frontend --port 8080 --type LoadBalancer +service/frontend exposed ~~~ -## Step 10: Expose the backend service +## Step 10: Deploy and expose the backend We now have two namespaces linked to form a Skupper network, but no services are exposed on it. Skupper uses the `skupper expose` command to select a service from one namespace for exposure on all the linked namespaces. -Use `skupper expose` to expose the backend service to the +Use `kubectl create deployment` to deploy the backend service in +East. Use `skupper expose` to expose the backend service to the frontend service. _**Console for East:**_ ~~~ shell +kubectl create deployment backend --image quay.io/skupper/hello-world-backend --replicas 3 skupper expose deployment/backend --port 8080 ~~~ _Sample output:_ ~~~ console +$ kubectl create deployment backend --image quay.io/skupper/hello-world-backend --replicas 3 +deployment.apps/backend created + $ skupper expose deployment/backend --port 8080 deployment backend exposed as backend ~~~ -## Step 11: Expose the frontend service - -We have established connectivity between the two namespaces and -made the backend in `east` available to the frontend in `west`. -Before we can test the application, we need external access to -the frontend. - -Use `kubectl expose` with `--type LoadBalancer` to open network -access to the frontend service. - -_**Console for West:**_ - -~~~ shell -kubectl expose deployment/frontend --port 8080 --type LoadBalancer -~~~ - -_Sample output:_ - -~~~ console -$ kubectl expose deployment/frontend --port 8080 --type LoadBalancer -service/frontend exposed -~~~ - -## Step 12: Test the application +## Step 11: Test the application Now we're ready to try it out. Use `kubectl get service/frontend` to look up the external IP of the frontend service. Then use @@ -425,27 +388,11 @@ kubectl delete deployment/backend ## Summary -This example locates the frontend and backend services in different -namespaces, on different clusters. Ordinarily, this means that they -have no way to communicate unless they are exposed to the public -internet. - -Introducing Skupper into each namespace allows us to create a virtual -application network that can connect services in different clusters. -Any service exposed on the application network is represented as a -local service in all of the linked namespaces. - -The backend service is located in `east`, but the frontend service -in `west` can "see" it as if it were local. When the frontend -sends a request to the backend, Skupper forwards the request to the -namespace where the backend is running and routes the response back to -the frontend. - - +A summary ## Next steps -Custom next steps +Some next steps ## About this example diff --git a/external/skewer-main/test-example/external/skewer-main b/external/skewer-main/example/external/skewer-main similarity index 100% rename from external/skewer-main/test-example/external/skewer-main rename to external/skewer-main/example/external/skewer-main diff --git a/external/skewer-main/test-example/plano b/external/skewer-main/example/plano similarity index 100% rename from external/skewer-main/test-example/plano rename to external/skewer-main/example/plano diff --git a/external/skewer-main/test-example/python/plano b/external/skewer-main/example/python/plano similarity index 100% rename from external/skewer-main/test-example/python/plano rename to external/skewer-main/example/python/plano diff --git a/external/skewer-main/test-example/python/skewer b/external/skewer-main/example/python/skewer similarity index 100% rename from external/skewer-main/test-example/python/skewer rename to external/skewer-main/example/python/skewer diff --git a/external/skewer-main/example/skewer.yaml b/external/skewer-main/example/skewer.yaml new file mode 100644 index 0000000..df450f0 --- /dev/null +++ b/external/skewer-main/example/skewer.yaml @@ -0,0 +1,42 @@ +title: Skupper Hello World +subtitle: A minimal HTTP application deployed across Kubernetes clusters using Skupper +github_actions_url: https://github.com/skupperproject/skewer/actions/workflows/main.yaml +overview: | + An overview +prerequisites: | + Some prerequisites +sites: + west: + title: West + platform: kubernetes + namespace: west + env: + KUBECONFIG: ~/.kube/config-west + east: + title: East + platform: kubernetes + namespace: east + env: + KUBECONFIG: ~/.kube/config-east +steps: + - standard: install_the_skupper_command_line_tool + - standard: configure_separate_console_sessions + - standard: access_your_clusters + - standard: set_up_your_namespaces + - standard: install_skupper_in_your_namespaces + - standard: check_the_status_of_your_namespaces + - standard: link_your_namespaces + - title: Fail on demand + commands: + west: + - run: | + if [ -n "${SKEWER_FAIL}" ]; then expr 1 / 0; fi + - standard: hello_world/deploy_and_expose_the_frontend + - standard: hello_world/deploy_and_expose_the_backend + - standard: hello_world/test_the_application + - standard: accessing_the_web_console + - standard: hello_world/cleaning_up +summary: | + A summary +next_steps: | + Some next steps diff --git a/external/skewer-main/python/skewer/main.py b/external/skewer-main/python/skewer/main.py index df789dd..5ef7b15 100644 --- a/external/skewer-main/python/skewer/main.py +++ b/external/skewer-main/python/skewer/main.py @@ -177,7 +177,7 @@ def run_steps_minikube(skewer_file, debug=False): run("minikube -p skewer delete") def run_steps(skewer_file, kubeconfigs=None, debug=False): - notice(f"Running steps (skewer_file='{get_absolute_path(skewer_file)}')") + notice(f"Running steps (skewer_file='{skewer_file}')") check_environment() @@ -317,11 +317,13 @@ def pause_for_demo(skewer_data): pass def generate_readme(skewer_file, output_file): - notice("Generating the readme") - notice(" Skewer file: " + get_absolute_path(skewer_file)) - notice(" Output file: " + get_absolute_path(output_file)) + notice(f"Generating the readme (skewer_file='{skewer_file}', output_file='{output_file}')") skewer_data = read_yaml(skewer_file) + + for site in get_sites(skewer_data): + site.check() + out = list() out.append(f"# {skewer_data['title']}") @@ -568,9 +570,9 @@ def __init__(self, name, data): self.name = name self.title = data.get("title", capitalize(self.name)) - self.platform = data["platform"] + self.platform = data.get("platform") self.namespace = data.get("namespace") - self.env = data["env"] + self.env = data.get("env") def __enter__(self): self._logging_context = logging_context(self.name) @@ -586,15 +588,30 @@ def __exit__(self, exc_type, exc_value, traceback): self._logging_context.__exit__(exc_type, exc_value, traceback) def check(self): - assert self.platform in ("kubernetes", "podman"), self.platform + if self.platform is None: + fail(f"{self} has no 'platform' attribute") + + if self.platform not in ("kubernetes", "podman"): + fail(f"{self} attribute 'platform' has an illegal value: {self.platform}") if self.platform == "kubernetes": - assert self.namespace is not None - assert "KUBECONFIG" in self.env + if self.namespace is None: + fail(f"Kubernetes {self} has no 'namespace' attribute") + + if "KUBECONFIG" not in self.env: + fail(f"Kubernetes {self} has no KUBECONFIG environment variable") if self.platform == "podman": - assert "SKUPPER_PLATFORM" in self.env - assert self.env["SKUPPER_PLATFORM"] == "podman" + if "SKUPPER_PLATFORM" not in self.env: + fail(f"Podman {self} has no SKUPPER_PLATFORM environment variable") + + platform = self.env["SKUPPER_PLATFORM"] + + if platform != "podman": + fail(f"Podman {self} environment variable SKUPPER_PLATFORM has an illegal value: {platform}") + + def __repr__(self): + return f"site '{self.name}'" def get_steps(skewer_data): for step_data in skewer_data["steps"]: diff --git a/external/skewer-main/python/skewer/standardsteps.yaml b/external/skewer-main/python/skewer/standardsteps.yaml index 4c51f9d..d2a8909 100644 --- a/external/skewer-main/python/skewer/standardsteps.yaml +++ b/external/skewer-main/python/skewer/standardsteps.yaml @@ -120,6 +120,7 @@ check_the_status_of_your_namespaces: _Sample output:_ ~~~ console + $ skupper status Skupper is enabled for namespace "" in interior mode. It is connected to 1 other site. It has 1 exposed service. The site console url is: The credentials for internal console-auth mode are held in secret: 'skupper-console-users' @@ -149,8 +150,7 @@ link_your_namespaces: commands: "0": - run: skupper token create ~/secret.token - output: | - Token written to ~/secret.token + output: Token written to ~/secret.token "1": - run: skupper link create ~/secret.token output: | @@ -163,31 +163,6 @@ link_your_namespaces: to use `scp` or a similar tool to transfer the token securely. By default, tokens expire after a single use or 15 minutes after creation. -test_the_application: - title: Test the application - preamble: | - Now we're ready to try it out. Use `kubectl get service/frontend` - to look up the external IP of the frontend service. Then use - `curl` or a similar tool to request the `/api/health` endpoint at - that address. - - **Note:** The `` field in the following commands is a - placeholder. The actual value is an IP address. - commands: - "0": - - run: kubectl get service/frontend - apply: readme - output: | - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE - frontend LoadBalancer 10.103.232.28 8080:30407/TCP 15s - - run: curl http://:8080/api/health - apply: readme - output: | - OK - - await_http_ok: [service/frontend, "http://{}:8080/api/health"] - postamble: | - If everything is in order, you can now access the web interface by - navigating to `http://:8080/` in your browser. accessing_the_web_console: title: Accessing the web console numbered: false @@ -209,8 +184,7 @@ accessing_the_web_console: The site console url is: The credentials for internal console-auth mode are held in secret: 'skupper-console-users' - run: kubectl get secret/skupper-console-users -o jsonpath={.data.admin} | base64 -d - output: | - + output: - await_console_ok: postamble: | Navigate to `` in your browser. When prompted, log @@ -225,3 +199,79 @@ cleaning_up: commands: "*": - run: skupper delete +hello_world/deploy_and_expose_the_backend: + title: Deploy and expose the backend + preamble: | + We now have two namespaces linked to form a Skupper network, but + no services are exposed on it. Skupper uses the `skupper + expose` command to select a service from one namespace for + exposure on all the linked namespaces. + + Use `kubectl create deployment` to deploy the backend service in + East. Use `skupper expose` to expose the backend service to the + frontend service. + commands: + "1": + - run: kubectl create deployment backend --image quay.io/skupper/hello-world-backend --replicas 3 + output: deployment.apps/backend created + - await_resource: deployment/backend + - run: skupper expose deployment/backend --port 8080 + output: deployment backend exposed as backend +hello_world/deploy_and_expose_the_frontend: + title: Deploy and expose the frontend + preamble: | + We have established connectivity between the two namespaces and + made the backend in `east` available to the frontend in `west`. + Before we can test the application, we need external access to the + frontend. + + Use `kubectl create deployment` to deploy the frontend service in + West. Use `kubectl expose` with `--type LoadBalancer` to open + network access to the frontend service. + commands: + "0": + - run: kubectl create deployment frontend --image quay.io/skupper/hello-world-frontend + output: deployment.apps/frontend created + - await_resource: deployment/frontend + - run: kubectl expose deployment/frontend --port 8080 --type LoadBalancer + output: service/frontend exposed +hello_world/test_the_application: + title: Test the application + preamble: | + Now we're ready to try it out. Use `kubectl get service/frontend` + to look up the external IP of the frontend service. Then use + `curl` or a similar tool to request the `/api/health` endpoint at + that address. + + **Note:** The `` field in the following commands is a + placeholder. The actual value is an IP address. + commands: + "0": + - await_resource: service/frontend + - run: kubectl get service/frontend + apply: readme + output: | + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + frontend LoadBalancer 10.103.232.28 8080:30407/TCP 15s + - run: curl http://:8080/api/health + apply: readme + output: OK + - await_http_ok: [service/frontend, "http://{}:8080/api/health"] + postamble: | + If everything is in order, you can now access the web interface by + navigating to `http://:8080/` in your browser. +hello_world/cleaning_up: + id: cleaning_up + title: Cleaning up + numbered: false + preamble: | + To remove Skupper and the other resources from this exercise, use + the following commands. + commands: + "0": + - run: skupper delete + - run: kubectl delete service/frontend + - run: kubectl delete deployment/frontend + "1": + - run: skupper delete + - run: kubectl delete deployment/backend diff --git a/external/skewer-main/python/skewer/tests.py b/external/skewer-main/python/skewer/tests.py index c83e41e..3a52bc1 100644 --- a/external/skewer-main/python/skewer/tests.py +++ b/external/skewer-main/python/skewer/tests.py @@ -25,7 +25,7 @@ def check_environment_(): @test def plano_(): - with working_dir("test-example"): + with working_dir("example"): run("./plano") run("./plano generate") @@ -35,7 +35,7 @@ def workflow(): @test def generate_readme_(): - with working_dir("test-example"): + with working_dir("example"): generate_readme("skewer.yaml", "README.md") check_file("README.md") @@ -54,13 +54,13 @@ def await_operations(): @test def run_steps_demo(): - with working_dir("test-example"): + with working_dir("example"): with working_env(SKEWER_DEMO=1, SKEWER_DEMO_NO_WAIT=1): run_steps_minikube("skewer.yaml", debug=True) @test def run_steps_debug(): - with working_dir("test-example"): + with working_dir("example"): with expect_error(): with working_env(SKEWER_FAIL=1): run_steps_minikube("skewer.yaml", debug=True) diff --git a/external/skewer-main/test-example/images/entities.svg b/external/skewer-main/test-example/images/entities.svg deleted file mode 100644 index 6a1ab87..0000000 --- a/external/skewer-main/test-example/images/entities.svg +++ /dev/null @@ -1,3 +0,0 @@ - - -
Frontend service
Frontend service
Skupper
Skupper
Kubernetes cluster 1
Kubernetes cluster 1
Namespace "west"
Namespace "west"
Namespace "east"
Namespace "east"
Kubernetes cluster 2
Kubernetes cluster 2
Backend service
Backend service
Skupper
Skupper
Public
network
Public<br/>network
diff --git a/external/skewer-main/test-example/images/sequence.svg b/external/skewer-main/test-example/images/sequence.svg deleted file mode 100644 index 20d27c1..0000000 --- a/external/skewer-main/test-example/images/sequence.svg +++ /dev/null @@ -1 +0,0 @@ -westeastCurlFrontendSkupperSkupperBackendBackendGET /         GET /api/hello      GET /api/hello      GET /api/hello"Hello 1"      "Hello 1"      "Hello 1""Hello 1"          diff --git a/external/skewer-main/test-example/images/sequence.txt b/external/skewer-main/test-example/images/sequence.txt deleted file mode 100644 index 6d081ea..0000000 --- a/external/skewer-main/test-example/images/sequence.txt +++ /dev/null @@ -1,22 +0,0 @@ -participant Curl - -participantgroup #cce5ff eu-north -participant Frontend -participant "Skupper" as Skupper1 #lightgreen -end - -participantgroup #ffe6cc us-east -participant "Skupper" as Skupper2 #lightgreen -participant Backend #yellow -end - -abox over Skupper1 #yellow: Backend - -Curl->Frontend: GET / -Frontend->Skupper1: GET /api/hello -Skupper1->Skupper2: GET /api/hello -Skupper2->Backend: GET /api/hello -Skupper2<-Backend: "Hello 1" -Skupper1<-Skupper2: "Hello 1" -Frontend<-Skupper1: "Hello 1" -Curl<-Frontend: "Hello 1" diff --git a/external/skewer-main/test-example/skewer.yaml b/external/skewer-main/test-example/skewer.yaml deleted file mode 100644 index ab2a493..0000000 --- a/external/skewer-main/test-example/skewer.yaml +++ /dev/null @@ -1,119 +0,0 @@ -title: Skupper Hello World -subtitle: A minimal HTTP application deployed across Kubernetes clusters using Skupper -github_actions_url: https://github.com/skupperproject/skewer/actions/workflows/main.yaml -overview: | - This example is a very simple multi-service HTTP application that can - be deployed across multiple Kubernetes clusters using Skupper. - - It contains two services: - - * A backend service that exposes an `/api/hello` endpoint. It - returns greetings of the form `Hi, . I am - ()`. - - * A frontend service that sends greetings to the backend and - fetches new greetings in response. - - With Skupper, you can place the backend in one cluster and the - frontend in another and maintain connectivity between the two - services without exposing the backend to the public internet. - - -prerequisites: | - Custom prerequisites -sites: - west: - title: West - platform: kubernetes - namespace: west - env: - KUBECONFIG: ~/.kube/config-west - east: - title: East - platform: kubernetes - namespace: east - env: - KUBECONFIG: ~/.kube/config-east -steps: - - standard: install_the_skupper_command_line_tool - - standard: configure_separate_console_sessions - - standard: access_your_clusters - - standard: set_up_your_namespaces - - standard: install_skupper_in_your_namespaces - - standard: check_the_status_of_your_namespaces - - standard: link_your_namespaces - - title: Fail on demand - commands: - west: - - run: | - if [ -n "${SKEWER_FAIL}" ]; then expr 1 / 0; fi - - title: Deploy the frontend and backend services - preamble: | - Use `kubectl create deployment` to deploy the frontend service - in `west` and the backend service in `east`. - commands: - west: - - run: kubectl create deployment frontend --image quay.io/skupper/hello-world-frontend - output: deployment.apps/frontend created - east: - - run: kubectl create deployment backend --image quay.io/skupper/hello-world-backend --replicas 3 - output: deployment.apps/backend created - - title: Expose the backend service - preamble: | - We now have two namespaces linked to form a Skupper network, but - no services are exposed on it. Skupper uses the `skupper - expose` command to select a service from one namespace for - exposure on all the linked namespaces. - - Use `skupper expose` to expose the backend service to the - frontend service. - commands: - east: - - await: deployment/backend - - run: skupper expose deployment/backend --port 8080 - output: deployment backend exposed as backend - - title: Expose the frontend service - preamble: | - We have established connectivity between the two namespaces and - made the backend in `east` available to the frontend in `west`. - Before we can test the application, we need external access to - the frontend. - - Use `kubectl expose` with `--type LoadBalancer` to open network - access to the frontend service. - commands: - west: - - await: deployment/frontend - - run: kubectl expose deployment/frontend --port 8080 --type LoadBalancer - output: service/frontend exposed - - standard: test_the_application - - standard: accessing_the_web_console - - standard: cleaning_up - commands: - west: - - run: skupper delete - - run: kubectl delete service/frontend - - run: kubectl delete deployment/frontend - east: - - run: skupper delete - - run: kubectl delete deployment/backend -summary: | - This example locates the frontend and backend services in different - namespaces, on different clusters. Ordinarily, this means that they - have no way to communicate unless they are exposed to the public - internet. - - Introducing Skupper into each namespace allows us to create a virtual - application network that can connect services in different clusters. - Any service exposed on the application network is represented as a - local service in all of the linked namespaces. - - The backend service is located in `east`, but the frontend service - in `west` can "see" it as if it were local. When the frontend - sends a request to the backend, Skupper forwards the request to the - namespace where the backend is running and routes the response back to - the frontend. - - -next_steps: | - Custom next steps diff --git a/skewer.yaml b/skewer.yaml index 7b3c476..dc189e1 100644 --- a/skewer.yaml +++ b/skewer.yaml @@ -210,7 +210,7 @@ steps: East to create a link. [install]: https://skupper.io/install/index.html - - standard: test_the_application + - standard: hello_world/test_the_application - standard: accessing_the_web_console - standard: cleaning_up commands: