Skip to content

Commit

Permalink
fix(dev-env): Provide working ui containers (#104)
Browse files Browse the repository at this point in the history
* fix(dev-env): Provide working ui containers
  • Loading branch information
uwe-mayer authored May 17, 2024
1 parent d077ccf commit 5752ae4
Show file tree
Hide file tree
Showing 15 changed files with 80 additions and 634 deletions.
86 changes: 36 additions & 50 deletions dev-env/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ The following containers run together:

- `greenhouse`: The greenhouse core controller
- `envtest`: Local kubernetes API Server and etcd with greenhouse CRDs
- `greenhouse-ui`: The greenhouse core ui hosting your plugin
- `app`: An example app integrated as a greenhouse plugin
- `greenhouse-ui`: The greenhouse core ui
- `app`: An example frontend for a greenhouse plugin
- `bootstrap`: A short living container bootstrapping some mock greenhouse resource for your plugin to interact with.

This setup should get you started to locally
Expand All @@ -19,14 +19,20 @@ This setup should get you started to locally

## Get started

The setup is provided via `docker-compose`.
The setup is provided via `docker compose`.

Spin everything up as follows:

(all `docker-compose` commands from within `./`):
(all `docker compose` commands from within `./`):

```
docker-compose up
docker compose up -d
```

You might have to build the `greenhouse-dev-ui` and `greenhouse-dev-app` images locally until we provide them in our registry by running

```
docker compose build greenhouse-ui app
```

Reach the frontend at [http://localhost:3001/](http://localhost:3001/)
Expand All @@ -42,8 +48,8 @@ kubectl get teams -A
Make sure to stay up to date with our `dev-env` images and pull from time to time:

```
docker-compose rm -f
docker-compose pull
docker compose rm -f
docker compose pull
```

### Linux users
Expand All @@ -53,32 +59,38 @@ To allow the docker containers full network access within f5 VPN you must activa
This is prepared by using [network-host.docker-compose.yaml](./network-host.docker-compose.yml) :

```
docker-compose -f network-host.docker-compose.yaml up
docker compose -f network-host.docker-compose.yaml up -d
```

In the following we aim to provide a more detailed view on the different containers:

## greenhouse-ui and app

The `greenhouse-ui` container hosts the greenhouse shell which will in it's place host your app as a plugin. It exposes the frontend on [http://localhost:3001](http://localhost:3001)
The `greenhouse-ui` container hosts the greenhouse shell which will in it's place will host your app as a plugin. It exposes the frontend on [http://localhost:3000](http://localhost:3000)

The `app` container hosts an exemplary juno frontend application for an [example-plugin](./bootstrap/example-plugin.yaml) that comes with the bootstrapped resources of the `dev-env`:
The `app` container hosts an exemplary greenhouse frontend application for an [example-plugin](./bootstrap/example-plugin.yaml) that comes with the bootstrapped resources of the `dev-env`:

- The `Spec.uiApplication` points to the `index.js` file hosted by the `app` container. It runs a nginx web server pointing at a built Juno/React app's index.js. Exemplary we integrated the [the juno example app](https://github.com/sapcc/juno/tree/main/apps/exampleapp) as the `example-plugins` frontend.
- The `Spec.uiApplication` points to the `index.js` file hosted by the `app` container. Exemplary we integrated the [team-admin microfrontend](https://github.com/cloudoperators/greenhouse/tree/main/ui/team-admin) as the `example-plugins` frontend.
- The `Spec.ClusterName` points to the cluster named `self`. This is the mock cluster running in the `envtest` container. See [EnvTest](#envtest)
- The `Spec.HelmChart` references an exemplary bitnami/mysql chart.

The ui of a greenhouse plugin always is a [juno application](https://github.com/sapcc/juno/blob/main/docs/build_and_host_app.md).

Juno among other things provides a powerful library of [ready to use frontend components](https://ui.juno.global.cloud.sap/?path=/story/components-badge--default).
The ui of a greenhouse plugin always is a standalone micro-frontend.

Take a look at the [best practices provided by the ui team](https://ui-team.global.cloud.sap/docs/projects/juno/bestpractices/).
We use [Juno Frontends](https://github.com/cloudoperators/juno)

### Start testing / developing your own

Looking at a `plugin.yaml` containing a `PluginDefinition`:

- The `Spec.HelmChart` references a packaged helm chart in a registry.
- The `Spec.uiApplication` points to the `index.js` file of a standalone javascript frontend application.
- The `Spec.ClusterName` points to a cluster onboarded to greenhouse.

#### Plugin with backend

To **develop** a plugin with a custom backend you will have some kind of controller interacting with kubernetes. To do so your client will consume a `kubeconfig`.
Greenhouse `Plugin` backends are shipped as [helm charts](https://helm.sh/). We expect your backend application to be deployable as such.

If you intend to write a plugin that interacts with `Greenhouse` resources, such as `teams`,`clusters`, etc. you will have some kind of controller interacting with the kubernetes API of `Greenhouse`. To do so your client will consume a `kubeconfig`.

The [EnvTest](#envtest) container provides a kubeconfig. Use it as such:

Expand All @@ -88,28 +100,30 @@ export KUBECONFIG=<path-to-repository>/dev-env/envtest/kubeconfig

Within `go` code you could create a client via the [GetConfigOrDie()](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/client/config#GetConfigOrDie) func which (among others) fallbacks to creating a client from a kubeconfig referenced via `KUBECONFIG` environment variable. Other clients provide similar methods.

To **test** your plugin with a backend (a.k.a. helm chart) the proposed way is:
To **test** your plugin (a.k.a. `PluginDefinition` yaml file) with a backend (a.k.a. helm chart) the proposed way is:

- Spin up the `dev-env` and export `KUBECONFIG` env var.
- Deploy your Plugin to the `dev-env` with the reference to your helm chart in `Spec.helmChart`
- Deploy your `PluginDefinition` to the `dev-env` with the reference to your helm chart in `Spec.helmChart`
- Onboard a cluster you have access to (e.g. local [minikube](https://minikube.sigs.k8s.io/docs/start/), [KIND](https://kind.sigs.k8s.io/docs/user/quick-start/) or other)

```
kubectl --namespace=test-org create secret generic <cluster-name> --type=greenhouse.sap/kubeconfig --from-file=kubeconfig=<your-cluster-kubeconfig.yaml>
```

- Check that your cluster is `ready` [in UI](<http://localhost:3001/?org=test-org&__s=(greenhouse:(a:greenhouse~Fmanagement),greenhouse~Fmanagement:(a:greenhouse~Fcluster~Fadmin))>) or via
- Check that your cluster is `ready` [in UI](<http://localhost:3000/?org=test-org&__s=(greenhouse:(a:greenhouse~Fmanagement),greenhouse~Fmanagement:(a:greenhouse~Fcluster~Fadmin))>) or via
```
kubectl get clusters -n test-org
```
- Deploy a Plugin to the `test-org` namespace with `Spec.ClusterName` set to your onboarded cluster
- The resources of your Plugin will be installed to your onboarded cluster into the `test-org` namespace. View your running Application there.
- Deploy a `Plugin` to the `test-org` namespace with `Spec.ClusterName` set to your onboarded cluster. Fill out the necessary `OptionValues`.
- The resources of your Plugin will be installed to your onboarded cluster into the `Spec.RekeaseNamespace` namespace. View your running Application there.

See [greenhouse](#greenhouse) for how to access the greenhouse controller logs.

#### UI

Start copying the example ui application into your own repo folder `<path-to-example-app>` as such:
We extracted the `team-admin` frontend into the `app` container.

Start copying this example ui application into your own repo folder `<path-to-example-app>` as such:

```
docker compose cp app:app/ <path-to-example-app>
Expand All @@ -125,34 +139,6 @@ npm run start

The frontend is served on [localhost:3000](http://localhost:3000) with a file watcher and live reload.

To actually view your code in the greenhouse frontend, execute the `build` script provided:

```
npm run build
```

This will build your application.
Then mount your app to the app container within [docker-compose.yaml](./docker-compose.yml). The nginx will serve your application now.

(uncomment lines in docker-compose.yaml):

```
services:
app:
image: ghcr.io/cloudoperators/greenhouse-dev-app:dev-latest
# uncomment to mount your folder:
# volumes:
# - /path/to/app/:/app/
```

Start the docker containers:

```
docker-compose up -d
```

You will now see your application running as a greenhouse plugin on [localhost:3001](http://localhost:3001)

## envtest

Runs a local k8s api server with a local etcd
Expand Down
12 changes: 7 additions & 5 deletions dev-env/bootstrap/example-plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: Apache-2.0

apiVersion: greenhouse.sap/v1alpha1
kind: Plugin
kind: PluginDefinition
metadata:
name: example-plugin
spec:
Expand All @@ -16,7 +16,7 @@ spec:
uiApplication:
name: example-plugin
version: "latest"
url: http://localhost:9090/index.js
url: http://localhost:8001/index.js
options:
- name: apiEndpoint
description: URL of k8s api endpoint
Expand All @@ -26,15 +26,17 @@ spec:
---

apiVersion: greenhouse.sap/v1alpha1
kind: PluginConfig
kind: Plugin
metadata:
name: example-plugin
namespace: test-org
spec:
clusterName: self
disabled: false
plugin: example-plugin
pluginDefinition: example-plugin
displayName: Example Plugin
optionValues:
- name: apiEndpoint
value: http://127.0.0.1:8090
value: http://127.0.0.1:8090
- name: isMock
value: "true"
24 changes: 12 additions & 12 deletions dev-env/bootstrap/plugins.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: Apache-2.0

apiVersion: greenhouse.sap/v1alpha1
kind: Plugin
kind: PluginDefinition
metadata:
name: test-plugin
spec:
Expand All @@ -14,7 +14,7 @@ spec:

---
apiVersion: greenhouse.sap/v1alpha1
kind: Plugin
kind: PluginDefinition
metadata:
name: test-plugin-2
spec:
Expand All @@ -25,54 +25,54 @@ spec:
version: "latest"
---
apiVersion: greenhouse.sap/v1alpha1
kind: PluginConfig
kind: Plugin
metadata:
name: test-pluginconfig-cluster-1
namespace: test-org
spec:
plugin: test-plugin
pluginDefinition: test-plugin
disabled: false
clusterName: "cluster-1"
---
apiVersion: greenhouse.sap/v1alpha1
kind: PluginConfig
kind: Plugin
metadata:
name: test-pluginconfig-cluster-2
namespace: test-org
spec:
plugin: test-plugin
pluginDefinition: test-plugin
disabled: false
clusterName: "cluster-2"

---
apiVersion: greenhouse.sap/v1alpha1
kind: PluginConfig
kind: Plugin
metadata:
name: test-pluginconfig-2-cluster-2
namespace: test-org
spec:
plugin: test-plugin-2
pluginDefinition: test-plugin-2
disabled: false
clusterName: "cluster-2"

---
apiVersion: greenhouse.sap/v1alpha1
kind: PluginConfig
kind: Plugin
metadata:
name: test-pluginconfig-cluster-3
namespace: test-org
spec:
plugin: test-plugin
pluginDefinition: test-plugin
disabled: false
clusterName: "cluster-3"

---
apiVersion: greenhouse.sap/v1alpha1
kind: PluginConfig
kind: Plugin
metadata:
name: test-pluginconfig-2-cluster-3
namespace: test-org
spec:
plugin: test-plugin-2
pluginDefinition: test-plugin-2
disabled: false
clusterName: "cluster-3"
12 changes: 3 additions & 9 deletions dev-env/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,15 @@ services:
retries: 5
greenhouse-ui:
image: ghcr.io/cloudoperators/greenhouse-dev-ui:main
# uncomment to mount your folder:
# volumes:
# - <path-to-your-ui-folder>/app:/app
environment:
- PORT=3001
- PORT=3000
ports:
- "3001:3001"
- "3000:3000"
build: ./ui/greenhouse
app:
image: ghcr.io/cloudoperators/greenhouse-dev-app:main
# uncomment to mount your folder:
# volumes:
# - /path/to/app/:/app/
ports:
- "9090:9090"
- "8001:8001"
build: ./ui/app
bootstrap:
image: ghcr.io/cloudoperators/greenhouse-dev-env:main
Expand Down
5 changes: 1 addition & 4 deletions dev-env/network-host.docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,11 @@ services:
greenhouse-ui:
image: ghcr.io/cloudoperators/greenhouse-dev-ui:main
environment:
- PORT=3001
- PORT=3000
network_mode: host
build: ./ui/greenhouse
app:
image: ghcr.io/cloudoperators/greenhouse-dev-app:main
# uncomment to mount your folder:
# volumes:
# - /path/to/app:/app
network_mode: host
build: ./ui/app
bootstrap:
Expand Down
3 changes: 0 additions & 3 deletions dev-env/ui/app/.gitignore

This file was deleted.

22 changes: 8 additions & 14 deletions dev-env/ui/app/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,15 @@
# SPDX-License-Identifier: Apache-2.0

FROM alpine/git:2.43.0 as git
RUN git clone https://github.com/sapcc/juno.git /juno
RUN git clone https://github.com/cloudoperators/greenhouse.git /greenhouse

FROM node:18.16-alpine3.18 as node
LABEL source_repository="https://github.com/sapcc/juno"
FROM node:18.20-alpine3.18 as node
LABEL source_repository="https://github.com/cloudoperators/greenhouse"
WORKDIR /app
COPY --from=git /juno/apps/exampleapp /app
COPY --from=git /juno/helpers/appProps.js /app/appProps.js
COPY ./package.json /app/package.json
COPY ./esbuild.config.js /app/esbuild.config.js
RUN cd /app && npm add -D esbuild && npm install && npm run build
COPY ./secretProps.json /app
COPY --from=git /greenhouse/ui/team-admin /app
COPY --from=git /greenhouse/ui/helpers/appProps.js /appProps.js
RUN cd /app && npm add -D esbuild && npm install -g http-server && npm install && npm run build

FROM nginx:1.25.5-alpine as nginx
LABEL source_repository="greenhouse"
COPY --from=node /app /app
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
ENTRYPOINT ["nginx", "-g", "daemon off;"]
CMD ["http-server", "--cors", "-p", "8001", "/app/build"]

Loading

0 comments on commit 5752ae4

Please sign in to comment.