From fee7a817b256ce4af89602af538d2c92036ef494 Mon Sep 17 00:00:00 2001 From: Justin Ross Date: Mon, 26 Feb 2024 07:48:10 -0500 Subject: [PATCH] WIP --- README.md | 181 ++++++++++-------- external/skewer/README.md | 142 ++++++++------ external/skewer/example/README.md | 18 +- external/skewer/example/skewer.yaml | 10 +- external/skewer/python/skewer/main.py | 12 +- .../skewer/python/skewer/standardsteps.yaml | 32 ++-- skewer.yaml | 122 +++++++++--- 7 files changed, 323 insertions(+), 194 deletions(-) diff --git a/README.md b/README.md index 003e969..c6eb185 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# Skupper Hello World +# Skupper Hello World using cluster policy [![main](https://github.com/ssorj/skupper-example-policy/actions/workflows/main.yaml/badge.svg)](https://github.com/ssorj/skupper-example-policy/actions/workflows/main.yaml) -#### A minimal HTTP application deployed across Kubernetes clusters using Skupper +#### Use policy to control site linking and service exposure This example is part of a [suite of examples][examples] showing the different ways you can use [Skupper][website] to connect services @@ -15,23 +15,44 @@ across cloud providers, data centers, and edge sites. #### Contents +* [Overview](#overview) * [Prerequisites](#prerequisites) * [Step 1: Install the Skupper command-line tool](#step-1-install-the-skupper-command-line-tool) -* [Step 2: Set up your namespaces](#step-2-set-up-your-namespaces) -* [Step 3: Deploy the frontend and backend](#step-3-deploy-the-frontend-and-backend) -* [Step 4: Enable policy enforcement](#step-4-enable-policy-enforcement) +* [Step 2: Set up your clusters](#step-2-set-up-your-clusters) +* [Step 3: Enable Skupper cluster policy](#step-3-enable-skupper-cluster-policy) +* [Step 4: Deploy the frontend and backend](#step-4-deploy-the-frontend-and-backend) * [Step 5: Create your sites](#step-5-create-your-sites) -* [Step 6: Attempt to link your sites without permission](#step-6-attempt-to-link-your-sites-without-permission) -* [Step 7: Attempt to expose the backend without permission](#step-7-attempt-to-expose-the-backend-without-permission) -* [Step 8: Grant permission to link your sites and expose the backend](#step-8-grant-permission-to-link-your-sites-and-expose-the-backend) -* [Step 9: Link your sites](#step-9-link-your-sites) -* [Step 10: Expose the backend](#step-10-expose-the-backend) -* [Step 11: Access the frontend](#step-11-access-the-frontend) +* [Step 6: Attempt to link your sites and expose the backend](#step-6-attempt-to-link-your-sites-and-expose-the-backend) +* [Step 7: Grant permission to link your sites and expose the backend](#step-7-grant-permission-to-link-your-sites-and-expose-the-backend) +* [Step 8: Link your sites and expose the backend](#step-8-link-your-sites-and-expose-the-backend) +* [Step 9: Access the frontend](#step-9-access-the-frontend) * [Cleaning up](#cleaning-up) * [Summary](#summary) * [Next steps](#next-steps) * [About this example](#about-this-example) +## Overview + +This example is a variant of [Skupper Hello World][hello-world] that +uses [Skupper cluster policy][policy] to restrict site linking and +service exposure. + +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. + +The frontend and backend run in different sites, on different +clusters. The example shows you how you can explicitly allow +linking of the two sites and exposure of the backend service. + +[hello-world]: https://github.com/skupperproject/skupper-example-hello-world +[policy]: https://skupper.io/docs/policy/index.html + ## Prerequisites * The `kubectl` command-line tool, version 1.15 or later @@ -65,12 +86,12 @@ Skupper][install-docs]. [install-script]: https://github.com/skupperproject/skupper-website/blob/main/input/install.sh [install-docs]: https://skupper.io/install/ -## Step 2: Set up your namespaces +## Step 2: Set up your clusters -Skupper is designed for use with multiple Kubernetes namespaces, -usually on different clusters. The `skupper` and `kubectl` -commands use your [kubeconfig][kubeconfig] and current context to -select the namespace where they operate. +Skupper is designed for use with multiple Kubernetes clusters. +The `skupper` and `kubectl` commands use your +[kubeconfig][kubeconfig] and current context to select the cluster +and namespace where they operate. [kubeconfig]: https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/ @@ -115,39 +136,70 @@ kubectl create namespace east kubectl config set-context --current --namespace east ~~~ -## Step 3: Deploy the frontend and backend +## Step 3: Enable Skupper cluster policy -This example runs the frontend and the backend in separate -Kubernetes namespaces, on different clusters. +To enable Skupper cluster policy, you install a Custom Resource +Definition (CRD) named `SkupperClusterPolicy`. Installing the +CRD requires cluster admin privileges. -Use `kubectl create deployment` to deploy the frontend in -namespace `west` and the backend in namespace -`east`. +The presence of the CRD in a cluster tells Skupper to enforce +cluster policy. + +_**Warning:**_ Once the CRD is installed, any existing Skupper +networks on the cluster will stop working because Skupper +cluster policy denies all operations not explicitly allowed in +the policy configuration. Be careful to define working policy +rules before you enable policy for existing networks. + +Use `kubectl apply` to install the CRD in each cluster. _**West:**_ ~~~ shell -kubectl create deployment frontend --image quay.io/skupper/hello-world-frontend +kubectl apply -f https://raw.githubusercontent.com/skupperproject/skupper/main/api/types/crds/skupper_cluster_policy_crd.yaml +~~~ + +_Sample output:_ + +~~~ console +$ kubectl apply -f https://raw.githubusercontent.com/skupperproject/skupper/main/api/types/crds/skupper_cluster_policy_crd.yaml +customresourcedefinition.apiextensions.k8s.io/skupperclusterpolicies.skupper.io created +clusterrole.rbac.authorization.k8s.io/skupper-service-controller created ~~~ _**East:**_ ~~~ shell -kubectl create deployment backend --image quay.io/skupper/hello-world-backend --replicas 3 +kubectl apply -f https://raw.githubusercontent.com/skupperproject/skupper/main/api/types/crds/skupper_cluster_policy_crd.yaml +~~~ + +_Sample output:_ + +~~~ console +$ kubectl apply -f https://raw.githubusercontent.com/skupperproject/skupper/main/api/types/crds/skupper_cluster_policy_crd.yaml +customresourcedefinition.apiextensions.k8s.io/skupperclusterpolicies.skupper.io created +clusterrole.rbac.authorization.k8s.io/skupper-service-controller created ~~~ -## Step 4: Enable policy enforcement +## Step 4: Deploy the frontend and backend + +This example runs the frontend and the backend in separate +Kubernetes namespaces, on different clusters. + +Use `kubectl create deployment` to deploy the frontend in +namespace `west` and the backend in namespace +`east`. _**West:**_ ~~~ shell -kubectl apply -f https://raw.githubusercontent.com/skupperproject/skupper/main/api/types/crds/skupper_cluster_policy_crd.yaml +kubectl create deployment frontend --image quay.io/skupper/hello-world-frontend ~~~ _**East:**_ ~~~ shell -kubectl apply -f https://raw.githubusercontent.com/skupperproject/skupper/main/api/types/crds/skupper_cluster_policy_crd.yaml +kubectl create deployment backend --image quay.io/skupper/hello-world-backend --replicas 3 ~~~ ## Step 5: Create your sites @@ -207,7 +259,16 @@ Skupper is enabled for namespace "east". It is not connected to any other sites. As you move through the steps below, you can use `skupper status` at any time to check your progress. -## Step 6: Attempt to link your sites without permission +## Step 6: Attempt to link your sites and expose the backend + +Let's first try to link our sites and expose the backend service +without permission. + +Use `skupper token create` in West to generate the token. This +is the first step in attempting to link the two sites. + +Use `skupper expose` to attempt to expose the backend service in +East. _**West:**_ @@ -222,8 +283,6 @@ $ skupper token create ~/secret.token Error: Failed to create token: Policy validation error: incoming links are not allowed ~~~ -## Step 7: Attempt to expose the backend without permission - _**East:**_ ~~~ shell @@ -237,7 +296,10 @@ $ skupper expose deployment/backend --port 8080 Error: Policy validation error: deployment/backend cannot be exposed ~~~ -## Step 8: Grant permission to link your sites and expose the backend +Because Skupper cluster policy is enabled, these operations are +denied. + +## Step 7: Grant permission to link your sites and expose the backend ~~~ yaml apiVersion: skupper.io/v1alpha1 @@ -274,28 +336,15 @@ _**East:**_ kubectl apply -f east/policy.yaml ~~~ -## Step 9: Link your sites - -A Skupper _link_ is a channel for communication between two sites. -Links serve as a transport for application connections and -requests. +## Step 8: Link your sites and expose the backend -Creating a link requires use of two `skupper` commands in -conjunction, `skupper token create` and `skupper link create`. +Now that we have permission granted, let's try again. -The `skupper token create` command generates a secret token that -signifies permission to create a link. The token also carries the -link details. Then, in a remote site, The `skupper link -create` command uses the token to create a link to the site -that generated it. +Use `skupper token create` in West to generate the token. Then, +use `skupper link create` in East to link the sites. -**Note:** The link token is truly a *secret*. Anyone who has the -token can link to your site. Make sure that only those you trust -have access to it. - -First, use `skupper token create` in site West to generate the -token. Then, use `skupper link create` in site East to link -the sites. +Use `skupper expose` to expose the backend service in East to +the frontend in West. _**West:**_ @@ -314,45 +363,21 @@ _**East:**_ ~~~ shell skupper link create ~/secret.token +skupper expose deployment/backend --port 8080 ~~~ _Sample output:_ ~~~ console $ skupper link create ~/secret.token -Site configured to link to https://10.105.193.154:8081/ed9c37f6-d78a-11ec-a8c7-04421a4c5042 (name=link1) +Site configured to link to (name=link1) Check the status of the link using 'skupper link status'. -~~~ - -If your terminal sessions are on different machines, you may need -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. - -## Step 10: Expose the backend - -We now have our sites 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 site for exposure in all the -linked sites. - -Use `skupper expose` to expose the backend service in East to -the frontend in West. - -_**East:**_ - -~~~ shell -skupper expose deployment/backend --port 8080 -~~~ - -_Sample output:_ -~~~ console $ skupper expose deployment/backend --port 8080 deployment backend exposed as backend ~~~ -## Step 11: Access the frontend +## Step 9: Access the frontend In order to use and test the application, we need external access to the frontend. @@ -406,6 +431,7 @@ _**West:**_ skupper delete kubectl delete service/frontend kubectl delete deployment/frontend +kubectl delete -f west/policy.yaml ~~~ _**East:**_ @@ -413,6 +439,7 @@ _**East:**_ ~~~ shell skupper delete kubectl delete deployment/backend +kubectl delete -f east/policy.yaml ~~~ ## Next steps diff --git a/external/skewer/README.md b/external/skewer/README.md index 33beebe..ea7e78f 100644 --- a/external/skewer/README.md +++ b/external/skewer/README.md @@ -8,6 +8,14 @@ A `skewer.yaml` file describes the steps and commands to achieve an objective using Skupper. Skewer takes the `skewer.yaml` file as input and produces two outputs: a `README.md` file and a test routine. +#### Contents + +* [An example example](#an-example-example) +* [Setting up Skewer for your own example](#setting-up-skewer-for-your-own-example) +* [Skewer YAML](#skewer-yaml) +* [Standard steps](#standard-steps) +* [Demo mode](#demo-mode) + ## An example example [Example `skewer.yaml` file](example/skewer.yaml) @@ -89,7 +97,7 @@ commands: ## Skewer YAML -The top level: +The top level of the `skewer.yaml` file: ~~~ yaml title: # Your example's title (required) @@ -103,7 +111,18 @@ summary: # Text to summarize what the user did (optional) next_steps: # Text linking to more examples (optional, has default text) ~~~ -To disable the GitHub workflow, set it to `null`. +For fields with default text such as `prerequisites` and `next_steps`, +you can include the default text inside your custom text by using the +`@default@` placeholder: + +~~~ yaml +next_steps: + @default@ + + This Way to the Egress. +~~~ + +To disable the GitHub workflow and CI badge, set `workflow` to `null`. A **site**: @@ -167,12 +186,69 @@ steps: west: ~~~ -Or you can use a named step from the library of standard steps: +The step commands are separated into named groups corresponding to the +sites. Each named group contains a list of command entries. Each +command entry has a `run` field containing a shell command and other +fields for awaiting completion or providing sample output. + +You can also use a named step from the library of [standard +steps](#standard-steps): + +~~~ yaml +- standard: kubernetes/set_up_your_clusters +~~~ + +A **command**: + +~~~ yaml +- run: # A shell command (required) + apply: # Use this command only for "readme" or "test" (default is both) + output: # Sample output to include in the README (optional) + expect_failure: # If true, check that the command fails and keep going (default false) +~~~ + +Only the `run` and `output` fields are used in the README content. +The `output` field is used as sample output only, not for any kind of +testing. + +The `apply` field is useful when you want the readme instructions to +be different from the test procedure, or you simply want to omit +something. + +There are also some special "await" commands that you can use to pause +for a condition you require before going to the next step. They are +used only for testing and do not impact the README. + +~~~ yaml +- await_resource: # A resource for which to await readiness (optional) + # Example: await_resource: deployment/frontend +- await_ingress: # A service for which to await an external hostname or IP (optional) + # Example: await_ingress: service/frontend +- await_http_ok: # A service and URL template for which to await an HTTP OK response (optional) + # Example: await_http_ok: [service/frontend, "http://{}:8080/api/hello"] +~~~ + +Example commands: ~~~ yaml -- standard: configure_separate_console_sessions +commands: + east: + - run: skupper expose deployment/backend --port 8080 + output: | + deployment backend exposed as backend + west: + - await_resource: service/backend + - run: kubectl get service/backend + output: | + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + backend ClusterIP 10.102.112.121 8080/TCP 30s ~~~ +## Standard steps + +Skewer includes a library of standard steps with descriptive text and +commands that we use a lot for our examples. + The standard steps are defined in [python/skewer/standardsteps.yaml](python/skewer/standardsteps.yaml). They are the following: @@ -181,13 +257,13 @@ They are the following: general/install_the_skupper_command_line_tool general/link_your_sites general/cleaning_up -kubernetes/set_up_your_namespaces -kubernetes/set_up_your_kubernetes_namespace # One namespace only +kubernetes/set_up_your_clusters +kubernetes/set_up_your_kubernetes_cluster # One cluster only kubernetes/create_your_sites kubernetes/link_your_sites kubernetes/access_the_frontend kubernetes/cleaning_up -podman/set_up_your_podman_network +podman/set_up_your_podman_environment hello_world/deploy_the_frontend_and_backend hello_world/expose_the_backend hello_world/access_the_frontend @@ -236,7 +312,7 @@ example might look like this: ~~~ yaml steps: - standard: general/install_the_skupper_command_line_tool - - standard: kubernetes/set_up_your_namespaces + - standard: kubernetes/set_up_your_clusters - standard: kubernetes/create_your_sites - standard: kubernetes/link_your_sites @@ -245,56 +321,6 @@ steps: - standard: kubernetes/cleaning_up ~~~ -The step commands are separated into named groups corresponding to the -sites. Each named group contains a list of command entries. Each -command entry has a `run` field containing a shell command and other -fields for awaiting completion or providing sample output. - -A **command**: - -~~~ yaml -- run: # A shell command (required) - apply: # Use this command only for "readme" or "test" (optional, default is both) - output: # Sample output to include in the README (optional) -~~~ - -Only the `run` and `output` fields are used in the README content. -The `output` field is used as sample output only, not for any kind of -testing. - -The `apply` field is useful when you want the readme instructions to -be different from the test procedure, or you simply want to omit -something. - -There are also some special "await" commands that you can use to pause -for a condition you require before going to the next step. They are -used only for testing and do not impact the README. - -~~~ yaml -- await_resource: # A resource for which to await readiness (optional) - # Example: await_resource: deployment/frontend -- await_ingress: # A service for which to await an external hostname or IP (optional) - # Example: await_ingress: service/frontend -- await_http_ok: # A service and URL template for which to await an HTTP OK response (optional) - # Example: await_http_ok: [service/frontend, "http://{}:8080/api/hello"] -~~~ - -Example commands: - -~~~ yaml -commands: - east: - - run: skupper expose deployment/backend --port 8080 - output: | - deployment backend exposed as backend - west: - - await_resource: service/backend - - run: kubectl get service/backend - output: | - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE - backend ClusterIP 10.102.112.121 8080/TCP 30s -~~~ - ## Demo mode Skewer has a mode where it executes all the steps, but before cleaning diff --git a/external/skewer/example/README.md b/external/skewer/example/README.md index 5aba426..23715be 100644 --- a/external/skewer/example/README.md +++ b/external/skewer/example/README.md @@ -18,7 +18,7 @@ across cloud providers, data centers, and edge sites. * [Overview](#overview) * [Prerequisites](#prerequisites) * [Step 1: Install the Skupper command-line tool](#step-1-install-the-skupper-command-line-tool) -* [Step 2: Set up your namespaces](#step-2-set-up-your-namespaces) +* [Step 2: Set up your clusters](#step-2-set-up-your-clusters) * [Step 3: Deploy the frontend and backend](#step-3-deploy-the-frontend-and-backend) * [Step 4: Create your sites](#step-4-create-your-sites) * [Step 5: Link your sites](#step-5-link-your-sites) @@ -60,12 +60,12 @@ Skupper][install-docs]. [install-script]: https://github.com/skupperproject/skupper-website/blob/main/input/install.sh [install-docs]: https://skupper.io/install/ -## Step 2: Set up your namespaces +## Step 2: Set up your clusters -Skupper is designed for use with multiple Kubernetes namespaces, -usually on different clusters. The `skupper` and `kubectl` -commands use your [kubeconfig][kubeconfig] and current context to -select the namespace where they operate. +Skupper is designed for use with multiple Kubernetes clusters. +The `skupper` and `kubectl` commands use your +[kubeconfig][kubeconfig] and current context to select the cluster +and namespace where they operate. [kubeconfig]: https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/ @@ -207,9 +207,9 @@ that generated it. token can link to your site. Make sure that only those you trust have access to it. -First, use `skupper token create` in site West to generate the -token. Then, use `skupper link create` in site East to link -the sites. +First, use `skupper token create` in West to generate the +token. Then, use `skupper link create` in East to link the +sites. _**West:**_ diff --git a/external/skewer/example/skewer.yaml b/external/skewer/example/skewer.yaml index 8af204b..8991c39 100644 --- a/external/skewer/example/skewer.yaml +++ b/external/skewer/example/skewer.yaml @@ -19,15 +19,19 @@ sites: KUBECONFIG: ~/.kube/config-east steps: - standard: general/install_the_skupper_command_line_tool - - standard: kubernetes/set_up_your_namespaces + - standard: kubernetes/set_up_your_clusters - standard: hello_world/deploy_the_frontend_and_backend - standard: kubernetes/create_your_sites - standard: kubernetes/link_your_sites - title: Fail on demand commands: west: - - run: | - if [ -n "${SKEWER_FAIL}" ]; then expr 1 / 0; fi + - run: "if [ -n \"${SKEWER_FAIL}\" ]; then expr 1 / 0; fi" + - title: Fail expectedly + commands: + west: + - run: "expr 1 / 0" + expect_failure: true - standard: hello_world/expose_the_backend - standard: hello_world/access_the_frontend - standard: hello_world/cleaning_up diff --git a/external/skewer/python/skewer/main.py b/external/skewer/python/skewer/main.py index df3e05e..fdb26ac 100644 --- a/external/skewer/python/skewer/main.py +++ b/external/skewer/python/skewer/main.py @@ -186,7 +186,16 @@ def run_step(model, step, work_dir, check=True): await_console_ok() if command.run: - run(command.run.replace("~", work_dir), shell=True, check=check) + proc = run(command.run.replace("~", work_dir), shell=True, check=False) + + if command.expect_failure: + if proc.exit_code == 0: + fail("A command expected to fail did not fail") + + continue + + if check and proc.exit_code > 0: + raise PlanoProcessError(proc) def pause_for_demo(model): notice("Pausing for demo time") @@ -675,6 +684,7 @@ def commands(self): class Command: run = object_property("run") + expect_failure = object_property("expect_failure", False) apply = object_property("apply") output = object_property("output") await_resource = object_property("await_resource") diff --git a/external/skewer/python/skewer/standardsteps.yaml b/external/skewer/python/skewer/standardsteps.yaml index d8bb6b0..2a69822 100644 --- a/external/skewer/python/skewer/standardsteps.yaml +++ b/external/skewer/python/skewer/standardsteps.yaml @@ -59,9 +59,9 @@ general/link_your_sites: token can link to your site. Make sure that only those you trust have access to it. - First, use `skupper token create` in site @site0@ to generate the - token. Then, use `skupper link create` in site @site1@ to link - the sites. + First, use `skupper token create` in @site0@ to generate the + token. Then, use `skupper link create` in @site1@ to link the + sites. commands: "0": - run: skupper token create ~/secret.token @@ -88,14 +88,14 @@ general/cleaning_up: commands: "*": - run: skupper delete -kubernetes/set_up_your_namespaces: - title: Set up your namespaces +kubernetes/set_up_your_clusters: + title: Set up your clusters platform: kubernetes preamble: | - Skupper is designed for use with multiple Kubernetes namespaces, - usually on different clusters. The `skupper` and `kubectl` - commands use your [kubeconfig][kubeconfig] and current context to - select the namespace where they operate. + Skupper is designed for use with multiple Kubernetes clusters. + The `skupper` and `kubectl` commands use your + [kubeconfig][kubeconfig] and current context to select the cluster + and namespace where they operate. [kubeconfig]: https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/ @@ -130,8 +130,8 @@ kubernetes/set_up_your_namespaces: - run: kubectl create namespace @namespace@ --dry-run=client -o yaml | kubectl apply -f - apply: test - run: kubectl config set-context --current --namespace @namespace@ -kubernetes/set_up_your_kubernetes_namespace: - title: Set up your Kubernetes namespace +kubernetes/set_up_your_kubernetes_cluster: + title: Set up your Kubernetes cluster platform: kubernetes preamble: | Open a new terminal window and log in to your cluster. Then @@ -203,9 +203,9 @@ kubernetes/link_your_sites: token can link to your site. Make sure that only those you trust have access to it. - First, use `skupper token create` in site @site0@ to generate the - token. Then, use `skupper link create` in site @site1@ to link - the sites. + First, use `skupper token create` in @site0@ to generate the + token. Then, use `skupper link create` in @site1@ to link the + sites. commands: "0": - run: skupper token create ~/secret.token @@ -267,8 +267,8 @@ kubernetes/cleaning_up: commands: "*": - run: skupper delete -podman/set_up_your_podman_network: - title: Set up your Podman network +podman/set_up_your_podman_environment: + title: Set up your Podman environment platform: podman preamble: | Open a new terminal window and set the `SKUPPER_PLATFORM` diff --git a/skewer.yaml b/skewer.yaml index 2713673..9e4fd37 100644 --- a/skewer.yaml +++ b/skewer.yaml @@ -1,21 +1,25 @@ -title: Skupper Hello World -subtitle: A minimal HTTP application deployed across Kubernetes clusters using Skupper -# overview: | -# This example is a very simple multi-service HTTP application -# deployed across Kubernetes clusters using Skupper. +title: Skupper Hello World using cluster policy +subtitle: Use policy to control site linking and service exposure +overview: | + This example is a variant of [Skupper Hello World][hello-world] that + uses [Skupper cluster policy][policy] to restrict site linking and + service exposure. -# It contains two services: + It contains two services: -# * A backend service that exposes an `/api/hello` endpoint. It -# returns greetings of the form `Hi, . I am -# ()`. + * 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. + * 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. + The frontend and backend run in different sites, on different + clusters. The example shows you how you can explicitly allow + linking of the two sites and exposure of the backend service. + + [hello-world]: https://github.com/skupperproject/skupper-example-hello-world + [policy]: https://skupper.io/docs/policy/index.html sites: west: title: West @@ -31,31 +35,58 @@ sites: KUBECONFIG: ~/.kube/config-east steps: - standard: general/install_the_skupper_command_line_tool - - standard: kubernetes/set_up_your_namespaces - - standard: hello_world/deploy_the_frontend_and_backend - - title: Enable policy enforcement + - standard: kubernetes/set_up_your_clusters + - title: Enable Skupper cluster policy + preamble: | + To enable Skupper cluster policy, you install a Custom Resource + Definition (CRD) named `SkupperClusterPolicy`. Installing the + CRD requires cluster admin privileges. + + The presence of the CRD in a cluster tells Skupper to enforce + cluster policy. + + _**Warning:**_ Once the CRD is installed, any existing Skupper + networks on the cluster will stop working because Skupper + cluster policy denies all operations not explicitly allowed in + the policy configuration. Be careful to define working policy + rules before you enable policy for existing networks. + + Use `kubectl apply` to install the CRD in each cluster. commands: west: - run: kubectl apply -f https://raw.githubusercontent.com/skupperproject/skupper/main/api/types/crds/skupper_cluster_policy_crd.yaml + output: | + customresourcedefinition.apiextensions.k8s.io/skupperclusterpolicies.skupper.io created + clusterrole.rbac.authorization.k8s.io/skupper-service-controller created east: - run: kubectl apply -f https://raw.githubusercontent.com/skupperproject/skupper/main/api/types/crds/skupper_cluster_policy_crd.yaml + output: | + customresourcedefinition.apiextensions.k8s.io/skupperclusterpolicies.skupper.io created + clusterrole.rbac.authorization.k8s.io/skupper-service-controller created + - standard: hello_world/deploy_the_frontend_and_backend - standard: kubernetes/create_your_sites - - title: Attempt to link your sites without permission + - title: Attempt to link your sites and expose the backend + preamble: | + Let's first try to link our sites and expose the backend service + without permission. + + Use `skupper token create` in West to generate the token. This + is the first step in attempting to link the two sites. + + Use `skupper expose` to attempt to expose the backend service in + East. commands: west: - run: skupper token create ~/secret.token - apply: readme + expect_failure: true output: "Error: Failed to create token: Policy validation error: incoming links are not allowed" - - run: "skupper token create ~/secret.token || :" - apply: test - - title: Attempt to expose the backend without permission - commands: east: - run: skupper expose deployment/backend --port 8080 - apply: readme + expect_failure: true output: "Error: Policy validation error: deployment/backend cannot be exposed" - - run: "skupper expose deployment/backend --port 8080 || :" - apply: test + postamble: | + Because Skupper cluster policy is enabled, these operations are + denied. - title: Grant permission to link your sites and expose the backend preamble: | ~~~ yaml @@ -83,11 +114,42 @@ steps: commands: west: - run: kubectl apply -f west/policy.yaml - - await_resource: SkupperClusterPolicy/west + - await_resource: skupperclusterpolicy/west east: - run: kubectl apply -f east/policy.yaml - - await_resource: SkupperClusterPolicy/east - - standard: kubernetes/link_your_sites - - standard: hello_world/expose_the_backend + - await_resource: skupperclusterpolicy/east + - title: Link your sites and expose the backend + preamble: | + Now that we have permission granted, let's try again. + + Use `skupper token create` in West to generate the token. Then, + use `skupper link create` in East to link the sites. + + Use `skupper expose` to expose the backend service in East to + the frontend in West. + commands: + west: + - run: skupper token create ~/secret.token + output: Token written to ~/secret.token + east: + - run: skupper link create ~/secret.token + output: | + Site configured to link to (name=link1) + Check the status of the link using 'skupper link status'. + - run: skupper link status --wait 60 + apply: test + - await_resource: deployment/backend + - run: skupper expose deployment/backend --port 8080 + output: deployment backend exposed as backend - standard: hello_world/access_the_frontend - standard: hello_world/cleaning_up + commands: + west: + - run: skupper delete + - run: kubectl delete service/frontend + - run: kubectl delete deployment/frontend + - run: kubectl delete -f west/policy.yaml + east: + - run: skupper delete + - run: kubectl delete deployment/backend + - run: kubectl delete -f east/policy.yaml