Merge branch 'nightly' of https://github.com/Shuffle/Shuffle into automation
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
|
||||
name: helm
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "charts/**"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install apt dependencies
|
||||
run: |
|
||||
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
|
||||
sudo apt-get install apt-transport-https -y --no-install-recommends
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install helm -y --no-install-recommends
|
||||
|
||||
- name: Update helm dependencies
|
||||
run: helm dependency update ./charts/shuffle
|
||||
|
||||
- name: Package Helm chart
|
||||
run: helm package ./charts/shuffle --destination ./charts
|
||||
|
||||
- name: Login to OCI registry (ghcr.io)
|
||||
run: helm registry login ghcr.io --username ${{ github.actor }} --password ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Push helm chart
|
||||
run: helm push ./charts/shuffle-*.tgz oci://ghcr.io/shuffle/shuffle/charts
|
||||
@@ -18,7 +18,7 @@ require (
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/h2non/filetype v1.1.3
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/shuffle/shuffle-shared v0.7.95
|
||||
github.com/shuffle/shuffle-shared v0.8.0
|
||||
golang.org/x/crypto v0.32.0
|
||||
google.golang.org/api v0.176.1
|
||||
google.golang.org/grpc v1.68.1
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
.DS_Store
|
||||
*.tgz
|
||||
charts/
|
||||
@@ -0,0 +1,23 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
extends: default
|
||||
|
||||
rules:
|
||||
line-length: disable
|
||||
braces: disable
|
||||
comments:
|
||||
require-starting-space: true
|
||||
ignore-shebangs: true
|
||||
min-spaces-from-content: 1
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
apiVersion: v2
|
||||
name: shuffle
|
||||
description: A Helm chart for deploying Shuffle on Kubernetes
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: nightly
|
||||
dependencies:
|
||||
- name: common
|
||||
version: ^2.23.0
|
||||
repository: oci://registry-1.docker.io/bitnamicharts
|
||||
- name: opensearch
|
||||
version: ^1.3.0
|
||||
repository: oci://registry-1.docker.io/bitnamicharts
|
||||
condition: opensearch.enabled
|
||||
@@ -0,0 +1,607 @@
|
||||
# Shuffle Helm chart
|
||||
|
||||
## Chart Template
|
||||
|
||||
The Bitnami Chart Template was used for creating this chart:
|
||||
|
||||
https://github.com/bitnami/charts/tree/7e44e64626f5b1fc6d56889cdfdeadc1f62c7cf1/template/CHART_NAME
|
||||
|
||||
Original license text:
|
||||
|
||||
```
|
||||
Copyright Broadcom, Inc. All Rights Reserved.
|
||||
|
||||
SPDX-License-Identifier: APACHE-2.0
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
# Install shuffle via helm (the shuffle namespace is hardcoded into the shuffle source code)
|
||||
helm install shuffle oci://ghcr.io/shuffle/shuffle/charts/shuffle --namespace shuffle --create-namespace
|
||||
```
|
||||
|
||||
Make sure that no other application is deployed to the shuffle namespace, as shuffle deletes kubernetes resources in this namespace.
|
||||
|
||||
Only a single deployment of shuffle is supported per namespace.
|
||||
|
||||
## Uninstallation
|
||||
|
||||
```sh
|
||||
# Uninstall shuffle via helm
|
||||
helm uninstall shuffle --namespace shuffle
|
||||
|
||||
# Remove additional resources created by shuffle (such as workers and apps)
|
||||
kubectl delete svc --namespace shuffle -l "app.kubernetes.io/managed-by in (shuffle-orborus,shuffle-worker)"
|
||||
kubectl delete deploy --namespace shuffle -l "app.kubernetes.io/managed-by in (shuffle-orborus,shuffle-worker)"
|
||||
```
|
||||
|
||||
## Secret Parameters
|
||||
|
||||
The helm chart was designed to not contain any secret data and does not allow configuring secret data using helm values.
|
||||
Instead, secret values must be passed to services using `extraEnvVarsSecret` or `extraEnvVars`.
|
||||
|
||||
The secrets need to be manually created. It is possible to run this helm chart without specifying any secrets.
|
||||
You will be prompted to create an admin user when visiting the shuffle dashboard for the first time.
|
||||
Note that information will not be encrypted without specifying the `SHUFFLE_ENCRYPTION_MODIFIER` value.
|
||||
|
||||
### Mounting env variables into a service
|
||||
|
||||
After creating secrets which hold sensitive information, you can mount them as environment variables into a
|
||||
service via the `extraEnvVarsSecret` or `extraEnvVars` values.
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
# Use a single secret, which holds environment variables.
|
||||
# Remember that the secret keys must exactly match the environment variable names.
|
||||
extraEnvVarsSecret: shuffle-backend-env
|
||||
|
||||
# Or mount each value explicitly
|
||||
extraEnvVars:
|
||||
- name: SHUFFLE_DEFAULT_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "shuffle-initial-user"
|
||||
key: username
|
||||
- name: SHUFFLE_DEFAULT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "shuffle-initial-user"
|
||||
key: password
|
||||
- name: SHUFFLE_DEFAULT_APIKEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "shuffle-initial-user"
|
||||
key: apikey
|
||||
- name: SHUFFLE_ENCRYPTION_MODIFIER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "shuffle-encryption"
|
||||
key: modifier
|
||||
```
|
||||
|
||||
### Backend
|
||||
|
||||
A list of environment variables containing secret values for the backend.
|
||||
|
||||
```yaml
|
||||
# OpenSearch password
|
||||
SHUFFLE_OPENSEARCH_PASSWORD: ""
|
||||
|
||||
# Basic auth credentials for downloading apps from git
|
||||
SHUFFLE_DOWNLOAD_AUTH_USERNAME: ""
|
||||
SHUFFLE_DOWNLOAD_AUTH_PASSWORD: ""
|
||||
|
||||
# Automatically create the initial admin user. Username and password have a min length of 3.
|
||||
# If not set, you are prompted with an admin user creation dialog when visiting the shuffle frontend for the first time.
|
||||
SHUFFLE_DEFAULT_USERNAME: admin
|
||||
SHUFFLE_DEFAULT_PASSWORD: MySecretAdminPassword1234!
|
||||
SHUFFLE_DEFAULT_APIKEY: "72E41083-A6F6-4A1B-8538-B06B577F47F0" # Shuffle uses uuid v4
|
||||
|
||||
# Encryption modifier. This HAS to be set to encrypt any authentication being used in Shuffle.
|
||||
# This is put together with other relevant values to ensure multiple parts are needed to decrypt.
|
||||
# If this key is lost or changed, you will have to reauthenticate all apps.
|
||||
# The encryption modifier is added to encrypted values to prevent rainbow table attacks. It can be any random string.
|
||||
SHUFFLE_ENCRYPTION_MODIFIER: "MyShuffleEncryptionModifier"
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
### Global parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||
| `global.imageRegistry` | Global Docker image registry | `""` |
|
||||
| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` |
|
||||
| `global.defaultStorageClass` | Global default StorageClass for Persistent Volume(s) | `""` |
|
||||
| `global.compatibility.openshift.adaptSecurityContext` | Adapt the securityContext sections of the deployment to make them compatible with Openshift restricted-v2 SCC: remove runAsUser, runAsGroup and fsGroup and let the platform use their allowed default IDs. Possible values: auto (apply if the detected running cluster is Openshift), force (perform the adaptation always), disabled (do not perform adaptation) | `auto` |
|
||||
| `global.compatibility.omitEmptySeLinuxOptions` | If set to true, removes the seLinuxOptions from the securityContexts when it is set to an empty object | `false` |
|
||||
|
||||
### Common parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------- | --------------- |
|
||||
| `kubeVersion` | Override Kubernetes version | `""` |
|
||||
| `nameOverride` | String to partially override common.names.name | `""` |
|
||||
| `fullnameOverride` | String to fully override common.names.fullname | `""` |
|
||||
| `namespaceOverride` | String to fully override common.names.namespace | `""` |
|
||||
| `commonLabels` | Labels to add to all deployed objects | `{}` |
|
||||
| `commonAnnotations` | Annotations to add to all deployed objects | `{}` |
|
||||
| `clusterDomain` | Kubernetes cluster domain name | `cluster.local` |
|
||||
| `extraDeploy` | Array of extra objects to deploy with the release | `[]` |
|
||||
| `diagnosticMode.enabled` | Enable diagnostic mode (all probes will be disabled and the command will be overridden) | `false` |
|
||||
| `diagnosticMode.command` | Command to override all containers in the chart release | `["sleep"]` |
|
||||
| `diagnosticMode.args` | Args to override all containers in the chart release | `["infinity"]` |
|
||||
|
||||
### Shared Shuffle Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| --------------------- | ------------------------------------------------------------- | --------------- |
|
||||
| `shuffle.baseUrl` | The external base URL under which Shuffle is reachable. | `""` |
|
||||
| `shuffle.org` | Default shuffle organization | `Shuffle` |
|
||||
| `shuffle.appRegistry` | The registry from / to which shuffle apps are pulled / pushed | `""` |
|
||||
| `shuffle.timezone` | The timezone used by Shuffle | `Europe/Berlin` |
|
||||
|
||||
### backend Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
|
||||
| `backend.image.registry` | backend image registry | `ghcr.io` |
|
||||
| `backend.image.repository` | backend image repository | `shuffle/shuffle-backend` |
|
||||
| `backend.image.digest` | backend image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag image tag (immutable tags are recommended) | `""` |
|
||||
| `backend.image.pullPolicy` | backend image pull policy | `IfNotPresent` |
|
||||
| `backend.image.pullSecrets` | backend image pull secrets | `[]` |
|
||||
| `backend.replicaCount` | Number of backend replicas to deploy | `1` |
|
||||
| `backend.containerPorts.http` | backend HTTP container port | `5001` |
|
||||
| `backend.extraContainerPorts` | Optionally specify extra list of additional ports for backend containers | `[]` |
|
||||
| `backend.livenessProbe.enabled` | Enable livenessProbe on backend containers | `false` |
|
||||
| `backend.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `0` |
|
||||
| `backend.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `15` |
|
||||
| `backend.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `1` |
|
||||
| `backend.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `4` |
|
||||
| `backend.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` |
|
||||
| `backend.readinessProbe.enabled` | Enable readinessProbe on backend containers | `false` |
|
||||
| `backend.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `0` |
|
||||
| `backend.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `5` |
|
||||
| `backend.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `1` |
|
||||
| `backend.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `3` |
|
||||
| `backend.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` |
|
||||
| `backend.startupProbe.enabled` | Enable startupProbe on backend containers | `false` |
|
||||
| `backend.startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `0` |
|
||||
| `backend.startupProbe.periodSeconds` | Period seconds for startupProbe | `1` |
|
||||
| `backend.startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `1` |
|
||||
| `backend.startupProbe.failureThreshold` | Failure threshold for startupProbe | `60` |
|
||||
| `backend.startupProbe.successThreshold` | Success threshold for startupProbe | `1` |
|
||||
| `backend.customLivenessProbe` | Custom livenessProbe that overrides the default one | `{}` |
|
||||
| `backend.customReadinessProbe` | Custom readinessProbe that overrides the default one | `{}` |
|
||||
| `backend.customStartupProbe` | Custom startupProbe that overrides the default one | `{}` |
|
||||
| `backend.resourcesPreset` | Set backend container resources according to one common preset (allowed values: none, nano, small, medium, large, xlarge, 2xlarge). This is ignored if backend.resources is set (backend.resources is recommended for production). | `small` |
|
||||
| `backend.resources` | Set backend container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` |
|
||||
| `backend.podSecurityContext.enabled` | Enable backend pods' Security Context | `true` |
|
||||
| `backend.podSecurityContext.fsGroupChangePolicy` | Set filesystem group change policy for backend pods | `Always` |
|
||||
| `backend.podSecurityContext.sysctls` | Set kernel settings using the sysctl interface for backend pods | `[]` |
|
||||
| `backend.podSecurityContext.supplementalGroups` | Set filesystem extra groups for backend pods | `[]` |
|
||||
| `backend.podSecurityContext.fsGroup` | Set fsGroup in backend pods' Security Context | `1001` |
|
||||
| `backend.containerSecurityContext.enabled` | Enabled backend container' Security Context | `true` |
|
||||
| `backend.containerSecurityContext.seLinuxOptions` | Set SELinux options in backend container | `{}` |
|
||||
| `backend.containerSecurityContext.runAsUser` | Set runAsUser in backend container' Security Context | `1000` |
|
||||
| `backend.containerSecurityContext.runAsGroup` | Set runAsGroup in backend container' Security Context | `1000` |
|
||||
| `backend.containerSecurityContext.runAsNonRoot` | Set runAsNonRoot in backend container' Security Context | `true` |
|
||||
| `backend.containerSecurityContext.readOnlyRootFilesystem` | Set readOnlyRootFilesystem in backend container' Security Context | `true` |
|
||||
| `backend.containerSecurityContext.privileged` | Set privileged in backend container' Security Context | `false` |
|
||||
| `backend.containerSecurityContext.allowPrivilegeEscalation` | Set allowPrivilegeEscalation in backend container' Security Context | `false` |
|
||||
| `backend.containerSecurityContext.capabilities.drop` | List of capabilities to be dropped in backend container | `["ALL"]` |
|
||||
| `backend.containerSecurityContext.seccompProfile.type` | Set seccomp profile in backend container | `RuntimeDefault` |
|
||||
| `backend.command` | Override default backend container command (useful when using custom images) | `[]` |
|
||||
| `backend.args` | Override default backend container args (useful when using custom images) | `[]` |
|
||||
| `backend.automountServiceAccountToken` | Mount Service Account token in backend pods | `true` |
|
||||
| `backend.hostAliases` | backend pods host aliases | `[]` |
|
||||
| `backend.daemonsetAnnotations` | Annotations for backend daemonset | `{}` |
|
||||
| `backend.deploymentAnnotations` | Annotations for backend deployment | `{}` |
|
||||
| `backend.statefulsetAnnotations` | Annotations for backend statefulset | `{}` |
|
||||
| `backend.podLabels` | Extra labels for backend pods | `{}` |
|
||||
| `backend.podAnnotations` | Annotations for backend pods | `{}` |
|
||||
| `backend.podAffinityPreset` | Pod affinity preset. Ignored if `backend.affinity` is set. Allowed values: `soft` or `hard` | `""` |
|
||||
| `backend.podAntiAffinityPreset` | Pod anti-affinity preset. Ignored if `backend.affinity` is set. Allowed values: `soft` or `hard` | `soft` |
|
||||
| `backend.nodeAffinityPreset.type` | Node affinity preset type. Ignored if `backend.affinity` is set. Allowed values: `soft` or `hard` | `""` |
|
||||
| `backend.nodeAffinityPreset.key` | Node label key to match. Ignored if `backend.affinity` is set | `""` |
|
||||
| `backend.nodeAffinityPreset.values` | Node label values to match. Ignored if `backend.affinity` is set | `[]` |
|
||||
| `backend.affinity` | Affinity for backend pods assignment | `{}` |
|
||||
| `backend.nodeSelector` | Node labels for backend pods assignment | `{}` |
|
||||
| `backend.tolerations` | Tolerations for backend pods assignment | `[]` |
|
||||
| `backend.updateStrategy.type` | backend deployment strategy type | `RollingUpdate` |
|
||||
| `backend.updateStrategy.type` | backend statefulset strategy type | `RollingUpdate` |
|
||||
| `backend.podManagementPolicy` | Pod management policy for backend statefulset | `OrderedReady` |
|
||||
| `backend.priorityClassName` | backend pods' priorityClassName | `""` |
|
||||
| `backend.topologySpreadConstraints` | Topology Spread Constraints for backend pod assignment spread across your cluster among failure-domains | `[]` |
|
||||
| `backend.schedulerName` | Name of the k8s scheduler (other than default) for backend pods | `""` |
|
||||
| `backend.terminationGracePeriodSeconds` | Seconds backend pods need to terminate gracefully | `""` |
|
||||
| `backend.lifecycleHooks` | for backend containers to automate configuration before or after startup | `{}` |
|
||||
| `backend.extraEnvVars` | Array with extra environment variables to add to backend containers | `[]` |
|
||||
| `backend.extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars for backend containers | `""` |
|
||||
| `backend.extraEnvVarsSecret` | Name of existing Secret containing extra env vars for backend containers | `""` |
|
||||
| `backend.extraVolumes` | Optionally specify extra list of additional volumes for the backend pods | `[]` |
|
||||
| `backend.extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for the backend containers | `[]` |
|
||||
| `backend.sidecars` | Add additional sidecar containers to the backend pods | `[]` |
|
||||
| `backend.initContainers` | Add additional init containers to the backend pods | `[]` |
|
||||
| `backend.pdb.create` | Enable/disable a Pod Disruption Budget creation | `true` |
|
||||
| `backend.pdb.minAvailable` | Minimum number/percentage of pods that should remain scheduled | `""` |
|
||||
| `backend.pdb.maxUnavailable` | Maximum number/percentage of pods that may be made unavailable. Defaults to `1` if both `backend.pdb.minAvailable` and `backend.pdb.maxUnavailable` are empty. | `""` |
|
||||
| `backend.autoscaling.vpa.enabled` | Enable VPA for backend pods | `false` |
|
||||
| `backend.autoscaling.vpa.annotations` | Annotations for VPA resource | `{}` |
|
||||
| `backend.autoscaling.vpa.controlledResources` | VPA List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory | `[]` |
|
||||
| `backend.autoscaling.vpa.maxAllowed` | VPA Max allowed resources for the pod | `{}` |
|
||||
| `backend.autoscaling.vpa.minAllowed` | VPA Min allowed resources for the pod | `{}` |
|
||||
| `backend.autoscaling.vpa.updatePolicy.updateMode` | Autoscaling update policy | `Auto` |
|
||||
| `backend.autoscaling.hpa.enabled` | Enable HPA for backend pods | `false` |
|
||||
| `backend.autoscaling.hpa.minReplicas` | Minimum number of replicas | `""` |
|
||||
| `backend.autoscaling.hpa.maxReplicas` | Maximum number of replicas | `""` |
|
||||
| `backend.autoscaling.hpa.targetCPU` | Target CPU utilization percentage | `""` |
|
||||
| `backend.autoscaling.hpa.targetMemory` | Target Memory utilization percentage | `""` |
|
||||
| `backend.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` |
|
||||
| `backend.serviceAccount.name` | The name of the ServiceAccount to use. | `""` |
|
||||
| `backend.serviceAccount.annotations` | Additional Service Account annotations (evaluated as a template) | `{}` |
|
||||
| `backend.serviceAccount.automountServiceAccountToken` | Automount service account token for the backend service account | `true` |
|
||||
| `backend.serviceAccount.imagePullSecrets` | Add image pull secrets to the backend service account | `[]` |
|
||||
| `backend.rbac.create` | Specifies whether RBAC resources should be created | `true` |
|
||||
| `backend.networkPolicy.enabled` | Specifies whether a NetworkPolicy should be created | `true` |
|
||||
| `backend.networkPolicy.allowExternal` | Don't require server label for connections | `true` |
|
||||
| `backend.networkPolicy.allowExternalEgress` | Allow the pod to access any range of port and all destinations. | `true` |
|
||||
| `backend.networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` |
|
||||
| `backend.networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy (ignored if allowExternalEgress=true) | `[]` |
|
||||
| `backend.cleanupSchedule` | The interval in seconds at which the cleanup job runs | `300` |
|
||||
| `backend.openSearch.url` | The URL at which OpenSearch is available | `http://{{ .Release.Name }}-opensearch:9200` |
|
||||
| `backend.openSearch.username` | The username that is used for authenticating with OpenSearch | `admin` |
|
||||
| `backend.openSearch.certificateFile` | The path to a custom OpenSearch certificate file | `""` |
|
||||
| `backend.openSearch.skipSSLVerify` | Skip SSL verification | `false` |
|
||||
| `backend.openSearch.indexPrefix` | A prefix for OpenSearch indices | `""` |
|
||||
| `backend.apps.downloadLocation` | The location to a git repository from which default appps are downloaded on startup. | `https://github.com/shuffle/python-apps` |
|
||||
| `backend.apps.downloadBranch` | The branch from which apps should be downloaded on startup. | `master` |
|
||||
| `backend.apps.forceUpdate` | Force an update of apps on startup. | `false` |
|
||||
|
||||
### frontend Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
|
||||
| `frontend.image.registry` | frontend image registry | `ghcr.io` |
|
||||
| `frontend.image.repository` | frontend image repository | `shuffle/shuffle-frontend` |
|
||||
| `frontend.image.digest` | frontend image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag image tag (immutable tags are recommended) | `""` |
|
||||
| `frontend.image.pullPolicy` | frontend image pull policy | `IfNotPresent` |
|
||||
| `frontend.image.pullSecrets` | frontend image pull secrets | `[]` |
|
||||
| `frontend.replicaCount` | Number of frontend replicas to deploy | `1` |
|
||||
| `frontend.containerPorts.http` | frontend HTTP container port | `80` |
|
||||
| `frontend.containerPorts.https` | frontend HTTPS container port | `443` |
|
||||
| `frontend.extraContainerPorts` | Optionally specify extra list of additional ports for frontend containers | `[]` |
|
||||
| `frontend.livenessProbe.enabled` | Enable livenessProbe on frontend containers | `false` |
|
||||
| `frontend.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `0` |
|
||||
| `frontend.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `15` |
|
||||
| `frontend.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `1` |
|
||||
| `frontend.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `4` |
|
||||
| `frontend.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` |
|
||||
| `frontend.readinessProbe.enabled` | Enable readinessProbe on frontend containers | `false` |
|
||||
| `frontend.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `0` |
|
||||
| `frontend.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `5` |
|
||||
| `frontend.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `1` |
|
||||
| `frontend.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `3` |
|
||||
| `frontend.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` |
|
||||
| `frontend.startupProbe.enabled` | Enable startupProbe on frontend containers | `false` |
|
||||
| `frontend.startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `0` |
|
||||
| `frontend.startupProbe.periodSeconds` | Period seconds for startupProbe | `1` |
|
||||
| `frontend.startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `1` |
|
||||
| `frontend.startupProbe.failureThreshold` | Failure threshold for startupProbe | `60` |
|
||||
| `frontend.startupProbe.successThreshold` | Success threshold for startupProbe | `1` |
|
||||
| `frontend.customLivenessProbe` | Custom livenessProbe that overrides the default one | `{}` |
|
||||
| `frontend.customReadinessProbe` | Custom readinessProbe that overrides the default one | `{}` |
|
||||
| `frontend.customStartupProbe` | Custom startupProbe that overrides the default one | `{}` |
|
||||
| `frontend.resourcesPreset` | Set frontend container resources according to one common preset (allowed values: none, nano, small, medium, large, xlarge, 2xlarge). This is ignored if frontend.resources is set (frontend.resources is recommended for production). | `nano` |
|
||||
| `frontend.resources` | Set frontend container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` |
|
||||
| `frontend.podSecurityContext.enabled` | Enable frontend pods' Security Context | `false` |
|
||||
| `frontend.podSecurityContext.fsGroupChangePolicy` | Set filesystem group change policy for frontend pods | `Always` |
|
||||
| `frontend.podSecurityContext.sysctls` | Set kernel settings using the sysctl interface for frontend pods | `[]` |
|
||||
| `frontend.podSecurityContext.supplementalGroups` | Set filesystem extra groups for frontend pods | `[]` |
|
||||
| `frontend.podSecurityContext.fsGroup` | Set fsGroup in frontend pods' Security Context | `1001` |
|
||||
| `frontend.containerSecurityContext.enabled` | Enabled frontend container' Security Context | `false` |
|
||||
| `frontend.containerSecurityContext.seLinuxOptions` | Set SELinux options in frontend container | `{}` |
|
||||
| `frontend.containerSecurityContext.runAsUser` | Set runAsUser in frontend container' Security Context | `101` |
|
||||
| `frontend.containerSecurityContext.runAsGroup` | Set runAsGroup in frontend container' Security Context | `101` |
|
||||
| `frontend.containerSecurityContext.runAsNonRoot` | Set runAsNonRoot in frontend container' Security Context | `true` |
|
||||
| `frontend.containerSecurityContext.readOnlyRootFilesystem` | Set readOnlyRootFilesystem in frontend container' Security Context | `true` |
|
||||
| `frontend.containerSecurityContext.privileged` | Set privileged in frontend container' Security Context | `false` |
|
||||
| `frontend.containerSecurityContext.allowPrivilegeEscalation` | Set allowPrivilegeEscalation in frontend container' Security Context | `false` |
|
||||
| `frontend.containerSecurityContext.capabilities.drop` | List of capabilities to be dropped in frontend container | `["ALL"]` |
|
||||
| `frontend.containerSecurityContext.seccompProfile.type` | Set seccomp profile in frontend container | `RuntimeDefault` |
|
||||
| `frontend.command` | Override default frontend container command (useful when using custom images) | `[]` |
|
||||
| `frontend.args` | Override default frontend container args (useful when using custom images) | `[]` |
|
||||
| `frontend.automountServiceAccountToken` | Mount Service Account token in frontend pods | `false` |
|
||||
| `frontend.hostAliases` | frontend pods host aliases | `[]` |
|
||||
| `frontend.daemonsetAnnotations` | Annotations for frontend daemonset | `{}` |
|
||||
| `frontend.deploymentAnnotations` | Annotations for frontend deployment | `{}` |
|
||||
| `frontend.statefulsetAnnotations` | Annotations for frontend statefulset | `{}` |
|
||||
| `frontend.podLabels` | Extra labels for frontend pods | `{}` |
|
||||
| `frontend.podAnnotations` | Annotations for frontend pods | `{}` |
|
||||
| `frontend.podAffinityPreset` | Pod affinity preset. Ignored if `frontend.affinity` is set. Allowed values: `soft` or `hard` | `""` |
|
||||
| `frontend.podAntiAffinityPreset` | Pod anti-affinity preset. Ignored if `frontend.affinity` is set. Allowed values: `soft` or `hard` | `soft` |
|
||||
| `frontend.nodeAffinityPreset.type` | Node affinity preset type. Ignored if `frontend.affinity` is set. Allowed values: `soft` or `hard` | `""` |
|
||||
| `frontend.nodeAffinityPreset.key` | Node label key to match. Ignored if `frontend.affinity` is set | `""` |
|
||||
| `frontend.nodeAffinityPreset.values` | Node label values to match. Ignored if `frontend.affinity` is set | `[]` |
|
||||
| `frontend.affinity` | Affinity for frontend pods assignment | `{}` |
|
||||
| `frontend.nodeSelector` | Node labels for frontend pods assignment | `{}` |
|
||||
| `frontend.tolerations` | Tolerations for frontend pods assignment | `[]` |
|
||||
| `frontend.updateStrategy.type` | frontend deployment strategy type | `RollingUpdate` |
|
||||
| `frontend.updateStrategy.type` | frontend statefulset strategy type | `RollingUpdate` |
|
||||
| `frontend.podManagementPolicy` | Pod management policy for frontend statefulset | `OrderedReady` |
|
||||
| `frontend.priorityClassName` | frontend pods' priorityClassName | `""` |
|
||||
| `frontend.topologySpreadConstraints` | Topology Spread Constraints for frontend pod assignment spread across your cluster among failure-domains | `[]` |
|
||||
| `frontend.schedulerName` | Name of the k8s scheduler (other than default) for frontend pods | `""` |
|
||||
| `frontend.terminationGracePeriodSeconds` | Seconds frontend pods need to terminate gracefully | `""` |
|
||||
| `frontend.lifecycleHooks` | for frontend containers to automate configuration before or after startup | `{}` |
|
||||
| `frontend.extraEnvVars` | Array with extra environment variables to add to frontend containers | `[]` |
|
||||
| `frontend.extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars for frontend containers | `""` |
|
||||
| `frontend.extraEnvVarsSecret` | Name of existing Secret containing extra env vars for frontend containers | `""` |
|
||||
| `frontend.extraVolumes` | Optionally specify extra list of additional volumes for the frontend pods | `[]` |
|
||||
| `frontend.extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for the frontend containers | `[]` |
|
||||
| `frontend.sidecars` | Add additional sidecar containers to the frontend pods | `[]` |
|
||||
| `frontend.initContainers` | Add additional init containers to the frontend pods | `[]` |
|
||||
| `frontend.pdb.create` | Enable/disable a Pod Disruption Budget creation | `true` |
|
||||
| `frontend.pdb.minAvailable` | Minimum number/percentage of pods that should remain scheduled | `""` |
|
||||
| `frontend.pdb.maxUnavailable` | Maximum number/percentage of pods that may be made unavailable. Defaults to `1` if both `frontend.pdb.minAvailable` and `frontend.pdb.maxUnavailable` are empty. | `""` |
|
||||
| `frontend.autoscaling.vpa.enabled` | Enable VPA for frontend pods | `false` |
|
||||
| `frontend.autoscaling.vpa.annotations` | Annotations for VPA resource | `{}` |
|
||||
| `frontend.autoscaling.vpa.controlledResources` | VPA List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory | `[]` |
|
||||
| `frontend.autoscaling.vpa.maxAllowed` | VPA Max allowed resources for the pod | `{}` |
|
||||
| `frontend.autoscaling.vpa.minAllowed` | VPA Min allowed resources for the pod | `{}` |
|
||||
| `frontend.autoscaling.vpa.updatePolicy.updateMode` | Autoscaling update policy | `Auto` |
|
||||
| `frontend.autoscaling.hpa.enabled` | Enable HPA for frontend pods | `false` |
|
||||
| `frontend.autoscaling.hpa.minReplicas` | Minimum number of replicas | `""` |
|
||||
| `frontend.autoscaling.hpa.maxReplicas` | Maximum number of replicas | `""` |
|
||||
| `frontend.autoscaling.hpa.targetCPU` | Target CPU utilization percentage | `""` |
|
||||
| `frontend.autoscaling.hpa.targetMemory` | Target Memory utilization percentage | `""` |
|
||||
| `frontend.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` |
|
||||
| `frontend.serviceAccount.name` | The name of the ServiceAccount to use. | `""` |
|
||||
| `frontend.serviceAccount.annotations` | Additional Service Account annotations (evaluated as a template) | `{}` |
|
||||
| `frontend.serviceAccount.automountServiceAccountToken` | Automount service account token for the frontend service account | `true` |
|
||||
| `frontend.serviceAccount.imagePullSecrets` | Add image pull secrets to the frontend service account | `[]` |
|
||||
| `frontend.networkPolicy.enabled` | Specifies whether a NetworkPolicy should be created | `true` |
|
||||
| `frontend.networkPolicy.allowExternal` | Don't require server label for connections | `true` |
|
||||
| `frontend.networkPolicy.allowExternalEgress` | Allow the pod to access any range of port and all destinations. | `true` |
|
||||
| `frontend.networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` |
|
||||
| `frontend.networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy (ignored if allowExternalEgress=true) | `[]` |
|
||||
|
||||
### orborus Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
|
||||
| `orborus.image.registry` | orborus image registry | `ghcr.io` |
|
||||
| `orborus.image.repository` | orborus image repository | `shuffle/shuffle-orborus` |
|
||||
| `orborus.image.digest` | orborus image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag image tag (immutable tags are recommended) | `""` |
|
||||
| `orborus.image.pullPolicy` | orborus image pull policy | `IfNotPresent` |
|
||||
| `orborus.image.pullSecrets` | orborus image pull secrets | `[]` |
|
||||
| `orborus.replicaCount` | Number of orborus replicas to deploy | `1` |
|
||||
| `orborus.containerPorts.http` | orborus HTTP container port | `8080` |
|
||||
| `orborus.extraContainerPorts` | Optionally specify extra list of additional ports for orborus containers | `[]` |
|
||||
| `orborus.livenessProbe.enabled` | Enable livenessProbe on orborus containers | `false` |
|
||||
| `orborus.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `0` |
|
||||
| `orborus.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `15` |
|
||||
| `orborus.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `1` |
|
||||
| `orborus.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `4` |
|
||||
| `orborus.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` |
|
||||
| `orborus.readinessProbe.enabled` | Enable readinessProbe on orborus containers | `false` |
|
||||
| `orborus.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `0` |
|
||||
| `orborus.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `5` |
|
||||
| `orborus.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `1` |
|
||||
| `orborus.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `3` |
|
||||
| `orborus.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` |
|
||||
| `orborus.startupProbe.enabled` | Enable startupProbe on orborus containers | `false` |
|
||||
| `orborus.startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `0` |
|
||||
| `orborus.startupProbe.periodSeconds` | Period seconds for startupProbe | `1` |
|
||||
| `orborus.startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `1` |
|
||||
| `orborus.startupProbe.failureThreshold` | Failure threshold for startupProbe | `60` |
|
||||
| `orborus.startupProbe.successThreshold` | Success threshold for startupProbe | `1` |
|
||||
| `orborus.customLivenessProbe` | Custom livenessProbe that overrides the default one | `{}` |
|
||||
| `orborus.customReadinessProbe` | Custom readinessProbe that overrides the default one | `{}` |
|
||||
| `orborus.customStartupProbe` | Custom startupProbe that overrides the default one | `{}` |
|
||||
| `orborus.resourcesPreset` | Set orborus container resources according to one common preset (allowed values: none, nano, small, medium, large, xlarge, 2xlarge). This is ignored if orborus.resources is set (orborus.resources is recommended for production). | `nano` |
|
||||
| `orborus.resources` | Set orborus container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` |
|
||||
| `orborus.podSecurityContext.enabled` | Enable orborus pods' Security Context | `true` |
|
||||
| `orborus.podSecurityContext.fsGroupChangePolicy` | Set filesystem group change policy for orborus pods | `Always` |
|
||||
| `orborus.podSecurityContext.sysctls` | Set kernel settings using the sysctl interface for orborus pods | `[]` |
|
||||
| `orborus.podSecurityContext.supplementalGroups` | Set filesystem extra groups for orborus pods | `[]` |
|
||||
| `orborus.podSecurityContext.fsGroup` | Set fsGroup in orborus pods' Security Context | `1001` |
|
||||
| `orborus.containerSecurityContext.enabled` | Enabled orborus container' Security Context | `true` |
|
||||
| `orborus.containerSecurityContext.seLinuxOptions` | Set SELinux options in orborus container | `{}` |
|
||||
| `orborus.containerSecurityContext.runAsUser` | Set runAsUser in orborus container' Security Context | `101` |
|
||||
| `orborus.containerSecurityContext.runAsGroup` | Set runAsGroup in orborus container' Security Context | `101` |
|
||||
| `orborus.containerSecurityContext.runAsNonRoot` | Set runAsNonRoot in orborus container' Security Context | `true` |
|
||||
| `orborus.containerSecurityContext.readOnlyRootFilesystem` | Set readOnlyRootFilesystem in orborus container' Security Context | `true` |
|
||||
| `orborus.containerSecurityContext.privileged` | Set privileged in orborus container' Security Context | `false` |
|
||||
| `orborus.containerSecurityContext.allowPrivilegeEscalation` | Set allowPrivilegeEscalation in orborus container' Security Context | `false` |
|
||||
| `orborus.containerSecurityContext.capabilities.drop` | List of capabilities to be dropped in orborus container | `["ALL"]` |
|
||||
| `orborus.containerSecurityContext.seccompProfile.type` | Set seccomp profile in orborus container | `RuntimeDefault` |
|
||||
| `orborus.command` | Override default orborus container command (useful when using custom images) | `[]` |
|
||||
| `orborus.args` | Override default orborus container args (useful when using custom images) | `[]` |
|
||||
| `orborus.automountServiceAccountToken` | Mount Service Account token in orborus pods | `true` |
|
||||
| `orborus.hostAliases` | orborus pods host aliases | `[]` |
|
||||
| `orborus.daemonsetAnnotations` | Annotations for orborus daemonset | `{}` |
|
||||
| `orborus.deploymentAnnotations` | Annotations for orborus deployment | `{}` |
|
||||
| `orborus.statefulsetAnnotations` | Annotations for orborus statefulset | `{}` |
|
||||
| `orborus.podLabels` | Extra labels for orborus pods | `{}` |
|
||||
| `orborus.podAnnotations` | Annotations for orborus pods | `{}` |
|
||||
| `orborus.podAffinityPreset` | Pod affinity preset. Ignored if `orborus.affinity` is set. Allowed values: `soft` or `hard` | `""` |
|
||||
| `orborus.podAntiAffinityPreset` | Pod anti-affinity preset. Ignored if `orborus.affinity` is set. Allowed values: `soft` or `hard` | `soft` |
|
||||
| `orborus.nodeAffinityPreset.type` | Node affinity preset type. Ignored if `orborus.affinity` is set. Allowed values: `soft` or `hard` | `""` |
|
||||
| `orborus.nodeAffinityPreset.key` | Node label key to match. Ignored if `orborus.affinity` is set | `""` |
|
||||
| `orborus.nodeAffinityPreset.values` | Node label values to match. Ignored if `orborus.affinity` is set | `[]` |
|
||||
| `orborus.affinity` | Affinity for orborus pods assignment | `{}` |
|
||||
| `orborus.nodeSelector` | Node labels for orborus pods assignment | `{}` |
|
||||
| `orborus.tolerations` | Tolerations for orborus pods assignment | `[]` |
|
||||
| `orborus.updateStrategy.type` | orborus deployment strategy type | `RollingUpdate` |
|
||||
| `orborus.updateStrategy.type` | orborus statefulset strategy type | `RollingUpdate` |
|
||||
| `orborus.podManagementPolicy` | Pod management policy for orborus statefulset | `OrderedReady` |
|
||||
| `orborus.priorityClassName` | orborus pods' priorityClassName | `""` |
|
||||
| `orborus.topologySpreadConstraints` | Topology Spread Constraints for orborus pod assignment spread across your cluster among failure-domains | `[]` |
|
||||
| `orborus.schedulerName` | Name of the k8s scheduler (other than default) for orborus pods | `""` |
|
||||
| `orborus.terminationGracePeriodSeconds` | Seconds orborus pods need to terminate gracefully | `""` |
|
||||
| `orborus.lifecycleHooks` | for orborus containers to automate configuration before or after startup | `{}` |
|
||||
| `orborus.extraEnvVars` | Array with extra environment variables to add to orborus containers | `[]` |
|
||||
| `orborus.extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars for orborus containers | `""` |
|
||||
| `orborus.extraEnvVarsSecret` | Name of existing Secret containing extra env vars for orborus containers | `""` |
|
||||
| `orborus.extraVolumes` | Optionally specify extra list of additional volumes for the orborus pods | `[]` |
|
||||
| `orborus.extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for the orborus containers | `[]` |
|
||||
| `orborus.sidecars` | Add additional sidecar containers to the orborus pods | `[]` |
|
||||
| `orborus.initContainers` | Add additional init containers to the orborus pods | `[]` |
|
||||
| `orborus.pdb.create` | Enable/disable a Pod Disruption Budget creation | `true` |
|
||||
| `orborus.pdb.minAvailable` | Minimum number/percentage of pods that should remain scheduled | `""` |
|
||||
| `orborus.pdb.maxUnavailable` | Maximum number/percentage of pods that may be made unavailable. Defaults to `1` if both `orborus.pdb.minAvailable` and `orborus.pdb.maxUnavailable` are empty. | `""` |
|
||||
| `orborus.autoscaling.vpa.enabled` | Enable VPA for orborus pods | `false` |
|
||||
| `orborus.autoscaling.vpa.annotations` | Annotations for VPA resource | `{}` |
|
||||
| `orborus.autoscaling.vpa.controlledResources` | VPA List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory | `[]` |
|
||||
| `orborus.autoscaling.vpa.maxAllowed` | VPA Max allowed resources for the pod | `{}` |
|
||||
| `orborus.autoscaling.vpa.minAllowed` | VPA Min allowed resources for the pod | `{}` |
|
||||
| `orborus.autoscaling.vpa.updatePolicy.updateMode` | Autoscaling update policy | `Auto` |
|
||||
| `orborus.autoscaling.hpa.enabled` | Enable HPA for orborus pods | `false` |
|
||||
| `orborus.autoscaling.hpa.minReplicas` | Minimum number of replicas | `""` |
|
||||
| `orborus.autoscaling.hpa.maxReplicas` | Maximum number of replicas | `""` |
|
||||
| `orborus.autoscaling.hpa.targetCPU` | Target CPU utilization percentage | `""` |
|
||||
| `orborus.autoscaling.hpa.targetMemory` | Target Memory utilization percentage | `""` |
|
||||
| `orborus.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` |
|
||||
| `orborus.serviceAccount.name` | The name of the ServiceAccount to use. | `""` |
|
||||
| `orborus.serviceAccount.annotations` | Additional Service Account annotations (evaluated as a template) | `{}` |
|
||||
| `orborus.serviceAccount.automountServiceAccountToken` | Automount service account token for the orborus service account | `true` |
|
||||
| `orborus.serviceAccount.imagePullSecrets` | Add image pull secrets to the orborus service account | `[]` |
|
||||
| `orborus.rbac.create` | Specifies whether RBAC resources should be created | `true` |
|
||||
| `orborus.networkPolicy.enabled` | Specifies whether a NetworkPolicy should be created | `true` |
|
||||
| `orborus.networkPolicy.allowExternal` | Don't require server label for connections | `true` |
|
||||
| `orborus.networkPolicy.allowExternalEgress` | Allow the pod to access any range of port and all destinations. | `true` |
|
||||
| `orborus.networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` |
|
||||
| `orborus.networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy (ignored if allowExternalEgress=true) | `[]` |
|
||||
|
||||
### worker Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
|
||||
| `worker.image.registry` | worker image registry | `ghcr.io` |
|
||||
| `worker.image.repository` | worker image repository | `shuffle/shuffle-worker` |
|
||||
| `worker.image.digest` | worker image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag image tag (immutable tags are recommended) | `""` |
|
||||
| `worker.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` |
|
||||
| `worker.serviceAccount.name` | The name of the ServiceAccount to use. | `""` |
|
||||
| `worker.serviceAccount.annotations` | Additional Service Account annotations (evaluated as a template) | `{}` |
|
||||
| `worker.serviceAccount.automountServiceAccountToken` | Automount service account token for the worker service account | `true` |
|
||||
| `worker.serviceAccount.imagePullSecrets` | Add image pull secrets to the worker service account | `[]` |
|
||||
| `worker.rbac.create` | Specifies whether RBAC resources should be created | `true` |
|
||||
| `worker.networkPolicy.enabled` | Specifies whether a NetworkPolicy should be created | `true` |
|
||||
| `worker.networkPolicy.allowExternal` | Don't require server label for connections | `true` |
|
||||
| `worker.networkPolicy.allowExternalEgress` | Allow the pod to access any range of port and all destinations. | `true` |
|
||||
| `worker.networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` |
|
||||
| `worker.networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy (ignored if allowExternalEgress=true) | `[]` |
|
||||
|
||||
### app Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| ------------------------------------------------- | ---------------------------------------------------------------------------------- | ------ |
|
||||
| `app.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` |
|
||||
| `app.serviceAccount.name` | The name of the ServiceAccount to use. | `""` |
|
||||
| `app.serviceAccount.annotations` | Additional Service Account annotations (evaluated as a template) | `{}` |
|
||||
| `app.serviceAccount.automountServiceAccountToken` | Automount service account token for the app service account | `true` |
|
||||
| `app.serviceAccount.imagePullSecrets` | Add image pull secrets to the app service account | `[]` |
|
||||
| `app.rbac.create` | Specifies whether RBAC resources should be created | `true` |
|
||||
| `app.networkPolicy.enabled` | Specifies whether a NetworkPolicy should be created | `true` |
|
||||
| `app.networkPolicy.allowExternal` | Don't require server label for connections | `true` |
|
||||
| `app.networkPolicy.allowExternalEgress` | Allow the pod to access any range of port and all destinations. | `true` |
|
||||
| `app.networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` |
|
||||
| `app.networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy (ignored if allowExternalEgress=true) | `[]` |
|
||||
|
||||
### Traffic Exposure Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| -------------------------- | ----------------------------------------------------------------------------------------------------- | --------------- |
|
||||
| `ingress.enabled` | Enable ingress record generation for frontend and backend | `false` |
|
||||
| `ingress.pathType` | Ingress path type for the frontend path | `Prefix` |
|
||||
| `ingress.backendPathType` | Ingress path type for the backend path | `Prefix` |
|
||||
| `ingress.apiVersion` | Force Ingress API version (automatically detected if not set) | `""` |
|
||||
| `ingress.hostname` | Default host for the ingress record | `shuffle.local` |
|
||||
| `ingress.ingressClassName` | IngressClass that will be be used to implement the Ingress (Kubernetes 1.18+) | `nginx` |
|
||||
| `ingress.path` | Ingress path for Shuffle frontend | `"/"` |
|
||||
| `ingress.backendPath` | Ingress path for Shuffle backend | `"/api/"` |
|
||||
| `ingress.annotations` | Additional annotations for the Ingress resource. | `{}` |
|
||||
| `ingress.tls` | Enable TLS configuration for the host defined at `ingress.hostname` parameter | `false` |
|
||||
| `ingress.selfSigned` | Create a TLS secret for this ingress record using self-signed certificates generated by Helm | `false` |
|
||||
| `ingress.extraHosts` | An array with additional hostname(s) to be covered with the ingress record | `[]` |
|
||||
| `ingress.extraPaths` | An array with additional arbitrary paths that may need to be added to the ingress under the main host | `[]` |
|
||||
| `ingress.extraTls` | TLS configuration for additional hostname(s) to be covered with this ingress record | `[]` |
|
||||
| `ingress.secrets` | Custom TLS certificates as secrets | `[]` |
|
||||
| `ingress.extraRules` | Additional rules to be covered with this ingress record | `[]` |
|
||||
|
||||
### Istio Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| --------------------------------------- | ------------------------------------------------------------------------------- | ------------------------ |
|
||||
| `istio.enabled` | Enable creation of an Istio Gateway and VirtualService for frontend and backend | `false` |
|
||||
| `istio.apiVersion` | The istio apiVersion to use for Gateway and VirtualService resources | `networking.istio.io/v1` |
|
||||
| `istio.hosts` | One or more hosts exposed by Istio | `[]` |
|
||||
| `istio.gateway.annotations` | Additional annotations for the Gateway resource | `{}` |
|
||||
| `istio.gateway.selector` | The selector matches the ingress gateway pod labels | `{ istio: ingress }` |
|
||||
| `istio.gateway.http.enabled` | Enable HTTP server port 80 | `true` |
|
||||
| `istio.gateway.http.httpsRedirect` | If set to true, a 301 redirect is send for all HTTP connections | `false` |
|
||||
| `istio.gateway.https.enabled` | Enable HTTPS server on port 443 | `false` |
|
||||
| `istio.gateway.https.tlsCredentialName` | The name of the secret that holds the TLS certs including the CA certificates. | `""` |
|
||||
| `istio.gateway.https.tlsCipherSuites` | If specified, only support the specified cipher list. | `[]` |
|
||||
| `istio.gateway.extraServers` | Additional servers for the Gateway resource | `[]` |
|
||||
| `istio.virtualService.annotations` | Additional annotations for the VirtualService resource. | `{}` |
|
||||
| `istio.virtualService.backendHeaders` | Header manipulation rules for backend traffic | `{}` |
|
||||
| `istio.virtualService.frontendHeaders` | Header manipulation rules for frontend traffic | `{}` |
|
||||
|
||||
### Persistence Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| ------------------------------------- | ------------------------------------------------- | ------------------- |
|
||||
| `persistence.enabled` | Enable persistence using Persistent Volume Claims | `true` |
|
||||
| `persistence.apps.existingClaim` | Name of an existing PVC to use | `""` |
|
||||
| `persistence.apps.storageClass` | PVC Storage Class for shuffle-apps volume | `""` |
|
||||
| `persistence.apps.subPath` | The sub path used in the volume | `""` |
|
||||
| `persistence.apps.accessModes` | The access mode of the volume | `["ReadWriteOnce"]` |
|
||||
| `persistence.apps.size` | The size of the volume | `5Gi` |
|
||||
| `persistence.apps.annotations` | Annotations for the PVC | `{}` |
|
||||
| `persistence.apps.selector` | Selector to match an existing Persistent Volume | `{}` |
|
||||
| `persistence.appBuilder.storageClass` | PVC Storage Class for backend-apps-claim volume | `""` |
|
||||
| `persistence.appBuilder.accessModes` | The access mode of the volume | `["ReadWriteOnce"]` |
|
||||
| `persistence.appBuilder.size` | The size of the volume | `5Gi` |
|
||||
| `persistence.appBuilder.annotations` | Annotations for the PVC | `{}` |
|
||||
| `persistence.appBuilder.selector` | Selector to match an existing Persistent Volume | `{}` |
|
||||
| `persistence.files.existingClaim` | Name of an existing PVC to use | `""` |
|
||||
| `persistence.files.storageClass` | PVC Storage Class for shuffle-files volume | `""` |
|
||||
| `persistence.files.subPath` | The sub path used in the volume | `""` |
|
||||
| `persistence.files.accessModes` | The access mode of the volume | `["ReadWriteOnce"]` |
|
||||
| `persistence.files.size` | The size of the volume | `5Gi` |
|
||||
| `persistence.files.annotations` | Annotations for the PVC | `{}` |
|
||||
| `persistence.files.selector` | Selector to match an existing Persistent Volume | `{}` |
|
||||
|
||||
### Init Container Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
|
||||
| `volumePermissions.enabled` | Enable init container that changes the owner/group of the PV mount point to `runAsUser:fsGroup` | `false` |
|
||||
| `volumePermissions.image.registry` | OS Shell + Utility image registry | `docker.io` |
|
||||
| `volumePermissions.image.repository` | OS Shell + Utility image repository | `bitnami/os-shell` |
|
||||
| `volumePermissions.image.pullPolicy` | OS Shell + Utility image pull policy | `IfNotPresent` |
|
||||
| `volumePermissions.image.pullSecrets` | OS Shell + Utility image pull secrets | `[]` |
|
||||
| `volumePermissions.resourcesPreset` | Set init container resources according to one common preset (allowed values: none, nano, small, medium, large, xlarge, 2xlarge). This is ignored if volumePermissions.resources is set (volumePermissions.resources is recommended for production). | `nano` |
|
||||
| `volumePermissions.resources` | Set init container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` |
|
||||
| `volumePermissions.containerSecurityContext.enabled` | Enabled init container' Security Context | `true` |
|
||||
| `volumePermissions.containerSecurityContext.seLinuxOptions` | Set SELinux options in init container | `{}` |
|
||||
| `volumePermissions.containerSecurityContext.runAsUser` | Set init container's Security Context runAsUser | `0` |
|
||||
|
||||
### OpenSearch Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| -------------------- | ----------------------------------------------------- | ------ |
|
||||
| `opensearch.enabled` | Switch to enable or disable the opensearch helm chart | `true` |
|
||||
|
||||
### Vault Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| --------------- | -------------------------------------------------------------------------- | ----- |
|
||||
| `vault.role` | Specify the Vault role, which should be used to get the secret from Vault. | `""` |
|
||||
| `vault.secrets` | A list of VaultSecrets to create | `[]` |
|
||||
|
||||
### Other Parameters
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
CHART NAME: {{ .Chart.Name }}
|
||||
CHART VERSION: {{ .Chart.Version }}
|
||||
APP VERSION: {{ .Chart.AppVersion }}
|
||||
|
||||
** Please be patient while the chart is being deployed **
|
||||
|
||||
{{- if .Values.diagnosticMode.enabled }}
|
||||
The chart has been deployed in diagnostic mode. All probes have been disabled and the command has been overwritten with:
|
||||
|
||||
command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 4 }}
|
||||
args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 4 }}
|
||||
|
||||
Get the list of pods by executing:
|
||||
|
||||
kubectl get pods --namespace {{ include "common.names.namespace" . | quote }} -l app.kubernetes.io/instance={{ .Release.Name }}
|
||||
|
||||
Access the pod you want to debug by executing
|
||||
|
||||
kubectl exec --namespace {{ include "common.names.namespace" . | quote }} -ti <NAME OF THE POD> -- bash
|
||||
|
||||
{{- end }}
|
||||
|
||||
To access shuffle using port-forwarding:
|
||||
|
||||
1. Run `kubectl port-forward -n shuffle svc/shuffle-frontend 8080:http`
|
||||
2. Visit http://localhost:8080 with your browser
|
||||
|
||||
@@ -0,0 +1,377 @@
|
||||
{{/*
|
||||
Return the common name for backend componentes
|
||||
*/}}
|
||||
{{- define "shuffle.backend.name" -}}
|
||||
{{- printf "%s-backend" (include "common.names.fullname" .) | trunc 63 -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the common name for frontend components
|
||||
*/}}
|
||||
{{- define "shuffle.frontend.name" -}}
|
||||
{{- printf "%s-frontend" (include "common.names.fullname" .) | trunc 63 -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the common name for orborus components
|
||||
*/}}
|
||||
{{- define "shuffle.orborus.name" -}}
|
||||
{{- printf "%s-orborus" (include "common.names.fullname" .) | trunc 63 -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the common name for worker components
|
||||
*/}}
|
||||
{{- define "shuffle.worker.name" -}}
|
||||
{{- printf "%s-worker" (include "common.names.fullname" .) | trunc 63 -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the common name for app components
|
||||
*/}}
|
||||
{{- define "shuffle.app.name" -}}
|
||||
{{- printf "%s-app" (include "common.names.fullname" .) | trunc 63 -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the common labels for backend components
|
||||
The shuffle app builder requires the io.kompose.service=backend label to be set on the backend pod.
|
||||
*/}}
|
||||
{{- define "shuffle.backend.labels" -}}
|
||||
{{- include "common.labels.standard" . }}
|
||||
app.kubernetes.io/component: backend
|
||||
io.kompose.service: backend
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the common labels for frontend components
|
||||
*/}}
|
||||
{{- define "shuffle.frontend.labels" -}}
|
||||
{{- include "common.labels.standard" . }}
|
||||
app.kubernetes.io/component: frontend
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the common labels for orborus components
|
||||
*/}}
|
||||
{{- define "shuffle.orborus.labels" -}}
|
||||
{{- include "common.labels.standard" . }}
|
||||
app.kubernetes.io/component: orborus
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the common labels for worker components
|
||||
*/}}
|
||||
{{- define "shuffle.worker.labels" -}}
|
||||
{{- include "common.labels.standard" . }}
|
||||
app.kubernetes.io/component: worker
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the common labels for app components
|
||||
*/}}
|
||||
{{- define "shuffle.app.labels" -}}
|
||||
{{- include "common.labels.standard" . }}
|
||||
app.kubernetes.io/component: app
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the match labels for backend components
|
||||
*/}}
|
||||
{{- define "shuffle.backend.matchLabels" -}}
|
||||
{{- include "common.labels.matchLabels" . }}
|
||||
app.kubernetes.io/component: backend
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the match labels for frontend components
|
||||
*/}}
|
||||
{{- define "shuffle.frontend.matchLabels" -}}
|
||||
{{- include "common.labels.matchLabels" . }}
|
||||
app.kubernetes.io/component: frontend
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the match labels for orborus components
|
||||
*/}}
|
||||
{{- define "shuffle.orborus.matchLabels" -}}
|
||||
{{- include "common.labels.matchLabels" . }}
|
||||
app.kubernetes.io/component: orborus
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the match labels for worker components
|
||||
NOTE: This does not match the labels from shuffle.worker.labels, but the labels set by the orborus GoLang app.
|
||||
*/}}
|
||||
{{- define "shuffle.worker.matchLabels" -}}
|
||||
app.kubernetes.io/name: shuffle-worker
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the match labels for app components
|
||||
NOTE: This does not match the labels from shuffle.worker.labels, but the labels set by the orborus GoLang app.
|
||||
*/}}
|
||||
{{- define "shuffle.app.matchLabels" -}}
|
||||
app.kubernetes.io/name: shuffle-app
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the proper image name (for the init container volume-permissions image)
|
||||
*/}}
|
||||
{{- define "shuffle.volumePermissions.image" -}}
|
||||
{{- include "common.images.image" ( dict "imageRoot" .Values.volumePermissions.image "global" .Values.global ) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the proper Shuffle backend image name
|
||||
*/}}
|
||||
{{- define "shuffle.backend.image" -}}
|
||||
{{- include "common.images.image" ( dict "imageRoot" .Values.backend.image "global" .Values.global ) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the proper Docker Image Registry Secret Names for the backend pod
|
||||
*/}}
|
||||
{{- define "shuffle.backend.imagePullSecrets" -}}
|
||||
{{- include "common.images.renderPullSecrets" (dict "images" (list .Values.backend.image) "context" $) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the proper Shuffle frontend image name
|
||||
*/}}
|
||||
{{- define "shuffle.frontend.image" -}}
|
||||
{{- include "common.images.image" ( dict "imageRoot" .Values.frontend.image "global" .Values.global ) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the proper Docker Image Registry Secret Names for the frontend pod
|
||||
*/}}
|
||||
{{- define "shuffle.frontend.imagePullSecrets" -}}
|
||||
{{- include "common.images.renderPullSecrets" (dict "images" (list .Values.frontend.image) "context" $) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the proper Shuffle orborus image name
|
||||
*/}}
|
||||
{{- define "shuffle.orborus.image" -}}
|
||||
{{- include "common.images.image" ( dict "imageRoot" .Values.orborus.image "global" .Values.global ) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the proper Docker Image Registry Secret Names for the orborus pod
|
||||
*/}}
|
||||
{{- define "shuffle.orborus.imagePullSecrets" -}}
|
||||
{{- include "common.images.renderPullSecrets" (dict "images" (list .Values.orborus.image) "context" $) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the proper Shuffle worker image name
|
||||
*/}}
|
||||
{{- define "shuffle.worker.image" -}}
|
||||
{{- include "common.images.image" ( dict "imageRoot" .Values.worker.image "global" .Values.global ) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use for the Shuffle backend
|
||||
*/}}
|
||||
{{- define "shuffle.backend.serviceAccount.name" -}}
|
||||
{{- if .Values.backend.serviceAccount.create -}}
|
||||
{{ default (include "shuffle.backend.name" .) .Values.backend.serviceAccount.name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else -}}
|
||||
{{ default "default" .Values.backend.serviceAccount.name }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the proper Docker Image Registry Secret Names for the backend service account
|
||||
*/}}
|
||||
{{- define "shuffle.backend.serviceAccount.imagePullSecrets" -}}
|
||||
{{- $pullSecrets := list }}
|
||||
|
||||
{{- range .Values.global.imagePullSecrets -}}
|
||||
{{- if kindIs "map" . -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" .name "context" .)) -}}
|
||||
{{- else -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" .)) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- range .Values.backend.serviceAccount.imagePullSecrets -}}
|
||||
{{- if kindIs "map" . -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" .name "context" .)) -}}
|
||||
{{- else -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" .)) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if (not (empty $pullSecrets)) -}}
|
||||
imagePullSecrets:
|
||||
{{- range $pullSecrets | uniq }}
|
||||
- name: {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use for the Shuffle frontend
|
||||
*/}}
|
||||
{{- define "shuffle.frontend.serviceAccount.name" -}}
|
||||
{{- if .Values.frontend.serviceAccount.create -}}
|
||||
{{ default (include "shuffle.frontend.name" .) .Values.frontend.serviceAccount.name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else -}}
|
||||
{{ default "default" .Values.frontend.serviceAccount.name }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the proper Docker Image Registry Secret Names for the frontend service account
|
||||
*/}}
|
||||
{{- define "shuffle.frontend.serviceAccount.imagePullSecrets" -}}
|
||||
{{- $pullSecrets := list }}
|
||||
|
||||
{{- range .Values.global.imagePullSecrets -}}
|
||||
{{- if kindIs "map" . -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" .name "context" .)) -}}
|
||||
{{- else -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" .)) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- range .Values.frontend.serviceAccount.imagePullSecrets -}}
|
||||
{{- if kindIs "map" . -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" .name "context" .)) -}}
|
||||
{{- else -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" .)) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if (not (empty $pullSecrets)) -}}
|
||||
imagePullSecrets:
|
||||
{{- range $pullSecrets | uniq }}
|
||||
- name: {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use for Shuffle orborus
|
||||
*/}}
|
||||
{{- define "shuffle.orborus.serviceAccount.name" -}}
|
||||
{{- if .Values.orborus.serviceAccount.create -}}
|
||||
{{ default (include "shuffle.orborus.name" .) .Values.orborus.serviceAccount.name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else -}}
|
||||
{{ default "default" .Values.orborus.serviceAccount.name }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the proper Docker Image Registry Secret Names for the orborus service account
|
||||
*/}}
|
||||
{{- define "shuffle.orborus.serviceAccount.imagePullSecrets" -}}
|
||||
{{- $pullSecrets := list }}
|
||||
|
||||
{{- range .Values.global.imagePullSecrets -}}
|
||||
{{- if kindIs "map" . -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" .name "context" .)) -}}
|
||||
{{- else -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" .)) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- range .Values.orborus.serviceAccount.imagePullSecrets -}}
|
||||
{{- if kindIs "map" . -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" .name "context" .)) -}}
|
||||
{{- else -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" .)) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if (not (empty $pullSecrets)) -}}
|
||||
imagePullSecrets:
|
||||
{{- range $pullSecrets | uniq }}
|
||||
- name: {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use for Shuffle workers
|
||||
*/}}
|
||||
{{- define "shuffle.worker.serviceAccount.name" -}}
|
||||
{{- if .Values.worker.serviceAccount.create -}}
|
||||
{{ default (include "shuffle.worker.name" .) .Values.worker.serviceAccount.name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else -}}
|
||||
{{ default "default" .Values.worker.serviceAccount.name }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the proper Docker Image Registry Secret Names for the worker service account
|
||||
*/}}
|
||||
{{- define "shuffle.worker.serviceAccount.imagePullSecrets" -}}
|
||||
{{- $pullSecrets := list }}
|
||||
|
||||
{{- range .Values.global.imagePullSecrets -}}
|
||||
{{- if kindIs "map" . -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" .name "context" .)) -}}
|
||||
{{- else -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" .)) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- range .Values.worker.serviceAccount.imagePullSecrets -}}
|
||||
{{- if kindIs "map" . -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" .name "context" .)) -}}
|
||||
{{- else -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" .)) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if (not (empty $pullSecrets)) -}}
|
||||
imagePullSecrets:
|
||||
{{- range $pullSecrets | uniq }}
|
||||
- name: {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use for Shuffle apps
|
||||
*/}}
|
||||
{{- define "shuffle.app.serviceAccount.name" -}}
|
||||
{{- if .Values.app.serviceAccount.create -}}
|
||||
{{ default (include "shuffle.app.name" .) .Values.app.serviceAccount.name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else -}}
|
||||
{{ default "default" .Values.app.serviceAccount.name }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the proper Docker Image Registry Secret Names for the app service account
|
||||
*/}}
|
||||
{{- define "shuffle.app.serviceAccount.imagePullSecrets" -}}
|
||||
{{- $pullSecrets := list }}
|
||||
|
||||
{{- range .Values.global.imagePullSecrets -}}
|
||||
{{- if kindIs "map" . -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" .name "context" .)) -}}
|
||||
{{- else -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" .)) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- range .Values.app.serviceAccount.imagePullSecrets -}}
|
||||
{{- if kindIs "map" . -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" .name "context" .)) -}}
|
||||
{{- else -}}
|
||||
{{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" .)) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if (not (empty $pullSecrets)) -}}
|
||||
imagePullSecrets:
|
||||
{{- range $pullSecrets | uniq }}
|
||||
- name: {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,28 @@
|
||||
# This PVC is always enabled, regardless of .Values.persistence.enabled,
|
||||
# as app building does not work without it.
|
||||
kind: PersistentVolumeClaim
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: backend-apps-claim # Hardcoded by shuffle-app-builder
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.backend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
annotations:
|
||||
{{- if eq .Values.persistence.resourcePolicy "keep" }}
|
||||
helm.sh/resource-policy: keep
|
||||
{{- end }}
|
||||
{{- if or .Values.persistence.appBuilder.annotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.persistence.appBuilder.annotations .Values.commonAnnotations ) "context" . ) }}
|
||||
{{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
accessModes:
|
||||
{{- range .Values.persistence.appBuilder.accessModes }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.appBuilder.size }}
|
||||
{{- if .Values.persistence.appBuilder.selector }}
|
||||
selector: {{- include "common.tplvalues.render" (dict "value" .Values.persistence.appBuilder.selector "context" $) | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- include "common.storage.class" ( dict "persistence" .Values.persistence.appBuilder "global" .Values.global ) | nindent 2 }}
|
||||
@@ -0,0 +1,30 @@
|
||||
{{- if .Values.persistence.enabled }}
|
||||
{{- if (not .Values.persistence.apps.existingClaim) }}
|
||||
kind: PersistentVolumeClaim
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: {{ printf "%s-apps" (include "shuffle.backend.name" .) }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.backend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
annotations:
|
||||
{{- if eq .Values.persistence.resourcePolicy "keep" }}
|
||||
helm.sh/resource-policy: keep
|
||||
{{- end }}
|
||||
{{- if or .Values.persistence.apps.annotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.persistence.apps.annotations .Values.commonAnnotations ) "context" . ) }}
|
||||
{{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
accessModes:
|
||||
{{- range .Values.persistence.apps.accessModes }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.apps.size }}
|
||||
{{- if .Values.persistence.apps.selector }}
|
||||
selector: {{- include "common.tplvalues.render" (dict "value" .Values.persistence.apps.selector "context" $) | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- include "common.storage.class" ( dict "persistence" .Values.persistence.apps "global" .Values.global ) | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,30 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "shuffle.backend.name" . }}-env
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.backend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
data:
|
||||
BACKEND_PORT: "5001"
|
||||
{{- if .Values.shuffle.baseUrl }}
|
||||
BASE_URL: "{{ .Values.shuffle.baseUrl }}"
|
||||
SSO_REDIRECT_URL: "{{ .Values.shuffle.baseUrl }}"
|
||||
{{- else }}
|
||||
BASE_URL: "http://{{ include "shuffle.backend.name" . }}:5001"
|
||||
{{- end }}
|
||||
ORG_ID: "{{ .Values.shuffle.org }}"
|
||||
SHUFFLE_APP_DOWNLOAD_LOCATION: "{{ .Values.backend.apps.downloadLocation }}"
|
||||
SHUFFLE_DOWNLOAD_AUTH_BRANCH: "{{ .Values.backend.apps.downloadBranch }}"
|
||||
SHUFFLE_APP_FORCE_UPDATE: "{{ .Values.backend.apps.forceUpdate }}"
|
||||
SHUFFLE_CHAT_DISABLED: "true"
|
||||
SHUFFLE_OPENSEARCH_URL: {{ include "common.tplvalues.render" (dict "value" .Values.backend.openSearch.url "context" $) }}
|
||||
SHUFFLE_OPENSEARCH_USERNAME: "{{ .Values.backend.openSearch.username }}"
|
||||
SHUFFLE_OPENSEARCH_CERTIFICATE_FILE: "{{ .Values.backend.openSearch.certificateFile }}"
|
||||
SHUFFLE_OPENSEARCH_SKIPSSL_VERIFY: "{{ .Values.backend.openSearch.skipSSLVerify }}"
|
||||
SHUFFLE_OPENSEARCH_INDEX_PREFIX: "{{ .Values.backend.openSearch.indexPrefix }}"
|
||||
SHUFFLE_RERUN_SCHEDULE: "{{ .Values.backend.cleanupSchedule }}"
|
||||
TZ: "{{ .Values.shuffle.timezone }}"
|
||||
REGISTRY_URL: "{{ .Values.shuffle.appRegistry }}"
|
||||
@@ -0,0 +1,224 @@
|
||||
apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }}
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ template "shuffle.backend.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.backend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if or .Values.backend.deploymentAnnotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" (dict "values" (list .Values.backend.deploymentAnnotations .Values.commonAnnotations) "context" .) }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if not .Values.backend.autoscaling.hpa.enabled }}
|
||||
replicas: {{ .Values.backend.replicaCount }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.updateStrategy }}
|
||||
strategy: {{- toYaml .Values.backend.updateStrategy | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- $podLabels := include "common.tplvalues.merge" (dict "values" (list .Values.backend.podLabels .Values.commonLabels) "context" .) }}
|
||||
selector:
|
||||
matchLabels: {{- include "shuffle.backend.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- if .Values.backend.podAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" (dict "value" .Values.backend.podAnnotations "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
labels: {{- include "shuffle.backend.labels" ( dict "customLabels" $podLabels "context" $ ) | nindent 8 }}
|
||||
spec:
|
||||
{{- include "shuffle.backend.imagePullSecrets" . | nindent 6 }}
|
||||
serviceAccountName: {{ template "shuffle.backend.serviceAccount.name" . }}
|
||||
automountServiceAccountToken: {{ .Values.backend.automountServiceAccountToken }}
|
||||
{{- if .Values.backend.hostAliases }}
|
||||
hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.backend.hostAliases "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.affinity }}
|
||||
affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.backend.affinity "context" $) | nindent 8 }}
|
||||
{{- else }}
|
||||
affinity:
|
||||
podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.backend.podAffinityPreset "component" "backend" "customLabels" $podLabels "context" $) | nindent 10 }}
|
||||
podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.backend.podAntiAffinityPreset "component" "backend" "customLabels" $podLabels "context" $) | nindent 10 }}
|
||||
nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.backend.nodeAffinityPreset.type "key" .Values.backend.nodeAffinityPreset.key "values" .Values.backend.nodeAffinityPreset.values) | nindent 10 }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.nodeSelector }}
|
||||
nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.backend.nodeSelector "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.tolerations }}
|
||||
tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.backend.tolerations "context" .) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.priorityClassName }}
|
||||
priorityClassName: {{ .Values.backend.priorityClassName | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.schedulerName }}
|
||||
schedulerName: {{ .Values.backend.schedulerName | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.topologySpreadConstraints }}
|
||||
topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.backend.topologySpreadConstraints "context" .) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.podSecurityContext.enabled }}
|
||||
securityContext: {{- omit .Values.backend.podSecurityContext "enabled" | toYaml | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.terminationGracePeriodSeconds }}
|
||||
terminationGracePeriodSeconds: {{ .Values.backend.terminationGracePeriodSeconds }}
|
||||
{{- end }}
|
||||
initContainers:
|
||||
{{- if and .Values.volumePermissions.enabled .Values.persistence.enabled }}
|
||||
- name: volume-permissions
|
||||
image: {{ include "shuffle.volumePermissions.image" . }}
|
||||
imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }}
|
||||
command:
|
||||
- /bin/bash
|
||||
- -ec
|
||||
- |
|
||||
chown -vR {{ .Values.backend.containerSecurityContext.runAsUser }}:{{ .Values.backend.podSecurityContext.fsGroup }} /app/generated && \
|
||||
chown -vR {{ .Values.backend.containerSecurityContext.runAsUser }}:{{ .Values.backend.podSecurityContext.fsGroup }} /shuffle-apps && \
|
||||
chown -vR {{ .Values.backend.containerSecurityContext.runAsUser }}:{{ .Values.backend.podSecurityContext.fsGroup }} /shuffle-files
|
||||
{{- if .Values.volumePermissions.containerSecurityContext.enabled }}
|
||||
securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.volumePermissions.containerSecurityContext "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.volumePermissions.resources }}
|
||||
resources: {{- toYaml .Values.volumePermissions.resources | nindent 12 }}
|
||||
{{- else if ne .Values.volumePermissions.resourcesPreset "none" }}
|
||||
resources: {{- include "common.resources.preset" (dict "type" .Values.volumePermissions.resourcesPreset) | nindent 12 }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
- name: shuffle-app-builder
|
||||
mountPath: /app/generated
|
||||
- name: shuffle-apps
|
||||
mountPath: /shuffle-apps
|
||||
{{- if .Values.persistence.apps.subPath }}
|
||||
subPath: {{ .Values.persistence.apps.subPath }}
|
||||
{{- end }}
|
||||
- name: shuffle-files
|
||||
mountPath: /shuffle-files
|
||||
{{- if .Values.persistence.files.subPath }}
|
||||
subPath: {{ .Values.persistence.apps.subPath }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.initContainers }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.backend.initContainers "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: backend
|
||||
image: {{ template "shuffle.backend.image" . }}
|
||||
imagePullPolicy: {{ .Values.backend.image.pullPolicy }}
|
||||
{{- if .Values.backend.containerSecurityContext.enabled }}
|
||||
securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.backend.containerSecurityContext "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.diagnosticMode.enabled }}
|
||||
command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }}
|
||||
{{- else if .Values.backend.command }}
|
||||
command: {{- include "common.tplvalues.render" (dict "value" .Values.backend.command "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.diagnosticMode.enabled }}
|
||||
args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }}
|
||||
{{- else if .Values.backend.args }}
|
||||
args: {{- include "common.tplvalues.render" (dict "value" .Values.backend.args "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
env:
|
||||
- name: RUNNING_MODE
|
||||
value: kubernetes
|
||||
- name: IS_KUBERNETES
|
||||
value: "true"
|
||||
- name: SHUFFLE_APP_HOTLOAD_FOLDER
|
||||
value: /shuffle-apps
|
||||
- name: SHUFFLE_FILE_LOCATION
|
||||
value: /shuffle-files
|
||||
{{- if .Values.backend.extraEnvVars }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.backend.extraEnvVars "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: {{ include "shuffle.backend.name" . }}-env
|
||||
{{- if .Values.backend.extraEnvVarsCM }}
|
||||
- configMapRef:
|
||||
name: {{ include "common.tplvalues.render" (dict "value" .Values.backend.extraEnvVarsCM "context" $) }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.extraEnvVarsSecret }}
|
||||
- secretRef:
|
||||
name: {{ include "common.tplvalues.render" (dict "value" .Values.backend.extraEnvVarsSecret "context" $) }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.resources }}
|
||||
resources: {{- toYaml .Values.backend.resources | nindent 12 }}
|
||||
{{- else if ne .Values.backend.resourcesPreset "none" }}
|
||||
resources: {{- include "common.resources.preset" (dict "type" .Values.backend.resourcesPreset) | nindent 12 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.backend.containerPorts.http }}
|
||||
{{- if .Values.backend.extraContainerPorts }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.backend.extraContainerPorts "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if not .Values.diagnosticMode.enabled }}
|
||||
{{- if .Values.backend.customLivenessProbe }}
|
||||
livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.backend.customLivenessProbe "context" $) | nindent 12 }}
|
||||
{{- else if .Values.backend.livenessProbe.enabled }}
|
||||
livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.backend.livenessProbe "enabled") "context" $) | nindent 12 }}
|
||||
httpGet:
|
||||
path: /api/v1/health
|
||||
port: {{ .Values.backend.containerPorts.http }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.customReadinessProbe }}
|
||||
readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.backend.customReadinessProbe "context" $) | nindent 12 }}
|
||||
{{- else if .Values.backend.readinessProbe.enabled }}
|
||||
readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.backend.readinessProbe "enabled") "context" $) | nindent 12 }}
|
||||
httpGet:
|
||||
path: /api/v1/health
|
||||
port: {{ .Values.backend.containerPorts.http }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.customStartupProbe }}
|
||||
startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.backend.customStartupProbe "context" $) | nindent 12 }}
|
||||
{{- else if .Values.backend.startupProbe.enabled }}
|
||||
startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.backend.startupProbe "enabled") "context" $) | nindent 12 }}
|
||||
httpGet:
|
||||
path: /api/v1/health
|
||||
port: {{ .Values.backend.containerPorts.http }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.lifecycleHooks }}
|
||||
lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.backend.lifecycleHooks "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
- name: shuffle-app-builder
|
||||
mountPath: /app/generated
|
||||
- name: shuffle-apps
|
||||
mountPath: /shuffle-apps
|
||||
{{- if .Values.persistence.apps.subPath }}
|
||||
subPath: {{ .Values.persistence.apps.subPath }}
|
||||
{{- end }}
|
||||
- name: shuffle-files
|
||||
mountPath: /shuffle-files
|
||||
{{- if .Values.persistence.files.subPath }}
|
||||
subPath: {{ .Values.persistence.apps.subPath }}
|
||||
{{- end }}
|
||||
- name: empty-dir
|
||||
mountPath: /tmp
|
||||
subPath: tmp-dir
|
||||
{{- if .Values.backend.extraVolumeMounts }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.backend.extraVolumeMounts "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.sidecars }}
|
||||
{{- include "common.tplvalues.render" ( dict "value" .Values.backend.sidecars "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: empty-dir
|
||||
emptyDir: {}
|
||||
- name: shuffle-app-builder
|
||||
persistentVolumeClaim:
|
||||
claimName: backend-apps-claim
|
||||
- name: shuffle-apps
|
||||
{{- if .Values.persistence.enabled }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ default (printf "%s-apps" (include "shuffle.backend.name" .)) .Values.persistence.apps.existingClaim }}
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
- name: shuffle-files
|
||||
{{- if .Values.persistence.enabled }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ default (printf "%s-files" (include "shuffle.backend.name" .)) .Values.persistence.apps.existingClaim }}
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.extraVolumes }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.backend.extraVolumes "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,30 @@
|
||||
{{- if .Values.persistence.enabled }}
|
||||
{{- if (not .Values.persistence.files.existingClaim) }}
|
||||
kind: PersistentVolumeClaim
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: {{ printf "%s-files" (include "shuffle.backend.name" .) }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.backend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
annotations:
|
||||
{{- if eq .Values.persistence.resourcePolicy "keep" }}
|
||||
helm.sh/resource-policy: keep
|
||||
{{- end }}
|
||||
{{- if or .Values.persistence.files.annotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.persistence.files.annotations .Values.commonAnnotations ) "context" . ) }}
|
||||
{{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
accessModes:
|
||||
{{- range .Values.persistence.files.accessModes }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.files.size }}
|
||||
{{- if .Values.persistence.files.selector }}
|
||||
selector: {{- include "common.tplvalues.render" (dict "value" .Values.persistence.files.selector "context" $) | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- include "common.storage.class" ( dict "persistence" .Values.persistence.files "global" .Values.global ) | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,43 @@
|
||||
{{- if .Values.backend.autoscaling.hpa.enabled }}
|
||||
apiVersion: {{ include "common.capabilities.hpa.apiVersion" . }}
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ include "shuffle.backend.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.backend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }}
|
||||
kind: Deployment
|
||||
name: {{ include "shuffle.backend.name" . }}
|
||||
minReplicas: {{ .Values.backend.autoscaling.hpa.minReplicas }}
|
||||
maxReplicas: {{ .Values.backend.autoscaling.hpa.maxReplicas }}
|
||||
metrics:
|
||||
{{- if .Values.backend.autoscaling.hpa.targetMemory }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
{{- if semverCompare "<1.23-0" (include "common.capabilities.kubeVersion" .) }}
|
||||
targetAverageUtilization: {{ .Values.backend.autoscaling.hpa.targetMemory }}
|
||||
{{- else }}
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .Values.worker.autoscaling.hpa.targetMemory }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.autoscaling.hpa.targetCPU }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
{{- if semverCompare "<1.23-0" (include "common.capabilities.kubeVersion" .) }}
|
||||
targetAverageUtilization: {{ .Values.backend.autoscaling.hpa.targetCPU }}
|
||||
{{- else }}
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .Values.worker.autoscaling.hpa.targetCPU }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,66 @@
|
||||
{{- if .Values.backend.networkPolicy.enabled }}
|
||||
kind: NetworkPolicy
|
||||
apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }}
|
||||
metadata:
|
||||
name: {{ template "shuffle.backend.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.backend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.backend.podLabels .Values.commonLabels ) "context" . ) }}
|
||||
podSelector:
|
||||
matchLabels: {{- include "shuffle.backend.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
egress:
|
||||
{{- if .Values.backend.networkPolicy.allowExternalEgress }}
|
||||
- {}
|
||||
{{- else }}
|
||||
# Allow DNS resolution with an in-cluster DNS server
|
||||
- ports:
|
||||
- port: 53
|
||||
protocol: UDP
|
||||
- port: 53
|
||||
protocol: TCP
|
||||
to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
{{- if .Values.backend.networkPolicy.extraEgress }}
|
||||
{{- include "common.tplvalues.render" ( dict "value" .Values.backend.networkPolicy.extraEgress "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
ingress:
|
||||
- ports:
|
||||
- port: {{ .Values.backend.containerPorts.http }}
|
||||
protocol: TCP
|
||||
{{- if not .Values.backend.networkPolicy.allowExternal }}
|
||||
from:
|
||||
# Allow traffic from orborus
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: {{ .Release.Namespace }}
|
||||
podSelector:
|
||||
matchLabels: {{ include "shuffle.orborus.matchLabels" . | nindent 14 }}
|
||||
|
||||
# Allow traffic from workers
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: {{ .Release.Namespace }}
|
||||
podSelector:
|
||||
matchLabels: {{ include "shuffle.worker.matchLabels" . | nindent 14 }}
|
||||
|
||||
# Allow traffic from apps
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: {{ .Release.Namespace }}
|
||||
podSelector:
|
||||
matchLabels: {{ include "shuffle.app.matchLabels" . | nindent 14 }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.networkPolicy.extraIngress }}
|
||||
{{- include "common.tplvalues.render" ( dict "value" .Values.backend.networkPolicy.extraIngress "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,21 @@
|
||||
{{- if .Values.backend.pdb.create }}
|
||||
apiVersion: {{ include "common.capabilities.policy.apiVersion" . }}
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ include "shuffle.backend.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.backend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.backend.pdb.minAvailable }}
|
||||
minAvailable: {{ .Values.backend.pdb.minAvailable }}
|
||||
{{- end }}
|
||||
{{- if or .Values.backend.pdb.maxUnavailable ( not .Values.backend.pdb.minAvailable ) }}
|
||||
maxUnavailable: {{ .Values.backend.pdb.maxUnavailable | default 1 }}
|
||||
{{- end }}
|
||||
{{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.backend.podLabels .Values.commonLabels ) "context" . ) }}
|
||||
selector:
|
||||
matchLabels: {{- include "shuffle.backend.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,18 @@
|
||||
{{ if .Values.backend.rbac.create }}
|
||||
kind: RoleBinding
|
||||
apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }}
|
||||
metadata:
|
||||
name: {{ include "shuffle.backend.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.backend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "shuffle.backend.serviceAccount.name" . }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ include "shuffle.backend.name" . }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,18 @@
|
||||
{{ if .Values.backend.rbac.create }}
|
||||
kind: Role
|
||||
apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }}
|
||||
metadata:
|
||||
name: {{ include "shuffle.backend.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.backend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["list"]
|
||||
- apiGroups: ["batch"]
|
||||
resources: ["jobs"]
|
||||
verbs: ["get", "create", "delete"]
|
||||
{{- end }}
|
||||
@@ -0,0 +1,14 @@
|
||||
{{- if .Values.backend.serviceAccount.create }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "shuffle.backend.serviceAccount.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.backend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if or .Values.backend.serviceAccount.annotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" (dict "values" (list .Values.backend.serviceAccount.annotations .Values.commonAnnotations) "context" .) }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
automountServiceAccountToken: {{ .Values.backend.serviceAccount.automountServiceAccountToken }}
|
||||
{{- include "shuffle.backend.serviceAccount.imagePullSecrets" . | nindent 0 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,18 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ template "shuffle.backend.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.backend.labels" (dict "customLabels" .Values.commonLabels "context" $) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.backend.containerPorts.http }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
{{- $podLabels := include "common.tplvalues.merge" (dict "values" (list .Values.backend.podLabels .Values.commonLabels) "context" .) }}
|
||||
selector: {{- include "shuffle.backend.matchLabels" (dict "customLabels" $podLabels "context" $) | nindent 4 }}
|
||||
@@ -0,0 +1,38 @@
|
||||
{{- if and (.Capabilities.APIVersions.Has "autoscaling.k8s.io/v1/VerticalPodAutoscaler") .Values.backend.autoscaling.vpa.enabled }}
|
||||
apiVersion: autoscaling.k8s.io/v1
|
||||
kind: VerticalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ include "shuffle.backend.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.backend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if or .Values.backend.autoscaling.vpa.annotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.backend.autoscaling.vpa.annotations .Values.commonAnnotations ) "context" . ) }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
resourcePolicy:
|
||||
containerPolicies:
|
||||
- containerName: backend
|
||||
{{- with .Values.backend.autoscaling.vpa.controlledResources }}
|
||||
controlledResources:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.backend.autoscaling.vpa.maxAllowed }}
|
||||
maxAllowed:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.backend.autoscaling.vpa.minAllowed }}
|
||||
minAllowed:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
targetRef:
|
||||
apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }}
|
||||
kind: Deployment
|
||||
name: {{ include "backend.names.name" . }}
|
||||
{{- if .Values.backend.autoscaling.vpa.updatePolicy }}
|
||||
updatePolicy:
|
||||
{{- with .Values.backend.autoscaling.vpa.updatePolicy.updateMode }}
|
||||
updateMode: {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,4 @@
|
||||
{{- range .Values.extraDeploy }}
|
||||
---
|
||||
{{ include "common.tplvalues.render" (dict "value" . "context" $) }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "shuffle.frontend.name" . }}-env
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.frontend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
data:
|
||||
@@ -0,0 +1,158 @@
|
||||
apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }}
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ template "shuffle.frontend.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.frontend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if or .Values.frontend.deploymentAnnotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" (dict "values" (list .Values.frontend.deploymentAnnotations .Values.commonAnnotations) "context" .) }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if not .Values.frontend.autoscaling.hpa.enabled }}
|
||||
replicas: {{ .Values.frontend.replicaCount }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.updateStrategy }}
|
||||
strategy: {{- toYaml .Values.frontend.updateStrategy | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- $podLabels := include "common.tplvalues.merge" (dict "values" (list .Values.frontend.podLabels .Values.commonLabels) "context" .) }}
|
||||
selector:
|
||||
matchLabels: {{- include "shuffle.frontend.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- if .Values.frontend.podAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" (dict "value" .Values.frontend.podAnnotations "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
labels: {{- include "shuffle.frontend.labels" ( dict "customLabels" $podLabels "context" $ ) | nindent 8 }}
|
||||
spec:
|
||||
{{- include "shuffle.frontend.imagePullSecrets" . | nindent 6 }}
|
||||
serviceAccountName: {{ template "shuffle.frontend.serviceAccount.name" . }}
|
||||
automountServiceAccountToken: {{ .Values.frontend.automountServiceAccountToken }}
|
||||
{{- if .Values.frontend.hostAliases }}
|
||||
hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.frontend.hostAliases "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.affinity }}
|
||||
affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.frontend.affinity "context" $) | nindent 8 }}
|
||||
{{- else }}
|
||||
affinity:
|
||||
podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.frontend.podAffinityPreset "component" "frontend" "customLabels" $podLabels "context" $) | nindent 10 }}
|
||||
podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.frontend.podAntiAffinityPreset "component" "frontend" "customLabels" $podLabels "context" $) | nindent 10 }}
|
||||
nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.frontend.nodeAffinityPreset.type "key" .Values.frontend.nodeAffinityPreset.key "values" .Values.frontend.nodeAffinityPreset.values) | nindent 10 }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.nodeSelector }}
|
||||
nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.frontend.nodeSelector "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.tolerations }}
|
||||
tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.frontend.tolerations "context" .) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.priorityClassName }}
|
||||
priorityClassName: {{ .Values.frontend.priorityClassName | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.schedulerName }}
|
||||
schedulerName: {{ .Values.frontend.schedulerName | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.topologySpreadConstraints }}
|
||||
topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.frontend.topologySpreadConstraints "context" .) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.podSecurityContext.enabled }}
|
||||
securityContext: {{- omit .Values.frontend.podSecurityContext "enabled" | toYaml | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.terminationGracePeriodSeconds }}
|
||||
terminationGracePeriodSeconds: {{ .Values.frontend.terminationGracePeriodSeconds }}
|
||||
{{- end }}
|
||||
initContainers:
|
||||
{{- if .Values.frontend.initContainers }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.frontend.initContainers "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: frontend
|
||||
image: {{ template "shuffle.frontend.image" . }}
|
||||
imagePullPolicy: {{ .Values.frontend.image.pullPolicy }}
|
||||
{{- if .Values.frontend.containerSecurityContext.enabled }}
|
||||
securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.frontend.containerSecurityContext "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.diagnosticMode.enabled }}
|
||||
command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }}
|
||||
{{- else if .Values.frontend.command }}
|
||||
command: {{- include "common.tplvalues.render" (dict "value" .Values.frontend.command "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.diagnosticMode.enabled }}
|
||||
args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }}
|
||||
{{- else if .Values.frontend.args }}
|
||||
args: {{- include "common.tplvalues.render" (dict "value" .Values.frontend.args "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
env:
|
||||
{{- if .Values.frontend.extraEnvVars }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.frontend.extraEnvVars "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: {{ include "shuffle.frontend.name" . }}-env
|
||||
{{- if .Values.frontend.extraEnvVarsCM }}
|
||||
- configMapRef:
|
||||
name: {{ include "common.tplvalues.render" (dict "value" .Values.frontend.extraEnvVarsCM "context" $) }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.extraEnvVarsSecret }}
|
||||
- secretRef:
|
||||
name: {{ include "common.tplvalues.render" (dict "value" .Values.frontend.extraEnvVarsSecret "context" $) }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.resources }}
|
||||
resources: {{- toYaml .Values.frontend.resources | nindent 12 }}
|
||||
{{- else if ne .Values.frontend.resourcesPreset "none" }}
|
||||
resources: {{- include "common.resources.preset" (dict "type" .Values.frontend.resourcesPreset) | nindent 12 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.frontend.containerPorts.http }}
|
||||
{{- if .Values.frontend.containerPorts.https }}
|
||||
- name: https
|
||||
containerPort: {{ .Values.frontend.containerPorts.https }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.extraContainerPorts }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.frontend.extraContainerPorts "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if not .Values.diagnosticMode.enabled }}
|
||||
{{- if .Values.frontend.customLivenessProbe }}
|
||||
livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.frontend.customLivenessProbe "context" $) | nindent 12 }}
|
||||
{{- else if .Values.frontend.livenessProbe.enabled }}
|
||||
livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.frontend.livenessProbe "enabled") "context" $) | nindent 12 }}
|
||||
httpGet:
|
||||
path: /
|
||||
port: {{ .Values.frontend.containerPorts.http }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.customReadinessProbe }}
|
||||
readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.frontend.customReadinessProbe "context" $) | nindent 12 }}
|
||||
{{- else if .Values.frontend.readinessProbe.enabled }}
|
||||
readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.frontend.readinessProbe "enabled") "context" $) | nindent 12 }}
|
||||
httpGet:
|
||||
path: /
|
||||
port: {{ .Values.frontend.containerPorts.http }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.customStartupProbe }}
|
||||
startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.frontend.customStartupProbe "context" $) | nindent 12 }}
|
||||
{{- else if .Values.frontend.startupProbe.enabled }}
|
||||
startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.frontend.startupProbe "enabled") "context" $) | nindent 12 }}
|
||||
httpGet:
|
||||
path: /
|
||||
port: {{ .Values.frontend.containerPorts.http }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.lifecycleHooks }}
|
||||
lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.frontend.lifecycleHooks "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
- name: empty-dir
|
||||
mountPath: /tmp
|
||||
subPath: tmp-dir
|
||||
{{- if .Values.frontend.extraVolumeMounts }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.frontend.extraVolumeMounts "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.sidecars }}
|
||||
{{- include "common.tplvalues.render" ( dict "value" .Values.frontend.sidecars "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: empty-dir
|
||||
emptyDir: {}
|
||||
{{- if .Values.frontend.extraVolumes }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.frontend.extraVolumes "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,43 @@
|
||||
{{- if .Values.frontend.autoscaling.hpa.enabled }}
|
||||
apiVersion: {{ include "common.capabilities.hpa.apiVersion" . }}
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ include "shuffle.frontend.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.frontend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }}
|
||||
kind: Deployment
|
||||
name: {{ include "shuffle.frontend.name" . }}
|
||||
minReplicas: {{ .Values.frontend.autoscaling.hpa.minReplicas }}
|
||||
maxReplicas: {{ .Values.frontend.autoscaling.hpa.maxReplicas }}
|
||||
metrics:
|
||||
{{- if .Values.frontend.autoscaling.hpa.targetMemory }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
{{- if semverCompare "<1.23-0" (include "common.capabilities.kubeVersion" .) }}
|
||||
targetAverageUtilization: {{ .Values.frontend.autoscaling.hpa.targetMemory }}
|
||||
{{- else }}
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .Values.worker.autoscaling.hpa.targetMemory }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.autoscaling.hpa.targetCPU }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
{{- if semverCompare "<1.23-0" (include "common.capabilities.kubeVersion" .) }}
|
||||
targetAverageUtilization: {{ .Values.frontend.autoscaling.hpa.targetCPU }}
|
||||
{{- else }}
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .Values.worker.autoscaling.hpa.targetCPU }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,47 @@
|
||||
{{- if .Values.frontend.networkPolicy.enabled }}
|
||||
kind: NetworkPolicy
|
||||
apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }}
|
||||
metadata:
|
||||
name: {{ template "shuffle.frontend.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.frontend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.frontend.podLabels .Values.commonLabels ) "context" . ) }}
|
||||
podSelector:
|
||||
matchLabels: {{- include "shuffle.frontend.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
egress:
|
||||
{{- if .Values.frontend.networkPolicy.allowExternalEgress }}
|
||||
- {}
|
||||
{{- else }}
|
||||
# Allow DNS resolution with an in-cluster DNS server
|
||||
- ports:
|
||||
- port: 53
|
||||
protocol: UDP
|
||||
- port: 53
|
||||
protocol: TCP
|
||||
to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
{{- if .Values.frontend.networkPolicy.extraEgress }}
|
||||
{{- include "common.tplvalues.render" ( dict "value" .Values.frontend.networkPolicy.extraEgress "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
ingress:
|
||||
{{ if .Values.frontend.networkPolicy.allowExternal }}
|
||||
- ports:
|
||||
- port: {{ .Values.frontend.containerPorts.http }}
|
||||
{{- if .Values.frontend.containerPorts.https }}
|
||||
- port: {{ .Values.frontend.containerPorts.https }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.frontend.networkPolicy.extraIngress }}
|
||||
{{- include "common.tplvalues.render" ( dict "value" .Values.frontend.networkPolicy.extraIngress "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,21 @@
|
||||
{{- if .Values.frontend.pdb.create }}
|
||||
apiVersion: {{ include "common.capabilities.policy.apiVersion" . }}
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ include "shuffle.frontend.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.frontend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.frontend.pdb.minAvailable }}
|
||||
minAvailable: {{ .Values.frontend.pdb.minAvailable }}
|
||||
{{- end }}
|
||||
{{- if or .Values.frontend.pdb.maxUnavailable ( not .Values.frontend.pdb.minAvailable ) }}
|
||||
maxUnavailable: {{ .Values.frontend.pdb.maxUnavailable | default 1 }}
|
||||
{{- end }}
|
||||
{{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.frontend.podLabels .Values.commonLabels ) "context" . ) }}
|
||||
selector:
|
||||
matchLabels: {{- include "shuffle.frontend.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,14 @@
|
||||
{{- if .Values.frontend.serviceAccount.create }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "shuffle.frontend.serviceAccount.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.frontend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if or .Values.frontend.serviceAccount.annotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" (dict "values" (list .Values.frontend.serviceAccount.annotations .Values.commonAnnotations) "context" .) }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
automountServiceAccountToken: {{ .Values.frontend.serviceAccount.automountServiceAccountToken }}
|
||||
{{- include "shuffle.frontend.serviceAccount.imagePullSecrets" . | nindent 0 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,24 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ template "shuffle.frontend.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.frontend.labels" (dict "customLabels" .Values.commonLabels "context" $) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.frontend.containerPorts.http }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
{{- if .Values.frontend.containerPorts.https }}
|
||||
- name: https
|
||||
port: {{ .Values.frontend.containerPorts.https }}
|
||||
targetPort: https
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
{{- $podLabels := include "common.tplvalues.merge" (dict "values" (list .Values.frontend.podLabels .Values.commonLabels) "context" .) }}
|
||||
selector: {{- include "shuffle.frontend.matchLabels" (dict "customLabels" $podLabels "context" $) | nindent 4 }}
|
||||
@@ -0,0 +1,38 @@
|
||||
{{- if and (.Capabilities.APIVersions.Has "autoscaling.k8s.io/v1/VerticalPodAutoscaler") .Values.frontend.autoscaling.vpa.enabled }}
|
||||
apiVersion: autoscaling.k8s.io/v1
|
||||
kind: VerticalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ include "shuffle.frontend.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.frontend.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if or .Values.frontend.autoscaling.vpa.annotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.frontend.autoscaling.vpa.annotations .Values.commonAnnotations ) "context" . ) }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
resourcePolicy:
|
||||
containerPolicies:
|
||||
- containerName: frontend
|
||||
{{- with .Values.frontend.autoscaling.vpa.controlledResources }}
|
||||
controlledResources:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.frontend.autoscaling.vpa.maxAllowed }}
|
||||
maxAllowed:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.frontend.autoscaling.vpa.minAllowed }}
|
||||
minAllowed:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
targetRef:
|
||||
apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }}
|
||||
kind: Deployment
|
||||
name: {{ include "frontend.names.name" . }}
|
||||
{{- if .Values.frontend.autoscaling.vpa.updatePolicy }}
|
||||
updatePolicy:
|
||||
{{- with .Values.frontend.autoscaling.vpa.updatePolicy.updateMode }}
|
||||
updateMode: {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,60 @@
|
||||
{{- if .Values.ingress.enabled }}
|
||||
apiVersion: {{ include "common.capabilities.ingress.apiVersion" . }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ template "common.names.fullname" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if or .Values.ingress.annotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" (dict "values" (list .Values.ingress.annotations .Values.commonAnnotations) "context" .) }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.ingress.ingressClassName (eq "true" (include "common.ingress.supportsIngressClassname" .)) }}
|
||||
ingressClassName: {{ .Values.ingress.ingressClassName | quote }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- if .Values.ingress.hostname }}
|
||||
- host: {{ .Values.ingress.hostname }}
|
||||
http:
|
||||
paths:
|
||||
{{- if .Values.ingress.extraPaths }}
|
||||
{{- toYaml .Values.ingress.extraPaths | nindent 10 }}
|
||||
{{- end }}
|
||||
- path: {{ .Values.ingress.path }}
|
||||
{{- if eq "true" (include "common.ingress.supportsPathType" .) }}
|
||||
pathType: {{ .Values.ingress.pathType }}
|
||||
{{- end }}
|
||||
backend: {{- include "common.ingress.backend" (dict "serviceName" (include "shuffle.frontend.name" .) "servicePort" "http" "context" $) | nindent 14 }}
|
||||
- path: {{ .Values.ingress.backendPath }}
|
||||
{{- if eq "true" (include "common.ingress.supportsPathType" .) }}
|
||||
pathType: {{ .Values.ingress.backendPathType }}
|
||||
{{- end }}
|
||||
backend: {{- include "common.ingress.backend" (dict "serviceName" (include "shuffle.backend.name" .) "servicePort" "http" "context" $) | nindent 14 }}
|
||||
|
||||
{{- end }}
|
||||
{{- range .Values.ingress.extraHosts }}
|
||||
- host: {{ .name | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: {{ default "/" .path }}
|
||||
{{- if eq "true" (include "common.ingress.supportsPathType" $) }}
|
||||
pathType: {{ default "ImplementationSpecific" .pathType }}
|
||||
{{- end }}
|
||||
backend: {{- include "common.ingress.backend" (dict "serviceName" (include "common.names.fullname" $) "servicePort" "http" "context" $) | nindent 14 }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.extraRules }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.ingress.extraRules "context" $) | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if or (and .Values.ingress.tls (or (include "common.ingress.certManagerRequest" ( dict "annotations" .Values.ingress.annotations )) .Values.ingress.selfSigned)) .Values.ingress.extraTls }}
|
||||
tls:
|
||||
{{- if and .Values.ingress.tls (or (include "common.ingress.certManagerRequest" ( dict "annotations" .Values.ingress.annotations )) .Values.ingress.selfSigned) }}
|
||||
- hosts:
|
||||
- {{ .Values.ingress.hostname | quote }}
|
||||
secretName: {{ printf "%s-tls" .Values.ingress.hostname }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.extraTls }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.ingress.extraTls "context" $) | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,39 @@
|
||||
{{- if .Values.ingress.enabled }}
|
||||
{{- if .Values.ingress.secrets }}
|
||||
{{- range .Values.ingress.secrets }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .name }}
|
||||
namespace: {{ include "common.names.namespace" $ | quote }}
|
||||
labels: {{- include "common.labels.standard" ( dict "customLabels" $.Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if $.Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" $.Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
type: kubernetes.io/tls
|
||||
data:
|
||||
tls.crt: {{ .certificate | b64enc }}
|
||||
tls.key: {{ .key | b64enc }}
|
||||
---
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if and .Values.ingress.tls .Values.ingress.selfSigned }}
|
||||
{{- $secretName := printf "%s-tls" .Values.ingress.hostname }}
|
||||
{{- $ca := genCA "shuffle-ca" 365 }}
|
||||
{{- $cert := genSignedCert .Values.ingress.hostname nil (list .Values.ingress.hostname) 365 $ca }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ $secretName }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
type: kubernetes.io/tls
|
||||
data:
|
||||
tls.crt: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "tls.crt" "defaultValue" $cert.Cert "context" $) }}
|
||||
tls.key: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "tls.key" "defaultValue" $cert.Key "context" $) }}
|
||||
ca.crt: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" $ca.Cert "context" $) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,42 @@
|
||||
{{- if .Values.istio.enabled }}
|
||||
apiVersion: "{{ .Values.istio.apiVersion }}"
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: {{ template "common.names.fullname" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if or .Values.istio.gateway.annotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" (dict "values" (list .Values.istio.gateway.annotations .Values.commonAnnotations) "context" .) }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
selector: {{- include "common.tplvalues.render" ( dict "value" .Values.istio.gateway.selector "context" $ ) | nindent 4 }}
|
||||
servers:
|
||||
{{- if .Values.istio.gateway.http.enabled }}
|
||||
- name: "{{ include "common.names.fullname" . }}-http"
|
||||
port:
|
||||
number: 80
|
||||
name: http
|
||||
protocol: HTTP
|
||||
hosts: {{ .Values.istio.hosts }}
|
||||
tls:
|
||||
httpsRedirect: {{ .Values.istio.gateway.http.httpsRedirect }}
|
||||
{{- end }}
|
||||
{{- if .Values.istio.gateway.https.enabled }}
|
||||
- name: "{{ include "common.names.fullname" . }}-https"
|
||||
port:
|
||||
number: 443
|
||||
name: https
|
||||
protocol: HTTPS
|
||||
hosts: {{ .Values.istio.hosts }}
|
||||
tls:
|
||||
credentialName: {{ .Values.istio.gateway.https.tlsCredentialName }}
|
||||
mode: SIMPLE
|
||||
{{- with .Values.istio.gateway.https.tlsCipherSuites }}
|
||||
cipherSuites: {{- include "common.tplvalues.render" ( dict "value" . "context" $ ) | nindent 10 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.istio.gateway.extraServers }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.istio.gateway.extraServers "context" $) | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,38 @@
|
||||
{{- if .Values.istio.enabled }}
|
||||
apiVersion: "{{ .Values.istio.apiVersion }}"
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: {{ template "common.names.fullname" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if or .Values.istio.gateway.annotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" (dict "values" (list .Values.istio.virtualService.annotations .Values.commonAnnotations) "context" .) }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
hosts: {{ .Values.istio.hosts }}
|
||||
gateways:
|
||||
- {{ include "common.names.fullname" . }}
|
||||
http:
|
||||
- name: backend
|
||||
match:
|
||||
- uri:
|
||||
prefix: /api
|
||||
route:
|
||||
- destination:
|
||||
host: {{ include "shuffle.backend.name" . }}
|
||||
port:
|
||||
number: {{ .Values.backend.containerPorts.http }}
|
||||
{{- with .Values.istio.virtualService.backendHeaders }}
|
||||
headers: {{- include "common.tplvalues.render" ( dict "value" . "context" $ ) | nindent 8 }}
|
||||
{{- end }}
|
||||
- name: frontend
|
||||
route:
|
||||
- destination:
|
||||
host: {{ include "shuffle.frontend.name" . }}
|
||||
port:
|
||||
number: {{ .Values.frontend.containerPorts.http }}
|
||||
{{- with .Values.istio.virtualService.frontendHeaders }}
|
||||
headers: {{- include "common.tplvalues.render" ( dict "value" . "context" $ ) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,19 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "shuffle.orborus.name" . }}-env
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.orborus.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
data:
|
||||
ENVIRONMENT_NAME: "{{ .Values.shuffle.org }}"
|
||||
ORG_ID: "{{ .Values.shuffle.org }}"
|
||||
TZ: "{{ .Values.shuffle.timezone }}"
|
||||
BASE_URL: "http://{{ include "shuffle.backend.name" . }}.{{ .Release.Namespace }}.svc.cluster.local:5001"
|
||||
KUBERNETES_NAMESPACE: "{{ .Release.Namespace }}"
|
||||
KUBERNETES_SERVICE_ACCOUNT: {{ include "shuffle.orborus.serviceAccount.name" . }}
|
||||
SHUFFLE_WORKER_IMAGE: "{{ include "shuffle.worker.image" . }}"
|
||||
REGISTRY_URL: "{{ .Values.shuffle.appRegistry }}"
|
||||
SHUFFLE_SWARM_CONFIG: run
|
||||
@@ -0,0 +1,162 @@
|
||||
apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }}
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ template "shuffle.orborus.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.orborus.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if or .Values.orborus.deploymentAnnotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" (dict "values" (list .Values.orborus.deploymentAnnotations .Values.commonAnnotations) "context" .) }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if not .Values.orborus.autoscaling.hpa.enabled }}
|
||||
replicas: {{ .Values.orborus.replicaCount }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.updateStrategy }}
|
||||
strategy: {{- toYaml .Values.orborus.updateStrategy | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- $podLabels := include "common.tplvalues.merge" (dict "values" (list .Values.orborus.podLabels .Values.commonLabels) "context" .) }}
|
||||
selector:
|
||||
matchLabels: {{- include "shuffle.orborus.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- if .Values.orborus.podAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" (dict "value" .Values.orborus.podAnnotations "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
labels: {{- include "shuffle.orborus.labels" ( dict "customLabels" $podLabels "context" $ ) | nindent 8 }}
|
||||
spec:
|
||||
{{- include "shuffle.orborus.imagePullSecrets" . | nindent 6 }}
|
||||
serviceAccountName: {{ template "shuffle.orborus.serviceAccount.name" . }}
|
||||
automountServiceAccountToken: {{ .Values.orborus.automountServiceAccountToken }}
|
||||
{{- if .Values.orborus.hostAliases }}
|
||||
hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.orborus.hostAliases "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.affinity }}
|
||||
affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.orborus.affinity "context" $) | nindent 8 }}
|
||||
{{- else }}
|
||||
affinity:
|
||||
podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.orborus.podAffinityPreset "component" "orborus" "customLabels" $podLabels "context" $) | nindent 10 }}
|
||||
podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.orborus.podAntiAffinityPreset "component" "orborus" "customLabels" $podLabels "context" $) | nindent 10 }}
|
||||
nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.orborus.nodeAffinityPreset.type "key" .Values.orborus.nodeAffinityPreset.key "values" .Values.orborus.nodeAffinityPreset.values) | nindent 10 }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.nodeSelector }}
|
||||
nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.orborus.nodeSelector "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.tolerations }}
|
||||
tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.orborus.tolerations "context" .) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.priorityClassName }}
|
||||
priorityClassName: {{ .Values.orborus.priorityClassName | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.schedulerName }}
|
||||
schedulerName: {{ .Values.orborus.schedulerName | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.topologySpreadConstraints }}
|
||||
topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.orborus.topologySpreadConstraints "context" .) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.podSecurityContext.enabled }}
|
||||
securityContext: {{- omit .Values.orborus.podSecurityContext "enabled" | toYaml | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.terminationGracePeriodSeconds }}
|
||||
terminationGracePeriodSeconds: {{ .Values.orborus.terminationGracePeriodSeconds }}
|
||||
{{- end }}
|
||||
initContainers:
|
||||
{{- if .Values.orborus.initContainers }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.orborus.initContainers "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: orborus
|
||||
image: {{ template "shuffle.orborus.image" . }}
|
||||
imagePullPolicy: {{ .Values.orborus.image.pullPolicy }}
|
||||
{{- if .Values.orborus.containerSecurityContext.enabled }}
|
||||
securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.orborus.containerSecurityContext "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.diagnosticMode.enabled }}
|
||||
command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }}
|
||||
{{- else if .Values.orborus.command }}
|
||||
command: {{- include "common.tplvalues.render" (dict "value" .Values.orborus.command "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.diagnosticMode.enabled }}
|
||||
args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }}
|
||||
{{- else if .Values.orborus.args }}
|
||||
args: {{- include "common.tplvalues.render" (dict "value" .Values.orborus.args "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
env:
|
||||
- name: RUNNING_MODE
|
||||
value: kubernetes
|
||||
- name: IS_KUBERNETES
|
||||
value: "true"
|
||||
- name: SHUFFLE_WORKER_SERVICE_ACCOUNT_NAME
|
||||
value: {{ include "shuffle.worker.serviceAccount.name" . }}
|
||||
- name: SHUFFLE_APP_SERVICE_ACCOUNT_NAME
|
||||
value: {{ include "shuffle.app.serviceAccount.name" . }}
|
||||
{{- if .Values.orborus.extraEnvVars }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.orborus.extraEnvVars "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: {{ include "shuffle.orborus.name" . }}-env
|
||||
{{- if .Values.orborus.extraEnvVarsCM }}
|
||||
- configMapRef:
|
||||
name: {{ include "common.tplvalues.render" (dict "value" .Values.orborus.extraEnvVarsCM "context" $) }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.extraEnvVarsSecret }}
|
||||
- secretRef:
|
||||
name: {{ include "common.tplvalues.render" (dict "value" .Values.orborus.extraEnvVarsSecret "context" $) }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.resources }}
|
||||
resources: {{- toYaml .Values.orborus.resources | nindent 12 }}
|
||||
{{- else if ne .Values.orborus.resourcesPreset "none" }}
|
||||
resources: {{- include "common.resources.preset" (dict "type" .Values.orborus.resourcesPreset) | nindent 12 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.orborus.containerPorts.http }}
|
||||
{{- if .Values.orborus.extraContainerPorts }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.orborus.extraContainerPorts "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if not .Values.diagnosticMode.enabled }}
|
||||
{{- if .Values.orborus.customLivenessProbe }}
|
||||
livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.orborus.customLivenessProbe "context" $) | nindent 12 }}
|
||||
{{- else if .Values.orborus.livenessProbe.enabled }}
|
||||
livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.orborus.livenessProbe "enabled") "context" $) | nindent 12 }}
|
||||
httpGet:
|
||||
path: /
|
||||
port: {{ .Values.orborus.containerPorts.http }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.customReadinessProbe }}
|
||||
readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.orborus.customReadinessProbe "context" $) | nindent 12 }}
|
||||
{{- else if .Values.orborus.readinessProbe.enabled }}
|
||||
readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.orborus.readinessProbe "enabled") "context" $) | nindent 12 }}
|
||||
httpGet:
|
||||
path: /
|
||||
port: {{ .Values.orborus.containerPorts.http }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.customStartupProbe }}
|
||||
startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.orborus.customStartupProbe "context" $) | nindent 12 }}
|
||||
{{- else if .Values.orborus.startupProbe.enabled }}
|
||||
startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.orborus.startupProbe "enabled") "context" $) | nindent 12 }}
|
||||
httpGet:
|
||||
path: /
|
||||
port: {{ .Values.orborus.containerPorts.http }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.lifecycleHooks }}
|
||||
lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.orborus.lifecycleHooks "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
- name: empty-dir
|
||||
mountPath: /tmp
|
||||
subPath: tmp-dir
|
||||
{{- if .Values.orborus.extraVolumeMounts }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.orborus.extraVolumeMounts "context" $) | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.sidecars }}
|
||||
{{- include "common.tplvalues.render" ( dict "value" .Values.orborus.sidecars "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: empty-dir
|
||||
emptyDir: {}
|
||||
{{- if .Values.orborus.extraVolumes }}
|
||||
{{- include "common.tplvalues.render" (dict "value" .Values.orborus.extraVolumes "context" $) | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,43 @@
|
||||
{{- if .Values.orborus.autoscaling.hpa.enabled }}
|
||||
apiVersion: {{ include "common.capabilities.hpa.apiVersion" . }}
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ include "shuffle.orborus.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.orborus.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }}
|
||||
kind: Deployment
|
||||
name: {{ include "shuffle.orborus.name" . }}
|
||||
minReplicas: {{ .Values.orborus.autoscaling.hpa.minReplicas }}
|
||||
maxReplicas: {{ .Values.orborus.autoscaling.hpa.maxReplicas }}
|
||||
metrics:
|
||||
{{- if .Values.orborus.autoscaling.hpa.targetMemory }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
{{- if semverCompare "<1.23-0" (include "common.capabilities.kubeVersion" .) }}
|
||||
targetAverageUtilization: {{ .Values.orborus.autoscaling.hpa.targetMemory }}
|
||||
{{- else }}
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .Values.worker.autoscaling.hpa.targetMemory }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.autoscaling.hpa.targetCPU }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
{{- if semverCompare "<1.23-0" (include "common.capabilities.kubeVersion" .) }}
|
||||
targetAverageUtilization: {{ .Values.orborus.autoscaling.hpa.targetCPU }}
|
||||
{{- else }}
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .Values.worker.autoscaling.hpa.targetCPU }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,72 @@
|
||||
{{- if .Values.orborus.networkPolicy.enabled }}
|
||||
kind: NetworkPolicy
|
||||
apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }}
|
||||
metadata:
|
||||
name: {{ template "shuffle.orborus.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.orborus.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.orborus.podLabels .Values.commonLabels ) "context" . ) }}
|
||||
podSelector:
|
||||
matchLabels: {{- include "shuffle.orborus.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
egress:
|
||||
{{- if .Values.orborus.networkPolicy.allowExternalEgress }}
|
||||
- {}
|
||||
{{- else }}
|
||||
# Allow DNS resolution with an in-cluster DNS server
|
||||
- ports:
|
||||
- port: 53
|
||||
protocol: UDP
|
||||
- port: 53
|
||||
protocol: TCP
|
||||
to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
# Allow access to backend
|
||||
- ports:
|
||||
- port: {{ .Values.backend.containerPorts.http }}
|
||||
protocol: TCP
|
||||
to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: {{ .Release.Namespace }}
|
||||
podSelector:
|
||||
matchLabels: {{ include "shuffle.backend.matchLabels" . | nindent 14 }}
|
||||
# Allow access to workers
|
||||
- ports:
|
||||
- port: 33333
|
||||
protocol: TCP
|
||||
to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: {{ .Release.Namespace }}
|
||||
podSelector:
|
||||
matchLabels: {{ include "shuffle.worker.matchLabels" . | nindent 14 }}
|
||||
{{- if .Values.orborus.networkPolicy.extraEgress }}
|
||||
{{- include "common.tplvalues.render" ( dict "value" .Values.orborus.networkPolicy.extraEgress "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
ingress:
|
||||
- ports:
|
||||
- port: {{ .Values.orborus.containerPorts.http }}
|
||||
protocol: TCP
|
||||
{{- if not .Values.orborus.networkPolicy.allowExternal }}
|
||||
from:
|
||||
# Allow traffic from workers
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: {{ .Release.Namespace }}
|
||||
podSelector:
|
||||
matchLabels: {{ include "shuffle.worker.matchLabels" . | nindent 14 }}
|
||||
{{- end }}
|
||||
{{- if .Values.orborus.networkPolicy.extraIngress }}
|
||||
{{- include "common.tplvalues.render" ( dict "value" .Values.orborus.networkPolicy.extraIngress "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,21 @@
|
||||
{{- if .Values.orborus.pdb.create }}
|
||||
apiVersion: {{ include "common.capabilities.policy.apiVersion" . }}
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ include "shuffle.orborus.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.orborus.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.orborus.pdb.minAvailable }}
|
||||
minAvailable: {{ .Values.orborus.pdb.minAvailable }}
|
||||
{{- end }}
|
||||
{{- if or .Values.orborus.pdb.maxUnavailable ( not .Values.orborus.pdb.minAvailable ) }}
|
||||
maxUnavailable: {{ .Values.orborus.pdb.maxUnavailable | default 1 }}
|
||||
{{- end }}
|
||||
{{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.orborus.podLabels .Values.commonLabels ) "context" . ) }}
|
||||
selector:
|
||||
matchLabels: {{- include "shuffle.orborus.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,18 @@
|
||||
{{ if .Values.orborus.rbac.create }}
|
||||
kind: RoleBinding
|
||||
apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }}
|
||||
metadata:
|
||||
name: {{ include "shuffle.orborus.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.orborus.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "shuffle.orborus.serviceAccount.name" . }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ include "shuffle.orborus.name" . }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,29 @@
|
||||
{{ if .Values.orborus.rbac.create }}
|
||||
kind: Role
|
||||
apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }}
|
||||
metadata:
|
||||
name: {{ include "shuffle.orborus.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.orborus.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- verbs:
|
||||
- list
|
||||
- create
|
||||
- delete
|
||||
apiGroups:
|
||||
- ''
|
||||
resources:
|
||||
- pods
|
||||
- services
|
||||
- verbs:
|
||||
- list
|
||||
- create
|
||||
- delete
|
||||
apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- deployments
|
||||
{{- end }}
|
||||
@@ -0,0 +1,14 @@
|
||||
{{- if .Values.orborus.serviceAccount.create }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "shuffle.orborus.serviceAccount.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.orborus.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if or .Values.orborus.serviceAccount.annotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" (dict "values" (list .Values.orborus.serviceAccount.annotations .Values.commonAnnotations) "context" .) }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
automountServiceAccountToken: {{ .Values.orborus.serviceAccount.automountServiceAccountToken }}
|
||||
{{- include "shuffle.orborus.serviceAccount.imagePullSecrets" . | nindent 0 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,38 @@
|
||||
{{- if and (.Capabilities.APIVersions.Has "autoscaling.k8s.io/v1/VerticalPodAutoscaler") .Values.orborus.autoscaling.vpa.enabled }}
|
||||
apiVersion: autoscaling.k8s.io/v1
|
||||
kind: VerticalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ include "shuffle.orborus.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.orborus.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if or .Values.orborus.autoscaling.vpa.annotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.orborus.autoscaling.vpa.annotations .Values.commonAnnotations ) "context" . ) }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
resourcePolicy:
|
||||
containerPolicies:
|
||||
- containerName: orborus
|
||||
{{- with .Values.orborus.autoscaling.vpa.controlledResources }}
|
||||
controlledResources:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.orborus.autoscaling.vpa.maxAllowed }}
|
||||
maxAllowed:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.orborus.autoscaling.vpa.minAllowed }}
|
||||
minAllowed:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
targetRef:
|
||||
apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }}
|
||||
kind: Deployment
|
||||
name: {{ include "orborus.names.name" . }}
|
||||
{{- if .Values.orborus.autoscaling.vpa.updatePolicy }}
|
||||
updatePolicy:
|
||||
{{- with .Values.orborus.autoscaling.vpa.updatePolicy.updateMode }}
|
||||
updateMode: {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,61 @@
|
||||
{{- if .Values.app.networkPolicy.enabled }}
|
||||
kind: NetworkPolicy
|
||||
apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }}
|
||||
metadata:
|
||||
name: {{ template "shuffle.app.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.app.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.app.podLabels .Values.commonLabels ) "context" . ) }}
|
||||
podSelector:
|
||||
matchLabels: {{- include "shuffle.app.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
egress:
|
||||
{{- if .Values.app.networkPolicy.allowExternalEgress }}
|
||||
- {}
|
||||
{{- else }}
|
||||
# Allow DNS resolution with an in-cluster DNS server
|
||||
- ports:
|
||||
- port: 53
|
||||
protocol: UDP
|
||||
- port: 53
|
||||
protocol: TCP
|
||||
to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
# Allow access to workers
|
||||
- ports:
|
||||
- port: 33333
|
||||
protocol: TCP
|
||||
to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: {{ .Release.Namespace }}
|
||||
podSelector:
|
||||
matchLabels: {{ include "shuffle.worker.matchLabels" . | nindent 14 }}
|
||||
{{- if .Values.app.networkPolicy.extraEgress }}
|
||||
{{- include "common.tplvalues.render" ( dict "value" .Values.app.networkPolicy.extraEgress "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
ingress:
|
||||
{{- if .Values.app.networkPolicy.allowExternal }}
|
||||
- {}
|
||||
{{- else }}
|
||||
# Allow access from workers. Apps will typicaly use port 80/TCP, but this is not enforced.
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: {{ .Release.Namespace }}
|
||||
podSelector:
|
||||
matchLabels: {{ include "shuffle.worker.matchLabels" . | nindent 14 }}
|
||||
{{- end }}
|
||||
{{- if .Values.app.networkPolicy.extraIngress }}
|
||||
{{- include "common.tplvalues.render" ( dict "value" .Values.app.networkPolicy.extraIngress "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,18 @@
|
||||
{{ if .Values.app.rbac.create }}
|
||||
kind: RoleBinding
|
||||
apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }}
|
||||
metadata:
|
||||
name: {{ template "shuffle.app.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.app.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "shuffle.app.serviceAccount.name" . }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ template "shuffle.app.name" . }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,15 @@
|
||||
{{ if .Values.app.rbac.create }}
|
||||
kind: Role
|
||||
apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }}
|
||||
metadata:
|
||||
name: {{ template "shuffle.app.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.app.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: [""]
|
||||
verbs: [""]
|
||||
{{- end }}
|
||||
@@ -0,0 +1,14 @@
|
||||
{{- if .Values.app.serviceAccount.create }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "shuffle.app.serviceAccount.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.app.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if or .Values.app.serviceAccount.annotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" (dict "values" (list .Values.app.serviceAccount.annotations .Values.commonAnnotations) "context" .) }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
automountServiceAccountToken: {{ .Values.app.serviceAccount.automountServiceAccountToken }}
|
||||
{{- include "shuffle.app.serviceAccount.imagePullSecrets" . | nindent 0 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,69 @@
|
||||
{{- if .Values.worker.networkPolicy.enabled }}
|
||||
kind: NetworkPolicy
|
||||
apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }}
|
||||
metadata:
|
||||
name: {{ template "shuffle.worker.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.worker.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.worker.podLabels .Values.commonLabels ) "context" . ) }}
|
||||
podSelector:
|
||||
matchLabels: {{- include "shuffle.worker.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
egress:
|
||||
{{- if .Values.worker.networkPolicy.allowExternalEgress }}
|
||||
- {}
|
||||
{{- else }}
|
||||
# Allow DNS resolution with an in-cluster DNS server
|
||||
- ports:
|
||||
- port: 53
|
||||
protocol: UDP
|
||||
- port: 53
|
||||
protocol: TCP
|
||||
to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
# Allow access to orborus
|
||||
- ports:
|
||||
- port: {{ .Values.orborus.containerPorts.http }}
|
||||
protocol: TCP
|
||||
to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: {{ .Release.Namespace }}
|
||||
podSelector:
|
||||
matchLabels: {{ include "shuffle.orborus.matchLabels" . | nindent 14 }}
|
||||
# Allow arbitrary connections to apps. Apps will typically use port 80/TCP, but this is not enforced.
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: {{ .Release.Namespace }}
|
||||
podSelector:
|
||||
matchLabels: {{ include "shuffle.app.matchLabels" . | nindent 14 }}
|
||||
{{- if .Values.worker.networkPolicy.extraEgress }}
|
||||
{{- include "common.tplvalues.render" ( dict "value" .Values.worker.networkPolicy.extraEgress "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
ingress:
|
||||
- ports:
|
||||
- port: 33333
|
||||
protocol: TCP
|
||||
{{- if not .Values.worker.networkPolicy.allowExternal }}
|
||||
from:
|
||||
# Allow traffic from orborus
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: {{ .Release.Namespace }}
|
||||
podSelector:
|
||||
matchLabels: {{ include "shuffle.orborus.matchLabels" . | nindent 14 }}
|
||||
{{- end }}
|
||||
{{- if .Values.worker.networkPolicy.extraIngress }}
|
||||
{{- include "common.tplvalues.render" ( dict "value" .Values.worker.networkPolicy.extraIngress "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,18 @@
|
||||
{{ if .Values.worker.rbac.create }}
|
||||
kind: RoleBinding
|
||||
apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }}
|
||||
metadata:
|
||||
name: {{ template "shuffle.worker.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.worker.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "shuffle.worker.serviceAccount.name" . }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ template "shuffle.worker.name" . }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,21 @@
|
||||
{{ if .Values.worker.rbac.create }}
|
||||
kind: Role
|
||||
apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }}
|
||||
metadata:
|
||||
name: {{ template "shuffle.worker.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.worker.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if .Values.commonAnnotations }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["list", "delete"]
|
||||
- apiGroups: [""]
|
||||
resources: ["services"]
|
||||
verbs: ["create"]
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["deployments"]
|
||||
verbs: ["list", "create"]
|
||||
{{- end }}
|
||||
@@ -0,0 +1,14 @@
|
||||
{{- if .Values.worker.serviceAccount.create }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "shuffle.worker.serviceAccount.name" . }}
|
||||
namespace: {{ include "common.names.namespace" . | quote }}
|
||||
labels: {{- include "shuffle.worker.labels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
|
||||
{{- if or .Values.worker.serviceAccount.annotations .Values.commonAnnotations }}
|
||||
{{- $annotations := include "common.tplvalues.merge" (dict "values" (list .Values.worker.serviceAccount.annotations .Values.commonAnnotations) "context" .) }}
|
||||
annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $ ) | nindent 4 }}
|
||||
{{- end }}
|
||||
automountServiceAccountToken: {{ .Values.worker.serviceAccount.automountServiceAccountToken }}
|
||||
{{- include "shuffle.worker.serviceAccount.imagePullSecrets" . | nindent 0 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,19 @@
|
||||
{{ range $index, $element := .Values.vault.secrets }}
|
||||
{{- $vaultRole := $element.vaultRole | default $.Values.vault.role }}
|
||||
---
|
||||
apiVersion: ricoberger.de/v1alpha1
|
||||
kind: VaultSecret
|
||||
metadata:
|
||||
name: {{ include "common.names.fullname" $ }}-{{ $element.name }}
|
||||
spec:
|
||||
type: {{ $element.type }}
|
||||
path: {{ $element.path }}
|
||||
{{- if $vaultRole }}
|
||||
vaultRole: {{ $vaultRole }}
|
||||
{{- end }}
|
||||
{{- range $k, $v := $element }}
|
||||
{{- if (not (has $k (list "name" "type" "path" "vaultRole"))) }}
|
||||
{{ $k }}: {{ $v }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -116,7 +116,7 @@ const AppGrid = (props) => {
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((response) => {
|
||||
if (response.success === true) {
|
||||
if (response?.success === true) {
|
||||
setFormMessage(response.reason);
|
||||
//toast("Thanks for submitting!")
|
||||
} else {
|
||||
@@ -307,7 +307,7 @@ const AppGrid = (props) => {
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(responseJson => {
|
||||
if (responseJson.success) {
|
||||
if (responseJson?.success) {
|
||||
setUserdata(responseJson);
|
||||
setAllActivatedAppIds(responseJson.active_apps)
|
||||
setIsLoggedIn(true);
|
||||
@@ -350,7 +350,7 @@ const AppGrid = (props) => {
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((responseJson) => {
|
||||
if (responseJson.success === false) {
|
||||
if (responseJson?.success === false) {
|
||||
toast.error(responseJson.reason);
|
||||
} else {
|
||||
//toast.success(`App ${type}d Successfully!`);
|
||||
@@ -414,7 +414,7 @@ const AppGrid = (props) => {
|
||||
scrollbarColor: "#494949 #2f2f2f",
|
||||
}}
|
||||
>
|
||||
{hits.map((data, index) => {
|
||||
{hits?.map((data, index) => {
|
||||
const appUrl =
|
||||
isCloud === true ?
|
||||
`/apps/${data.objectID}`
|
||||
@@ -556,7 +556,7 @@ const AppGrid = (props) => {
|
||||
}}
|
||||
>
|
||||
<span>
|
||||
{data.tags.slice(0, 1).map((tag, tagIndex) => (
|
||||
{data?.tags?.slice(0, 1)?.map((tag, tagIndex) => (
|
||||
<span key={tagIndex}>
|
||||
{normalizedString(tag)}
|
||||
{tagIndex < 1 ? ", " : ""}
|
||||
@@ -569,7 +569,7 @@ const AppGrid = (props) => {
|
||||
) : (
|
||||
<div style={{ width: 230, textOverflow: "ellipsis", overflow: 'hidden', whiteSpace: 'nowrap', }}>
|
||||
{data.tags &&
|
||||
data.tags.map((tag, tagIndex) => (
|
||||
data?.tags?.map((tag, tagIndex) => (
|
||||
<span key={tagIndex}>
|
||||
{normalizedString(tag)}
|
||||
{tagIndex < data.tags.length - 1 ? ", " : ""}
|
||||
@@ -760,7 +760,7 @@ const AppGrid = (props) => {
|
||||
};
|
||||
|
||||
const transformRefinementListItems = items =>
|
||||
items.map(item => ({
|
||||
items?.map(item => ({
|
||||
...item,
|
||||
label: item.label === 'true' ? 'App Editor' : 'Python',
|
||||
}));
|
||||
@@ -1103,7 +1103,7 @@ const AppGrid = (props) => {
|
||||
}
|
||||
});
|
||||
|
||||
const categoryArray = Object.keys(categoryCountMap).map((category) => ({
|
||||
const categoryArray = Object.keys(categoryCountMap)?.map((category) => ({
|
||||
category,
|
||||
count: categoryCountMap[category],
|
||||
}));
|
||||
@@ -1169,7 +1169,7 @@ const AppGrid = (props) => {
|
||||
{!isLoading && (
|
||||
<Collapse in={isCategoreListExpanded}>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start', width: '100%' }}>
|
||||
{topCategories.map((data, index) => (
|
||||
{topCategories?.map((data, index) => (
|
||||
<Button
|
||||
key={data.category}
|
||||
style={{
|
||||
@@ -1247,7 +1247,7 @@ const AppGrid = (props) => {
|
||||
});
|
||||
}
|
||||
|
||||
const tagArray = Object.keys(tagCountMap).map((tag) => ({
|
||||
const tagArray = Object.keys(tagCountMap)?.map((tag) => ({
|
||||
tag,
|
||||
count: tagCountMap[tag],
|
||||
}));
|
||||
@@ -1308,7 +1308,7 @@ const AppGrid = (props) => {
|
||||
</Button>
|
||||
<Collapse in={isActionLabelExpanded}>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start', width: '100%', }}>
|
||||
{topTags && topTags.length > 0 && topTags.map((data, index) => (
|
||||
{topTags && topTags.length > 0 && topTags?.map((data, index) => (
|
||||
<Button
|
||||
key={index}
|
||||
onClick={() => handleCheckboxChange(index)}
|
||||
@@ -1419,7 +1419,7 @@ const AppGrid = (props) => {
|
||||
|
||||
<Collapse in={isCreatedWithExpanded}>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start', width: '100%' }}>
|
||||
{AppCreatedWithOptions.map((data, index) => (
|
||||
{AppCreatedWithOptions?.map((data, index) => (
|
||||
<Button
|
||||
style={{
|
||||
display: "inline-flex",
|
||||
@@ -1689,7 +1689,7 @@ const AppGrid = (props) => {
|
||||
maxHeight: 570,
|
||||
}}
|
||||
>
|
||||
{filteredUserAppdata.map((data, index) => {
|
||||
{filteredUserAppdata?.map((data, index) => {
|
||||
const isMouseOverOnCloudIcon = false;
|
||||
const xs = 12;
|
||||
const rowHandler = 12;
|
||||
@@ -1847,8 +1847,8 @@ const AppGrid = (props) => {
|
||||
<div style={{minWidth: 120, overflow: "hidden", }}>
|
||||
{data.generated !== true ?
|
||||
<div>
|
||||
{data.tags &&
|
||||
data.tags.slice(0,2).map((tag, tagIndex) => (
|
||||
{data?.tags &&
|
||||
data?.tags?.slice(0,2)?.map((tag, tagIndex) => (
|
||||
<span key={tagIndex}>
|
||||
{normalizedString(tag)}
|
||||
{tagIndex < data.tags.length - 1 ? ", " : ""}
|
||||
@@ -1888,7 +1888,7 @@ const AppGrid = (props) => {
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((responseJson) => {
|
||||
if (responseJson.success === false) {
|
||||
if (responseJson?.success === false) {
|
||||
toast.error(responseJson.reason);
|
||||
} else {
|
||||
toast.success("App Deactivated Successfully. Reload UI to see updated changes.")
|
||||
|
||||
@@ -179,7 +179,7 @@ const AppSearchButtons = (props) => {
|
||||
|
||||
|
||||
return (
|
||||
<Grid item xs={xsValue} style={{ alignItems: "center", marginTop: 5, }}
|
||||
<Grid item xs={xsValue} style={{ alignItems: "center", marginTop: 5, maxWidth: "50%", minWidth: "50%" }}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
>
|
||||
|
||||
@@ -24,11 +24,14 @@ import {
|
||||
Checkbox,
|
||||
MenuItem,
|
||||
DialogContent,
|
||||
FormControl,
|
||||
Select,
|
||||
} from "@mui/material";
|
||||
|
||||
import {
|
||||
Link as LinkIcon,
|
||||
AutoFixHigh as AutoFixHighIcon,
|
||||
AutoFixNormal as AutoFixNormalIcon,
|
||||
Edit as EditIcon,
|
||||
FileCopy as FileCopyIcon,
|
||||
SelectAll as SelectAllIcon,
|
||||
@@ -50,8 +53,8 @@ import {
|
||||
Business as BusinessIcon,
|
||||
Visibility as VisibilityIcon,
|
||||
VisibilityOff as VisibilityOffIcon,
|
||||
CheckBox,
|
||||
Key,
|
||||
Clear as ClearIcon,
|
||||
Add as AddIcon,
|
||||
} from "@mui/icons-material";
|
||||
import { validateJson, } from "../views/Workflows.jsx";
|
||||
import { Context } from "../context/ContextApi.jsx";
|
||||
@@ -91,15 +94,40 @@ const CacheView = memo((props) => {
|
||||
const [showDistributionPopup, setShowDistributionPopup] = useState(false);
|
||||
const [selectedSubOrg, setSelectedSubOrg] = useState([]);
|
||||
const [selectedCacheKey, setSelectedCacheKey] = useState("");
|
||||
|
||||
// Direct category migration from ../components/Files.jsx
|
||||
const [selectAllChecked, setSelectAllChecked] = React.useState(false)
|
||||
const [renderTextBox, setRenderTextBox] = React.useState(false);
|
||||
const [fileCategories, setFileCategories] = React.useState(["default"]);
|
||||
const [selectedCategory, setSelectedCategory] = React.useState("default");
|
||||
const [selectedFileId, setSelectedFileId] = React.useState("");
|
||||
const [updateToThisCategory, setUpdateToThisCategory] = useState("")
|
||||
const [showFileCategoryPopup, setShowFileCategoryPopup] = React.useState(false);
|
||||
const [selectedFiles, setSelectedFiles] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
if(orgId?.length >0){
|
||||
listOrgCache(orgId);
|
||||
if (orgId?.length > 0) {
|
||||
listOrgCache(orgId, selectedCategory)
|
||||
}
|
||||
}, [orgId])
|
||||
|
||||
const handleKeyDown = (event) => {
|
||||
if (event.key === 'Enter') {
|
||||
fileCategories.push(event.target.value);
|
||||
setSelectedCategory(event.target.value);
|
||||
setRenderTextBox(false);
|
||||
}
|
||||
|
||||
if (event.key === 'Escape'){ // not working for some reasons
|
||||
console.log('escape pressed')
|
||||
setRenderTextBox(false);
|
||||
}
|
||||
}
|
||||
}, [orgId]);
|
||||
|
||||
|
||||
const listOrgCache = (orgId) => {
|
||||
fetch(globalUrl + `/api/v1/orgs/${orgId}/list_cache`, {
|
||||
const listOrgCache = (orgId, category) => {
|
||||
const url = `${globalUrl}/api/v1/orgs/${orgId}/list_cache${category !== undefined ? `?category=${category.replaceAll(" ", "_")}` : ""}`
|
||||
fetch(url, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
@@ -119,6 +147,19 @@ const CacheView = memo((props) => {
|
||||
if (responseJson.success === true) {
|
||||
setListCache(responseJson.keys);
|
||||
setCachedLoaded(true);
|
||||
|
||||
if (fileCategories.length === 1 && fileCategories[0] === "default") {
|
||||
var newcategories = ["default"]
|
||||
for (var key in responseJson.keys) {
|
||||
if (responseJson.keys[key].category !== undefined && responseJson.keys[key].category !== null && responseJson.keys[key].category !== "" && !fileCategories.includes(responseJson.keys[key].category)) {
|
||||
newcategories.push(responseJson.keys[key].category);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("CATEGORIES: ", newcategories)
|
||||
|
||||
setFileCategories(newcategories)
|
||||
}
|
||||
}
|
||||
|
||||
if (responseJson.cursor !== undefined && responseJson.cursor !== null && responseJson.cursor !== "") {
|
||||
@@ -132,15 +173,12 @@ const CacheView = memo((props) => {
|
||||
|
||||
|
||||
const deleteCache = (orgId, key) => {
|
||||
//toast("Attempting to delete Cache");
|
||||
|
||||
// method: "DELETE",
|
||||
const method = "POST"
|
||||
//const url = `${globalUrl}/api/v1/orgs/${orgId}/cache/${key}`
|
||||
const url = `${globalUrl}/api/v1/orgs/${orgId}/delete_cache`
|
||||
const parsed = {
|
||||
"org_id": orgId,
|
||||
"key": key,
|
||||
"category": selectedCategory === "" || selectedCategory === "default" ? "" : selectedCategory,
|
||||
}
|
||||
|
||||
fetch(url, {
|
||||
@@ -155,7 +193,7 @@ const CacheView = memo((props) => {
|
||||
if (response.status === 200) {
|
||||
toast("Successfully deleted Cache");
|
||||
setTimeout(() => {
|
||||
listOrgCache(orgId);
|
||||
listOrgCache(orgId, selectedCategory)
|
||||
}, 1000);
|
||||
} else {
|
||||
toast("Failed deleting Cache. Does it still exist?");
|
||||
@@ -167,7 +205,12 @@ const CacheView = memo((props) => {
|
||||
};
|
||||
|
||||
const editOrgCache = (orgId) => {
|
||||
const cache = { key: dataValue.key , value: value };
|
||||
const cache = {
|
||||
key: dataValue.key,
|
||||
value: value,
|
||||
category: selectedCategory,
|
||||
}
|
||||
|
||||
setCacheInput([cache]);
|
||||
|
||||
fetch(globalUrl + `/api/v1/orgs/${orgId}/set_cache`, {
|
||||
@@ -191,7 +234,7 @@ const CacheView = memo((props) => {
|
||||
.then((responseJson) => {
|
||||
setAddCache(responseJson);
|
||||
toast("Cache Edited Successfully!");
|
||||
listOrgCache(orgId);
|
||||
listOrgCache(orgId, selectedCategory);
|
||||
setModalOpen(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
@@ -200,9 +243,13 @@ const CacheView = memo((props) => {
|
||||
};
|
||||
|
||||
const addOrgCache = (orgId) => {
|
||||
const cache = { key: key, value: value };
|
||||
const cache = {
|
||||
key: key,
|
||||
value: value,
|
||||
category: selectedCategory,
|
||||
}
|
||||
|
||||
setCacheInput([cache]);
|
||||
console.log("cache input:", cacheInput)
|
||||
|
||||
fetch(globalUrl + `/api/v1/orgs/${orgId}/set_cache`, {
|
||||
|
||||
@@ -224,8 +271,8 @@ const CacheView = memo((props) => {
|
||||
})
|
||||
.then((responseJson) => {
|
||||
setAddCache(responseJson);
|
||||
toast("New key Added Successfully!");
|
||||
listOrgCache(orgId);
|
||||
toast("New key added Successfully!");
|
||||
listOrgCache(orgId, selectedCategory);
|
||||
setModalOpen(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
@@ -243,7 +290,9 @@ const CacheView = memo((props) => {
|
||||
setValue(JSON.stringify(parsedjson, null, 2))
|
||||
} catch (e) {
|
||||
console.log("Error parsing JSON: ", e)
|
||||
//return JSON.stringify(inputvalue);
|
||||
toast.info("Invalid JSON.", {
|
||||
autoClose: 1500,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,13 +355,14 @@ const CacheView = memo((props) => {
|
||||
>
|
||||
<DialogTitle>
|
||||
<span style={{ color: "white" }}>
|
||||
{ editCache ? "Edit Key" : "Add Key" }
|
||||
{ editCache ? "Edit Key" : "Add Key"}{selectedCategory === "" || selectedCategory === "default" ? "" : ` in category '${selectedCategory}'`}
|
||||
</span>
|
||||
</DialogTitle>
|
||||
<div style={{ paddingLeft: "30px", paddingRight: '30px', backgroundColor: "#212121", }}>
|
||||
Key
|
||||
<TextField
|
||||
color="primary"
|
||||
disabled={editCache}
|
||||
style={{ backgroundColor: theme.palette.textFieldStyle.backgroundColor }}
|
||||
autoFocus
|
||||
InputProps={{
|
||||
@@ -345,7 +395,7 @@ const CacheView = memo((props) => {
|
||||
autoFixJson(value)
|
||||
}}
|
||||
>
|
||||
<AutoFixHighIcon />
|
||||
<AutoFixNormalIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</div>
|
||||
@@ -436,15 +486,18 @@ const CacheView = memo((props) => {
|
||||
|
||||
const changeDistribution = (id, selectedSubOrg) => {
|
||||
|
||||
editFileConfig(id, [...new Set(selectedSubOrg)])
|
||||
editFileConfig(id, [...new Set(selectedSubOrg)], selectedCategory)
|
||||
}
|
||||
|
||||
const editFileConfig = (id, selectedSubOrg, cacheKey) => {
|
||||
|
||||
const editFileConfig = (id, selectedSubOrg, category) => {
|
||||
const data = {
|
||||
Key: id,
|
||||
action: "suborg_distribute",
|
||||
selected_suborgs: selectedSubOrg,
|
||||
category: category === undefined || category === "" || category === "default" ? "" : category,
|
||||
}
|
||||
|
||||
console.log("data: ", data);
|
||||
|
||||
const url = `${globalUrl}/api/v1/orgs/${orgId}/cache/config`;
|
||||
@@ -467,7 +520,7 @@ const CacheView = memo((props) => {
|
||||
} else {
|
||||
toast("Successfully updated datastore!");
|
||||
setTimeout(() => {
|
||||
listOrgCache(orgId);
|
||||
listOrgCache(orgId, selectedCategory);
|
||||
setShowDistributionPopup(false);
|
||||
}, 1000);
|
||||
}
|
||||
@@ -579,7 +632,7 @@ const CacheView = memo((props) => {
|
||||
<div style={{height: "100%", maxHeight: 1700, overflowY: "auto", scrollbarColor: '#494949 transparent', scrollbarWidth: 'thin'}}>
|
||||
<div style={{ height: "100%", width: "calc(100% - 20px)", scrollbarColor: '#494949 transparent', scrollbarWidth: 'thin' }}>
|
||||
<div style={{ marginTop: isSelectedDataStore?null:20, marginBottom: 20 }}>
|
||||
<h2 style={{ display: isSelectedDataStore?null: "inline" }}>Shuffle Datastore</h2>
|
||||
<h2 style={{ display: isSelectedDataStore?null: "inline" }}>Shuffle Datastore {selectedCategory === "" || selectedCategory === "default" ? "" : `- Category '${selectedCategory}'`}</h2>
|
||||
<span style={{ marginLeft: isSelectedDataStore?null:25, color:isSelectedDataStore?"#9E9E9E":null}}>
|
||||
Datastore is a permanent key-value database for storing data that can be used cross-workflow. <br/>You can store anything from lists of IPs to complex configurations.
|
||||
<a
|
||||
@@ -609,10 +662,175 @@ const CacheView = memo((props) => {
|
||||
style={{ marginLeft: 16, marginRight: 15, backgroundColor: isSelectedDataStore?"#2F2F2F":null, boxShadow: isSelectedDataStore ? "none":null,textTransform: isSelectedDataStore ? 'capitalize':null,borderRadius:isSelectedDataStore?4:null, width:isSelectedDataStore?81:null, height:isSelectedDataStore?40:null, }}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => listOrgCache(orgId)}
|
||||
onClick={() => listOrgCache(orgId,selectedCategory)}
|
||||
>
|
||||
<CachedIcon />
|
||||
</Button>
|
||||
|
||||
{fileCategories !== undefined &&
|
||||
fileCategories !== null &&
|
||||
fileCategories.length > 1 ? (
|
||||
<FormControl style={{ minWidth: 150, maxWidth: 150 }}>
|
||||
<Select
|
||||
labelId="input-namespace-select-label"
|
||||
id="input-namespace-select-id"
|
||||
style={{
|
||||
color: "white",
|
||||
minWidth: 122,
|
||||
maxWidth: 122,
|
||||
height: 35,
|
||||
float: "right",
|
||||
position: 'relative',
|
||||
top: 8
|
||||
}}
|
||||
value={selectedCategory}
|
||||
onChange={(event) => {
|
||||
//if (selectAllChecked || listCache.length > 0) {
|
||||
if (selectAllChecked || selectedFiles.length > 0) {
|
||||
setUpdateToThisCategory(event.target.value)
|
||||
setShowFileCategoryPopup(true)
|
||||
return
|
||||
}
|
||||
|
||||
setSelectedCategory(event.target.value)
|
||||
if (event.target.value === "all" || event.target.value === "default") {
|
||||
listOrgCache(orgId)
|
||||
} else {
|
||||
listOrgCache(orgId, event.target.value)
|
||||
}
|
||||
|
||||
|
||||
// Add it to the url as a query
|
||||
if (window.location.search.includes("category=")) {
|
||||
const newurl = window.location.href.replace(/category=[^&]+/, `category=${event.target.value}`)
|
||||
window.history.pushState({ path: newurl }, "", newurl)
|
||||
} else {
|
||||
window.history.pushState({ path: window.location.href }, "", `${window.location.href}&category=${event.target.value}`)
|
||||
}
|
||||
}}
|
||||
>
|
||||
{fileCategories.map((data, index) => {
|
||||
return (
|
||||
<MenuItem
|
||||
key={index}
|
||||
value={data}
|
||||
style={{ color: "white" }}
|
||||
>
|
||||
{data.replaceAll("_", " ")}
|
||||
</MenuItem>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
<Dialog
|
||||
PaperProps={{
|
||||
sx: {
|
||||
borderRadius: theme?.palette?.DialogStyle?.borderRadius,
|
||||
border: theme?.palette?.DialogStyle?.border,
|
||||
fontFamily: theme?.typography?.fontFamily,
|
||||
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
|
||||
zIndex: 1000,
|
||||
'& .MuiDialogContent-root': {
|
||||
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
|
||||
},
|
||||
'& .MuiDialogTitle-root': {
|
||||
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
|
||||
},
|
||||
'& .MuiDialogActions-root': {
|
||||
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
|
||||
},
|
||||
},
|
||||
}}
|
||||
open={showFileCategoryPopup}
|
||||
onClose={() => {
|
||||
setShowFileCategoryPopup(false)
|
||||
}}
|
||||
>
|
||||
<DialogTitle>File Categories</DialogTitle>
|
||||
<DialogContent>
|
||||
Please note that your selected files ({selectedFileId?.length}) will be moved to the <kbd>{updateToThisCategory}</kbd> category.
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setShowFileCategoryPopup(false)
|
||||
}}
|
||||
style={{fontSize: 16, textTransform: 'none'}}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
//handleUpdateFileCategory(updateToThisCategory)
|
||||
toast.error("Not implemented.")
|
||||
}}
|
||||
style={{fontSize: 16, textTransform: 'none', color: "#1a1a1a", backgroundColor: "#ff8544"}}
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</FormControl>
|
||||
) : null}
|
||||
|
||||
<div style={{display: "inline-flex", position:"relative", top: 8}}>
|
||||
{renderTextBox ?
|
||||
<Tooltip title={"Close"} style={{}} aria-label={""}>
|
||||
<Button
|
||||
style={{ marginLeft: 5, marginRight: 15, height: 35, borderRadius: 4, backgroundColor: "#494949", textTransform: 'none', fontSize: 16, color: "#f1f1f1" }}
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
setRenderTextBox(false);
|
||||
console.log(" close clicked")
|
||||
}}
|
||||
>
|
||||
<ClearIcon/>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
:
|
||||
<Tooltip title={"Add new file category"} style={{}} aria-label={""}>
|
||||
<Button
|
||||
style={{ marginLeft: 5, marginRight: 15, width: 169, height: 35, borderRadius: 4, backgroundColor: "#494949", textTransform: 'none', fontSize: 16, color: "#f1f1f1" }}
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
setRenderTextBox(true);
|
||||
}}
|
||||
>
|
||||
<AddIcon/>
|
||||
Category (beta)
|
||||
</Button>
|
||||
</Tooltip>
|
||||
}
|
||||
|
||||
{renderTextBox && <TextField
|
||||
onKeyPress={(event)=>{
|
||||
handleKeyDown(event);
|
||||
if(event.key === 'Enter' && selectedFileId.length > 0){
|
||||
//setShowFileCategoryPopup(true)
|
||||
setUpdateToThisCategory(event.target.value)
|
||||
}
|
||||
|
||||
}}
|
||||
style={{
|
||||
height: 35,
|
||||
width: 200,
|
||||
marginTop: 0,
|
||||
}}
|
||||
InputProps={{
|
||||
style: {
|
||||
color: "white",
|
||||
height: 35,
|
||||
fontSize: 16,
|
||||
borderRadius: 4,
|
||||
paddingTop: 0,
|
||||
},
|
||||
}}
|
||||
color="primary"
|
||||
placeholder="Category name"
|
||||
required
|
||||
margin="dense"
|
||||
defaultValue={""}
|
||||
autoFocus
|
||||
/>}</div>
|
||||
{isSelectedDataStore? null :<Divider
|
||||
style={{
|
||||
marginTop: 20,
|
||||
@@ -704,6 +922,16 @@ const CacheView = memo((props) => {
|
||||
</ListItem>
|
||||
|
||||
): listCache?.map((data, index) => {
|
||||
var category = selectedCategory
|
||||
if (selectedCategory === "default") {
|
||||
category = ""
|
||||
}
|
||||
|
||||
if (data?.category === undefined && category === "") {
|
||||
} else if (data?.category !== category) {
|
||||
return null
|
||||
}
|
||||
|
||||
var bgColor = isSelectedDataStore? "#212121":"#27292d";
|
||||
if (index % 2 === 0) {
|
||||
bgColor = isSelectedDataStore? "#1A1A1A":"#1f2023";
|
||||
|
||||
@@ -191,6 +191,10 @@ const EditWorkflow = (props) => {
|
||||
var upload = "";
|
||||
var total_count = 0
|
||||
|
||||
const isCloud =
|
||||
window.location.host === "localhost:3002" ||
|
||||
window.location.host === "shuffler.io";
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
anchor={"right"}
|
||||
@@ -624,6 +628,7 @@ const EditWorkflow = (props) => {
|
||||
All
|
||||
</MenuItem>
|
||||
{userdata.orgs.map((data, index) => {
|
||||
|
||||
var skipOrg = false;
|
||||
if (data.creator_org !== undefined && data.creator_org !== null && data.creator_org === userdata.active_org.id) {
|
||||
// Finds the parent org
|
||||
@@ -631,6 +636,8 @@ const EditWorkflow = (props) => {
|
||||
return null
|
||||
}
|
||||
|
||||
const correctRegion = data?.region_url === userdata?.region_url
|
||||
|
||||
const imagesize = 22
|
||||
const imageStyle = {
|
||||
width: imagesize,
|
||||
@@ -664,7 +671,11 @@ const EditWorkflow = (props) => {
|
||||
|
||||
|
||||
return (
|
||||
<MenuItem key={index} value={data.id}>
|
||||
<MenuItem
|
||||
key={index}
|
||||
value={data.id}
|
||||
disabled={isCloud && !correctRegion}
|
||||
>
|
||||
<Checkbox checked={innerWorkflow.suborg_distribution !== undefined && innerWorkflow.suborg_distribution !== null && innerWorkflow.suborg_distribution.includes(data.id)} />
|
||||
{image}{" "}
|
||||
<span style={{ marginLeft: 8 }}>
|
||||
@@ -1135,14 +1146,26 @@ const EditWorkflow = (props) => {
|
||||
</FormControl>
|
||||
</div>
|
||||
|
||||
<Divider style={{marginTop: 75, marginBottom: 75, }}/>
|
||||
|
||||
<Typography variant="h4" style={{ marginTop: 100, }}>
|
||||
|
||||
<Typography variant="h4" style={{ }}>
|
||||
Publishing
|
||||
|
||||
<Chip
|
||||
style={{ marginLeft: 20, marginTop: 10, }}
|
||||
color={workflow?.public === true ? "primary" : "secondary"}
|
||||
variant={workflow?.public === true ? "default" : "outlined"}
|
||||
label={workflow?.public === true ? "Public" : "NOT Public"}
|
||||
/>
|
||||
</Typography>
|
||||
<Typography variant="body2" color="textSecondary" style={{ marginTop: 10, }}>
|
||||
Publishing is related to making the workflow itself public. When publishing a workflow, all the details (except sensitive info) become available to everyone. The details below will help a user understand this better. When a workflow is published, you keep the original, and a copy enters the workflow search, and is associated with your <a href="/creators" style={{ textDecoration: "none", color: "#f86a3e" }} target="_blank">creator account</a>, if you have one. You can always unpublish the workflow after. When ready to publish, click the three dots next to a workflow on the main workflow screen. After publishing, you can find it in the Shuffle search engine.
|
||||
Publishing is related to making this workflow itself public. When publishing a workflow, all the details (except sensitive info) become available to anyone. The fields below will help a user and Shuffle's system understand your workflow better. When a workflow is published, you keep the original, and a copy enters the Shuffle workflow search, and is associated with your <a href="/creators" style={{ textDecoration: "none", color: "#f86a3e" }} target="_blank">creator</a> or partner account, if you have one. You can always unpublish the workflow after. When ready to publish, click the three dots next to a workflow on the main workflow page.
|
||||
|
||||
You can always unpublish a workflow after.
|
||||
</Typography>
|
||||
|
||||
|
||||
<LocalizationProvider style={{marginLeft: 0, }} dateAdapter={AdapterDayjs}>
|
||||
<DatePicker
|
||||
sx={{
|
||||
@@ -1172,9 +1195,21 @@ const EditWorkflow = (props) => {
|
||||
setInnerWorkflow(innerWorkflow)
|
||||
}}
|
||||
>
|
||||
<Tooltip title="Agentic workflows takes an input based on input questions (forms) and performs actions based on it by itself, using Large Action Models & Singul">
|
||||
<FormControlLabel value="agentic" control={<Radio />} label="Agentic" />
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip title="Trigger workflows are typically running a schedule to get some data, doing some deduplication before sending it to a subflow or standalone workflow.">
|
||||
<FormControlLabel value="trigger" control={<Radio />} label="Trigger" />
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip title="Subflow workflows are typically used to subprocess some data, and in some cases return the result to the parent workflow.">
|
||||
<FormControlLabel value="subflow" control={<Radio />} label="Subflow" />
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip title="Standalone is default. This has no impact on Shuffle as a system.">
|
||||
<FormControlLabel value="standalone" control={<Radio />} label="Standalone" />
|
||||
</Tooltip>
|
||||
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
|
||||
@@ -89,7 +89,6 @@ const Files = memo((props) => {
|
||||
console.log('escape pressed')
|
||||
setRenderTextBox(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const changeDistribution = (id, selectedSubOrg) => {
|
||||
@@ -1051,6 +1050,7 @@ const Files = memo((props) => {
|
||||
</Dialog>
|
||||
</FormControl>
|
||||
) : null}
|
||||
|
||||
<div style={{display: "inline-flex", position:"relative", top: 8}}>
|
||||
{renderTextBox ?
|
||||
<Tooltip title={"Close"} style={{}} aria-label={""}>
|
||||
|
||||
@@ -721,11 +721,7 @@ useEffect(() => {
|
||||
margin_left:
|
||||
org.creator_org !== undefined &&
|
||||
org.creator_org !== null &&
|
||||
org.creator_org.length > 0
|
||||
? org.id === userdata.active_org.id
|
||||
? 0
|
||||
: 20
|
||||
: 0,
|
||||
org.creator_org.length > 0 ? 20 : 0,
|
||||
};
|
||||
}) || []
|
||||
);
|
||||
|
||||
@@ -74,7 +74,7 @@ const OrgHeaderexpandedNew = (props) => {
|
||||
getContentAnchorEl: () => null,
|
||||
};
|
||||
|
||||
const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
const [orgDescription, setOrgDescription] = React.useState(
|
||||
selectedOrganization.description
|
||||
);
|
||||
@@ -187,29 +187,29 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
setDocumentationReference(selectedOrganization?.defaults?.documentation_reference)
|
||||
}
|
||||
|
||||
if (uploadRepo !== selectedOrganization?.defaults?.workflow_upload_repo){
|
||||
if (uploadRepo !== selectedOrganization?.defaults?.workflow_upload_repo) {
|
||||
setUploadRepo(selectedOrganization?.defaults?.workflow_upload_repo)
|
||||
}
|
||||
|
||||
if (uploadBranch !== selectedOrganization?.defaults?.workflow_upload_branch){
|
||||
if (uploadBranch !== selectedOrganization?.defaults?.workflow_upload_branch) {
|
||||
setUploadBranch(selectedOrganization?.defaults?.workflow_upload_branch)
|
||||
}
|
||||
|
||||
if (uploadUsername !== selectedOrganization?.defaults?.workflow_upload_username){
|
||||
if (uploadUsername !== selectedOrganization?.defaults?.workflow_upload_username) {
|
||||
setUploadUsername(selectedOrganization?.defaults?.workflow_upload_username)
|
||||
}
|
||||
|
||||
if (uploadToken !== selectedOrganization?.defaults?.workflow_upload_token){
|
||||
if (uploadToken !== selectedOrganization?.defaults?.workflow_upload_token) {
|
||||
setUploadToken(selectedOrganization?.defaults?.workflow_upload_token)
|
||||
}
|
||||
}, [selectedOrganization])
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedOrganization !== undefined && selectedOrganization !== null) {
|
||||
if((orgName === undefined || orgName === null || orgName.length === 0) && selectedOrganization?.name !== orgName) {
|
||||
if ((orgName === undefined || orgName === null || orgName.length === 0) && selectedOrganization?.name !== orgName) {
|
||||
setOrgName(selectedOrganization?.name)
|
||||
}
|
||||
if((orgDescription === undefined || orgDescription === null || orgDescription.length === 0) && selectedOrganization?.description !== orgDescription) {
|
||||
if ((orgDescription === undefined || orgDescription === null || orgDescription.length === 0) && selectedOrganization?.description !== orgDescription) {
|
||||
setOrgDescription(selectedOrganization?.description)
|
||||
}
|
||||
}
|
||||
@@ -262,21 +262,21 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
});
|
||||
}
|
||||
|
||||
const handleSendChangeRegionMail = (region)=> {
|
||||
if(selectedOrganization === undefined || selectedOrganization === null){
|
||||
const handleSendChangeRegionMail = (region) => {
|
||||
if (selectedOrganization === undefined || selectedOrganization === null) {
|
||||
toast.error("Failed to send request for changing region. Please contact support@shuffler.io.")
|
||||
return
|
||||
}
|
||||
let destinationRegion = region;
|
||||
if (region === "US") {
|
||||
destinationRegion = "us-west2";
|
||||
} else if (region === "EU") {
|
||||
destinationRegion = "europe-west3";
|
||||
} else if (region === "CA") {
|
||||
destinationRegion = "northamerica-northeast1";
|
||||
} else if (region === "UK") {
|
||||
destinationRegion = "europe-west2";
|
||||
}
|
||||
|
||||
const regionToCloudRegion = {
|
||||
'US': 'us-west2',
|
||||
'EU': 'europe-west3',
|
||||
'CA': 'northamerica-northeast1',
|
||||
'UK': 'europe-west2',
|
||||
'EU-2': 'europe-west3'
|
||||
};
|
||||
|
||||
const destinationRegion = regionToCloudRegion[region] || region;
|
||||
|
||||
var data = {
|
||||
dst_region: destinationRegion
|
||||
@@ -284,7 +284,7 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
|
||||
toast.info("Sending request for changing region to " + region)
|
||||
|
||||
fetch(`${globalUrl}/api/v1/orgs/${selectedOrganization?.id}/change/region/request`,{
|
||||
fetch(`${globalUrl}/api/v1/orgs/${selectedOrganization?.id}/change/region/request`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
@@ -292,13 +292,13 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
},
|
||||
credentials: "include",
|
||||
body: JSON.stringify(data),
|
||||
}).then((response)=>{
|
||||
if(response.status !== 200){
|
||||
}).then((response) => {
|
||||
if (response.status !== 200) {
|
||||
toast.error("Failed to send request for changing region. Please contact support@shuffler.io.")
|
||||
}else{
|
||||
toast.success("successfully send request for changing region. We will contact you shortly.")
|
||||
} else {
|
||||
toast.success("Successfully sent request for region change. We will process the move and contact you shortly.")
|
||||
}
|
||||
}).catch((err)=>{
|
||||
}).catch((err) => {
|
||||
console.log(err)
|
||||
toast.error("Failed to send request for changing region. Please contact support@shuffler.io.")
|
||||
})
|
||||
@@ -307,13 +307,13 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
const setSelectedRegion = (region) => {
|
||||
|
||||
// send a POST request to /api/v1/orgs/{org_id}/region with the region as the body
|
||||
if(region === "US") {
|
||||
if (region === "US") {
|
||||
region = "us-west2"
|
||||
} else if(region === "EU") {
|
||||
} else if (region === "EU") {
|
||||
region = "europe-west2"
|
||||
} else if(region === "CA") {
|
||||
} else if (region === "CA") {
|
||||
region = "northamerica-northeast1"
|
||||
} else if(region === "UK") {
|
||||
} else if (region === "UK") {
|
||||
region = "europe-west2"
|
||||
} else if (region === "EU-2") {
|
||||
region = "europe-west3"
|
||||
@@ -355,7 +355,7 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
const orgSaveButton = (
|
||||
<Tooltip title="Save any unsaved data" placement="bottom">
|
||||
<Button
|
||||
style={{ width: 244, height: 51, display: 'flex', justifyContent:'center', textTransform: 'capitalize', padding: "16px, 24px, 16px, 24px", borderRadius: 4, backgroundColor: "#ff8544", color: "#1a1a1a", fontSize: 16, }}
|
||||
style={{ width: 244, height: 51, display: 'flex', justifyContent: 'center', textTransform: 'capitalize', padding: "16px, 24px, 16px, 24px", borderRadius: 4, backgroundColor: "#ff8544", color: "#1a1a1a", fontSize: 16, }}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={
|
||||
@@ -444,7 +444,7 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
<div style={{ flex: "3", color: "white" }}>
|
||||
<div style={{ marginTop: 8, display: "flex" }} />
|
||||
<div style={{ display: "flex" }}>
|
||||
<div style={{width: "100%", maxWidth: 434, marginRight: 10}}>
|
||||
<div style={{ width: "100%", maxWidth: 434, marginRight: 10 }}>
|
||||
Name
|
||||
<TextField
|
||||
required
|
||||
@@ -466,7 +466,7 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
variant="outlined"
|
||||
value={orgName}
|
||||
onBlur={() => {
|
||||
if((orgName !== selectedOrganization?.name) && (orgName !== "")) {
|
||||
if ((orgName !== selectedOrganization?.name) && (orgName !== "")) {
|
||||
handleEditOrg(
|
||||
orgName,
|
||||
orgDescription,
|
||||
@@ -497,7 +497,8 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
auto_provision: selectedOrganization?.sso_config?.auto_provision,
|
||||
}
|
||||
)
|
||||
}}}
|
||||
}
|
||||
}}
|
||||
onChange={(e) => {
|
||||
if (e.target.value.length > 100) {
|
||||
toast("Choose a shorter name.");
|
||||
@@ -529,7 +530,7 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
id="multiselect-status"
|
||||
multiple
|
||||
value={selectedStatus}
|
||||
onChange={(event) => {handleStatusChange(event);setSelectedStatus(event.target.value)}}
|
||||
onChange={(event) => { handleStatusChange(event); setSelectedStatus(event.target.value) }}
|
||||
input={<OutlinedInput />}
|
||||
renderValue={(selected) => selected.join(', ')}
|
||||
MenuProps={MenuProps}
|
||||
@@ -543,15 +544,15 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
</Select>
|
||||
</FormControl>
|
||||
</div>
|
||||
): null}
|
||||
) : null}
|
||||
|
||||
|
||||
{isCloud ? (
|
||||
<div style={{ marginLeft: 13, fontSize: 16, color: "#9E9E9E" }} >
|
||||
Region
|
||||
<RegionChangeModal selectedOrganization={selectedOrganization} setSelectedRegion={setSelectedRegion} userdata={userdata} handleSendChangeRegionMail={handleSendChangeRegionMail}/>
|
||||
<RegionChangeModal selectedOrganization={selectedOrganization} setSelectedRegion={setSelectedRegion} userdata={userdata} handleSendChangeRegionMail={handleSendChangeRegionMail} />
|
||||
</div>
|
||||
): null}
|
||||
) : null}
|
||||
</div>
|
||||
<div style={{ marginTop: "10px" }} />
|
||||
About
|
||||
@@ -575,7 +576,8 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
variant="outlined"
|
||||
placeholder="A description for the organization"
|
||||
value={orgDescription}
|
||||
onBlur={() => {if((orgDescription !== selectedOrganization?.description) && (orgDescription !== "")) {
|
||||
onBlur={() => {
|
||||
if ((orgDescription !== selectedOrganization?.description) && (orgDescription !== "")) {
|
||||
handleEditOrg(
|
||||
orgName,
|
||||
orgDescription,
|
||||
@@ -606,7 +608,8 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
auto_provision: selectedOrganization?.sso_config?.auto_provision,
|
||||
}
|
||||
)
|
||||
}}}
|
||||
}
|
||||
}}
|
||||
onChange={(e) => {
|
||||
setOrgDescription(e.target.value);
|
||||
}}
|
||||
@@ -672,7 +675,7 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
placeholder="Paste a URL to an external reference for this implementation"
|
||||
value={documentationReference}
|
||||
onBlur={() => {
|
||||
if(documentationReference !== selectedOrganization?.defaults?.documentation_reference) {
|
||||
if (documentationReference !== selectedOrganization?.defaults?.documentation_reference) {
|
||||
handleEditOrg(
|
||||
orgName,
|
||||
orgDescription,
|
||||
@@ -732,7 +735,7 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
<Grid item xs={12} style={{ marginTop: 20, }}>
|
||||
<Typography variant="h4" style={{ textAlign: "left", color: "rgba(241, 241, 241, 1)", fontSize: 24, fontWeight: 600, }}>Workflow Backup Repository</Typography>
|
||||
<Typography variant="body2" style={{ textAlign: "left", marginTop: 8, color: "#9E9E9E", fontSize: 16, fontWeight: 400 }}>
|
||||
Decide where workflows are backed up in a Git repository. Will create logs and notifications if upload fails. The repository and branch must already have been initialized. Files will show up in the repo root in the /orgId/workflow-status/workflowId.json format. <b>MSSP:</b> If suborg exists, this will automatically be applied for them as well (not retroactive). <a href="/docs/configuration#environment-variables" style={{textDecoration: "none", color: "#f86a3e"}} target="_blank">Credentials are encrypted.</a>
|
||||
Decide where workflows are backed up in a Git repository. Will create logs and notifications if upload fails. The repository and branch must already have been initialized. Files will show up in the repo root in the /orgId/workflow-status/workflowId.json format. <b>MSSP:</b> If suborg exists, this will automatically be applied for them as well (not retroactive). <a href="/docs/configuration#environment-variables" style={{ textDecoration: "none", color: "#f86a3e" }} target="_blank">Credentials are encrypted.</a>
|
||||
</Typography>
|
||||
<Grid container style={{ marginTop: 10, }} spacing={2}>
|
||||
<Grid item xs={6} style={{}}>
|
||||
@@ -1080,14 +1083,14 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
||||
|
||||
export default OrgHeaderexpandedNew;
|
||||
|
||||
const RegionChangeModal = memo(({selectedOrganization, setSelectedRegion, userdata, handleSendChangeRegionMail}) => {
|
||||
const RegionChangeModal = memo(({ selectedOrganization, setSelectedRegion, userdata, handleSendChangeRegionMail }) => {
|
||||
// Show from options: "us-west2", "europe-west2", "europe-west3", "northamerica-northeast1"
|
||||
// var regions = ["us-west2", "europe-west2", "europe-west3", "northamerica-northeast1"]
|
||||
const regionMapping = {
|
||||
"US": "us",
|
||||
"EU-2": "eu",
|
||||
"CA": "ca",
|
||||
"UK": "gb"
|
||||
"UK": "gb",
|
||||
};
|
||||
|
||||
//let regiontag = "UK";
|
||||
@@ -1095,6 +1098,7 @@ const RegionChangeModal = memo(({selectedOrganization, setSelectedRegion, userda
|
||||
let regionCode = "gb";
|
||||
|
||||
const regionsplit = selectedOrganization?.region_url?.split(".");
|
||||
|
||||
if (regionsplit?.length > 2 && !regionsplit[0]?.includes("shuffler")) {
|
||||
const namesplit = regionsplit[0]?.split("/");
|
||||
regiontag = namesplit[namesplit.length - 1];
|
||||
@@ -1103,25 +1107,26 @@ const RegionChangeModal = memo(({selectedOrganization, setSelectedRegion, userda
|
||||
regiontag = "US";
|
||||
regionCode = "us";
|
||||
} else if (regiontag === "frankfurt") {
|
||||
regiontag = "EU";
|
||||
regiontag = "EU-2";
|
||||
regionCode = "eu";
|
||||
} else if (regiontag === "ca") {
|
||||
regiontag = "CA";
|
||||
regionCode = "ca";
|
||||
}
|
||||
}
|
||||
return (
|
||||
|
||||
return (
|
||||
<FormControl style={{ display: "flex", flexDirection: "column", marginTop: 5, alignItems: "center" }} >
|
||||
{/* <InputLabel id="demo-simple-select-label">Region</InputLabel> */}
|
||||
<Select
|
||||
labelId="demo-simple-select-label"
|
||||
id="demo-simple-select"
|
||||
value={regiontag}
|
||||
style={{minWidth: 120, height: 35, borderRadius: 4 }}
|
||||
style={{ minWidth: 120, height: 35, borderRadius: 4 }}
|
||||
onChange={(e) => {
|
||||
if(userdata?.support){
|
||||
if (userdata?.support) {
|
||||
setSelectedRegion(e.target.value)
|
||||
}else{
|
||||
} else {
|
||||
handleSendChangeRegionMail(e.target.value)
|
||||
}
|
||||
}}
|
||||
@@ -1144,11 +1149,11 @@ return (
|
||||
</MenuItem>
|
||||
);
|
||||
} else {
|
||||
return <MenuItem sx={{display: 'flex'}} key={index} value={region}>
|
||||
return <MenuItem sx={{ display: 'flex' }} key={index} value={region}>
|
||||
<img
|
||||
src={`https://flagcdn.com/48x36/${regionImageCode}.png`}
|
||||
alt={region}
|
||||
style={{ marginRight: 10, width: 20, height: 18,}}
|
||||
style={{ marginRight: 10, width: 20, height: 18, }}
|
||||
/>
|
||||
{region}
|
||||
</MenuItem>;
|
||||
@@ -1156,5 +1161,5 @@ return (
|
||||
})}
|
||||
</Select>
|
||||
</FormControl>
|
||||
);
|
||||
);
|
||||
})
|
||||
|
||||
@@ -214,6 +214,20 @@ const ParsedAction = (props) => {
|
||||
}
|
||||
}, [expansionModalOpen])
|
||||
|
||||
/*
|
||||
useEffect(() => {
|
||||
// This will have the OLD selectedAction, not the new one huh?
|
||||
// How do we map the fields correctly?
|
||||
if (selectedAction === undefined || selectedAction === null) {
|
||||
console.log("Selected action is undefined")
|
||||
return
|
||||
}
|
||||
|
||||
console.log("Selected action: ", selectedAction?.name, selectedAction)
|
||||
|
||||
}, [selectedAction])
|
||||
*/
|
||||
|
||||
useEffect(() => {
|
||||
// Changes the order of params to show in order:
|
||||
// auth, required, optional
|
||||
@@ -347,7 +361,7 @@ const ParsedAction = (props) => {
|
||||
}
|
||||
|
||||
if (keyorder.join(",") !== newkeyorder.join(",")) {
|
||||
//toast("KEYORDER CHANGED!")
|
||||
console.log("KEYORDER CHANGED! DID ACTION AS WELL?", keyorder, newkeyorder)
|
||||
|
||||
setSelectedActionParameters(newparams)
|
||||
selectedAction.parameters = newparams
|
||||
@@ -872,7 +886,7 @@ const ParsedAction = (props) => {
|
||||
}
|
||||
}
|
||||
return { ...param, value: paramvalue, error: message }
|
||||
});
|
||||
})
|
||||
|
||||
setSelectedActionParameters(newParameters)
|
||||
setActionlist(newActionList)
|
||||
@@ -3645,6 +3659,14 @@ const ParsedAction = (props) => {
|
||||
);
|
||||
|
||||
|
||||
if ((multiline === undefined || multiline === false) && ((data?.autocompleted === true || data?.field_active === true) || data.name.startsWith("${") && data.name.endsWith("}"))) {
|
||||
multiline = true
|
||||
}
|
||||
|
||||
if (data?.autocompleted === true || data?.field_active === true) {
|
||||
rows = "1"
|
||||
}
|
||||
|
||||
var datafield = (
|
||||
<Tooltip
|
||||
title={tooltipDescription}
|
||||
@@ -3725,7 +3747,8 @@ const ParsedAction = (props) => {
|
||||
setScrollConfig(scrollConfig)
|
||||
}
|
||||
}}
|
||||
rows={data.name.startsWith("${") && data.name.endsWith("}") ? 2 : rows}
|
||||
minRows={rows}
|
||||
maxRows={6}
|
||||
color="primary"
|
||||
// defaultValue={data.value}
|
||||
value={
|
||||
@@ -4034,7 +4057,8 @@ const ParsedAction = (props) => {
|
||||
helperText={returnHelperText(data.name, data.value)}
|
||||
fullWidth
|
||||
multiline={multiline}
|
||||
rows={"3"}
|
||||
minRows={3}
|
||||
maxRows={6}
|
||||
color="primary"
|
||||
defaultValue={data.value}
|
||||
type={"text"}
|
||||
@@ -4580,7 +4604,7 @@ const ParsedAction = (props) => {
|
||||
data.field_active === true ?
|
||||
<Tooltip
|
||||
color="primary"
|
||||
title={"This is an Simplified field to make the body easier to use. NOT required according to the API documentation. If this is filled, it will be overridden in the Advanced Body"}
|
||||
title={"This is a Simplified Field to make the body easier to use. NOT required according to the API documentation. If this is filled, it will be overridden in the Advanced Body"}
|
||||
placement="top"
|
||||
>
|
||||
<PriorityHighIcon
|
||||
|
||||
@@ -354,13 +354,13 @@ const RuntimeDebugger = (props) => {
|
||||
var imageSource = "";
|
||||
if (params?.row?.org?.id?.length > 0) {
|
||||
if (params?.row?.org?.image?.length > 0){
|
||||
imageSource = params.row.org.image
|
||||
imageSource = params?.row.org?.image
|
||||
}else {
|
||||
imageSource = "/images/no_image.png"
|
||||
}
|
||||
}else {
|
||||
if (userdata.active_org.image?.length > 0){
|
||||
imageSource = userdata.active_org.image
|
||||
imageSource = userdata?.active_org?.image
|
||||
}else {
|
||||
imageSource = "/images/no_image.png"
|
||||
}
|
||||
@@ -370,7 +370,7 @@ const RuntimeDebugger = (props) => {
|
||||
<span style={{}} onClick={() => {
|
||||
//setStatus(params.row.status)
|
||||
}}>
|
||||
{userdata?.active_org?.creator_org?.length === 0 ? (
|
||||
{userdata?.active_org?.creator_org?.length === 0 && suborgWorkflowRuns ? (
|
||||
<img src={imageSource} alt={source} style={{borderRadius: theme.palette?.borderRadius, height: imageSize, width: imageSize, }} />
|
||||
) : null}
|
||||
<Tooltip title={source} placement="top">
|
||||
@@ -924,28 +924,13 @@ const RuntimeDebugger = (props) => {
|
||||
onClick={() => setSearchQuery('')}
|
||||
/>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
style={{
|
||||
color: "#1A1A1A",
|
||||
border: "none",
|
||||
padding: "10px 20px",
|
||||
width: 100,
|
||||
height: 35,
|
||||
borderRadius: 4,
|
||||
backgroundColor: "#FF8544",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
>
|
||||
Search
|
||||
</button>
|
||||
</InputAdornment>
|
||||
),
|
||||
|
||||
}}
|
||||
onChange={(e)=>{handleQueryChange(e)}}
|
||||
color="primary"
|
||||
placeholder="Filter by Workflow Name, Status, Execution Argument, Results.."
|
||||
placeholder="Filter by Workflow Name, Status, Execution Argument, Results"
|
||||
id="shuffle_search_field"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -109,6 +109,12 @@ const SearchData = props => {
|
||||
}
|
||||
}, [searchOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
if (currentRefinement !== inputValue) {
|
||||
refine(inputValue);
|
||||
}
|
||||
}, [currentRefinement]);
|
||||
|
||||
return (
|
||||
|
||||
<form id="search_form" noValidate type="searchbox" action="" role="search" onClick={() => {
|
||||
|
||||
@@ -27,6 +27,7 @@ import { SetJsonDotnotation } from "../views/AngularWorkflow.jsx";
|
||||
import Draggable from "react-draggable";
|
||||
|
||||
import {
|
||||
Storage as StorageIcon,
|
||||
FullscreenExit as FullscreenExitIcon,
|
||||
Extension as ExtensionIcon,
|
||||
Apps as AppsIcon,
|
||||
@@ -90,7 +91,7 @@ const pythonFilters = [
|
||||
{ "name": "Using Shuffle variables", "value": `import json\nnodevalue = r\"\"\"$exec\"\"\"\nif not nodevalue:\n nodevalue = r\"\"\"{\"sample\": \"string\", \"int\": 1}\"\"\"\n \njsondata = json.loads(nodevalue)\nprint(jsondata)`, "example": `` },
|
||||
{ "name": "Print Execution ID", "value": `print(self.current_execution_id)`, "example": `` },
|
||||
{ "name": "Get full execution details", "value": `print(self.full_execution)`, "example": `` },
|
||||
{ "name": "Use files", "value": `# Create a sample file\nfiles = [{\n \"name\": \"test.txt\",\n \"data\": \"Testdata\"\n}]\nret = self.set_files(files)\n\n# Get the content of the file from Shuffle storage\n# Originally a byte string in the \"data\" key\nfile_content = (self.get_file(ret[0])[\"data\"]).decode()\nprint(file_content)`, "example": `` },
|
||||
{ "name": "Use files", "value": `# Create a sample file\nfiles = [{\n \"filename\": \"test.txt\",\n \"data\": \"Testdata\"\n}]\nret = self.set_files(files)\n\n# Get the content of the file from Shuffle storage\n# Originally a byte string in the \"data\" key\nfile_content = (self.get_file(ret[0])[\"data\"]).decode()\nprint(file_content)`, "example": `` },
|
||||
|
||||
{ "name": "Use datastore", "value": `key = \"testkey\"\nvalue = \"The value of the testkey\"\n\nself.set_cache(key, value)\n\n# Print the details of the key after it's been updated\n# To get the value, use self.get_cache(key)[\"value\"]\nprint(self.get_cache(key))`, "example": `` },
|
||||
{ "name": "Run an App Action", "value": `response = shuffle.run_app(app_id="app", action="action_name", auth="authentication_id", params={})\nprint(response)`, "example": ``, "disabled": true, },
|
||||
@@ -1805,9 +1806,11 @@ const CodeEditor = (props) => {
|
||||
) : innerdata.type === "workflow_variable" ||
|
||||
innerdata.type === "execution_variable" ? (
|
||||
<FavoriteBorderIcon style={{ marginRight: 10 }} />
|
||||
) : (
|
||||
) :
|
||||
innerdata.type === "Shuffle DB" ?
|
||||
<StorageIcon style={{ marginRight: 10, }} />
|
||||
:
|
||||
<ScheduleIcon style={{ marginRight: 10 }} />
|
||||
);
|
||||
|
||||
const handleExecArgumentHover = (inside) => {
|
||||
var exec_text_field = document.getElementById(
|
||||
@@ -1877,8 +1880,6 @@ const CodeEditor = (props) => {
|
||||
menuPosition1.left = 0
|
||||
}
|
||||
|
||||
//console.log("POS1: ", menuPosition1)
|
||||
|
||||
return parsedPaths.length > 0 ? (
|
||||
<NestedMenuItem
|
||||
key={innerdata.name}
|
||||
|
||||
@@ -1335,7 +1335,7 @@ const UserManagmentTab = memo((props) => {
|
||||
}}
|
||||
>
|
||||
<ListItem style={{ width: "100%", padding: "10px 10px 10px 0px", verticalAlign: 'middle', borderBottom: "1px solid #494949", display: "table-row" }}>
|
||||
{["Username", "API Key", "Role", "Active", "Type", "MFA", ...(selectedOrganization?.child_orgs?.length > 0 ? ["Suborgs"]: []), "Actions", "Last Login"].map((header, index) => (
|
||||
{["Username", /*"API Key",*/ "Role", /*"Active",*/ "Type", "MFA", ...(selectedOrganization?.child_orgs?.length > 0 ? ["Suborgs"]: []), "Actions", "Last Login"].map((header, index) => (
|
||||
<ListItemText
|
||||
key={index}
|
||||
primary={header}
|
||||
@@ -1458,6 +1458,8 @@ const UserManagmentTab = memo((props) => {
|
||||
}}
|
||||
style={{display:'table-cell', verticalAlign: 'middle' }}
|
||||
/>
|
||||
|
||||
{/*
|
||||
<ListItemText
|
||||
style={{
|
||||
textAlign: "center",
|
||||
@@ -1488,6 +1490,8 @@ const UserManagmentTab = memo((props) => {
|
||||
)
|
||||
}
|
||||
/>
|
||||
*/}
|
||||
|
||||
<ListItemText
|
||||
primary={
|
||||
<Select
|
||||
@@ -1552,10 +1556,12 @@ const UserManagmentTab = memo((props) => {
|
||||
}
|
||||
style={{ display:'table-cell', verticalAlign: 'middle' }}
|
||||
/>
|
||||
|
||||
<ListItemText
|
||||
primary={data.active ? "True" : "False"}
|
||||
style={{display:'table-cell',verticalAlign: 'middle' , padding: "8px", textAlign: "center", color: data.active ? "#02CB70" : "#F53434" }}
|
||||
/>
|
||||
|
||||
<ListItemText
|
||||
primary={
|
||||
data.login_type === undefined ||
|
||||
@@ -1566,6 +1572,8 @@ const UserManagmentTab = memo((props) => {
|
||||
}
|
||||
style={{ display:'table-cell',verticalAlign: 'middle', padding: "8px", }}
|
||||
/>
|
||||
|
||||
{/*
|
||||
<ListItemText
|
||||
primary={
|
||||
data?.mfa_info !== undefined &&
|
||||
@@ -1576,6 +1584,8 @@ const UserManagmentTab = memo((props) => {
|
||||
}
|
||||
style={{ display:'table-cell', verticalAlign: 'middle',padding: "8px", color: data.mfa_info.active ? "#02CB70" : "#F53434" }}
|
||||
/>
|
||||
*/}
|
||||
|
||||
{selectedOrganization?.child_orgs !== undefined &&
|
||||
selectedOrganization?.child_orgs !== null &&
|
||||
selectedOrganization?.child_orgs?.length > 0 ? (
|
||||
|
||||
@@ -28,7 +28,16 @@ import { validateJson, GetIconInfo } from "../views/Workflows.jsx";
|
||||
import theme from "../theme.jsx";
|
||||
const itemHeight = 24
|
||||
|
||||
export const getParentNodes = (workflow, action) => {
|
||||
export const getParentNodes = (workflow, action, count) => {
|
||||
if (count === undefined) {
|
||||
count = 0
|
||||
}
|
||||
|
||||
// 50 levels of parent nodes
|
||||
if (count > 50) {
|
||||
return []
|
||||
}
|
||||
|
||||
if (action === undefined || action === null) {
|
||||
return []
|
||||
}
|
||||
@@ -81,8 +90,7 @@ export const getParentNodes = (workflow, action) => {
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME: This part is only handling first level,
|
||||
// but needs to recurse
|
||||
// FIXME: recursion
|
||||
var incomingEdges = []
|
||||
for (var branchkey in workflow.branches) {
|
||||
const branch = workflow.branches[branchkey]
|
||||
@@ -90,13 +98,19 @@ export const getParentNodes = (workflow, action) => {
|
||||
continue
|
||||
}
|
||||
|
||||
// Go up in the levels
|
||||
// FIXME: Go up in the levels
|
||||
// This somehow creates infinite recursion for now, so
|
||||
// we are skipping it.
|
||||
// This function is also not used for cytoscape recursion,
|
||||
// so it doesn't matter much (yet)
|
||||
/*
|
||||
const parents = getParentNodes(workflow, {
|
||||
id: branch.source_id,
|
||||
})
|
||||
}, count+1)
|
||||
if (parents.length > 0) {
|
||||
incomingEdges = incomingEdges.concat(parents)
|
||||
}
|
||||
*/
|
||||
|
||||
incomingEdges.push(branch)
|
||||
}
|
||||
@@ -215,8 +229,6 @@ const WorkflowValidationTimeline = (props) => {
|
||||
}
|
||||
}
|
||||
|
||||
//const parents = getParentNodes(workflow, action)
|
||||
//console.log("PARENTS", key, parents)
|
||||
if (parents !== undefined && parents !== null && parents.length > 0) {
|
||||
const parentfound = parents.find((element) => element.id === startnodeId)
|
||||
if (parentfound !== undefined) {
|
||||
|
||||
@@ -574,7 +574,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
}, [editWorkflowModalOpen])
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedTrigger !== undefined && selectedTrigger.parameters !== undefined && selectedTrigger.parameters !== undefined && selectedTrigger.parameters.length > 1) {
|
||||
if (selectedTrigger !== undefined && selectedTrigger?.parameters !== undefined && selectedTrigger?.parameters !== null && selectedTrigger?.parameters?.length > 1) {
|
||||
// Right now just setting for the subflow
|
||||
setSelectedTriggerValue(selectedTrigger?.parameters[1]?.value)
|
||||
}
|
||||
@@ -1203,18 +1203,15 @@ const AngularWorkflow = (defaultprops) => {
|
||||
if (workflowExecutions.length > 0) {
|
||||
// Look for the ID
|
||||
for (let execkey in workflowExecutions) {
|
||||
if (
|
||||
workflowExecutions[execkey].results === undefined ||
|
||||
workflowExecutions[execkey].results === null
|
||||
) {
|
||||
continue;
|
||||
if (workflowExecutions[execkey].results === undefined || workflowExecutions[execkey].results === null) {
|
||||
continue
|
||||
}
|
||||
|
||||
var foundResult = workflowExecutions[execkey].results.find(
|
||||
(result) => result.action.id === item.id
|
||||
);
|
||||
)
|
||||
if (foundResult === undefined) {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
|
||||
const validated = validateJson(foundResult.result)
|
||||
@@ -4863,6 +4860,177 @@ const AngularWorkflow = (defaultprops) => {
|
||||
})
|
||||
};
|
||||
|
||||
// Check if it already has any non-decorator branches attached to it
|
||||
const findClosestNode = (event, nodedata) => {
|
||||
if (cy === undefined || cy === null) {
|
||||
console.log("Cy is undefined or null")
|
||||
return
|
||||
}
|
||||
|
||||
if (event === undefined || event === null) {
|
||||
console.log("Event is undefined or null")
|
||||
return
|
||||
}
|
||||
|
||||
if (event.target === undefined || event.target === null) {
|
||||
console.log("Event target is undefined or null")
|
||||
return
|
||||
}
|
||||
|
||||
if (!((nodedata?.trigger_type === "SUBFLOW" || nodedata?.trigger_type === "USERINPUT" || nodedata?.type === "ACTION") && !nodedata?.isStartNode)) {
|
||||
//console.log("Not a valid node to find closest node for")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (nodedata.finished === false) {
|
||||
//console.log("Node is not finished")
|
||||
return
|
||||
}
|
||||
|
||||
const branches = cy.elements('edge').jsons()
|
||||
var branchFound = false
|
||||
var decoratorNodeIds = []
|
||||
var decoratorIds = []
|
||||
for (var branchkey in branches) {
|
||||
if (branches[branchkey].data.source === nodedata.id || branches[branchkey].data.target === nodedata.id) {
|
||||
decoratorIds.push(branches[branchkey].data.id)
|
||||
|
||||
if (branches[branchkey].data.decorator === true) {
|
||||
|
||||
// Add the source/destination
|
||||
if (branches[branchkey].data.source === nodedata.id) {
|
||||
decoratorNodeIds.push(branches[branchkey].data.target)
|
||||
} else {
|
||||
decoratorNodeIds.push(branches[branchkey].data.source)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
//branchFound = true
|
||||
//break
|
||||
}
|
||||
}
|
||||
|
||||
if (!branchFound) {
|
||||
var relevantNodes = []
|
||||
|
||||
const minDistance = 185
|
||||
const draggedNode = event.target
|
||||
const allnodes = cy.nodes().jsons()
|
||||
for (var nodekey in allnodes) {
|
||||
const node = allnodes[nodekey]
|
||||
if (node.data.id === nodedata.id) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Decorators
|
||||
if (node.data.attachedTo !== undefined) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (node.position === undefined || node.position === null || node.position.x === undefined || node.position.y === undefined) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (node.data.type !== "ACTION" && node.data.type !== "TRIGGER") {
|
||||
continue
|
||||
}
|
||||
|
||||
const distance = Math.sqrt(
|
||||
Math.pow(draggedNode.position('x') - node.position.x, 2) +
|
||||
Math.pow(draggedNode.position('y') - node.position.y, 2)
|
||||
)
|
||||
|
||||
if (decoratorNodeIds.includes(node.data.id)) {
|
||||
|
||||
// Drag a little farther to remove it
|
||||
if (distance > minDistance + 75) {
|
||||
// Remove the branch? Why?
|
||||
const edgeToRemove = cy.getElementById(branches[branchkey].data.id)
|
||||
if (edgeToRemove !== null && edgeToRemove !== undefined) {
|
||||
//console.log("Removing edge: ", edgeToRemove)
|
||||
edgeToRemove.remove()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (distance < minDistance) {
|
||||
relevantNodes.push(node)
|
||||
//minDistance = distance
|
||||
//closestNode = node
|
||||
}
|
||||
}
|
||||
|
||||
for (var key in relevantNodes) {
|
||||
const closestNode = relevantNodes[key]
|
||||
if (closestNode.data.app_name === "Webhook" || closestNode.data.app_name === "Schedule") {
|
||||
return
|
||||
}
|
||||
|
||||
// Checks if the branch already exists between the nodes
|
||||
if (decoratorIds.length > 0) {
|
||||
var foundBranch = false
|
||||
for (var decoratorkey in decoratorIds) {
|
||||
const decoratorEdge = cy.getElementById(decoratorIds[decoratorkey])
|
||||
if (decoratorEdge === null || decoratorEdge === undefined) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if source and destination exists with a branch
|
||||
const sourceId = decoratorEdge.data("source")
|
||||
const targetId = decoratorEdge.data("target")
|
||||
if ((sourceId === closestNode.data.id && targetId === nodedata.id) || (sourceId === nodedata.id && targetId === closestNode.data.id)) {
|
||||
foundBranch = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (foundBranch) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
const newId = uuidv4()
|
||||
cy.add({
|
||||
group: "edges",
|
||||
data: {
|
||||
decorator: true,
|
||||
id: newId,
|
||||
_id: newId,
|
||||
source: closestNode.data.id,
|
||||
target: nodedata.id,
|
||||
label: releaseToConnectLabel,
|
||||
conditions: [],
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// FIXME: This is the start of a highlighter for the node
|
||||
// to better match it up with other elements
|
||||
// 1. Get current node's position in X/Y on the screen
|
||||
// 2. Draw a red line on the X and Y axis for positioning
|
||||
|
||||
// Draw a red div line in the HTML
|
||||
const position = event.target.position()
|
||||
const redline = document.getElementById("redline")
|
||||
if (redline !== null && redline !== undefined) {
|
||||
redline.style.display = "block"
|
||||
redline.style.position = "absolute"
|
||||
redline.style.left = position.x + "px"
|
||||
redline.style.top = position.y + "px"
|
||||
redline.style.height = "10000px"
|
||||
redline.style.width = 1
|
||||
console.log("REDLINE!")
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
const onNodeDrag = (event, selectedAction) => {
|
||||
const nodedata = event.target.data();
|
||||
|
||||
@@ -4906,161 +5074,9 @@ const AngularWorkflow = (defaultprops) => {
|
||||
return;
|
||||
}
|
||||
|
||||
// Finds closest partner to show edge to connect to
|
||||
if ((nodedata.trigger_type === "SUBFLOW" || nodedata.trigger_type === "USERINPUT" || nodedata.type === "ACTION") && !nodedata.isStartNode) {
|
||||
// Check if it already has any non-decorator branches attached to it
|
||||
const branches = cy.elements('edge').jsons()
|
||||
var branchFound = false
|
||||
var decoratorIds = []
|
||||
for (var branchkey in branches) {
|
||||
if (branches[branchkey].data.source === nodedata.id || branches[branchkey].data.target === nodedata.id) {
|
||||
|
||||
if (branches[branchkey].data.decorator === true) {
|
||||
|
||||
// Add the source/destination
|
||||
if (branches[branchkey].data.source === nodedata.id) {
|
||||
decoratorIds.push(branches[branchkey].data.target)
|
||||
} else {
|
||||
decoratorIds.push(branches[branchkey].data.source)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
branchFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (!branchFound) {
|
||||
//console.log("Found action during drag. Checking closest nodes as it doesn't have a valid branch")
|
||||
var closestNode = null
|
||||
var minDistance = 300
|
||||
|
||||
const draggedNode = event.target
|
||||
const allnodes = cy.nodes().jsons()
|
||||
for (var nodekey in allnodes) {
|
||||
const node = allnodes[nodekey]
|
||||
if (node.data.id === nodedata.id) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Decorators
|
||||
if (node.data.attachedTo !== undefined) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (node.position === undefined || node.position === null || node.position.x === undefined || node.position.y === undefined) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (node.data.type !== "ACTION" && node.data.type !== "TRIGGER") {
|
||||
continue
|
||||
}
|
||||
|
||||
const distance = Math.sqrt(
|
||||
Math.pow(draggedNode.position('x') - node.position.x, 2) +
|
||||
Math.pow(draggedNode.position('y') - node.position.y, 2)
|
||||
)
|
||||
|
||||
if (decoratorIds.includes(node.data.id)) {
|
||||
//console.log("Found existing decorator for: ", node.data.app_name, "Distance: ", distance)
|
||||
|
||||
if (distance > 300) {
|
||||
// Remove the branch
|
||||
const edgeToRemove = cy.getElementById(branches[branchkey].data.id)
|
||||
if (edgeToRemove !== null && edgeToRemove !== undefined) {
|
||||
//console.log("Removing edge: ", edgeToRemove)
|
||||
edgeToRemove.remove()
|
||||
//decoratorIds.splice(decoratorIds.indexOf(node.data.id), 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance
|
||||
closestNode = node
|
||||
}
|
||||
}
|
||||
|
||||
if (closestNode !== null && closestNode !== undefined) {
|
||||
if (closestNode.data.app_name === "Webhook" || closestNode.data.app_name === "Schedule") {
|
||||
return
|
||||
}
|
||||
|
||||
//console.log("Closest node app: ", closestNode.data.app_name, "Distance: ", minDistance)
|
||||
|
||||
/*
|
||||
if (decoratorIds.length > 0) {
|
||||
console.log("Decorators already exists. If within distance of 15 add to existing, otherwise remove old and add new: ", decoratorIds)
|
||||
for (var decoratorkey in decoratorIds) {
|
||||
const decoratorEdge = cy.getElementById(decoratorIds[decoratorkey])
|
||||
if (decoratorEdge === null || decoratorEdge === undefined) {
|
||||
continue
|
||||
}
|
||||
|
||||
const sourceNode = cy.getElementById(decoratorEdge.data.source)
|
||||
const targetNode = cy.getElementById(decoratorEdge.data.target)
|
||||
|
||||
const distance = Math.sqrt(
|
||||
Math.pow(draggedNode.position('x') - sourceNode.position('x'), 2) +
|
||||
Math.pow(draggedNode.position('y') - sourceNode.position('y'), 2)
|
||||
)
|
||||
|
||||
// Check plus minus 15 in distance from mindistance
|
||||
if (distance > minDistance - 15 && distance < minDistance + 15) {
|
||||
console.log("Within distance of 15, add to existing edge")
|
||||
} else {
|
||||
console.log("Outside distance of 15, remove old edge and add new")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (decoratorIds.length === 0) {
|
||||
//const edgeCurve = calculateEdgeCurve(draggedNode.position(), closestNode.position)
|
||||
//currentedge.style('control-point-distance', edgeCurve.distance)
|
||||
//currentedge.style('control-point-weight', edgeCurve.weight)
|
||||
|
||||
const newId = uuidv4()
|
||||
cy.add({
|
||||
group: "edges",
|
||||
data: {
|
||||
decorator: true,
|
||||
id: newId,
|
||||
_id: newId,
|
||||
source: closestNode.data.id,
|
||||
target: nodedata.id,
|
||||
label: releaseToConnectLabel,
|
||||
conditions: [],
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// FIXME: This is the start of a highlighter for the node
|
||||
// to better match it up with other elements
|
||||
// 1. Get current node's position in X/Y on the screen
|
||||
// 2. Draw a red line on the X and Y axis for positioning
|
||||
|
||||
// Draw a red div line in the HTML
|
||||
const position = event.target.position()
|
||||
const redline = document.getElementById("redline")
|
||||
if (redline !== null && redline !== undefined) {
|
||||
redline.style.display = "block"
|
||||
redline.style.position = "absolute"
|
||||
redline.style.left = position.x + "px"
|
||||
redline.style.top = position.y + "px"
|
||||
redline.style.height = "10000px"
|
||||
redline.style.width = 1
|
||||
console.log("REDLINE!")
|
||||
}
|
||||
*/
|
||||
|
||||
findClosestNode(event, nodedata)
|
||||
}
|
||||
|
||||
if (originalLocation.x === 0 && originalLocation.y === 0 && nodedata.position !== undefined) {
|
||||
@@ -5222,7 +5238,9 @@ const AngularWorkflow = (defaultprops) => {
|
||||
name: item.label,
|
||||
autocomplete: itemlabelComplete,
|
||||
example: exampledata,
|
||||
};
|
||||
}
|
||||
|
||||
console.log("VALUE: ", actionvalue)
|
||||
|
||||
actionlist.push(actionvalue);
|
||||
}
|
||||
@@ -5463,6 +5481,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
// https://stackoverflow.com/questions/16677856/cy-onselect-callback-only-once
|
||||
// onNodeClick
|
||||
const onNodeSelect = (event, newAppAuth) => {
|
||||
|
||||
// Forces all states to update at the same time,
|
||||
// Otherwise everything is SUPER slow
|
||||
|
||||
@@ -5636,7 +5655,14 @@ const AngularWorkflow = (defaultprops) => {
|
||||
}
|
||||
|
||||
ReactDOM.unstable_batchedUpdates(() => {
|
||||
const selectedNodes = cy.$(':selected')
|
||||
if (data.isButton) {
|
||||
if (selectedNodes?.length > 1) {
|
||||
event.target.unselect()
|
||||
//console.log(": ", selectedNodes.length)
|
||||
return
|
||||
}
|
||||
|
||||
if (data.buttonType === "suggestion") {
|
||||
if (cy === undefined) {
|
||||
console.log("Cy not defined yet")
|
||||
@@ -5736,7 +5762,6 @@ const AngularWorkflow = (defaultprops) => {
|
||||
return
|
||||
|
||||
} else if (data.buttonType === "copy") {
|
||||
console.log("COPY!");
|
||||
|
||||
// 1. Find parent
|
||||
// 2. Find branches for parent
|
||||
@@ -5877,6 +5902,14 @@ const AngularWorkflow = (defaultprops) => {
|
||||
}
|
||||
|
||||
if (data.type === "ACTION") {
|
||||
if (selectedNodes?.length > 1) {
|
||||
console.log("Unselecting ACTION due to multiple nodes selected")
|
||||
setSelectedAction({})
|
||||
setSelectedApp({})
|
||||
setSelectedComment({})
|
||||
return
|
||||
}
|
||||
|
||||
setSelectedComment({})
|
||||
|
||||
// FIXME: is this what is mapping it an actual action in the workflow? wtf?
|
||||
@@ -6198,8 +6231,10 @@ const AngularWorkflow = (defaultprops) => {
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
setSelectedApp(curapp)
|
||||
setSelectedAction(curaction)
|
||||
}, 50)
|
||||
|
||||
cy.removeListener("drag");
|
||||
cy.removeListener("free");
|
||||
@@ -6222,6 +6257,14 @@ const AngularWorkflow = (defaultprops) => {
|
||||
setSelectedActionEnvironment(env);
|
||||
}
|
||||
} else if (data.type === "TRIGGER") {
|
||||
if (selectedNodes?.length > 1) {
|
||||
console.log("Unselecting ACTION due to multiple nodes selected")
|
||||
setSelectedAction({})
|
||||
setSelectedApp({})
|
||||
setSelectedComment({})
|
||||
return
|
||||
}
|
||||
|
||||
setSelectedComment({})
|
||||
if (workflow.triggers === null) {
|
||||
workflow.triggers = []
|
||||
@@ -6423,6 +6466,14 @@ const AngularWorkflow = (defaultprops) => {
|
||||
//setSelectedActionEnvironment(data.env)
|
||||
}, 25)
|
||||
} else if (data.type === "COMMENT") {
|
||||
if (selectedNodes?.length > 1) {
|
||||
console.log("Unselecting ACTION due to multiple nodes selected")
|
||||
setSelectedAction({})
|
||||
setSelectedApp({})
|
||||
setSelectedComment({})
|
||||
return
|
||||
}
|
||||
|
||||
setSelectedComment(data);
|
||||
} else {
|
||||
toast("Can't handle node type " + data.type);
|
||||
@@ -7431,26 +7482,21 @@ const AngularWorkflow = (defaultprops) => {
|
||||
};
|
||||
|
||||
const handlePaste = (event) => {
|
||||
//console.log("EV: ", event)
|
||||
if (
|
||||
event.path !== undefined &&
|
||||
event.path !== null &&
|
||||
event.path.length > 0
|
||||
) {
|
||||
//console.log("PATH: ", event.path[0])
|
||||
if (event.path[0].localName !== "body") {
|
||||
//console.log("Skipping because body is not targeted")
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//console.log("PATH2: ", event.target)
|
||||
if (
|
||||
event.target !== undefined &&
|
||||
event.target !== null
|
||||
) {
|
||||
if (event.target.localName !== "body") {
|
||||
//console.log("Skipping because body is not targeted")
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -7460,12 +7506,10 @@ const AngularWorkflow = (defaultprops) => {
|
||||
const clipboard = (event.originalEvent || event).clipboardData.getData(
|
||||
"text/plain"
|
||||
);
|
||||
//console.log("Text: ", clipboard)
|
||||
//window.document.execCommand('insertText', false, text);
|
||||
//
|
||||
|
||||
try {
|
||||
const allnodes = cy.nodes().jsons()
|
||||
var parsedjson = JSON.parse(clipboard);
|
||||
// Check if array
|
||||
if (!Array.isArray(parsedjson)) {
|
||||
console.log("Not array! Adding to array.")
|
||||
parsedjson = [parsedjson]
|
||||
@@ -7473,7 +7517,6 @@ const AngularWorkflow = (defaultprops) => {
|
||||
|
||||
for (let jsonkey in parsedjson) {
|
||||
var item = parsedjson[jsonkey];
|
||||
console.log("Adding: ", item);
|
||||
|
||||
if (item.data === undefined || item.data === null) {
|
||||
console.log("Appending from here")
|
||||
@@ -7493,13 +7536,31 @@ const AngularWorkflow = (defaultprops) => {
|
||||
item.data.isStartNode = false
|
||||
}
|
||||
|
||||
// Find a cy.data() label with the same name
|
||||
const foundnodes = allnodes.filter((data) => {
|
||||
//console.log("COMP: ", data.data.label, item.data.label)
|
||||
if (data.data.label === undefined || data.data.label === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
return data.data.label === item.data.label
|
||||
})
|
||||
|
||||
if (foundnodes !== undefined && foundnodes !== null && foundnodes.length > 0) {
|
||||
// Weird naming copy lol
|
||||
item.data.label = item.data.label + "_copy_" + allnodes.length
|
||||
}
|
||||
|
||||
item.data.id = uuidv4()
|
||||
|
||||
cy.add({
|
||||
group: item.group,
|
||||
data: item.data,
|
||||
position: item.position,
|
||||
});
|
||||
position: {
|
||||
x: item.position.x+20,
|
||||
y: item.position.y+20,
|
||||
},
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Error pasting: ", e);
|
||||
@@ -9572,7 +9633,12 @@ const AngularWorkflow = (defaultprops) => {
|
||||
console.log("Error fitting cytoscape (4): ", error)
|
||||
}
|
||||
|
||||
|
||||
cy.on("boxselect", "node", (e) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
console.log("BOXSELECT: ", e.boxSelectElements)
|
||||
if (e.target.data("isButton") || e.target.data("isDescriptor") || e.target.data("isSuggestion")) {
|
||||
e.target.unselect();
|
||||
}
|
||||
@@ -9582,10 +9648,15 @@ const AngularWorkflow = (defaultprops) => {
|
||||
|
||||
cy.on("boxstart", (e) => {
|
||||
console.log("START");
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
});
|
||||
|
||||
cy.on("boxend", (e) => {
|
||||
console.log("END: ", cy)
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
console.log("END: ", e.target, cy)
|
||||
var cydata = cy.$(":selected").jsons();
|
||||
if (cydata !== undefined && cydata !== null && cydata.length > 0) {
|
||||
// Unselect all nodes
|
||||
@@ -10658,6 +10729,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// HTML -> Canvas overlap check
|
||||
if (
|
||||
e.pageX > cycontainer.offsetLeft
|
||||
@@ -10670,6 +10742,9 @@ const AngularWorkflow = (defaultprops) => {
|
||||
return
|
||||
}
|
||||
|
||||
findClosestNode({
|
||||
target: currentnode,
|
||||
}, currentnode.data())
|
||||
|
||||
currentnode[0].renderedPosition("x", e.pageX - cycontainer.offsetLeft)
|
||||
currentnode[0].renderedPosition("y", e.pageY - cycontainer.offsetTop)
|
||||
@@ -17381,11 +17456,11 @@ const AngularWorkflow = (defaultprops) => {
|
||||
selectedTrigger.status === "running"
|
||||
}
|
||||
defaultValue={
|
||||
selectedTrigger?.parameters === undefined || selectedTrigger?.parameters === null || selectedTrigger?.parameters?.length === 0 ? isCloud || selectedTrigger?.environment === "cloud" ? "*/25 * * * *" : "60" : selectedTrigger.parameters[0]?.value
|
||||
selectedTrigger?.parameters === undefined || selectedTrigger?.parameters === null || selectedTrigger?.parameters?.length === 0 ? isCloud || selectedTrigger?.environment === "cloud" ? "*/25 * * * *" : "60" : selectedTrigger?.parameters[0]?.value
|
||||
}
|
||||
color="primary"
|
||||
placeholder={
|
||||
selectedTrigger.parameters === undefined ? isCloud || selectedTrigger?.environment === "cloud" ? "*/25 * * * *" : "60" : selectedTrigger.parameters[0]?.value
|
||||
selectedTrigger.parameters === undefined || selectedTrigger?.parameters === null || selectedTrigger?.parameters?.length === 0 ? isCloud || selectedTrigger?.environment === "cloud" ? "*/25 * * * *" : "60" : selectedTrigger?.parameters[0]?.value
|
||||
}
|
||||
onBlur={(e) => {
|
||||
setTriggerCronWrapper(e.target.value);
|
||||
@@ -17734,10 +17809,24 @@ const AngularWorkflow = (defaultprops) => {
|
||||
onChange={(e) => {
|
||||
if (lastSaved === false && originalWorkflow.id === workflow.id) {
|
||||
setSuborgWorkflows([])
|
||||
|
||||
saveWorkflow(workflow, undefined, undefined, e.target.value)
|
||||
toast.warn(`Saving workflow first due to detected changes. If more than 10 auth`, {
|
||||
|
||||
/* Standard re-loads */
|
||||
setAllTriggers(undefined)
|
||||
setSelectedTriggerIndex(-1)
|
||||
|
||||
getEnvironments(e.target.value)
|
||||
getAppAuthentication(undefined, undefined, undefined, e.target.value)
|
||||
getFiles(e.target.value)
|
||||
listOrgCache(e.target.value)
|
||||
/* Standard re-loads */
|
||||
|
||||
toast.warn(`Saving workflow first due to detected changes.`, {
|
||||
autoClose: 2000,
|
||||
})
|
||||
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -17761,12 +17850,14 @@ const AngularWorkflow = (defaultprops) => {
|
||||
}
|
||||
|
||||
ReactDOM.unstable_batchedUpdates(() => {
|
||||
/* Standard re-loads */
|
||||
setAllTriggers(undefined)
|
||||
setSelectedTriggerIndex(-1)
|
||||
getEnvironments(e.target.value)
|
||||
getAppAuthentication(undefined, undefined, undefined, e.target.value)
|
||||
getFiles(e.target.value)
|
||||
listOrgCache(e.target.value)
|
||||
/* Standard re-loads */
|
||||
|
||||
// Reset the save button to ensure random saves don't occur during move
|
||||
setLastSaved(true)
|
||||
@@ -19035,7 +19126,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
{workflow.public || userdata.support == true ?
|
||||
<Tooltip
|
||||
color="secondary"
|
||||
title="Download public workflow"
|
||||
title="Download workflow"
|
||||
placement="top-start"
|
||||
>
|
||||
<span>
|
||||
@@ -20038,7 +20129,8 @@ const AngularWorkflow = (defaultprops) => {
|
||||
}
|
||||
}
|
||||
|
||||
to_be_copied.replaceAll(" ", "_");
|
||||
to_be_copied = to_be_copied.replaceAll(" ", "_");
|
||||
console.log("COPY: ", to_be_copied);
|
||||
const elementName = "copy_element_shuffle";
|
||||
var copyText = document.getElementById(elementName);
|
||||
if (copyText !== null && copyText !== undefined) {
|
||||
@@ -21563,7 +21655,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
|
||||
if (data.name === "shuffle_action_logs" && data.value !== undefined && data.value !== null && data.value.length > 0 && data.value.includes("add env SHUFFLE_LOGS_DISABLED")) {
|
||||
return (
|
||||
<div style={{ maxWidth: 600, marginTop: 15, overflowX: "hidden", }}>
|
||||
<div style={{ maxWidth: 600, marginTop: 75, overflowX: "hidden", }}>
|
||||
<Typography
|
||||
variant="body1"
|
||||
style={{}}
|
||||
@@ -21571,7 +21663,7 @@ const AngularWorkflow = (defaultprops) => {
|
||||
<b>Action Logs</b>
|
||||
</Typography>
|
||||
<Typography variant="body2" style={{ whiteSpace: 'pre-line', }}>
|
||||
Logs for an action are not available without <a style={{ color: "#FF8544", }} href="/admin?tab=locations" target="_blank" rel="noopener noreferrer">an onprem environment</a> with the <a style={{ color: "#FF8544", }} href="/docs/configuration#scaling-shuffle" target="_blank" rel="noopener noreferrer">SHUFFLE_LOGS_DISABLED</a> environment variable set to false: SHUFFLE_LOGS_DISABLED=false. Logs are enabled by default, except in scale mode.
|
||||
More log details for this action are not available without <a style={{ color: "#FF8544", }} href="/admin?tab=locations" target="_blank" rel="noopener noreferrer">an onprem environment</a> with the <a style={{ color: "#FF8544", }} href="/docs/configuration#scaling-shuffle" target="_blank" rel="noopener noreferrer">SHUFFLE_LOGS_DISABLED</a> environment variable set to false: SHUFFLE_LOGS_DISABLED=false. Logs are enabled by default, except in scale mode.
|
||||
</Typography>
|
||||
</div>
|
||||
)
|
||||
@@ -22139,9 +22231,9 @@ const AngularWorkflow = (defaultprops) => {
|
||||
variant="h6"
|
||||
style={{ marginBottom: 0, marginTop: 0 }}
|
||||
>
|
||||
Variables <span style={{ fontSize: 10 }}>(click to expand)</span>
|
||||
Variable & Debug info <span style={{ fontSize: 10 }}>({selectedResult?.action?.parameters?.length})</span>
|
||||
</Typography>
|
||||
{selectedResult.action.parameters.map((data, index) => {
|
||||
{selectedResult?.action?.parameters?.map((data, index) => {
|
||||
if (data.value.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -176,16 +176,18 @@ export const GetParsedPaths = (inputdata, basekey) => {
|
||||
}
|
||||
|
||||
if (typeof inputdata !== "object") {
|
||||
return parsedValues;
|
||||
return parsedValues
|
||||
}
|
||||
|
||||
for (const [key, value] of Object.entries(inputdata)) {
|
||||
for (var [key, value] of Object.entries(inputdata)) {
|
||||
key = key.replaceAll(" ", "_")
|
||||
|
||||
// Check if loop or JSON
|
||||
const extra = basekey.length > 0 ? splitkey : "";
|
||||
const basekeyname = `${basekey
|
||||
.slice(1, basekey.length)
|
||||
.split(".")
|
||||
.join(splitkey)}${extra}${key}`;
|
||||
.join(splitkey)}${extra}${key}`
|
||||
|
||||
// Handle direct loop!
|
||||
if (!isNaN(key) && basekey === "") {
|
||||
@@ -205,7 +207,8 @@ export const GetParsedPaths = (inputdata, basekey) => {
|
||||
type: "list",
|
||||
name: `${splitkey}list`,
|
||||
autocomplete: `${basekey.replaceAll(" ", "_")}.#`,
|
||||
});
|
||||
})
|
||||
|
||||
const returnValues = GetParsedPaths(value, `${basekey}.#`);
|
||||
for (var subkey in returnValues) {
|
||||
parsedValues.push(returnValues[subkey]);
|
||||
|
||||
@@ -49,7 +49,7 @@ const searchClient = algoliasearch(
|
||||
);
|
||||
|
||||
// AppCard Component
|
||||
const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl, deactivatedIndexes, currTab, handleAppClick, leftSideBarOpenByClick, userdata, fetchApps }) => {
|
||||
const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl, deactivatedIndexes, currTab, handleAppClick, leftSideBarOpenByClick, userdata, fetchApps, appsToShow, setAppsToShow, setUserApps, }) => {
|
||||
const navigate = useNavigate();
|
||||
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io" || window.location.host === "localhost:3000";
|
||||
const appUrl = isCloud ? `/apps/${data.id}` : `https://shuffler.io/apps/${data.id}`;
|
||||
@@ -223,6 +223,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
|
||||
)
|
||||
}
|
||||
<Button
|
||||
disabled={data?.reference_org === userdata?.active_org?.id}
|
||||
className="deactivate-button"
|
||||
sx={{
|
||||
width: 110,
|
||||
@@ -244,7 +245,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
const url = `${globalUrl}/api/v1/apps/${data.id}/deactivate`;
|
||||
toast("Deactivating app. Please wait...");
|
||||
//toast("Deactivating app. Please wait...");
|
||||
fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
@@ -256,10 +257,25 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
|
||||
.then((response) => response.json())
|
||||
.then((responseJson) => {
|
||||
if (responseJson.success === false) {
|
||||
if (responseJson?.reason !== undefined && responseJson?.reason !== null && responseJson?.reason !== "") {
|
||||
toast.error(responseJson.reason);
|
||||
} else {
|
||||
toast.success("App Deactivated Successfully.");
|
||||
fetchApps();
|
||||
toast.error("Failed to deactivate app. Please try again later.")
|
||||
}
|
||||
} else {
|
||||
toast.success("App deactivated successfully. Will take effect on refresh..")
|
||||
|
||||
/*
|
||||
// This somehow didn't work
|
||||
if (appsToShow !== undefined && appsToShow !== null && appsToShow.length > 0) {
|
||||
const newApps = appsToShow?.filter((app) => app.id !== data.id)
|
||||
if (newApps !== undefined && newApps !== null && newApps.length > 0) {
|
||||
setAppsToShow(newApps)
|
||||
setUserApps(newApps)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
@@ -1860,8 +1876,6 @@ const Apps2 = (props) => {
|
||||
color: "#FF8544"
|
||||
}
|
||||
|
||||
console.log("User", userdata)
|
||||
|
||||
return (
|
||||
<div style={{ paddingTop: 70, paddingLeft: leftSideBarOpenByClick ? 200 : 0, transition: "padding-left 0.3s ease", backgroundColor: "#1A1A1A", fontFamily: theme?.typography?.fontFamily, zoom: 0.7, }}>
|
||||
<InstantSearch searchClient={searchClient} indexName="appsearch">
|
||||
@@ -2247,6 +2261,10 @@ const Apps2 = (props) => {
|
||||
leftSideBarOpenByClick={leftSideBarOpenByClick}
|
||||
userdata={userdata}
|
||||
fetchApps={fetchApps}
|
||||
|
||||
setUserApps={setUserApps}
|
||||
appsToShow={appsToShow}
|
||||
setAppsToShow={setAppsToShow}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@@ -2296,6 +2314,9 @@ const Apps2 = (props) => {
|
||||
<AppCard key={index} data={data} index={index} mouseHoverIndex={mouseHoverIndex} setMouseHoverIndex={setMouseHoverIndex} globalUrl={globalUrl} deactivatedIndexes={deactivatedIndexes} currTab={currTab} userdata={userdata}
|
||||
handleAppClick={handleAppClick} leftSideBarOpenByClick={leftSideBarOpenByClick}
|
||||
fetchApps={fetchApps}
|
||||
setUserApps={setUserApps}
|
||||
appsToShow={appsToShow}
|
||||
setAppsToShow={setAppsToShow}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -77,6 +77,24 @@ const RunWorkflow = (defaultprops) => {
|
||||
const [boxWidth, setBoxWidth] = React.useState(500)
|
||||
const [inputQuestions, setInputQuestions] = React.useState([])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (workflow === undefined || workflow === null || Object.keys(workflow).length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if (workflow.input_questions === undefined || workflow.input_questions === null) {
|
||||
return
|
||||
}
|
||||
|
||||
// Checks if it's a user input-node based or not
|
||||
if ((answer !== undefined && answer !== null) || (foundSourcenode !== undefined && foundSourcenode !== null)) {
|
||||
} else {
|
||||
setInputQuestions(workflow.input_questions)
|
||||
setUpdate(Math.random())
|
||||
}
|
||||
}, [workflow])
|
||||
|
||||
const IframeWrapper = (props) => {
|
||||
var propsCopy = JSON.parse(JSON.stringify(props))
|
||||
propsCopy.width = 400
|
||||
|
||||
@@ -447,6 +447,7 @@ const Welcome = (props) => {
|
||||
}
|
||||
|
||||
navigate("/welcome?tab=2")
|
||||
setActiveStep(1)
|
||||
setShowWelcome(true)
|
||||
}}>
|
||||
<CardActionArea style={actionObject}>
|
||||
|
||||
@@ -553,6 +553,10 @@ export const validateJson = (showResult) => {
|
||||
// Check fields if they can be parsed too
|
||||
try {
|
||||
for (const [key, value] of Object.entries(result)) {
|
||||
if (typeof value === "string") {
|
||||
value = value.replaceAll(" ", "_")
|
||||
}
|
||||
|
||||
if (typeof value === "string" && (value.startsWith("{") || value.startsWith("["))) {
|
||||
//console.log("CHECKING STRING: ", value)
|
||||
|
||||
@@ -573,6 +577,10 @@ export const validateJson = (showResult) => {
|
||||
// Usually only reaches here if raw array > dict > value
|
||||
if (typeof showResult !== "array") {
|
||||
for (const [subkey, subvalue] of Object.entries(value)) {
|
||||
if (typeof subvalue === "string") {
|
||||
subvalue = subvalue.replaceAll(" ", "_")
|
||||
}
|
||||
|
||||
if (typeof subvalue === "string" && (subvalue.startsWith("{") || subvalue.startsWith("["))) {
|
||||
const inside_result = validateJson(subvalue)
|
||||
if (inside_result.valid) {
|
||||
@@ -1841,9 +1849,13 @@ const Workflows = (props) => {
|
||||
|
||||
var parsedworkflows = [];
|
||||
for (var key in newSubflows) {
|
||||
if (key === data.id) {
|
||||
continue
|
||||
}
|
||||
|
||||
const foundWorkflow = workflows.find(
|
||||
(workflow) => workflow.id === newSubflows[key]
|
||||
);
|
||||
)
|
||||
if (foundWorkflow !== undefined && foundWorkflow !== null) {
|
||||
parsedworkflows.push(foundWorkflow);
|
||||
}
|
||||
@@ -1854,7 +1866,7 @@ const Workflows = (props) => {
|
||||
"Appending subflows during export: ",
|
||||
parsedworkflows.length
|
||||
);
|
||||
data.subflows = parsedworkflows;
|
||||
data.subflows = parsedworkflows
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1935,6 +1935,10 @@ const Workflows2 = (props) => {
|
||||
|
||||
var parsedworkflows = [];
|
||||
for (var key in newSubflows) {
|
||||
if (key === data.id) {
|
||||
continue
|
||||
}
|
||||
|
||||
const foundWorkflow = workflows.find(
|
||||
(workflow) => workflow.id === newSubflows[key]
|
||||
);
|
||||
@@ -2362,7 +2366,6 @@ const Workflows2 = (props) => {
|
||||
|
||||
<MenuItem
|
||||
style={{ backgroundColor: theme.palette.inputColor, color: "white" }}
|
||||
disabled={isDistributed}
|
||||
onClick={() => {
|
||||
setDeleteModalOpen(true);
|
||||
setSelectedWorkflowId(data.id);
|
||||
|
||||
@@ -10,7 +10,7 @@ require (
|
||||
github.com/docker/docker v27.5.0+incompatible
|
||||
github.com/docker/go-connections v0.5.0
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/shuffle/shuffle-shared v0.7.95
|
||||
github.com/shuffle/shuffle-shared v0.8.0
|
||||
k8s.io/api v0.30.2
|
||||
k8s.io/apimachinery v0.30.2
|
||||
)
|
||||
|
||||
@@ -319,6 +319,8 @@ github.com/shuffle/shuffle-shared v0.7.82 h1:La11F5jp9bNtM3VuR9PawyWo90/vZ+1Txo4
|
||||
github.com/shuffle/shuffle-shared v0.7.82/go.mod h1:bBXhEsPKjxln0mFnSeri7gIJ3tL/636Sh5NyTyNrvIQ=
|
||||
github.com/shuffle/shuffle-shared v0.7.83 h1:OyyDo0ii8rOYHN5wGbcM94JuDKLmbZ9jhMQ0+/KMb0A=
|
||||
github.com/shuffle/shuffle-shared v0.7.83/go.mod h1:bBXhEsPKjxln0mFnSeri7gIJ3tL/636Sh5NyTyNrvIQ=
|
||||
github.com/shuffle/shuffle-shared v0.7.96 h1:mH6Bkzn8QIFntkcUxPfyMZJY2r7PNKfc0zWYjZXYQm8=
|
||||
github.com/shuffle/shuffle-shared v0.7.96/go.mod h1:bBXhEsPKjxln0mFnSeri7gIJ3tL/636Sh5NyTyNrvIQ=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
|
||||
@@ -142,6 +142,7 @@ func init() {
|
||||
os.Setenv("SHUFFLE_PIPELINE_AUTH", pipelineApikey)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// form id of current running container
|
||||
@@ -1239,18 +1240,20 @@ func deployK8sWorker(image string, identifier string, env []string) error {
|
||||
}
|
||||
|
||||
func deployWorker(image string, identifier string, env []string, executionRequest shuffle.ExecutionRequest) error {
|
||||
|
||||
|
||||
if len(os.Getenv("REGISTRY_URL")) > 0 && os.Getenv("REGISTRY_URL") != "" {
|
||||
env = append(env, fmt.Sprintf("REGISTRY_URL=%s", os.Getenv("REGISTRY_URL")))
|
||||
}
|
||||
|
||||
// if isKubernetes == "true" {
|
||||
// err := deployK8sWorker(image, identifier, env, executionRequest)
|
||||
// if err != nil {
|
||||
// log.Printf("[ERROR] Failed deploying Kubernetes worker: %s", err)
|
||||
// }
|
||||
if swarmConfig == "run" || swarmConfig == "swarm" || isKubernetes == "true" {
|
||||
// FIXME: Should we handle replies properly?
|
||||
// In certain cases, a workflow may e.g. be aborted already. If it's aborted, that returns
|
||||
// a 401 from the worker, which returns an error here
|
||||
go sendWorkerRequest(executionRequest, image, env)
|
||||
|
||||
// return err
|
||||
// }
|
||||
return nil
|
||||
}
|
||||
|
||||
// Binds is the actual "-v" volume.
|
||||
// Max 20% CPU every second
|
||||
@@ -1298,6 +1301,10 @@ func deployWorker(image string, identifier string, env []string, executionReques
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//var swarmConfig = os.Getenv("SHUFFLE_SWARM_CONFIG")
|
||||
parsedUuid := uuid.NewV4()
|
||||
|
||||
config := &container.Config{
|
||||
Image: image,
|
||||
Env: env,
|
||||
@@ -1305,22 +1312,12 @@ func deployWorker(image string, identifier string, env []string, executionReques
|
||||
|
||||
if isKubernetes != "true" {
|
||||
hostConfig.NetworkMode = container.NetworkMode(fmt.Sprintf("container:%s", containerId))
|
||||
|
||||
if strings.ToLower(cleanupEnv) != "false" {
|
||||
hostConfig.AutoRemove = true
|
||||
}
|
||||
}
|
||||
|
||||
//var swarmConfig = os.Getenv("SHUFFLE_SWARM_CONFIG")
|
||||
parsedUuid := uuid.NewV4()
|
||||
if swarmConfig == "run" || swarmConfig == "swarm" || isKubernetes == "true" {
|
||||
// FIXME: Should we handle replies properly?
|
||||
// In certain cases, a workflow may e.g. be aborted already. If it's aborted, that returns
|
||||
// a 401 from the worker, which returns an error here
|
||||
go sendWorkerRequest(executionRequest, image, env)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//log.Printf("[INFO] Identifier: %s", identifier)
|
||||
cont, err := dockercli.ContainerCreate(
|
||||
context.Background(),
|
||||
@@ -1354,6 +1351,8 @@ func deployWorker(image string, identifier string, env []string, executionReques
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("WORKER STARTING WITH ENV: %#v", env)
|
||||
|
||||
containerStartOptions := container.StartOptions{}
|
||||
err = dockercli.ContainerStart(context.Background(), cont.ID, containerStartOptions)
|
||||
if err != nil {
|
||||
@@ -1388,27 +1387,30 @@ func deployWorker(image string, identifier string, env []string, executionReques
|
||||
log.Printf("[INFO][%s] Worker Container created (2). Environment %s: docker logs %s", executionRequest.ExecutionId, environment, cont.ID)
|
||||
}
|
||||
|
||||
//stats, err := cli.ContainerInspect(context.Background(), containerName)
|
||||
//if err != nil {
|
||||
// log.Printf("Failed checking worker %s", containerName)
|
||||
// return
|
||||
//}
|
||||
stats, err := dockercli.ContainerInspect(context.Background(), containerName)
|
||||
if err != nil {
|
||||
log.Printf("[WARNING] Failed checking worker %s", containerName)
|
||||
return nil
|
||||
}
|
||||
|
||||
//containerStatus := stats.ContainerJSONBase.State.Status
|
||||
//if containerStatus != "running" {
|
||||
// log.Printf("Status of %s is %s. Should be running. Will reset", containerName, containerStatus)
|
||||
// err = stopWorker(containerName)
|
||||
// if err != nil {
|
||||
// log.Printf("Failed stopping worker %s", execution.ExecutionId)
|
||||
// return
|
||||
// }
|
||||
containerStatus := stats.ContainerJSONBase.State.Status
|
||||
if containerStatus != "running" {
|
||||
log.Printf("[ERROR] Status of %s is %s. Should be running. Will reset", containerName, containerStatus)
|
||||
}
|
||||
/*
|
||||
err = stopWorker(containerName)
|
||||
if err != nil {
|
||||
log.Printf("Failed stopping worker %s", execution.ExecutionId)
|
||||
return nil
|
||||
}
|
||||
|
||||
// err = deployWorke(cli, workerImage, containerName, env)
|
||||
// if err != nil {
|
||||
// log.Printf("Failed executing worker %s in state %s", execution.ExecutionId, containerStatus)
|
||||
// return
|
||||
// }
|
||||
//}
|
||||
err = deployWorker(dockercli, workerImage, containerName, env)
|
||||
if err != nil {
|
||||
log.Printf("Failed executing worker %s in state %s", execution.ExecutionId, containerStatus)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
log.Printf("[INFO][%s] New Worker created. Environment %s: docker logs %s", executionRequest.ExecutionId, environment, cont.ID)
|
||||
}
|
||||
@@ -1917,6 +1919,10 @@ func main() {
|
||||
cleanupEnv = "true"
|
||||
}
|
||||
|
||||
if len(cleanupEnv) > 0 {
|
||||
log.Printf("[DEBUG] Verbose mode. NOT cleaning up. Cleanup env: %s", cleanupEnv)
|
||||
}
|
||||
|
||||
workerTimeout := 600
|
||||
if workerTimeoutEnv != "" {
|
||||
tmpInt, err := strconv.Atoi(workerTimeoutEnv)
|
||||
|
||||
@@ -8,7 +8,7 @@ require (
|
||||
github.com/docker/docker v27.5.0+incompatible
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/shuffle/shuffle-shared v0.7.95
|
||||
github.com/shuffle/shuffle-shared v0.8.0
|
||||
k8s.io/api v0.30.2
|
||||
k8s.io/apimachinery v0.30.2
|
||||
k8s.io/client-go v0.30.2
|
||||
|
||||
Reference in New Issue
Block a user