diff --git a/charts/rucio-webui/Chart.yaml b/charts/rucio-webui/Chart.yaml index 2e7d06c..37cf404 100644 --- a/charts/rucio-webui/Chart.yaml +++ b/charts/rucio-webui/Chart.yaml @@ -1,7 +1,7 @@ name: rucio-webui -version: 34.0.0 +version: 34.0.1 apiVersion: v1 -description: A Helm chart to deploy the new webui (2.0) servers for Rucio +description: A Helm chart to deploy the new Rucio Webui keywords: - data-management - science diff --git a/charts/rucio-webui/README.md b/charts/rucio-webui/README.md index e69de29..cb7f8c7 100644 --- a/charts/rucio-webui/README.md +++ b/charts/rucio-webui/README.md @@ -0,0 +1,168 @@ +# Rucio + +## Data Management for science in the Big Data era. + +Rucio is a software framework that provides functionality to organize, manage, and access large volumes of scientific data using customisable policies. The data can be spread across globally distributed locations and across heterogeneous data centers, uniting different storage and network technologies as a single federated entity. Rucio offers advanced features such as distributed data recovery or adaptive replication, and is highly scalable, modular, and extensible. Rucio has been originally developed to meet the requirements of the high-energy physics experiment ATLAS, and is continuously extended to support LHC experiments and other diverse scientific communities. + +## QuickStart + +Add the Rucio Helm repository to your local Helm installation: +```bash +helm repo add rucio https://rucio.github.io/helm-charts +``` + +## Introduction + +This chart bootstraps a Rucio WebUI deployment and service on a Kubernetes cluster using the Helm Package manager. + +Rucio WebUI is a [NextJS](https://nextjs.org/) application that provides a web interface to interact with the Rucio server. The application is packaged via PM2 and served using Apache. + +## Configuration +The default configuration values for this chart are listed in `values.yaml` our you can get them with: + +```bash +helm inspect values rucio/rucio-webui +``` + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install` as shown before. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install \ + --name my-release \ + -f values.yaml \ + rucio/rucio-webui +``` +### Basic Configuration +At the bare minimum, you will need to provide the following parameters: +`config.webui.rucio_host` - The hostname of the Rucio server to connect to. +`config.webui.rucio_auth_host` - The hostname of the Rucio authentication server to connect to. +`config.webui.hostname` - The hostname of the WebUI server. +`config.webui.project_url`- The public URL of your collaboration's project page. + +### VO Configuration +To configure multiple vo's, you can use the `config.webui.vo` parameter. This parameter is a csv string of the short names of the vo's you want to configure. For example, to configure the `atlas` and `cms` vo's, you would set `config.webui.vo` to `atl,cms`. + +For each VO, you will have to provide parameters in the `config.vo` section. For example, +```yaml +config: + vo: + atl: + name: ATLAS + oidc_enabled: "False" + oidc_providers: "" + cms: + name: CMS + oidc_enabled: "False" + oidc_providers: "" +``` + +## Service, TLS Termination and Certificates +By default, the WebUI pods will listen on port 80 using plain HTTP and the default services are of type `ClusterIP` on port 80. To run the pods with https you will first have to install the necessary hostcert, hostkey and ca-bundles. + +The host certificates and CA bundle must be created before the pod start. The certificates and CA bundle must be provided as secrets in the same namespace as the WebUI pod. The secret names must be prepended with the same `Release.Name` of the chart. The secret must contain the following: + +### CA Bundle +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: {.Release.Name}-cafile + namespace: {your_namespace} +data: + ca.pem: {base64 encoded ca.pem} +type: Opaque +``` +### Hostcert +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: {.Release.Name}-hostcert + namespace: {your_namespace} +data: + hostcert.pem: {base64 encoded hostcert.pem} +type: Opaque +``` + +### Hostkey +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: {.Release.Name}-hostkey + namespace: {your_namespace} +data: + hostkey.pem: {base64 encoded hostkey.pem} +type: Opaque +``` +### Generate Secrets +You can generate the secrets using the following commands: +```bash +kubectl create secret generic -server-hostcert --from-file=hostcert.pem=/path/to/hostcert.pem +kubectl create secret generic -server-hostkey --from-file=hostkey.pem=/path/to/hostkey.pem +kubectl create secret generic -server-cafile --from-file=ca.pem=/path/to/ca.pem +``` +### Enable HTTPS +To enable HTTPS, you will have to set the `config.webui.useSSL` parameter to `true`. You will also have to adapt the service to port 443: +```yaml +service: + type: ClusterIP + port: 443 + targetPort: 443 + protocol: TCP + name: https +``` + +Furthermore, you can also change the service type depending on how you want to expose the WebUI. For example, to expose the WebUI using a `LoadBalancer` service, you would set the `service.type` parameter to `LoadBalancer`. To expose the WebUI using a `NodePort` service, you would set the `service.type` parameter to `NodePort` and the `service.nodePort` parameter to the desired port. + +## Ingress +If you want to use and ingress controller to expose the servers you will have to +configure them separately. In this case the service type should stay as +`ClusterIP`. A simple ingress for the api server would like this: + + ingress: + enabled: true + path: / + hosts: + - my.rucio.test + +In case you want to use HTTPS with an ingress you should not change the service +as explained above but instead let the ingress controller handle the TLS +connection and then pass the requests using plain HTTP inside the cluster. + +You will have to install the valid certificate and key as a secret in the +cluster that you can then configure in the ingress definition: +```bash +kubectl create secret tls rucio-webui.tls-secret --key=tls.key --cert=tls.crt +``` +```yaml + ingress: + enabled: true + path: / + hosts: + - my.rucio.test + tls: + - secretName: rucio-server.tls-secret +``` + +## Additional Configuration +The webui container can be fully configured by providing the environment variables listed [here](https://github.com/rucio/containers/tree/master/webui#configuration). You can specify the `Full Name` of the variable in the `optionalConfig` section of the `values.yaml` file. Please note that the `Full Name` implies the `RUCIO_WEBUI_` prefix or the `RUCIO_HTTPD_` or the `RUCIO_` prefix, depending the on configuration group. + +## Logs +The `config.logs.exposeHttpdLogs` parameter will start a sidecar container that will expose the logs of the Apache server. The logs will be available at the `/var/log/httpd` directory of the container and can also be accessed as `stdout` of the busybox container. + +The `config.logs.exposeWebuiLogs` parameter will start a sidecar container that will expose the logs of the WebUI application. The logs will be available at the `/var/log/webui` directory of the container and can also be accessed as `stdout` of the busybox container. + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + + $ helm delete my-release --purge + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Getting Support + +If you are looking for support, please contact us via one of our [official channels](https://rucio.cern.ch/documentation/contact_us/). \ No newline at end of file diff --git a/charts/rucio-webui/templates/deployment.yaml b/charts/rucio-webui/templates/deployment.yaml index 71ea6df..8f2c357 100644 --- a/charts/rucio-webui/templates/deployment.yaml +++ b/charts/rucio-webui/templates/deployment.yaml @@ -50,7 +50,9 @@ spec: secretName: {{ template "rucio.fullname" . }}.config.yaml - name: httpdlog emptyDir: {} - {{- if eq .Values.service.useSSL true }} + - name: webui-log + emptyDir: {} + {{- if eq .Values.useSSL true }} - name: hostcert secret: secretName: {{ .Release.Name }}-hostcert @@ -72,13 +74,21 @@ spec: claimName: {{ $val.name }} {{- end}} containers: - {{- if .Values.exposeErrorLogs }} + {{- if .Values.config.logs.exposeHttpdLogs }} - name: httpd-error-log image: busybox args: [/bin/sh, -c, 'tail -n+1 -F /var/log/httpd/error_log'] volumeMounts: - name: httpdlog mountPath: /var/log/httpd + {{- end }} + {{- if .Values.config.logs.exposeWebuiLogs }} + - name: webui-log + image: busybox + args: [/bin/sh, -c, 'tail -n+1 -F /var/log/webui/rucio-webui-out.log /var/log/webui/rucio-webui-error.log'] + volumeMounts: + - name: webui-log + mountPath: /var/log/webui/ {{- end }} - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" @@ -87,18 +97,21 @@ spec: - name: http containerPort: 80 protocol: TCP - {{- if .Values.service.useSSL }} + {{- if .Values.useSSL }} - name: https containerPort: 443 protocol: TCP {{- end }} volumeMounts: - - name: config - mountPath: /opt/rucio/etc/conf.d/10_common.json - subPath: common.json + {{- if .Values.config.logs.exposeHttpdLogs }} - name: httpdlog mountPath: /var/log/httpd - {{- if .Values.service.useSSL }} + {{- end }} + {{- if .Values.config.logs.exposeWebuiLogs }} + - name: webui-log + mountPath: /root/.pm2/logs/ + {{- end }} + {{- if .Values.useSSL }} - name: hostcert mountPath: /etc/grid-security/hostcert.pem subPath: hostcert.pem @@ -123,19 +136,19 @@ spec: - name: RUCIO_HTTPD_{{ $key | snakecase | upper }} value: {{ $val | quote }} {{- end }} - {{- range $key, $val := .Values.config.httpdWebui }} - - name: RUCIO_{{ $key | snakecase | upper }} + {{- range $key, $val := .Values.config.webui }} + - name: RUCIO_WEBUI_{{ $key | snakecase | upper }} value: {{ $val | quote }} {{- end }} - {{ range $i, $provider := .Values.config.oidcProviders }} - {{- range $key, $val := $provider }} - - name: RUCIO_CFG_OIDC_REACT_APP_{{ $key | snakecase | upper }}_{{ $i }} + {{ range $provider, $data := .Values.config.oidc_providers }} + {{- range $key, $val := $data }} + - name: RUCIO_WEBUI_OIDC_PROVIDER_{{ $provider | snakecase | upper }}_{{ $key | snakecase | upper}} value: {{ $val | quote }} {{- end }} {{- end }} - {{- range $key, $val := .Values.config.react }} - {{- if and (ne $key "rucioHost") (ne $key "rucioAuthHost") }} - - name: {{ $key | upper }} + {{ range $vo, $data := .Values.config.vo }} + {{- range $key, $val := $data }} + - name: RUCIO_WEBUI_VO_{{ $vo | snakecase | upper }}_{{ $key | snakecase | upper}} value: {{ $val | quote }} {{- end }} {{- end }} @@ -143,19 +156,21 @@ spec: - name: {{ $key1 | upper }} value: "{{ $val1 }}" {{- end}} - - name: RUCIO_HOST - value: {{ required "A valid rucioHost value pointing to the rucio server is required" .Values.config.react.rucioHost }} - - name: RUCIO_AUTH_HOST - value: {{ required "A valid rucioAuthHost value pointing to the rucio auth server is required" .Values.config.react.rucioAuthHost }} - - name: RUCIO_OVERRIDE_CONFIGS - value: "/opt/rucio/etc/conf.d/" + - name: RUCIO_WEBUI_RUCIO_HOST + value: {{ required "A valid rucioHost value pointing to the rucio server is required" .Values.config.webui.rucio_host }} + - name: RUCIO_WEBUI_RUCIO_AUTH_HOST + value: {{ required "A valid rucioAuthHost value pointing to the rucio auth server is required" .Values.config.webui.rucio_auth_host }} + - name: RUCIO_LOG_LEVEL + value: "INFO" + - name: RUCIO_ENABLE_LOGS + value: "True" - name: RUCIO_LOG_FORMAT value: '[%{%Y-%m-%d %H:%M:%S}t]\t%v\t%h\t%{X-Forwarded-For}i\t%{X-Rucio-RequestId}i\t%>s\t%I\t%B\t%D\t\"%r\"\t\"%{X-Rucio-Auth-Token}i\"\t\"%{User-Agent}i\"\t%{X-Rucio-Script}i' - {{- if not .Values.service.useSSL }} - - name: RUCIO_ENABLE_SSL + {{- if not .Values.useSSL }} + - name: RUCIO_WEBUI_ENABLE_SSL value: "False" {{- else }} - - name: RUCIO_ENABLE_SSL + - name: RUCIO_WEBUI_ENABLE_SSL value: "True" {{- end }} resources: @@ -164,7 +179,7 @@ spec: imagePullSecrets: {{ toYaml . | indent 6 }} {{- end}} - {{- with .Values.nodeSelector }} +{{- with .Values.nodeSelector }} nodeSelector: {{ toYaml . | indent 8 }} {{- end }} diff --git a/charts/rucio-webui/templates/service.yaml b/charts/rucio-webui/templates/service.yaml index 43f0286..5ac633a 100644 --- a/charts/rucio-webui/templates/service.yaml +++ b/charts/rucio-webui/templates/service.yaml @@ -13,16 +13,28 @@ metadata: {{ toYaml . | indent 4 }} {{- end }} spec: - type: {{ $.Values.service.type }} + type: {{ .Values.service.type }} ports: - - port: {{ ternary 443 80 $.Values.service.useSSL }} - targetPort: {{ ternary "https" "http" $.Values.service.useSSL }} - protocol: TCP - {{- if $.Values.service.nodePort }} - nodePort: {{ $.Values.service.nodePort }} - {{- end }} - name: {{ ternary "https" "http" $.Values.service.useSSL }} + - port: {{ .Values.service.port }} + targetPort: {{ .Values.service.targetPort }} + protocol: {{ .Values.service.protocol }} + name: {{ .Values.service.name }} selector: app: {{ template "rucio.name" . }} release: {{ .Release.Name }} +{{- if .Values.service.nodePort }} + nodePort: {{ .Values.service.nodePort }} +{{- end }} +{{- if .Values.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} +{{- end }} +{{- if .Values.service.loadBalancerClass }} + loadBalancerClass: {{ .Values.service.loadBalancerClass }} +{{- end }} +{{- if .Values.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }} +{{- end }} +{{- if not .Values.service.allocateLoadBalancerNodePorts }} + allocateLoadBalancerNodePorts: {{ .Values.service.allocateLoadBalancerNodePorts }} +{{- end }} {{- end }} \ No newline at end of file diff --git a/charts/rucio-webui/values.yaml b/charts/rucio-webui/values.yaml index 16dae54..8cbf7c2 100644 --- a/charts/rucio-webui/values.yaml +++ b/charts/rucio-webui/values.yaml @@ -1,10 +1,7 @@ -# Default values for rucio. +# Default values for rucio webui. # This is a YAML-formatted file. # Declare variables to be passed into your templates. -# When set, run extra busybox containers in the relevant pods to also expose the error logs -exposeErrorLogs: True - # replicaCount gives the number of server pods to run replicaCount: 1 @@ -18,17 +15,29 @@ minReadySeconds: 5 image: repository: rucio/rucio-webui - tag: release-1.30.0 + tag: release-33.0.0 pullPolicy: Always imagePullSecrets: [] # - name: docker-regcreds +useSSL: true + service: - type: NodePort - # Run the webui server on port 443 instead of 80 and accept X509 certificates - useSSL: true - # nodePort: + type: ClusterIP + port: 80 + targetPort: 80 + protocol: TCP + name: http + annotations: + {} + # loadbalancer.openstack.org/network-id: "" + # service.beta.kubernetes.io/openstack-internal-load-balancer: "true" + # loadbalancer.openstack.org/cascade-delete: "false" + loadBalancerIP: null + loadBalancerClass: null + externalTrafficPolicy: null + allocateLoadBalancerNodePorts: true ingress: enabled: false @@ -38,7 +47,6 @@ ingress: nginx.ingress.kubernetes.io/ssl-redirect: "true" path: / hosts: [] - # - my.rucio.test secretMounts: [] # - volumeName: gcssecret @@ -49,53 +57,69 @@ secretMounts: [] config: ## values used to configure apache, sets environment variables in the webui container that begin with RUCIO_HTTPD_ httpd: - legacy_dn: "False" - # mpm_mode: "event" - # start_servers: "1" - # min_spare_threads: "1" - # max_spare_threads: "20" - # threads_per_child: "5" - # max_clients: "20" - # max_requests_per_child: "8192" - # timeout: 300 - # min_spare_servers: "1" - # max_spare_servers: "5" - # server_limit: "10" - # keep_alive: "On" - # keep_alive_timeout: "5" - # max_keep_alive_requests: "128" - # threads_limit: "128" - # max_request_workers: "1280" - # max_connections_per_child: "2048" + mpm_mode: "event" + start_servers: "1" + min_spare_threads: "1" + max_spare_threads: "20" + threads_per_child: "5" + max_clients: "20" + max_requests_per_child: "8192" + timeout: 300 + min_spare_servers: "1" + max_spare_servers: "5" + server_limit: "10" + keep_alive: "On" + keep_alive_timeout: "5" + max_keep_alive_requests: "128" + threads_limit: "128" + max_request_workers: "1280" + max_connections_per_child: "2048" ## Rucio WebUI specific configuration for apache - httpdWebui: - hostname: kube-playground-7p7333rqr5xx-node-0.cern.ch - # server_admin: - logLevel: 'info' - - ## Configuration for OIDC providers - oidcProviders: # [] - - name: "CERN SSO" - clientId: "rucio-webui" - authorizationEndpoint: "https://login.cern.ch/adfs/oauth2/authorize" - tokenEndpoint: "https://login.cern.ch/adfs/oauth2/token" - redirectUri: "https://rucio-webui.cern.ch/auth/oidc/callback" - scopes: "openid profile email" - - ## Configuration for the WebUI React App - react: - rucioHost: - rucioAuthHost: - # webui_login_page_image_primary: "" Mount the image as secret and set the path here - # webui_login_page_image_secondary: "" Mount the image as secret and set the path here - + webui: + rucio_host: "rucio-server" + rucio_auth_host: "rucio-server" + hostname: "webui-host" + project_url: "https://rucio.cern.ch" + multivo_enabled: "False" + # A csv string of vos containing their short names. For example: "def,atl,cms" + vo_list: "def" + vo_default: "def" + oidc_enabled: "False" + # A csv string of names of supported oidc providers that will be configured in the webui. For example: "cern,indico" + oidc_providers: "" + + oidc_providers: + cern: + client_id: "" + client_secret: "" + authorization_url: "" + token_url: "" + refresh_token_url: "" + userinfo_url: "" + redirect_url: "" + + vo: + def: + name: "default" + oidc_enabled: "False" + oidc_providers: "" + # Example of a second VO + # atl: + # name: "atlas" + # oidc_enabled: "False" + # oidc_providers: "" + + logs: + exposeHttpdLogs: true + exposeWebuiLogs: true # additional environment variables to set in the webui container optionalConfig: {} +persistentVolumes: {} -resources: {} +resources: # limits: # cpu: 100m # memory: 128Mi