diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000..44517ecf --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +@Ontotext-AD/tes diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..a9ae12bd --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +tes@ontotext.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/.github/ISSUE_TEMPLATE/bug_template.yml b/.github/ISSUE_TEMPLATE/bug_template.yml new file mode 100644 index 00000000..7fe8e61f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_template.yml @@ -0,0 +1,50 @@ +name: 🐞 Bug report +description: File a bug/issue +title: "[BUG] " +labels: ["bug"] +body: + - type: checkboxes + attributes: + label: Is there an existing issue for this? + description: Please search to see if an issue already exists for the bug you encountered. + options: + - label: I have searched the existing issues + required: true + - type: textarea + attributes: + label: Affected Version + description: The version of the Helm chart you are using. + validations: + required: true + - type: textarea + attributes: + label: Current Behavior + description: A concise description of what you're experiencing. + validations: + required: true + - type: textarea + attributes: + label: Expected Behavior + description: A concise description of what you expected to happen. + validations: + required: true + - type: textarea + attributes: + label: Steps To Reproduce + description: Steps to reproduce the behavior. + placeholder: | + 1. In this environment... + 1. With this config... + 1. Run '...' + 1. See error... + validations: + required: false + - type: textarea + attributes: + label: Anything else? + description: | + Links? References? Screenshots? Anything that will give us more context about the issue you are encountering! + + Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..2bf36a53 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,6 @@ +blank_issues_enabled: true + +contact_links: + - name: GraphDB Support + url: graphdb-support@ontotext.com + about: Please, report any type of vulnerability issues via email diff --git a/.github/security.md b/.github/security.md new file mode 100644 index 00000000..fffe75e7 --- /dev/null +++ b/.github/security.md @@ -0,0 +1,6 @@ +# Security Policy + +## Reporting a Vulnerability + +If you believe you've discovered a security vulnerability, please do not submit issues on GitHub. +Instead, report it via email at [graphdb-support@ontotext.com](mailto:graphdb-support@ontotext.com?subject=GraphDB%20Helm%20Vulnerability). diff --git a/.gitignore b/.gitignore index ca869f1e..da59e065 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,8 @@ # Helm values_overrides.yaml template_output.yaml + +# Sensitive files +*.license +*.gpg +*.pgp diff --git a/CHANGELOG.md b/CHANGELOG.md index 93c84141..8c170490 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,161 @@ # GraphDB Helm chart release notes +## Version 11.0.0 + +Version 11 of the chart addresses a bunch of legacy issues and aims to provide much better user experience and reliability. + +### Highlights + +* Version - The Helm chart is no longer tied with the version of GraphDB and has a separate development and release cycle. +* Naming - Removed hardcoded resource names in favor of using the name templates from [_labels.tpl](templates/_labels.tpl) +* Labels - Added the possibility to provide custom labels and annotations to almost every single resource +* Implementation Agnostic - Removed the dependency of particular ingress controllers and storage classes +* Security - Enabled security context by default +* Configurations - Added multiple new configurations to customize both GraphDB and the Kubernetes resources + +### Breaking + +- Updated the chart to require Kubernetes version 1.26+ +- Enabled security context by default for all pods and containers +- Updated the GraphDB deployment URL to be http://graphdb.127.0.0.1.nip.io/ by default, see `configuration.externalUrl` +- Resource names are no longer hardcoded and are using the templates for `nameOverride` and `fullnameOverride` +- Updated the ingress to be agnostic to the ingress implementation. It will no longer assume that NGINX is the ingress controller in the + cluster and will no longer deploy NGINX specific annotations by default. Removed anything related to NGINX as configurations. +- Removed setting FQDN as hostnames in GraphDB and the proxy in favor of dynamically resolving and configuring the hostnames in the provisioning init + containers +- Removed the default value from `global.imageRegistry`, the chart now uses the value from `image.registry` +- Removed `global.storageClass` in favor of using by default the default storage class in the cluster. Templates will no longer + use `global.storageClass`. +- Renamed `extraLabels` to just `labels` +- Moved `images.graphdb` configurations to just `image` +- Moved `deployment.imagePullPolicy` to `image.pullPolicy` and `deployment.imagePullSecret` to `image.pullSecrets` + - Note that `image.pullSecrets` is now a list +- Moved `deployment.ingress` to just `ingress` +- Moved `deployment.tls` to `ingress.tls` +- Moved `graphdb` and `graphdb.node` configurations on the root level +- Moved all proxy configurations from `graphdb.clusterProxy` to just `proxy` +- Renamed `proxy.persistence.enablePersistence` toggle to just `enabled` +- Moved `proxy.serviceType` to `proxy.service.type` +- Configmaps from `graphdb.configs` are now under `configuration`, `repositories`, `cluster` and `security` with a different structure allowing + better reuse of existing configmaps +- Moved `graphdb.clusterConfig` configurations + - Moved `graphdb.clusterConfig.nodesCount` to `replicas` + - Moved the rest of `graphdb.clusterConfig` configurations under `cluster`, `cluster.config` and `cluster.config.params` +- Moved `graphdb.security` configurations to `security` + - Moved `provisioningUsername` and `provisioningPassword` under `security.provisioner` +- Moved job related configurations from `graphdb` (e.g. `graphdb.jobResources`) to a new root section `jobs` +- Moved `graphdb.node.service` configurations to `headlessService` +- Moved `graphdb.import_directory_mount` configurations to `import.volumeMount` +- Renamed `pdb` to `podDisruptionBudget` and renamed `podDisruptionBudget.create` to `podDisruptionBudget.enabled` for consistency +- Renamed `messageSize` to `messageSizeKB` in the cluster creation configuration in `cluster.config.params` +- Renamed `java_args` to `defaultJavaArguments` and added a separate `javaArguments` that can be used for additional configurations, + see `configuration` and `proxy.configuration` +- Removed configuration overrides from the default `GDB_JAVA_OPTS`: `enable-context-index`, `entity-pool-implementation` + and `health.max.query.time.seconds` +- Removed the default logback XML configuration and configmap in favor of an [example](examples/custom-logback) and a new configuration options + under `configuration.logback` and `proxy.configuration.logback` +- Renamed GraphDB storage PVC template name prefix to `storage` and server import folder to `import` +- Moved `persistence.volumeClaimTemplateSpec` to `persistence.volumeClaimTemplate.spec` +- Updated the Service type of the proxy to be ClusterIP by default, see `proxy.service.type` +- And more, please refer to [values.yaml](values.yaml) + +### New + +- Added GraphDB and GraphDB proxy hostnames resolution in the init containers +- Added new annotation checksums for GraphDB and GraphDB proxy in order to detect changes in the properties configmaps + and ultimately trigger rolling update +- Added default Secret objects for GraphDB and the proxy that contain sensitive GraphDB configurations +- Added `serviceAccount` configurations allowing you to create or use an existing service account for the GraphDB pods +- Added more feature toggles: + - `headlessService.enabled` + - `proxy.service.enabled` + - `proxy.headlessService.enabled` + - `persistence.enabled` + - `proxy.persistence.enabled` + - `cluster.jobs.createCluster.enabled` - Enables or disables the cluster creation Job + - `cluster.jobs.patchCluster.enabled` - Enables or disables the Job for patching the cluster configuration + - `cluster.jobs.scaleCluster.enabled` - Enables or disables the Jobs for scaling up or down the cluster +- Added `image.digest` to optionally provide an expected digest of the image +- Added `annotations` for additional common annotations across all resources +- Added separate `proxy.labels` and `proxy.annotations` configurations for the cluster proxy +- Added new `global.clusterDomain` for reconfiguring the default Kubernetes cluster domain suffix in case it is different than `cluster.local` +- Added `namespaceOverride` for overriding the deployment namespace for all resources in case of multi-namespace deployment +- Added new configuration options for the default ingress `ingress`: + - Ability to override the `host` and `path` for GraphDB from `configuration.externalUrl` + - Ability to change the Ingress path type with `ingress.pathType` + - Inserting additional hosts and TLS configurations with `ingress.extraHosts` and `ingress.extraTLS` +- Added `security.admin` for configuring the initial password of the administrator user +- Added `security.initialUsers.users` for inserting additional users into the default initial user.js configuration +- Added `security.provisioner.existingSecret` and `security.provisioner.tokenKey` to provide an existing authentication token +- Added `cluster.token.existingSecret` and `cluster.token.secretKey` for using an existing Secret instead of providing the cluster secret + token as plaintext in values.yaml +- Added `cluster.config.existingConfigmap` to specify a custom configmap key if needed +- Added `configuration.properties` and `proxy.configuration.properties` for appending additional inline GraphDB configurations in their properties + configmaps +- Added `configuration.secretProperties` and `proxy.secretProperties` for appending additional inline sensitive GraphDB configurations if needed +- Added `configuration.extraProperties.existingConfigmap` and `proxy.configuration.extraProperties.existingConfigmap` for appending GraphDB properties + from an existing ConfigMap resource +- Added `configuration.extraProperties.existingSecret` and `proxy.configuration.extraProperties.existingSecret` for appending GraphDB properties from + an existing Secret resource +- Added a Service for single GraphDB deployments, configured with new configurations under `service` +- Added new configurations for the Service resources `service`, `headlessService`, `proxy.service` and `proxy.headlessService`: + - Added `labels` configurations for insertion of additional labels + - Added `ports` mappings in each Service + - Added `extraPorts` for mapping additional ports, use in combination with `extraContainerPorts` +- Added `containerPorts` and `proxy.containerPorts` for mapping the ports on which GraphDB listens on +- Added `extraContainerPorts` and `proxy.extraContainerPorts` to open additional container ports +- Added `service.externalTrafficPolicy` and `service.proxy.externalTrafficPolicy` to override the policy to Local if needed +- Added `service.healthCheckNodePort` and `service.proxy.healthCheckNodePort` to define a specific node port for LB health checks +- Added `service.loadBalancerClass` and `service.proxy.loadBalancerClass` to select a specific load balancer implementation +- Added `service.loadBalancerSourceRanges` and `service.proxy.loadBalancerSourceRanges` to restrict the external ingress traffic from the LB +- Added `service.externalIPs` and `service.proxy.externalIPs` to use existing external IPs +- Added `persistence.emptyDir` and `proxy.persistence.emptyDir` configurations for an emptyDir volume that will be used when the persistence is + disabled +- Added `tempVolume` configurations for an emptyDir volume mapped to the /tmp folder in the GraphDB containers +- Added configurations for extra `labels` and `annotations` for all persistent volume claim + templates: `persistence.volumeClaimTemplate`, `proxy.persistence.volumeClaimTemplate` and `import.volumeMount.volumeClaimTemplate` +- Added `imagePullPolicy` configuration to the Jobs containers +- Added `jobs.backoffLimit` for configuring the retry count for all jobs +- Added `jobs.ttlSecondsAfterFinished` for configuring the time in seconds for all jobs before deleting finished pods +- Added `jobs.persistence.emptyDir` configurations for the default temporary storage for all jobs +- Added `proxy.command` and `proxy.args` that override the default container entrypoint and command, use for troubleshooting +- Added `proxy.pdb` for configuring a pod disruption budget for the GraphDB Proxy +- Added `proxy.logback` configurations for providing the proxy with a custom Logback XML configuration +- Added `proxy.initContainerSecurityContext` and `proxy.initContainerResources` to avoid using the configurations from GraphDB +- Added `automountServiceAccountToken` with default value `false` effectively ejecting the service account token by default +- Added `updateStrategy` and `proxy.updateStrategy` for controlling the strategy when updating pods +- Added `podManagementPolicy` and `proxy.podManagementPolicy` for configuring how the pods are created and scaled +- Added `schedulerName` and `proxy.schedulerName` for overriding the default Kubernetes scheduler +- Added `dnsConfig`, `dnsPolicy`, `proxy.dnsConfig` and `proxy.dnsPolicy` for customizing the DNS resolution if needed +- Added `extraContainers` and `proxy.extraContainers` for inserting additional containers into the pods of GraphDB and the GraphDB proxy +- Added `initContainerDataPermissions` and `proxy.initContainerDataPermissions` for changing permissions in the storage volumes if needed +- Added `extraVolumeClaimTemplates` and `proxy.extraVolumeClaimTemplates` +- Added `extraObjects` as a way to insert additional Kubernetes objects into the deployment +- Added `priorityClassName` and `proxy.priorityClassName` configurations + +### Updates + +- GraphDB and GraphDB proxy properties configmaps are now applied by default +- References to existing configmaps and secrets are now processed as templates +- Node scheduling configurations are now processed as templates +- Values in `labels`, `annotations` and `imagePullSecrets` are now evaluated as templates +- Removed unused busybox image configurations from `images.busybox` +- Renamed the port mappings of GraphDB and GraphDB proxy to `http` and `rpc` +- Service resources and probes now refer to the target ports by their nicknames instead of explicit port numbers +- Added trimming when loading files in the configmaps and secrets +- Cluster jobs now automatically resolve the cluster domain +- Removed `files/config/graphdb.properties` and `files/config/proxy/graphdb.properties` and moved any defined properties directly into the ConfigMap + declarations +- Moved GraphDB specific properties from `GDB_JAVA_OPTS` into the properties ConfigMaps +- Added `-XX:-UseCompressedOops` in the default Java arguments to allow allocating heap sizes larger than 32GBs when the max heap size is based on + the `-XX:MaxRAMPercentage` Java option +- Ejected the default service account token in the GraphDB proxy pods +- Overhauled NOTES.txt to be more helpful +- Added default resource limits and requests for all init containers and provisioning jobs +- PodDisruptionBudget are enabled by default for both GraphDB and GraphDB proxy +- Updated init containers to invoke `bash` instead of `sh` +- Updated the default memory limits and requests to 4Gi + ## Version 10.6.0-R2 ### New @@ -34,7 +190,8 @@ ## Version 10.4.1 -- Added configurations for specifying resource values for all remaining containers, see `graphdb.node.initContainerResources` and `graphdb.jobResources`. +- Added configurations for specifying resource values for all remaining containers, see `graphdb.node.initContainerResources` + and `graphdb.jobResources`. ## Version 10.3.1-R2 diff --git a/Chart.yaml b/Chart.yaml index af758155..446ece58 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -3,11 +3,11 @@ # apiVersion: v2 name: graphdb -description: GraphDB is an enterprise ready Semantic Graph Database +description: GraphDB is a highly efficient, scalable and robust graph database with RDF and SPARQL support. type: application -version: 10.6.4 +version: 11.0.0 appVersion: 10.6.4 -kubeVersion: ^1.22.0-0 +kubeVersion: ^1.26.0-0 home: https://graphdb.ontotext.com/ icon: https://graphdb.ontotext.com/home/images/visual_Logo_GraphDB_02_12_2015.png maintainers: diff --git a/README.md b/README.md index d9aa3241..6903e5eb 100644 --- a/README.md +++ b/README.md @@ -1,263 +1,103 @@ -# Helm charts for GraphDB +# Helm Chart for GraphDB [![CI](https://github.com/Ontotext-AD/graphdb-helm/actions/workflows/ci.yml/badge.svg)](https://github.com/Ontotext-AD/graphdb-helm/actions/workflows/ci.yml) -![Version: 10.6.4](https://img.shields.io/badge/Version-10.6.4-informational?style=flat-square) +![Version: 11.0.0](https://img.shields.io/badge/Version-11.0.0-informational?style=flat-square) ![AppVersion: 10.6.4](https://img.shields.io/badge/AppVersion-10.6.4-informational?style=flat-square) -You can download the GraphDB Helm chart, including all sub-charts managed by Ontotext, from the [Ontotext Helm repository](https://maven.ontotext.com/repository/helm-public/). +<!-- +TODO: Add ArtifactHub badge when ready +[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/ontotext)](https://artifacthub.io/packages/helm/ontotext/graphdb) +--> -## Install -### Prerequisites - -#### Getting Started - -If this is your first time installing a Helm chart, you should read the following introductions -before continuing: - -- Docker https://docs.docker.com/get-started/ -- Kubernetes concepts https://kubernetes.io/docs/concepts/ -- Minikube https://kubernetes.io/docs/setup/learning-environment/minikube/ -- Helm https://helm.sh/docs/intro/quickstart/ - -#### Binaries -- Install Helm 3: https://helm.sh/docs/intro/install/ -- Install `kubectl`: https://kubernetes.io/docs/tasks/tools/install-kubectl/ - -**Note**: `sudo` may be required. - -#### Kubernetes environment - -##### Minikube - -Follow the install documentation https://kubernetes.io/docs/setup/learning-environment/minikube/ -for Minikube. +Welcome to the official [Helm](https://helm.sh/) chart repository for [GraphDB](https://www.ontotext.com/products/graphdb/)! +This Helm chart makes it easy to deploy and manage [GraphDB](https://www.ontotext.com/products/graphdb/) on your [Kubernetes](https://kubernetes.io/) cluster. -**Driver** +--- -Carefully choose the suitable Minikube driver https://minikube.sigs.k8s.io/docs/drivers/ for -your system. +:warning: **Important**: Beginning from version 11, the Helm chart has its own release cycle and is no longer tied to the version of GraphDB. -**Warning**: Some of them are compatible but have know issues. For example, the `docker` driver -does not support the ingress add-on which is required while the `none` driver goes into DNS -resolve loop in some Linux distributions. +--- -**Resources** +## Quickstart -It's important to define resource limitations for the Minikube environment, otherwise it will -default to limits that may not be sufficient to deploy the whole chart. - -The default resource limitations require around **12GB** of RAM. This is configurable per service in -[values.yaml](values.yaml) and should be tuned for every deployment. - -When starting Minikube, it's preferable to define a bit more than the required amount. -For example, to create a Minikube environment in VirtualBox with 8 CPUs and 16GB of memory, use: - -```bash -minikube start --vm-driver=virtualbox --cpus=8 --memory=16000 +```shell +helm repo add ontotext https://maven.ontotext.com/repository/helm-public/ +helm install graphdb ontotext/graphdb ``` -**Addons** +## About GraphDB -Minikube has built in services as part of its add-on system. By default, some of the required -plugins are disabled and have to be enabled. +<p align="center"> + <a href="https://www.ontotext.com/products/graphdb/"> + <picture> + <img src="https://www.ontotext.com/wp-content/uploads/2022/09/Logo-GraphDB.svg" alt="GraphDB logo" title="GraphDB" height="75"> + </picture> + </a> +</p> -To expose services, enable Minikube's ingress with: +Ontotext GraphDB is a highly efficient, scalable and robust graph database with RDF and SPARQL support. With excellent enterprise features, +integration with external search applications, compatibility with industry standards, and both community and commercial support, GraphDB is the +preferred database choice of both small independent developers and big enterprises. -```bash -minikube addons enable ingress -``` +<!-- +TODO: Info about the basic Helm chart features ? +## Features +--> -To collect metrics, enable Minikube's metrics server with: +## Prerequisites -```bash -minikube addons enable metrics-server -``` - -To enable Minikube's monitoring dashboard with: +* Kubernetes v1.26+ +* Helm v3.8+ -```bash -minikube dashboard -``` +### Getting Started -**DNS Resolving** +If this is your first time installing a Helm chart, you should read the following introductions before continuing: -The chart is deployed with a Kubernetes ingress service that is configured to listen for requests -on a specific hostname. Any other requests are not handled. +- Docker https://docs.docker.com/get-started/ +- Kubernetes concepts https://kubernetes.io/docs/concepts/ +- Helm https://helm.sh/docs/intro/quickstart/ -This hostname is specified in [values.yaml](values.yaml) under `deployment.host`. -By default, it's configured for `localhost` which is suitable for the `none` Minikube driver. -In every other case you have to reconfigure it to a hostname that is DNS resolvable. +After getting familiar with the above, you need to install the following binaries on your machine: -Some options are: +- Install Helm 3: https://helm.sh/docs/intro/install/ +- Install `kubectl`: https://kubernetes.io/docs/tasks/tools/install-kubectl/ -* Configure or update an existing DNS server - recommended for production deployment -* Update your hosts file - suitable for local development +Next, you would need access to a Kubernetes cluster. You can set up a local one or use one of the cloud providers, e.g.: -To find out the IP address of the Minikube environment, use: +* Minikube https://minikube.sigs.k8s.io/docs/ +* kind https://kind.sigs.k8s.io/ +* Amazon EKS https://aws.amazon.com/eks/ +* Azure AKS https://azure.microsoft.com/en-us/products/kubernetes-service +* Google GKE https://cloud.google.com/kubernetes-engine -```bash -minikube ip -``` +### GraphDB License -If you wish to access GraphDB locally on http://graphdb.local/ and the IP address of -the Minikube environment is `192.168.99.102` you should modify your hosts file with: +To use GraphDB Enterprise Edition features, you need a license. +If you have a GraphDB license, create a Secret object with a `graphdb.license` data entry: -``` -192.168.99.102 graphdb.local +```shell +kubectl create secret generic graphdb-license --from-file graphdb.license=graphdb.license ``` -See this how-to https://www.howtogeek.com/27350/beginner-geek-how-to-edit-your-hosts-file/ -about modifying the hosts file in different OS. - -#### Secrets - -If you have a GraphDB license, create a secret with a `graphdb.license` -data entry: - -```bash -kubectl create secret generic graphdb-license --from-file graphdb.license -``` -then add the secret name to the values.yaml file as `graphdb.node.license` +Then add the secret name to the values.yaml file under the `license.existingSecret` configuration. **Note**: Secret names can differ from the given examples in the [values.yaml](values.yaml), but their configurations should be updated to refer to the correct ones. Note that the licenses can be set for all node instances. Please setup correctly according to the licensing agreements. -#### Updating an expired GraphDB license - -When the helm chart is installed the license will be provisioned through the secret set in the `graphdb.node.license` value. -When a license expires you'll have to update the secret, so GraphDB instances don't get provisioned with the old license. -In order NOT to restart your current GraphDB instances, you can copy your new license named `graphdb.license` in your GraphDB pods in folder `/opt/graphdb/home/work`. -It's important to name your file exactly `graphdb.license`! - -```bash -kubectl delete secret graphdb-license -kubectl create secret generic graphdb-license --from-file graphdb.license -kubectl cp graphdb.license graphdb-node-0:/opt/graphdb/home/work -``` - -**Note**: If you use a standalone GraphDB you can also change it through the workbench, but if you don't update the secret next restart will provision the old license. - -### Cluster migration from GraphDB 9.x to 10.0 - -**Warning**: Before starting the migration change your master into read only mode. The process is irreversible and full backup is HIGHLY advisable. At minimum backup the PV of the worker you are planing to use for migration. - -The Helm chart is completely new and not backwards-compatible. - -1. Make all masters read only, you can use the workbench. -2. Using the workbench disconnect all repositories of the worker which we are going to use to migrate to 10.0. -If you've used the official GraphDB helm chart you can select any worker. In case of a custom implementation select one that can easily be scaled down. - - **Note**: Only the repositories that are on the worker will be migrated into the new cluster! -3. Get the PV information of the worker, noting down the capacity and the access mode: - ```bash - kubectl get pv - ``` -4. Note down the resource limits of the worker node: - ```bash - kubectl get pod graphdb-worker-<selected-worker> -o yaml | grep -B 2 memory - ``` -5. Make sure all the important settings saved in the settings.js of the master are present in the worker's. Their only difference - should be the lack of locations in the worker's settings. - ```bash - kubectl cp graphdb-master-1-0:/opt/graphdb/home/work/workbench/settings.js settings_m.js - kubectl cp graphdb-worker-<selected-worker>:/opt/graphdb/home/work/workbench/settings.js settings_w.js - diff settings_m.js settings_w.js - ``` - If anything other than the locations is different between the files assume that the master's file is correct and copy it to the worker: - ```bash - kubectl cp settings_m.js graphdb-worker-<selected-worker>:/opt/graphdb/home/work/workbench/settings.js - ``` -6. During a replication of a node GraphDB 10 can take double the storage which 9.x takes, so you might need to increase your PV size! To do this - we recommend checking the documentation of your cloud service provider but in general the procedure is: - - Make sure `allowVolumeExpansion: true` is set in your used storageClass. - - Request a change in volume capacity by editing your PVC's `spec.resources.requests.storage` - - Verify the change has taken effect with `get pvc <pvc-name> -o yaml` and checking the `status.capacity` field. -7. Scale down the selected worker. In the official GraphDB every worker has it's' own statefulset. - List all the statefulsets to find the name of the worker you want to scale down: - ```bash - kubectl get statefulsets - ``` - Then change the number of replicas to 0: - ```bash - kubectl scale statefulsets <stateful-set-name> --replicas=0 - ``` -8. Once the worker is down patch the worker's PV with `"persistentVolumeReclaimPolicy":"Retain"`: - ```bash - kubectl patch pv <worker-pv-name> -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' - ``` -9. Delete the worker's PVC. - ```bash - kubectl delete pvc <worker-pvc-name> - ``` -10. Patch the PV with `"claimRef":null` so it can go from status Released to Available: - ```bash - kubectl patch pv <worker-pv-name> -p '{"spec":{"claimRef":null}}' - ``` -11. Patch the PV with `claimRef` matching the PVC that will be generated by the `volumeClaimTemplates`: - ```bash - kubectl patch pv <worker-pv-name> -p '{"spec":{"claimRef":{"name":"graphdb-node-data-dynamic-pvc-graphdb-node-0"}}}' - ``` -12. Create a namespace for the GraphDB 10 helm chart, so we can deploy it without having to delete our 9.x cluster: - ```bash - kubectl create namespace <new-namespace-name> - ``` -13. Patch/Move the worker's PV to the new namespace: - ```bash - kubectl patch pv <worker-pv-name> -p '{"spec":{"claimRef":{"namespace":"<namespace-name>"}}}' - ``` -14. Create a secret with your license in the new namespace: - ```bash - graphdb-license --from-file graphdb.license -n <new-namespace-name> - ``` -15. Install the 10.0 Helm chart. Remember to edit: -- `graphdb.node.resources.limits.memory` and `graphdb.node.resources.requests.memory` to the ones used by the old workers. -- `graphdb.nodesCount:` The raft protocol recommends an odd amount of nodes. Set to the amount of workers you had in the old cluster. -- `graphdb.node.persistance.volumeClaimTemplateSpec.accessModes` and `graphdb.node.persistance.volumeClaimTemplateSpec.resources.requests.storage` to the ones used by the old PVs. -- `graphdb.clusetConfig.clusterCreationTimeout` high enough so the data from the old worker has time to replicate to all the new nodes. This depends on network speed between the nodes and the read/write performance of the storage. If the replication is expected to take more than 5 minutes add an equivalent `--timeout XXm` to the helm install command. -- `deployment.host` to temporary address where you can test everything is working. - -16. Once you confirm everything has migrated and works as expected you can free up the old `deployment.host` and upgrade the new cluster to it. - -**Note**: If you decide to revert to 9.x and don't have a backup of the worker's PV, you won't be able to use the old PV as GraphDB 10's repositories and settings aren't backward compatible. -Your best course of action would be to make sure it will provision a new clean PV, scale the replica back from 0, recreate the worker repositories and reconnect them to the old master repositories letting GraphDB replicate the data. - -### Quick Start - -The Helm chart includes an example repository configuration TTLs. - -To install the GraphDB on `graphdb.local`: - -```bash -helm install --set deployment.host=graphdb.local graphdb . -``` +## Install -After a few seconds, Helm will print out the result from installing GraphDB. -You should see the following output: +### Version Compatability -``` -------------------------------------------------------------------------------- - ____ _ ____ ____ - / ___|_ __ __ _ _ __ | |__ | _ \| __ ) - | | _| '__/ _` | '_ \| '_ \| | | | _ \ - | |_| | | | (_| | |_) | | | | |_| | |_) | - \____|_| \__,_| .__/|_| |_|____/|____/ - |_| -------------------------------------------------------------------------------- -version: 10.0.0 -GDB cluster: true - -** Please be patient while the chart is being deployed and services are available ** -You can check their status with kubectl get pods - -Endpoints: -* GraphDB workbench: http://graphdb.local/graphdb -``` +The next table highlights the version mapping between the Helm chart and the deployed GraphDB. -### Repository +| Helm chart version | GraphDB version | +|--------------------|-----------------| +| 10.x | 10.0 - 10.6.4 | +| 11.0 | 10.6.4 | -You can install GraphDB's Helm chart from our public Helm repository as well. +### Install from Repository -1. Add Ontotext repository with +1. Add Ontotext repository ```shell helm repo add ontotext https://maven.ontotext.com/repository/helm-public/ @@ -269,11 +109,19 @@ You can install GraphDB's Helm chart from our public Helm repository as well. helm install graphdb ontotext/graphdb ``` +3. Upgrade GraphDB deployment + + ```shell + helm upgrade --install graphdb ontotext/graphdb + ``` + +See [Configuration](#configuration) and [values.yaml](values.yaml) on how to customize your GraphDB deployment. + ### Provenance -Helm can verify the origin and integrity of the Helm chart by +Helm can verify the origin and integrity of the Helm chart by: -1. Importing the public GnuPG key: +1. Importing the public GnuPG key for GraphDB Helm: ```shell gpg --keyserver keyserver.ubuntu.com --recv-keys 8E1B45AF8157DB82 @@ -287,46 +135,47 @@ Helm can verify the origin and integrity of the Helm chart by helm install --verify graphdb ontotext/graphdb ``` -Note that the verification works only when installing from a local tar.gz or when installing from the repository. +**Note**: The verification works only when installing from a local tar.gz or when installing from the repository. -## Persistence +Check the official documentation for more information https://helm.sh/docs/topics/provenance/ -By default, the Helm chart is deploying persistent volumes that store data on the host path. -This is useful for local Minikube deployments. However, in a cloud environment with multiple node -cluster this would lead to rescheduling and **data loss**. +### Uninstall -See https://kubernetes.io/docs/concepts/storage/volumes/. +To remove the deployed GraphDB, use: -### Local deployment +```shell +helm uninstall graphdb +``` -Local persistent volumes are configured with `graphdb.node.persistence` from [values.yaml](values.yaml). +**Note**: It is important to note that this will not remove any data, so the next time it is installed, the data will be loaded by its components. -### Cloud deployment +## Upgrading -For cloud deployment, you have to prepare persistent disks, storage class (or classes) and finally -persistent volumes manifests. Once this is done, every component must be reconfigured in -[values.yaml](values.yaml) to point to the new persistent volume and not the default one. Each -component has a section `persistence` that has to be updated. +The Helm chart follows [Semantic Versioning v2](https://semver.org/) so any breaking changes will be rolled out only in MAJOR versions of the chart. -## API Gateway +Please, always check out the migration guides in [UPGRADE.md](UPGRADE.md) before switching to another major version of the Helm chart. -The services are proxied using nginx Ingress gateway. By default, it is configured to route: +## Configuration -- GraphDB Workbench -- GraphDB cluster proxy if the cluster deployment is enabled +Every component and resource is configured with sensible defaults in [values.yaml](values.yaml). +Make sure you read it thoroughly, understand each property and the impact of changing any one of them. -## Customizing +Helm allows you to override values from [values.yaml](values.yaml) in several ways. +See https://helm.sh/docs/chart_template_guide/values_files/. -Every component in configured with sensible defaults. Some of them are applied from -[values.yaml](values.yaml). Make sure you read it thoroughly, understand each property and the -impact of changing any one of them. +* Using a separate values.yaml with overrides: + ```shell + helm install graphdb ontotext/graphdb -f overrides.yaml + ``` -**Note**: If you are familiar with Kubernetes, you could modify the component's configuration -templates directly. +* Overriding specific values: + ```shell + helm install graphdb ontotext/graphdb --set security.enabled=true + ``` -#### Ontop repositories +### Ontop repositories -Ontop repositories require a jdbc driver. To use this type of repository, you have to provide a jdbc driver named `jdbc-driver.jar`. +Ontop repositories require a JDBC driver. To use this type of repository, you have to provide a JDBC driver named `jdbc-driver.jar`. It must be located in each GraphDB instance in which you wish to use with Ontop repository, in the folder `/opt/graphdb/home/jdbc-driver`. The directory is part of the GraphDB home directory which is persistent, so the driver will persist after a restart or reschedule of a GraphDB pod. @@ -340,73 +189,65 @@ There are 3 important configuration sections: #### GraphDB cluster configuration -With the release of GraphDB 10, master nodes are no longer needed for a cluster, so the size of the cluster is controlled by just one property: `graphdb.clusterConfig.nodesCount`. +With the release of GraphDB 10, master nodes are no longer needed for a cluster, so the size of the cluster is controlled by just one property: `replicas`. You will need at least three GraphDB installations to create a fully functional cluster. Remember that the Raft algorithm recommends an odd number of nodes, so a cluster of five nodes is a good choice. -Note: If "1" is selected as node count, the launched node will be standalone and no instances of the cluster proxy will be deployed! +Note: If `1` is selected as node count, the launched node will be standalone and no instances of the cluster proxy will be deployed! -- The section `graphdb.clusterConfig` can be used to configure a GraphDB cluster. +- The section `cluster.config` can be used to configure a GraphDB cluster. -See more about the cluster here: https://graphdb.ontotext.com/documentation/10.0/cluster-basics.html +See more about the cluster here: https://graphdb.ontotext.com/documentation/10.6/cluster-basics.html -#### Deploying GraphDB with security +### Deploying GraphDB with security -GraphDB's Helm chart supports deploying GraphDB with or without security. This can be toggled through `graphdb.security.enabled`. +GraphDB's Helm chart supports deploying GraphDB with or without security. This can be toggled through `security.enabled`. If it is deployed with security enabled, a special provisioning user is used for repository provisioning, cluster linking, health checks and so on. Additional users can be added through the users file: `files/config/users.js`. The users are described with their roles, username and a bcrypt64 password. -The file can be provisioned before GraphDB's startup with the `usersConfigMap` configmap or left to default. -It can be overridden with other configmap containing the `users.js` file. +The file can be provisioned before GraphDB's startup with the `security.initialUsers` configurations. +It can be overridden with other configmap containing the `users.js` file with `security.initialUsers.existingSecret`. Note that the `provisioning` user is required when security is turned on! By default, if the security is turned on, GraphDB's basic security method is used. More complicated security configurations can be configured using additional configurations in `graphdb.properties`. -See https://graphdb.ontotext.com/documentation/10.0/access-control.html +See https://graphdb.ontotext.com/documentation/10.6/access-control.html Prior to GraphDB 10.0.0 the users and their settings were saved in the `settings.js` file. -#### Provisioning additional properties and settings +### Provisioning additional properties and settings -Most of GraphDB's properties can be passed through `java_args`. Another option is to supply a `graphdb.properties` file. -This file can be provisioned on during GraphDB's startup using `propertiesConfigMap`configmap or left to default. -It can be overridden with other configmap containing the `graphdb.properties` file. +Most of GraphDB's properties can be passed through `configuration.properties` or `configuration.javaArguments`. +Another option is to supply a `graphdb.properties` file. +This file can be provisioned on during GraphDB's startup using `configuration.extraProperties.existingConfigmap`. The `graphdb.properties` file is also used for more complex security configurations such as LDAP, Oauth, Kerberos. Some additional settings are kept in the `settings.js` file. Most of those settings are internal for GraphDB and better left managed by the client. -The file can be provisioned before GraphDB's startup with the `settingsConfigMap` configmap or left to default. -It can be overridden with other configmap containing the `settings.js` file. +The file can be provisioned before GraphDB's startup with the `configuration.initialSettings.existingSecret` configuration. Note the `settings.js` must contain `security.enabled" : true` property when security is turned on! -GraphDB uses logback to configure logging using the `logback.xml` file. -The file can be provisioned before GraphDB's startup with the `logbackConfigMap` configmap or left to default. -It can be overridden with other configmap containing the `logback.xml` file. +GraphDB uses Logback to configure logging using the `logback.xml` file. +The file can be provisioned before GraphDB's startup with the `configuration.logback.existingConfigmap` configuration. + +See https://graphdb.ontotext.com/documentation/10.6/directories-and-config-properties.html#configuration-properties + +See https://graphdb.ontotext.com/documentation/10.6/access-control.html -See https://graphdb.ontotext.com/documentation/10.0/configuring-graphdb.html?highlight=properties -See https://graphdb.ontotext.com/documentation/10.0/access-control.html +### Importing data from existing persistent volume -#### Importing data from existing persistent volume GraphDB supports attaching a folder as an import directory. The directory's content s visible in the Workbench and can be imported. -In the Helm chart you can use existing PV as an import directory. This is done through `graphdb.import_directory_mount` using a `volumeClaimTemplateSpec`. -This way a dynamic PV/PVC can be provisioned, or you can use an existing PV. If an existing PV is used, have in mind that the dynamically provisioned PVC name is `graphdb-server-import-dir-graphdb-master-1-0`, so an appropriate `claimRef` must be added to the existing PV. +In the Helm chart you can use existing PV as an import directory. This is done through `import.volumeMount` using a `volumeClaimTemplateSpec`. +This way a dynamic PV/PVC can be provisioned, or you can use an existing PV with an appropriate `claimRef`. ### Networking By default, GraphDB's Helm chart comes with a default Ingress. -The Ingress =can be disabled by switching `ingress.enabled` to false. +The Ingress can be disabled by switching `ingress.enabled` to false. ### Cloud deployments specifics -Some cloud kubernetes clusters have some specifics that should be noted. Here are some useful tips on some cloud K8s clusters: - -##### Google cloud - -In Google's k8s cluster services, the root directory is not writable. By default, GraphDB's chart uses `/data` directory to store instances data. -If you're using Google cloud, please change this path to something else, not located on the root level. - -By default, the ingress used in the helm chart utilizes NGINX as ingress.class. -The easiest way to make it work inside the GKE is by deploying a NGINX ingress controller. Information on how that can be achieved can be found here: https://cloud.google.com/community/tutorials/nginx-ingress-gke +Some cloud Kubernetes clusters have some specifics that should be noted. Here are some useful tips on some cloud K8s clusters: ##### Microsoft Azure @@ -415,32 +256,11 @@ not good enough for GraphDB, and we recommend against using it in production env See https://github.com/Azure/AKS/issues/223 -### values.yaml - -Helm allows you to override values from [values.yaml](values.yaml) in several ways. -See https://helm.sh/docs/chart_template_guide/values_files/. - -- Preparing another *values.yaml*: - -```bash -helm install graphdb . -f overrides.yaml -``` - -- Overriding specific values: - -```bash -helm install graphdb . --set deployment.host=graphdb.local --set security.enabled=true -``` - ### Deployment Some important properties to update according to your deployment are: -* `deployment.protocol` and `deployment.host` - configure the ingress -controller and some components on which they are accessible. The `deployment.host` must be a -resolvable hostname and not an IP address. -* `deployment.storage` configures components where to store their persistent data on the host system -running the Kubernetes environment. +* `configuration.externalUrl` - Configures the address at which the Ingress controller and GraphDB are accessible. ### Resources @@ -457,124 +277,343 @@ See the Kubernetes documentation https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ about defining resource limits. -## Values +## Examples -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| deployment.host | string | `"localhost"` | | -| deployment.imagePullPolicy | string | `"IfNotPresent"` | Defines the policy with which components will request their image. | -| deployment.ingress | object | `{"annotations":{},"class":"nginx","enabled":true,"maxRequestSize":"512M","timeout":{"connect":5,"read":600,"send":600}}` | Ingress related configurations | -| deployment.ingress.annotations | object | `{}` | Sets extra ingress annotations | -| deployment.ingress.maxRequestSize | string | `"512M"` | Sets the maximum size for all requests to the underlying Nginx | -| deployment.ingress.timeout | object | `{"connect":5,"read":600,"send":600}` | Default timeouts in seconds for the underlying Nginx. | -| deployment.protocol | string | `"http"` | The hostname and protocol at which the graphdb will be accessible. Needed to configure ingress as well as some components require it to properly render their UIs | -| deployment.tls.enabled | bool | `false` | Feature toggle for SSL termination. Disabled by default. If TLS is enabled, the protocol should also be updated (https) | -| deployment.tls.secretName | string | `nil` | Name of a Kubernetes secret object with the key and certificate. If TLS is enabled, it's required to be provided, depending on the deployment. | -| extraLabels | object | `{}` | | -| global.imagePullSecrets | list | `[]` | | -| global.imageRegistry | string | `"docker.io"` | | -| global.storageClass | string | `"standard"` | | -| graphdb.clusterConfig.clusterCreationTimeout | int | `60` | Timeout for the cluster creation CURL query. Note: By default helm waits for Kubernetes commands to complete for 5 minutes. You can increase that by adding "--timeout 10m" to the helm command. | -| graphdb.clusterConfig.clusterSecret | string | `"s3cr37"` | A secret used for secure communication amongst the nodes in the cluster. | -| graphdb.clusterConfig.electionMinTimeout | int | `8000` | Cluster configuration parameters: Refer to https://graphdb.ontotext.com/documentation/10.6/creating-a-cluster.html#creation-parameters The minimum wait time in milliseconds for a heartbeat from a leader. | -| graphdb.clusterConfig.electionRangeTimeout | int | `6000` | | -| graphdb.clusterConfig.existingClusterConfig | string | `nil` | Use a custom JSON configuration when creating the cluster, see https://graphdb.ontotext.com/documentation/10.6/creating-a-cluster.html#creation-parameters The resources expect a configmap containing a key "cluster-config.json" with the JSON for cluster creation | -| graphdb.clusterConfig.heartbeatInterval | int | `2000` | | -| graphdb.clusterConfig.messageSize | int | `64` | | -| graphdb.clusterConfig.nodesCount | int | `1` | Number of GraphDB nodes to be used in the cluster. Set value to 1 to run a standalone GraphDB instance. | -| graphdb.clusterConfig.transactionLogMaximumSizeGB | int | `50` | | -| graphdb.clusterConfig.verificationTimeout | int | `1500` | | -| graphdb.clusterProxy.affinity | object | `{}` | | -| graphdb.clusterProxy.extraEnv | list | `[]` | | -| graphdb.clusterProxy.extraEnvFrom | list | `[]` | | -| graphdb.clusterProxy.extraInitContainers | list | `[]` | | -| graphdb.clusterProxy.extraVolumeMounts | list | `[]` | | -| graphdb.clusterProxy.extraVolumes | list | `[]` | | -| graphdb.clusterProxy.headlessService | object | `{"annotations":{}}` | GraphDB cluster proxy headless service configurations | -| graphdb.clusterProxy.java_args | string | `"-XX:MaxRAMPercentage=70 -Ddefault.min.distinct.threshold=100m -XX:+UseContainerSupport"` | Java arguments with which the cluster proxy instances will be launched. GraphDB configuration properties can also be passed here in the format -Dprop=value | -| graphdb.clusterProxy.livenessProbe | object | `{"httpGet":{"path":"/proxy/health","port":"gdb-proxy-port"},"initialDelaySeconds":120,"periodSeconds":10,"timeoutSeconds":5}` | Configurations for the GraphDB cluster proxy liveness probe. Misconfigured probe can lead to a failing cluster. | -| graphdb.clusterProxy.nodeSelector | object | `{}` | | -| graphdb.clusterProxy.persistence | object | `{"enablePersistence":true,"volumeClaimTemplateSpec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"500Mi"}}}}` | Persistence configurations. By default, Helm will use a PV that reads and writes to the host file system. | -| graphdb.clusterProxy.podAnnotations | object | `{}` | | -| graphdb.clusterProxy.podLabels | object | `{}` | | -| graphdb.clusterProxy.podSecurityContext | object | `{}` | | -| graphdb.clusterProxy.readinessProbe | object | `{"httpGet":{"path":"/proxy/ready","port":"gdb-proxy-port"},"periodSeconds":10,"timeoutSeconds":5}` | Configurations for the GraphDB cluster proxy readiness probe. Misconfigured probe can lead to a failing cluster. | -| graphdb.clusterProxy.replicas | int | `1` | Number of cluster proxies used to access the GraphDB cluster | -| graphdb.clusterProxy.resources | object | `{"limits":{"memory":"1500Mi"},"requests":{"cpu":"100m","memory":"1500Mi"}}` | Minimum requirements for a successfully running GraphDB cluster proxy | -| graphdb.clusterProxy.revisionHistoryLimit | int | `10` | | -| graphdb.clusterProxy.securityContext | object | `{}` | | -| graphdb.clusterProxy.service | object | `{"annotations":{}}` | GraphDB cluster proxy service configurations | -| graphdb.clusterProxy.serviceType | string | `"LoadBalancer"` | Service type used by the graphdb-cluster-proxy service Note: If using ALB in AWS EKS this will default to being on the public internet | -| graphdb.clusterProxy.startupProbe | object | `{"failureThreshold":60,"httpGet":{"path":"/proxy/ready","port":"gdb-proxy-port"},"periodSeconds":5,"timeoutSeconds":3}` | Configurations for the GraphDB cluster proxy startup probe. Misconfigured probe can lead to a failing cluster. | -| graphdb.clusterProxy.terminationGracePeriodSeconds | int | `30` | | -| graphdb.clusterProxy.tolerations | list | `[]` | | -| graphdb.clusterProxy.topologySpreadConstraints | list | `[]` | | -| graphdb.configs | string | `nil` | References to configuration maps containing settings.js, users.js, graphdb.properties, and logback.xml files to overwrite the default GraphDB configuration. For reference see https://graphdb.ontotext.com/documentation/10.6/directories-and-config-properties.html | -| graphdb.import_directory_mount.enabled | bool | `false` | | -| graphdb.import_directory_mount.volumeClaimTemplateSpec.accessModes[0] | string | `"ReadWriteOnce"` | | -| graphdb.import_directory_mount.volumeClaimTemplateSpec.resources.requests.storage | string | `"10Gi"` | | -| graphdb.jobPodSecurityContext | object | `{}` | | -| graphdb.jobResources | object | `{}` | | -| graphdb.jobSecurityContext | object | `{}` | | -| graphdb.node.affinity | object | `{}` | | -| graphdb.node.args | string | `nil` | | -| graphdb.node.command | string | `nil` | | -| graphdb.node.extraEnv | list | `[]` | | -| graphdb.node.extraEnvFrom | list | `[]` | | -| graphdb.node.extraInitContainers | list | `[]` | | -| graphdb.node.extraVolumeMounts | list | `[]` | | -| graphdb.node.extraVolumes | list | `[]` | | -| graphdb.node.initContainerResources | object | `{}` | | -| graphdb.node.initContainerSecurityContext | object | `{}` | | -| graphdb.node.java_args | string | `"-XX:MaxRAMPercentage=70 -Ddefault.min.distinct.threshold=100m -XX:+UseContainerSupport"` | Java arguments with which node instances will be launched. GraphDB configuration properties can also be passed here in the format -Dprop=value | -| graphdb.node.license | string | `nil` | Reference to a secret containing 'graphdb.license' file to be used by the nodes. Important: Must be created beforehand | -| graphdb.node.licenseFilename | string | `"graphdb.license"` | File name of the GraphDB license file in the existing license secret. Default is graphdb.license | -| graphdb.node.livenessProbe | object | `{"httpGet":{"path":"/protocol","port":"graphdb"},"initialDelaySeconds":60,"periodSeconds":10,"timeoutSeconds":5}` | Configurations for the GraphDB node liveness probe. Misconfigured probe can lead to a failing cluster. | -| graphdb.node.nodeSelector | object | `{}` | | -| graphdb.node.persistence | object | `{"volumeClaimTemplateSpec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"5Gi"}}}}` | Persistence configurations. By default, Helm will use a PV that reads and writes to the host file system. | -| graphdb.node.podAnnotations | object | `{}` | | -| graphdb.node.podLabels | object | `{}` | | -| graphdb.node.podSecurityContext | object | `{}` | | -| graphdb.node.readinessProbe | object | `{"httpGet":{"path":"/protocol","port":"graphdb"},"initialDelaySeconds":5,"periodSeconds":10,"timeoutSeconds":5}` | Configurations for the GraphDB node readiness probe. Misconfigured probe can lead to a failing cluster. | -| graphdb.node.resources | object | `{"limits":{"memory":"2Gi"},"requests":{"cpu":0.5,"memory":"2Gi"}}` | Below are minimum requirements for data sets of up to 50 million RDF triples For resizing, refer according to the GraphDB documentation https://graphdb.ontotext.com/documentation/10.6/requirements.html | -| graphdb.node.revisionHistoryLimit | int | `10` | | -| graphdb.node.securityContext | object | `{}` | | -| graphdb.node.service | object | `{"annotations":{}}` | GraphDB node service configurations | -| graphdb.node.startupProbe | object | `{"failureThreshold":30,"httpGet":{"path":"/protocol","port":"graphdb"},"periodSeconds":10,"timeoutSeconds":5}` | Configurations for the GraphDB node startup probe. Misconfigured probe can lead to a failing cluster. | -| graphdb.node.terminationGracePeriodSeconds | int | `120` | | -| graphdb.node.tolerations | list | `[]` | | -| graphdb.node.topologySpreadConstraints | list | `[]` | | -| graphdb.pdb.create | bool | `false` | | -| graphdb.pdb.maxUnavailable | string | `nil` | | -| graphdb.pdb.minAvailable | string | `"51%"` | | -| graphdb.security.enabled | bool | `false` | | -| graphdb.security.provisioningPassword | string | `"iHaveSuperpowers"` | | -| graphdb.security.provisioningUsername | string | `"provisioner"` | | -| graphdb.workbench.subpath | string | `"/graphdb"` | This is the sub path at which GraphDB workbench can be opened. Should be configured in the API gateway (or any other proxy in front) | -| images.busybox.repository | string | `"busybox"` | | -| images.busybox.tag | string | `"1.36.1"` | | -| images.graphdb.registry | string | `"docker.io"` | | -| images.graphdb.repository | string | `"ontotext/graphdb"` | | -| images.graphdb.tag | string | `""` | | - -## Uninstall -To remove the deployed GraphDB, use: +Checkout the [examples/](examples) folder in this repository. -```bash -helm uninstall graphdb +## Guides + +### Updating an expired GraphDB license + +When the license expires, you will have to update the Secret object and restart the GraphDB pods in order to load the new license. + +In avoid restarting your current GraphDB instances, you can copy the new license directly into your GraphDB containers, in the folder `/opt/graphdb/home/conf`. +It's important to name your file exactly `graphdb.license`! + +```shell +kubectl delete secret graphdb-license +kubectl create secret generic graphdb-license --from-file graphdb.license=graphdb.license +kubectl cp graphdb.license graphdb-pod-0:/opt/graphdb/home/conf/ +kubectl cp graphdb.license graphdb-pod-1:/opt/graphdb/home/conf/ +kubectl cp graphdb.license graphdb-pod-2:/opt/graphdb/home/conf/ ``` -**Note**: It is important to note that this will not remove any data, so the next time it -is installed, the data will be loaded by its components. +## Values -Provisioning will be skipped also. +<!-- +IMPORTANT: This is generated by helm-docs, do not attempt modifying it on hand as it will be automatically generated. +--> -## Troubleshoot +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | | +| annotations | object | `{}` | | +| args | list | `[]` | | +| automountServiceAccountToken | bool | `false` | | +| cluster.clusterCreationTimeout | int | `60` | | +| cluster.config.configmapKey | string | `"cluster-config.json"` | | +| cluster.config.existingConfigmap | string | `""` | | +| cluster.config.params.electionMinTimeout | int | `8000` | | +| cluster.config.params.electionRangeTimeout | int | `6000` | | +| cluster.config.params.heartbeatInterval | int | `2000` | | +| cluster.config.params.messageSizeKB | int | `64` | | +| cluster.config.params.transactionLogMaximumSizeGB | int | `50` | | +| cluster.config.params.verificationTimeout | int | `1500` | | +| cluster.jobs.createCluster.enabled | bool | `true` | | +| cluster.jobs.patchCluster.enabled | bool | `true` | | +| cluster.jobs.scaleCluster.enabled | bool | `true` | | +| cluster.token.existingSecret | string | `""` | | +| cluster.token.secret | string | `"s3cr37"` | | +| cluster.token.secretKey | string | `""` | | +| command | list | `[]` | | +| configuration.defaultJavaArguments | string | `"-XX:+UseContainerSupport -XX:MaxRAMPercentage=70 -XX:-UseCompressedOops -Ddefault.min.distinct.threshold=100m"` | | +| configuration.externalUrl | string | `"http://graphdb.127.0.0.1.nip.io/"` | | +| configuration.extraProperties.configmapKey | string | `"graphdb.properties"` | | +| configuration.extraProperties.existingConfigmap | string | `""` | | +| configuration.extraProperties.existingSecret | string | `""` | | +| configuration.extraProperties.secretKey | string | `"graphdb.properties"` | | +| configuration.initialSettings.configmapKey | string | `"settings.js"` | | +| configuration.initialSettings.existingConfigmap | string | `""` | | +| configuration.javaArguments | string | `""` | | +| configuration.logback.configmapKey | string | `"logback.xml"` | | +| configuration.logback.existingConfigmap | string | `""` | | +| configuration.properties | object | `{}` | | +| configuration.secretProperties | object | `{}` | | +| containerPorts.http | int | `7200` | | +| containerPorts.rpc | int | `7300` | | +| dnsConfig | object | `{}` | | +| dnsPolicy | string | `""` | | +| extraContainerPorts | object | `{}` | | +| extraContainers | list | `[]` | | +| extraEnv | list | `[]` | | +| extraEnvFrom | list | `[]` | | +| extraInitContainers | list | `[]` | | +| extraObjects | list | `[]` | | +| extraVolumeClaimTemplates | list | `[]` | | +| extraVolumeMounts | list | `[]` | | +| extraVolumes | list | `[]` | | +| fullnameOverride | string | `""` | | +| global.clusterDomain | string | `"cluster.local"` | | +| global.imagePullSecrets | list | `[]` | | +| global.imageRegistry | string | `""` | | +| headlessService.annotations | object | `{}` | | +| headlessService.enabled | bool | `true` | | +| headlessService.extraPorts | list | `[]` | | +| headlessService.labels | object | `{}` | | +| headlessService.ports.http | int | `7200` | | +| headlessService.ports.rpc | int | `7300` | | +| image.digest | string | `""` | | +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.pullSecrets | list | `[]` | | +| image.registry | string | `"docker.io"` | | +| image.repository | string | `"ontotext/graphdb"` | | +| image.tag | string | `""` | | +| import.volumeMount.enabled | bool | `false` | | +| import.volumeMount.volumeClaimTemplate.annotations | object | `{}` | | +| import.volumeMount.volumeClaimTemplate.labels | object | `{}` | | +| import.volumeMount.volumeClaimTemplate.name | string | `"import"` | | +| import.volumeMount.volumeClaimTemplate.spec.accessModes[0] | string | `"ReadWriteOnce"` | | +| import.volumeMount.volumeClaimTemplate.spec.resources.requests.storage | string | `"10Gi"` | | +| ingress.annotations | object | `{}` | | +| ingress.className | string | `""` | | +| ingress.enabled | bool | `true` | | +| ingress.extraHosts | list | `[]` | | +| ingress.extraTLS | list | `[]` | | +| ingress.host | string | `""` | | +| ingress.labels | object | `{}` | | +| ingress.path | string | `""` | | +| ingress.pathType | string | `"Prefix"` | | +| ingress.tls.enabled | bool | `false` | | +| ingress.tls.secretName | string | `nil` | | +| initContainerDataPermissions.enabled | bool | `false` | | +| initContainerDataPermissions.securityContext.runAsNonRoot | bool | `false` | | +| initContainerDataPermissions.securityContext.runAsUser | int | `0` | | +| initContainerResources.limits.cpu | string | `"50m"` | | +| initContainerResources.limits.memory | string | `"16Mi"` | | +| initContainerResources.requests.cpu | string | `"50m"` | | +| initContainerResources.requests.memory | string | `"16Mi"` | | +| initContainerSecurityContext.allowPrivilegeEscalation | bool | `false` | | +| initContainerSecurityContext.capabilities.drop[0] | string | `"ALL"` | | +| initContainerSecurityContext.readOnlyRootFilesystem | bool | `true` | | +| initContainerSecurityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| jobs.backoffLimit | int | `10` | | +| jobs.persistence.emptyDir.sizeLimit | string | `"10Mi"` | | +| jobs.podSecurityContext.fsGroup | int | `10001` | | +| jobs.podSecurityContext.fsGroupChangePolicy | string | `"OnRootMismatch"` | | +| jobs.podSecurityContext.runAsGroup | int | `10001` | | +| jobs.podSecurityContext.runAsNonRoot | bool | `true` | | +| jobs.podSecurityContext.runAsUser | int | `10001` | | +| jobs.podSecurityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| jobs.resources.limits.cpu | string | `"50m"` | | +| jobs.resources.limits.ephemeral-storage | string | `"10Mi"` | | +| jobs.resources.limits.memory | string | `"16Mi"` | | +| jobs.resources.requests.cpu | string | `"50m"` | | +| jobs.resources.requests.ephemeral-storage | string | `"10Mi"` | | +| jobs.resources.requests.memory | string | `"16Mi"` | | +| jobs.securityContext.allowPrivilegeEscalation | bool | `false` | | +| jobs.securityContext.capabilities.drop[0] | string | `"ALL"` | | +| jobs.securityContext.readOnlyRootFilesystem | bool | `true` | | +| jobs.securityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| jobs.ttlSecondsAfterFinished | int | `300` | | +| labels | object | `{}` | | +| license.existingSecret | string | `""` | | +| license.licenseFilename | string | `"graphdb.license"` | | +| livenessProbe.httpGet.path | string | `"/protocol"` | | +| livenessProbe.httpGet.port | string | `"http"` | | +| livenessProbe.initialDelaySeconds | int | `60` | | +| livenessProbe.periodSeconds | int | `10` | | +| livenessProbe.timeoutSeconds | int | `5` | | +| nameOverride | string | `""` | | +| namespaceOverride | string | `""` | | +| nodeSelector | object | `{}` | | +| persistence.emptyDir.sizeLimit | string | `"1Gi"` | | +| persistence.enabled | bool | `true` | | +| persistence.volumeClaimTemplate.annotations | object | `{}` | | +| persistence.volumeClaimTemplate.labels | object | `{}` | | +| persistence.volumeClaimTemplate.name | string | `"storage"` | | +| persistence.volumeClaimTemplate.spec.accessModes[0] | string | `"ReadWriteOnce"` | | +| persistence.volumeClaimTemplate.spec.resources.requests.storage | string | `"5Gi"` | | +| podAnnotations | object | `{}` | | +| podDisruptionBudget.enabled | bool | `true` | | +| podDisruptionBudget.maxUnavailable | string | `""` | | +| podDisruptionBudget.minAvailable | string | `"51%"` | | +| podLabels | object | `{}` | | +| podManagementPolicy | string | `"Parallel"` | | +| podSecurityContext.fsGroup | int | `10001` | | +| podSecurityContext.fsGroupChangePolicy | string | `"OnRootMismatch"` | | +| podSecurityContext.runAsGroup | int | `10001` | | +| podSecurityContext.runAsNonRoot | bool | `true` | | +| podSecurityContext.runAsUser | int | `10001` | | +| podSecurityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| priorityClassName | string | `""` | | +| proxy.affinity | object | `{}` | | +| proxy.annotations | object | `{}` | | +| proxy.args | list | `[]` | | +| proxy.command | list | `[]` | | +| proxy.configuration.defaultJavaArguments | string | `"-XX:+UseContainerSupport -XX:MaxRAMPercentage=70"` | | +| proxy.configuration.extraProperties.configmapKey | string | `"graphdb.properties"` | | +| proxy.configuration.extraProperties.existingConfigmap | string | `""` | | +| proxy.configuration.extraProperties.existingSecret | string | `""` | | +| proxy.configuration.extraProperties.secretKey | string | `"graphdb.properties"` | | +| proxy.configuration.javaArguments | string | `""` | | +| proxy.configuration.logback.configmapKey | string | `"logback.xml"` | | +| proxy.configuration.logback.existingConfigmap | string | `""` | | +| proxy.configuration.properties | object | `{}` | | +| proxy.configuration.secretProperties | object | `{}` | | +| proxy.containerPorts.http | int | `7200` | | +| proxy.containerPorts.rpc | int | `7300` | | +| proxy.dnsConfig | object | `{}` | | +| proxy.dnsPolicy | string | `""` | | +| proxy.extraContainerPorts | object | `{}` | | +| proxy.extraContainers | list | `[]` | | +| proxy.extraEnv | list | `[]` | | +| proxy.extraEnvFrom | list | `[]` | | +| proxy.extraInitContainers | list | `[]` | | +| proxy.extraVolumeClaimTemplates | list | `[]` | | +| proxy.extraVolumeMounts | list | `[]` | | +| proxy.extraVolumes | list | `[]` | | +| proxy.fullnameOverride | string | `""` | | +| proxy.headlessService.annotations | object | `{}` | | +| proxy.headlessService.enabled | bool | `true` | | +| proxy.headlessService.extraPorts | list | `[]` | | +| proxy.headlessService.labels | object | `{}` | | +| proxy.headlessService.ports.http | int | `7200` | | +| proxy.headlessService.ports.rpc | int | `7300` | | +| proxy.initContainerDataPermissions.enabled | bool | `false` | | +| proxy.initContainerDataPermissions.securityContext.runAsNonRoot | bool | `false` | | +| proxy.initContainerDataPermissions.securityContext.runAsUser | int | `0` | | +| proxy.initContainerResources.limits.cpu | string | `"50m"` | | +| proxy.initContainerResources.limits.memory | string | `"16Mi"` | | +| proxy.initContainerResources.requests.cpu | string | `"50m"` | | +| proxy.initContainerResources.requests.memory | string | `"16Mi"` | | +| proxy.initContainerSecurityContext.allowPrivilegeEscalation | bool | `false` | | +| proxy.initContainerSecurityContext.capabilities.drop[0] | string | `"ALL"` | | +| proxy.initContainerSecurityContext.readOnlyRootFilesystem | bool | `true` | | +| proxy.initContainerSecurityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| proxy.labels | object | `{}` | | +| proxy.livenessProbe.httpGet.path | string | `"/proxy/health"` | | +| proxy.livenessProbe.httpGet.port | string | `"http"` | | +| proxy.livenessProbe.initialDelaySeconds | int | `120` | | +| proxy.livenessProbe.periodSeconds | int | `10` | | +| proxy.livenessProbe.timeoutSeconds | int | `5` | | +| proxy.nameOverride | string | `""` | | +| proxy.nodeSelector | object | `{}` | | +| proxy.persistence.emptyDir.sizeLimit | string | `"500Mi"` | | +| proxy.persistence.enabled | bool | `true` | | +| proxy.persistence.volumeClaimTemplate.annotations | object | `{}` | | +| proxy.persistence.volumeClaimTemplate.labels | object | `{}` | | +| proxy.persistence.volumeClaimTemplate.name | string | `"storage"` | | +| proxy.persistence.volumeClaimTemplate.spec.accessModes[0] | string | `"ReadWriteOnce"` | | +| proxy.persistence.volumeClaimTemplate.spec.resources.requests.storage | string | `"500Mi"` | | +| proxy.podAnnotations | object | `{}` | | +| proxy.podDisruptionBudget.enabled | bool | `true` | | +| proxy.podDisruptionBudget.maxUnavailable | string | `""` | | +| proxy.podDisruptionBudget.minAvailable | string | `"51%"` | | +| proxy.podLabels | object | `{}` | | +| proxy.podManagementPolicy | string | `"Parallel"` | | +| proxy.podSecurityContext.fsGroup | int | `10001` | | +| proxy.podSecurityContext.fsGroupChangePolicy | string | `"OnRootMismatch"` | | +| proxy.podSecurityContext.runAsGroup | int | `10001` | | +| proxy.podSecurityContext.runAsNonRoot | bool | `true` | | +| proxy.podSecurityContext.runAsUser | int | `10001` | | +| proxy.podSecurityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| proxy.priorityClassName | string | `""` | | +| proxy.readinessProbe.httpGet.path | string | `"/proxy/ready"` | | +| proxy.readinessProbe.httpGet.port | string | `"http"` | | +| proxy.readinessProbe.periodSeconds | int | `10` | | +| proxy.readinessProbe.timeoutSeconds | int | `5` | | +| proxy.replicas | int | `3` | | +| proxy.resources.limits.memory | string | `"1500Mi"` | | +| proxy.resources.requests.cpu | string | `"100m"` | | +| proxy.resources.requests.memory | string | `"1500Mi"` | | +| proxy.revisionHistoryLimit | int | `10` | | +| proxy.schedulerName | string | `""` | | +| proxy.securityContext.allowPrivilegeEscalation | bool | `false` | | +| proxy.securityContext.capabilities.drop[0] | string | `"ALL"` | | +| proxy.securityContext.readOnlyRootFilesystem | bool | `true` | | +| proxy.securityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| proxy.service.annotations | object | `{}` | | +| proxy.service.enabled | bool | `true` | | +| proxy.service.externalIPs | list | `[]` | | +| proxy.service.externalTrafficPolicy | string | `""` | | +| proxy.service.extraPorts | list | `[]` | | +| proxy.service.healthCheckNodePort | string | `""` | | +| proxy.service.labels | object | `{}` | | +| proxy.service.loadBalancerClass | string | `""` | | +| proxy.service.loadBalancerSourceRanges | list | `[]` | | +| proxy.service.nodePort | string | `""` | | +| proxy.service.ports.http | int | `7200` | | +| proxy.service.type | string | `"ClusterIP"` | | +| proxy.startupProbe.failureThreshold | int | `60` | | +| proxy.startupProbe.httpGet.path | string | `"/proxy/ready"` | | +| proxy.startupProbe.httpGet.port | string | `"http"` | | +| proxy.startupProbe.periodSeconds | int | `5` | | +| proxy.startupProbe.timeoutSeconds | int | `3` | | +| proxy.terminationGracePeriodSeconds | int | `30` | | +| proxy.tolerations | list | `[]` | | +| proxy.topologySpreadConstraints | list | `[]` | | +| proxy.updateStrategy.type | string | `"RollingUpdate"` | | +| readinessProbe.httpGet.path | string | `"/protocol"` | | +| readinessProbe.httpGet.port | string | `"http"` | | +| readinessProbe.initialDelaySeconds | int | `5` | | +| readinessProbe.periodSeconds | int | `10` | | +| readinessProbe.timeoutSeconds | int | `5` | | +| replicas | int | `1` | | +| repositories.existingConfigmap | string | `""` | | +| resources.limits.memory | string | `"4Gi"` | | +| resources.requests.cpu | string | `"500m"` | | +| resources.requests.memory | string | `"4Gi"` | | +| revisionHistoryLimit | int | `10` | | +| schedulerName | string | `""` | | +| security.admin.initialPassword | string | `""` | | +| security.enabled | bool | `false` | | +| security.initialUsers.existingSecret | string | `""` | | +| security.initialUsers.secretKey | string | `"users.js"` | | +| security.initialUsers.users | object | `{}` | | +| security.provisioner.existingSecret | string | `""` | | +| security.provisioner.password | string | `"iHaveSuperpowers"` | | +| security.provisioner.tokenKey | string | `"GRAPHDB_AUTH_TOKEN"` | | +| security.provisioner.username | string | `"provisioner"` | | +| securityContext.allowPrivilegeEscalation | bool | `false` | | +| securityContext.capabilities.drop[0] | string | `"ALL"` | | +| securityContext.readOnlyRootFilesystem | bool | `true` | | +| securityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| service.annotations | object | `{}` | | +| service.enabled | bool | `true` | | +| service.externalIPs | list | `[]` | | +| service.externalTrafficPolicy | string | `""` | | +| service.extraPorts | list | `[]` | | +| service.healthCheckNodePort | string | `""` | | +| service.labels | object | `{}` | | +| service.loadBalancerClass | string | `""` | | +| service.loadBalancerSourceRanges | list | `[]` | | +| service.nodePort | string | `""` | | +| service.ports.http | int | `7200` | | +| service.type | string | `"ClusterIP"` | | +| serviceAccount.annotations | object | `{}` | | +| serviceAccount.create | bool | `false` | | +| serviceAccount.name | string | `""` | | +| startupProbe.failureThreshold | int | `30` | | +| startupProbe.httpGet.path | string | `"/protocol"` | | +| startupProbe.httpGet.port | string | `"http"` | | +| startupProbe.periodSeconds | int | `10` | | +| startupProbe.timeoutSeconds | int | `5` | | +| tempVolume.emptyDir.sizeLimit | string | `"128Mi"` | | +| tempVolume.enabled | bool | `true` | | +| terminationGracePeriodSeconds | int | `120` | | +| tolerations | list | `[]` | | +| topologySpreadConstraints | list | `[]` | | +| updateStrategy.type | string | `"RollingUpdate"` | | + +## Troubleshooting **Helm install hangs** If there is no output after `helm install`, it is likely that a hook cannot execute. -Check the logs with `kubectl logs`. +Check their logs with `kubectl logs`. + +Another reason could be that the default timeout of 5 minutes for Helm `install` or `upgrade` is not enough. +You can increase the timeout by adding `--timeout 10m` (or more) to the Helm command. **Connection issues** @@ -588,3 +627,11 @@ https://kubernetes.io/docs/tasks/administer-cluster/dns-debugging-resolution/. | Name | Email | Url | | ---- | ------ | --- | | Ontotext GraphDB team | <graphdb-support@ontotext.com> | | + +## Contributing + +If you have any suggestions, bug reports, or feature requests, please open an issue or submit a pull request. + +## License + +This code is released under the Apache 2.0 License. See [LICENSE](LICENSE) for more details. diff --git a/README.md.gotmpl b/README.md.gotmpl index e15a57c2..1b13a2f8 100644 --- a/README.md.gotmpl +++ b/README.md.gotmpl @@ -1,263 +1,103 @@ -# Helm charts for GraphDB +# Helm Chart for GraphDB [![CI](https://github.com/Ontotext-AD/graphdb-helm/actions/workflows/ci.yml/badge.svg)](https://github.com/Ontotext-AD/graphdb-helm/actions/workflows/ci.yml) {{ template "chart.versionBadge" . }} {{ template "chart.appVersionBadge" . }} -You can download the GraphDB Helm chart, including all sub-charts managed by Ontotext, from the [Ontotext Helm repository](https://maven.ontotext.com/repository/helm-public/). +<!-- +TODO: Add ArtifactHub badge when ready +[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/ontotext)](https://artifacthub.io/packages/helm/ontotext/graphdb) +--> -## Install -### Prerequisites - -#### Getting Started - -If this is your first time installing a Helm chart, you should read the following introductions -before continuing: - -- Docker https://docs.docker.com/get-started/ -- Kubernetes concepts https://kubernetes.io/docs/concepts/ -- Minikube https://kubernetes.io/docs/setup/learning-environment/minikube/ -- Helm https://helm.sh/docs/intro/quickstart/ - -#### Binaries -- Install Helm 3: https://helm.sh/docs/intro/install/ -- Install `kubectl`: https://kubernetes.io/docs/tasks/tools/install-kubectl/ - -**Note**: `sudo` may be required. - -#### Kubernetes environment - -##### Minikube - -Follow the install documentation https://kubernetes.io/docs/setup/learning-environment/minikube/ -for Minikube. +Welcome to the official [Helm](https://helm.sh/) chart repository for [GraphDB](https://www.ontotext.com/products/graphdb/)! +This Helm chart makes it easy to deploy and manage [GraphDB](https://www.ontotext.com/products/graphdb/) on your [Kubernetes](https://kubernetes.io/) cluster. -**Driver** +--- -Carefully choose the suitable Minikube driver https://minikube.sigs.k8s.io/docs/drivers/ for -your system. +:warning: **Important**: Beginning from version 11, the Helm chart has its own release cycle and is no longer tied to the version of GraphDB. -**Warning**: Some of them are compatible but have know issues. For example, the `docker` driver -does not support the ingress add-on which is required while the `none` driver goes into DNS -resolve loop in some Linux distributions. +--- -**Resources** +## Quickstart -It's important to define resource limitations for the Minikube environment, otherwise it will -default to limits that may not be sufficient to deploy the whole chart. - -The default resource limitations require around **12GB** of RAM. This is configurable per service in -[values.yaml](values.yaml) and should be tuned for every deployment. - -When starting Minikube, it's preferable to define a bit more than the required amount. -For example, to create a Minikube environment in VirtualBox with 8 CPUs and 16GB of memory, use: - -```bash -minikube start --vm-driver=virtualbox --cpus=8 --memory=16000 +```shell +helm repo add ontotext https://maven.ontotext.com/repository/helm-public/ +helm install graphdb ontotext/graphdb ``` -**Addons** +## About GraphDB -Minikube has built in services as part of its add-on system. By default, some of the required -plugins are disabled and have to be enabled. +<p align="center"> + <a href="https://www.ontotext.com/products/graphdb/"> + <picture> + <img src="https://www.ontotext.com/wp-content/uploads/2022/09/Logo-GraphDB.svg" alt="GraphDB logo" title="GraphDB" height="75"> + </picture> + </a> +</p> -To expose services, enable Minikube's ingress with: +Ontotext GraphDB is a highly efficient, scalable and robust graph database with RDF and SPARQL support. With excellent enterprise features, +integration with external search applications, compatibility with industry standards, and both community and commercial support, GraphDB is the +preferred database choice of both small independent developers and big enterprises. -```bash -minikube addons enable ingress -``` +<!-- +TODO: Info about the basic Helm chart features ? +## Features +--> -To collect metrics, enable Minikube's metrics server with: +## Prerequisites -```bash -minikube addons enable metrics-server -``` - -To enable Minikube's monitoring dashboard with: +* Kubernetes v1.26+ +* Helm v3.8+ -```bash -minikube dashboard -``` +### Getting Started -**DNS Resolving** +If this is your first time installing a Helm chart, you should read the following introductions before continuing: -The chart is deployed with a Kubernetes ingress service that is configured to listen for requests -on a specific hostname. Any other requests are not handled. +- Docker https://docs.docker.com/get-started/ +- Kubernetes concepts https://kubernetes.io/docs/concepts/ +- Helm https://helm.sh/docs/intro/quickstart/ -This hostname is specified in [values.yaml](values.yaml) under `deployment.host`. -By default, it's configured for `localhost` which is suitable for the `none` Minikube driver. -In every other case you have to reconfigure it to a hostname that is DNS resolvable. +After getting familiar with the above, you need to install the following binaries on your machine: -Some options are: +- Install Helm 3: https://helm.sh/docs/intro/install/ +- Install `kubectl`: https://kubernetes.io/docs/tasks/tools/install-kubectl/ -* Configure or update an existing DNS server - recommended for production deployment -* Update your hosts file - suitable for local development +Next, you would need access to a Kubernetes cluster. You can set up a local one or use one of the cloud providers, e.g.: -To find out the IP address of the Minikube environment, use: +* Minikube https://minikube.sigs.k8s.io/docs/ +* kind https://kind.sigs.k8s.io/ +* Amazon EKS https://aws.amazon.com/eks/ +* Azure AKS https://azure.microsoft.com/en-us/products/kubernetes-service +* Google GKE https://cloud.google.com/kubernetes-engine -```bash -minikube ip -``` +### GraphDB License -If you wish to access GraphDB locally on http://graphdb.local/ and the IP address of -the Minikube environment is `192.168.99.102` you should modify your hosts file with: +To use GraphDB Enterprise Edition features, you need a license. +If you have a GraphDB license, create a Secret object with a `graphdb.license` data entry: +```shell +kubectl create secret generic graphdb-license --from-file graphdb.license=graphdb.license ``` -192.168.99.102 graphdb.local -``` - -See this how-to https://www.howtogeek.com/27350/beginner-geek-how-to-edit-your-hosts-file/ -about modifying the hosts file in different OS. -#### Secrets - -If you have a GraphDB license, create a secret with a `graphdb.license` -data entry: - -```bash -kubectl create secret generic graphdb-license --from-file graphdb.license -``` -then add the secret name to the values.yaml file as `graphdb.node.license` +Then add the secret name to the values.yaml file under the `license.existingSecret` configuration. **Note**: Secret names can differ from the given examples in the [values.yaml](values.yaml), but their configurations should be updated to refer to the correct ones. Note that the licenses can be set for all node instances. Please setup correctly according to the licensing agreements. -#### Updating an expired GraphDB license - -When the helm chart is installed the license will be provisioned through the secret set in the `graphdb.node.license` value. -When a license expires you'll have to update the secret, so GraphDB instances don't get provisioned with the old license. -In order NOT to restart your current GraphDB instances, you can copy your new license named `graphdb.license` in your GraphDB pods in folder `/opt/graphdb/home/work`. -It's important to name your file exactly `graphdb.license`! - -```bash -kubectl delete secret graphdb-license -kubectl create secret generic graphdb-license --from-file graphdb.license -kubectl cp graphdb.license graphdb-node-0:/opt/graphdb/home/work -``` - -**Note**: If you use a standalone GraphDB you can also change it through the workbench, but if you don't update the secret next restart will provision the old license. - -### Cluster migration from GraphDB 9.x to 10.0 - -**Warning**: Before starting the migration change your master into read only mode. The process is irreversible and full backup is HIGHLY advisable. At minimum backup the PV of the worker you are planing to use for migration. - -The Helm chart is completely new and not backwards-compatible. - -1. Make all masters read only, you can use the workbench. -2. Using the workbench disconnect all repositories of the worker which we are going to use to migrate to 10.0. -If you've used the official GraphDB helm chart you can select any worker. In case of a custom implementation select one that can easily be scaled down. - - **Note**: Only the repositories that are on the worker will be migrated into the new cluster! -3. Get the PV information of the worker, noting down the capacity and the access mode: - ```bash - kubectl get pv - ``` -4. Note down the resource limits of the worker node: - ```bash - kubectl get pod graphdb-worker-<selected-worker> -o yaml | grep -B 2 memory - ``` -5. Make sure all the important settings saved in the settings.js of the master are present in the worker's. Their only difference - should be the lack of locations in the worker's settings. - ```bash - kubectl cp graphdb-master-1-0:/opt/graphdb/home/work/workbench/settings.js settings_m.js - kubectl cp graphdb-worker-<selected-worker>:/opt/graphdb/home/work/workbench/settings.js settings_w.js - diff settings_m.js settings_w.js - ``` - If anything other than the locations is different between the files assume that the master's file is correct and copy it to the worker: - ```bash - kubectl cp settings_m.js graphdb-worker-<selected-worker>:/opt/graphdb/home/work/workbench/settings.js - ``` -6. During a replication of a node GraphDB 10 can take double the storage which 9.x takes, so you might need to increase your PV size! To do this - we recommend checking the documentation of your cloud service provider but in general the procedure is: - - Make sure `allowVolumeExpansion: true` is set in your used storageClass. - - Request a change in volume capacity by editing your PVC's `spec.resources.requests.storage` - - Verify the change has taken effect with `get pvc <pvc-name> -o yaml` and checking the `status.capacity` field. -7. Scale down the selected worker. In the official GraphDB every worker has it's' own statefulset. - List all the statefulsets to find the name of the worker you want to scale down: - ```bash - kubectl get statefulsets - ``` - Then change the number of replicas to 0: - ```bash - kubectl scale statefulsets <stateful-set-name> --replicas=0 - ``` -8. Once the worker is down patch the worker's PV with `"persistentVolumeReclaimPolicy":"Retain"`: - ```bash - kubectl patch pv <worker-pv-name> -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' - ``` -9. Delete the worker's PVC. - ```bash - kubectl delete pvc <worker-pvc-name> - ``` -10. Patch the PV with `"claimRef":null` so it can go from status Released to Available: - ```bash - kubectl patch pv <worker-pv-name> -p '{"spec":{"claimRef":null}}' - ``` -11. Patch the PV with `claimRef` matching the PVC that will be generated by the `volumeClaimTemplates`: - ```bash - kubectl patch pv <worker-pv-name> -p '{"spec":{"claimRef":{"name":"graphdb-node-data-dynamic-pvc-graphdb-node-0"}}}' - ``` -12. Create a namespace for the GraphDB 10 helm chart, so we can deploy it without having to delete our 9.x cluster: - ```bash - kubectl create namespace <new-namespace-name> - ``` -13. Patch/Move the worker's PV to the new namespace: - ```bash - kubectl patch pv <worker-pv-name> -p '{"spec":{"claimRef":{"namespace":"<namespace-name>"}}}' - ``` -14. Create a secret with your license in the new namespace: - ```bash - graphdb-license --from-file graphdb.license -n <new-namespace-name> - ``` -15. Install the 10.0 Helm chart. Remember to edit: -- `graphdb.node.resources.limits.memory` and `graphdb.node.resources.requests.memory` to the ones used by the old workers. -- `graphdb.nodesCount:` The raft protocol recommends an odd amount of nodes. Set to the amount of workers you had in the old cluster. -- `graphdb.node.persistance.volumeClaimTemplateSpec.accessModes` and `graphdb.node.persistance.volumeClaimTemplateSpec.resources.requests.storage` to the ones used by the old PVs. -- `graphdb.clusetConfig.clusterCreationTimeout` high enough so the data from the old worker has time to replicate to all the new nodes. This depends on network speed between the nodes and the read/write performance of the storage. If the replication is expected to take more than 5 minutes add an equivalent `--timeout XXm` to the helm install command. -- `deployment.host` to temporary address where you can test everything is working. - -16. Once you confirm everything has migrated and works as expected you can free up the old `deployment.host` and upgrade the new cluster to it. - -**Note**: If you decide to revert to 9.x and don't have a backup of the worker's PV, you won't be able to use the old PV as GraphDB 10's repositories and settings aren't backward compatible. -Your best course of action would be to make sure it will provision a new clean PV, scale the replica back from 0, recreate the worker repositories and reconnect them to the old master repositories letting GraphDB replicate the data. - -### Quick Start - -The Helm chart includes an example repository configuration TTLs. - -To install the GraphDB on `graphdb.local`: +## Install -```bash -helm install --set deployment.host=graphdb.local graphdb . -``` +### Version Compatability -After a few seconds, Helm will print out the result from installing GraphDB. -You should see the following output: +The next table highlights the version mapping between the Helm chart and the deployed GraphDB. -``` -------------------------------------------------------------------------------- - ____ _ ____ ____ - / ___|_ __ __ _ _ __ | |__ | _ \| __ ) - | | _| '__/ _` | '_ \| '_ \| | | | _ \ - | |_| | | | (_| | |_) | | | | |_| | |_) | - \____|_| \__,_| .__/|_| |_|____/|____/ - |_| -------------------------------------------------------------------------------- -version: 10.0.0 -GDB cluster: true - -** Please be patient while the chart is being deployed and services are available ** -You can check their status with kubectl get pods - -Endpoints: -* GraphDB workbench: http://graphdb.local/graphdb -``` +| Helm chart version | GraphDB version | +|--------------------|-----------------| +| 10.x | 10.0 - 10.6.4 | +| 11.0 | 10.6.4 | -### Repository +### Install from Repository -You can install GraphDB's Helm chart from our public Helm repository as well. - -1. Add Ontotext repository with +1. Add Ontotext repository ```shell helm repo add ontotext https://maven.ontotext.com/repository/helm-public/ @@ -269,11 +109,19 @@ You can install GraphDB's Helm chart from our public Helm repository as well. helm install graphdb ontotext/graphdb ``` +3. Upgrade GraphDB deployment + + ```shell + helm upgrade --install graphdb ontotext/graphdb + ``` + +See [Configuration](#configuration) and [values.yaml](values.yaml) on how to customize your GraphDB deployment. + ### Provenance -Helm can verify the origin and integrity of the Helm chart by +Helm can verify the origin and integrity of the Helm chart by: -1. Importing the public GnuPG key: +1. Importing the public GnuPG key for GraphDB Helm: ```shell gpg --keyserver keyserver.ubuntu.com --recv-keys 8E1B45AF8157DB82 @@ -287,46 +135,47 @@ Helm can verify the origin and integrity of the Helm chart by helm install --verify graphdb ontotext/graphdb ``` -Note that the verification works only when installing from a local tar.gz or when installing from the repository. +**Note**: The verification works only when installing from a local tar.gz or when installing from the repository. -## Persistence +Check the official documentation for more information https://helm.sh/docs/topics/provenance/ -By default, the Helm chart is deploying persistent volumes that store data on the host path. -This is useful for local Minikube deployments. However, in a cloud environment with multiple node -cluster this would lead to rescheduling and **data loss**. +### Uninstall -See https://kubernetes.io/docs/concepts/storage/volumes/. +To remove the deployed GraphDB, use: -### Local deployment +```shell +helm uninstall graphdb +``` -Local persistent volumes are configured with `graphdb.node.persistence` from [values.yaml](values.yaml). +**Note**: It is important to note that this will not remove any data, so the next time it is installed, the data will be loaded by its components. -### Cloud deployment +## Upgrading -For cloud deployment, you have to prepare persistent disks, storage class (or classes) and finally -persistent volumes manifests. Once this is done, every component must be reconfigured in -[values.yaml](values.yaml) to point to the new persistent volume and not the default one. Each -component has a section `persistence` that has to be updated. +The Helm chart follows [Semantic Versioning v2](https://semver.org/) so any breaking changes will be rolled out only in MAJOR versions of the chart. -## API Gateway +Please, always check out the migration guides in [UPGRADE.md](UPGRADE.md) before switching to another major version of the Helm chart. -The services are proxied using nginx Ingress gateway. By default, it is configured to route: +## Configuration -- GraphDB Workbench -- GraphDB cluster proxy if the cluster deployment is enabled +Every component and resource is configured with sensible defaults in [values.yaml](values.yaml). +Make sure you read it thoroughly, understand each property and the impact of changing any one of them. -## Customizing +Helm allows you to override values from [values.yaml](values.yaml) in several ways. +See https://helm.sh/docs/chart_template_guide/values_files/. -Every component in configured with sensible defaults. Some of them are applied from -[values.yaml](values.yaml). Make sure you read it thoroughly, understand each property and the -impact of changing any one of them. +* Using a separate values.yaml with overrides: + ```shell + helm install graphdb ontotext/graphdb -f overrides.yaml + ``` -**Note**: If you are familiar with Kubernetes, you could modify the component's configuration -templates directly. +* Overriding specific values: + ```shell + helm install graphdb ontotext/graphdb --set security.enabled=true + ``` -#### Ontop repositories +### Ontop repositories -Ontop repositories require a jdbc driver. To use this type of repository, you have to provide a jdbc driver named `jdbc-driver.jar`. +Ontop repositories require a JDBC driver. To use this type of repository, you have to provide a JDBC driver named `jdbc-driver.jar`. It must be located in each GraphDB instance in which you wish to use with Ontop repository, in the folder `/opt/graphdb/home/jdbc-driver`. The directory is part of the GraphDB home directory which is persistent, so the driver will persist after a restart or reschedule of a GraphDB pod. @@ -340,73 +189,65 @@ There are 3 important configuration sections: #### GraphDB cluster configuration -With the release of GraphDB 10, master nodes are no longer needed for a cluster, so the size of the cluster is controlled by just one property: `graphdb.clusterConfig.nodesCount`. +With the release of GraphDB 10, master nodes are no longer needed for a cluster, so the size of the cluster is controlled by just one property: `replicas`. You will need at least three GraphDB installations to create a fully functional cluster. Remember that the Raft algorithm recommends an odd number of nodes, so a cluster of five nodes is a good choice. -Note: If "1" is selected as node count, the launched node will be standalone and no instances of the cluster proxy will be deployed! +Note: If `1` is selected as node count, the launched node will be standalone and no instances of the cluster proxy will be deployed! -- The section `graphdb.clusterConfig` can be used to configure a GraphDB cluster. +- The section `cluster.config` can be used to configure a GraphDB cluster. -See more about the cluster here: https://graphdb.ontotext.com/documentation/10.0/cluster-basics.html +See more about the cluster here: https://graphdb.ontotext.com/documentation/10.6/cluster-basics.html -#### Deploying GraphDB with security +### Deploying GraphDB with security -GraphDB's Helm chart supports deploying GraphDB with or without security. This can be toggled through `graphdb.security.enabled`. +GraphDB's Helm chart supports deploying GraphDB with or without security. This can be toggled through `security.enabled`. If it is deployed with security enabled, a special provisioning user is used for repository provisioning, cluster linking, health checks and so on. Additional users can be added through the users file: `files/config/users.js`. The users are described with their roles, username and a bcrypt64 password. -The file can be provisioned before GraphDB's startup with the `usersConfigMap` configmap or left to default. -It can be overridden with other configmap containing the `users.js` file. +The file can be provisioned before GraphDB's startup with the `security.initialUsers` configurations. +It can be overridden with other configmap containing the `users.js` file with `security.initialUsers.existingSecret`. Note that the `provisioning` user is required when security is turned on! By default, if the security is turned on, GraphDB's basic security method is used. More complicated security configurations can be configured using additional configurations in `graphdb.properties`. -See https://graphdb.ontotext.com/documentation/10.0/access-control.html +See https://graphdb.ontotext.com/documentation/10.6/access-control.html Prior to GraphDB 10.0.0 the users and their settings were saved in the `settings.js` file. -#### Provisioning additional properties and settings +### Provisioning additional properties and settings -Most of GraphDB's properties can be passed through `java_args`. Another option is to supply a `graphdb.properties` file. -This file can be provisioned on during GraphDB's startup using `propertiesConfigMap`configmap or left to default. -It can be overridden with other configmap containing the `graphdb.properties` file. +Most of GraphDB's properties can be passed through `configuration.properties` or `configuration.javaArguments`. +Another option is to supply a `graphdb.properties` file. +This file can be provisioned on during GraphDB's startup using `configuration.extraProperties.existingConfigmap`. The `graphdb.properties` file is also used for more complex security configurations such as LDAP, Oauth, Kerberos. Some additional settings are kept in the `settings.js` file. Most of those settings are internal for GraphDB and better left managed by the client. -The file can be provisioned before GraphDB's startup with the `settingsConfigMap` configmap or left to default. -It can be overridden with other configmap containing the `settings.js` file. +The file can be provisioned before GraphDB's startup with the `configuration.initialSettings.existingSecret` configuration. Note the `settings.js` must contain `security.enabled" : true` property when security is turned on! -GraphDB uses logback to configure logging using the `logback.xml` file. -The file can be provisioned before GraphDB's startup with the `logbackConfigMap` configmap or left to default. -It can be overridden with other configmap containing the `logback.xml` file. +GraphDB uses Logback to configure logging using the `logback.xml` file. +The file can be provisioned before GraphDB's startup with the `configuration.logback.existingConfigmap` configuration. -See https://graphdb.ontotext.com/documentation/10.0/configuring-graphdb.html?highlight=properties -See https://graphdb.ontotext.com/documentation/10.0/access-control.html +See https://graphdb.ontotext.com/documentation/10.6/directories-and-config-properties.html#configuration-properties + +See https://graphdb.ontotext.com/documentation/10.6/access-control.html + +### Importing data from existing persistent volume -#### Importing data from existing persistent volume GraphDB supports attaching a folder as an import directory. The directory's content s visible in the Workbench and can be imported. -In the Helm chart you can use existing PV as an import directory. This is done through `graphdb.import_directory_mount` using a `volumeClaimTemplateSpec`. -This way a dynamic PV/PVC can be provisioned, or you can use an existing PV. If an existing PV is used, have in mind that the dynamically provisioned PVC name is `graphdb-server-import-dir-graphdb-master-1-0`, so an appropriate `claimRef` must be added to the existing PV. +In the Helm chart you can use existing PV as an import directory. This is done through `import.volumeMount` using a `volumeClaimTemplateSpec`. +This way a dynamic PV/PVC can be provisioned, or you can use an existing PV with an appropriate `claimRef`. ### Networking By default, GraphDB's Helm chart comes with a default Ingress. -The Ingress =can be disabled by switching `ingress.enabled` to false. +The Ingress can be disabled by switching `ingress.enabled` to false. ### Cloud deployments specifics -Some cloud kubernetes clusters have some specifics that should be noted. Here are some useful tips on some cloud K8s clusters: - -##### Google cloud - -In Google's k8s cluster services, the root directory is not writable. By default, GraphDB's chart uses `/data` directory to store instances data. -If you're using Google cloud, please change this path to something else, not located on the root level. - -By default, the ingress used in the helm chart utilizes NGINX as ingress.class. -The easiest way to make it work inside the GKE is by deploying a NGINX ingress controller. Information on how that can be achieved can be found here: https://cloud.google.com/community/tutorials/nginx-ingress-gke +Some cloud Kubernetes clusters have some specifics that should be noted. Here are some useful tips on some cloud K8s clusters: ##### Microsoft Azure @@ -415,32 +256,11 @@ not good enough for GraphDB, and we recommend against using it in production env See https://github.com/Azure/AKS/issues/223 -### values.yaml - -Helm allows you to override values from [values.yaml](values.yaml) in several ways. -See https://helm.sh/docs/chart_template_guide/values_files/. - -- Preparing another *values.yaml*: - -```bash -helm install graphdb . -f overrides.yaml -``` - -- Overriding specific values: - -```bash -helm install graphdb . --set deployment.host=graphdb.local --set security.enabled=true -``` - ### Deployment Some important properties to update according to your deployment are: -* `deployment.protocol` and `deployment.host` - configure the ingress -controller and some components on which they are accessible. The `deployment.host` must be a -resolvable hostname and not an IP address. -* `deployment.storage` configures components where to store their persistent data on the host system -running the Kubernetes environment. +* `configuration.externalUrl` - Configures the address at which the Ingress controller and GraphDB are accessible. ### Resources @@ -457,28 +277,44 @@ See the Kubernetes documentation https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ about defining resource limits. -## Values +## Examples -{{ template "chart.valuesTable" . }} +Checkout the [examples/](examples) folder in this repository. -## Uninstall -To remove the deployed GraphDB, use: +## Guides -```bash -helm uninstall graphdb +### Updating an expired GraphDB license + +When the license expires, you will have to update the Secret object and restart the GraphDB pods in order to load the new license. + +In avoid restarting your current GraphDB instances, you can copy the new license directly into your GraphDB containers, in the folder `/opt/graphdb/home/conf`. +It's important to name your file exactly `graphdb.license`! + +```shell +kubectl delete secret graphdb-license +kubectl create secret generic graphdb-license --from-file graphdb.license=graphdb.license +kubectl cp graphdb.license graphdb-pod-0:/opt/graphdb/home/conf/ +kubectl cp graphdb.license graphdb-pod-1:/opt/graphdb/home/conf/ +kubectl cp graphdb.license graphdb-pod-2:/opt/graphdb/home/conf/ ``` -**Note**: It is important to note that this will not remove any data, so the next time it -is installed, the data will be loaded by its components. +## Values -Provisioning will be skipped also. +<!-- +IMPORTANT: This is generated by helm-docs, do not attempt modifying it on hand as it will be automatically generated. +--> -## Troubleshoot +{{ template "chart.valuesTable" . }} + +## Troubleshooting **Helm install hangs** If there is no output after `helm install`, it is likely that a hook cannot execute. -Check the logs with `kubectl logs`. +Check their logs with `kubectl logs`. + +Another reason could be that the default timeout of 5 minutes for Helm `install` or `upgrade` is not enough. +You can increase the timeout by adding `--timeout 10m` (or more) to the Helm command. **Connection issues** @@ -490,3 +326,11 @@ https://kubernetes.io/docs/tasks/administer-cluster/dns-debugging-resolution/. ## Maintainers {{ template "chart.maintainersTable" . }} + +## Contributing + +If you have any suggestions, bug reports, or feature requests, please open an issue or submit a pull request. + +## License + +This code is released under the Apache 2.0 License. See [LICENSE](LICENSE) for more details. diff --git a/UPGRADE.md b/UPGRADE.md new file mode 100644 index 00000000..f385bb6a --- /dev/null +++ b/UPGRADE.md @@ -0,0 +1,269 @@ +# GraphDB Helm Chart Upgrade Guide + +## From 10.x to 11 + +Before continuing, familiarize yourself with the new configuration structure in [values.yaml](values.yaml) as well as with +the [changelog for version 11](CHANGELOG.md#version-1100). + +### Configurations + +Version 11 of the Helm chart introduces a lot of changes to the configurations and their structure in [values.yaml](values.yaml). +Here are the most notable steps that you should be aware of: + +**Kubernetes Version** + +The Helm chart is updated to require a minimum Kubernetes version of 1.26. +Refer to the official Kubernetes documentation on how to move to a newer version if needed. +We strongly advise to operate a Kubernetes cluster with version that has not reached its End Of Life. + +**Naming** + +The resource names are no longer hardcoded in version 11. If you want to keep the old ones, you can override the following configurations from +[values.yaml](values.yaml): `fullnameOverride` and `proxy.fullnameOverride`. + +**GraphDB URL** + +The old version 10 of the chart had several configuration properties that defined the external URL of GraphDB: `deployment.protocol`, +`deployment.host` and `graphdb.workbench.subpath`. +In version 11, they have been combined into a single configuration property `configuration.externalUrl`. +Make sure to update it accordingly. + +Note that the default URL configuration now uses https://nip.io/ which avoids having to edit your hosts file, compared to version 10. +However, this is suitable only for local development, so you'd have to update it to a real resolvable URL according to your environment and +requirements. + +**Ingress** + +If you use the Ingress for accessing GraphDB: Version 11 removes the default use of specific ingress controllers. +It's up to you to properly set up the default ingress controller in your cluster or to properly configure the default Ingress in this chart with +the `ingress` configuration in [values.yaml](values.yaml). + +For configuring the Ingress to work with the NGINX controller, you can check the examples in [examples/ingress-nginx/](examples/ingress-nginx) folder. + +**Storage Class** + +Version 11 removes the hardcoded storage class from `global.storageClass`. +If you don't have a default storage class in your cluster, you can define the storage class for GraphDB's PVC +with `persistence.volumeClaimTemplate.spec.storageClassName` for GraphDB and `persistence.volumeClaimTemplate.spec.storageClassName` for the proxy (if +enabled). + +**Persistence** + +Persistence configurations from `graphdb.node.persistence` have been moved to `persistence` and `graphdb.clusterProxy.persitence` +to `proxy.persistence`. + +**Cluster** + +Version 11 now uses `replicas` instead of `graphdb.clusterConfig.nodesCount` to control the deployment of GraphDB proxies and the creation of the +cluster. + +Note that all other cluster related configurations have been moved under the `cluster` section in [values.yaml](values.yaml). + +**Security** + +Note that all security configurations have been moved under the `security` section in [values.yaml](values.yaml). + +The provisioning user credentials are now under `security.provisioner`. + +**Other** + +See [11.0.0 Breaking Changes section](./CHANGELOG.md) for more details on migrating other configurations. + +### Data Migration + +Due to the amount of breaking changes in version 11, any volumes created by version 10 won't be reused automatically. +Here are two options to migrate GraphDB data for version 11, each of which require some downtime. + +**Backup and Restore** + +Probably the easiest migration option is to use GraphDB's own +[backup and restore](https://graphdb.ontotext.com/documentation/10.6/backup-and-restore.html) functionality. + +1. Follow GraphDB's documentation on how to trigger a Backup, you can choose: + - [Local backup](https://graphdb.ontotext.com/documentation/10.6/backup-and-restore.html#creating-a-backup) + - [Cloud backup](https://graphdb.ontotext.com/documentation/10.6/backup-and-restore.html#creating-and-restoring-cloud-backups) +2. Uninstall the old deployment. Note that this won't remove your existing PVs. +3. Install the new version of the Helm chart +4. Use the restore operation: + - Restore from [local backup](https://graphdb.ontotext.com/documentation/10.6/backup-and-restore.html#restoring-from-a-backup) + - Restore from [cloud backup](https://graphdb.ontotext.com/documentation/10.6/backup-and-restore.html#restoring-from-a-cloud-backup) + +The downside of this option is that if there are a lot of GBs of data to be backed up and later restored, this option would be the slowest. + +**Matching PVC claims** + +To minimize the downtime from **Backup and Restore**, you could reuse the existing Persistent Volumes from the deployment made with version 10 of +the chart. The procedure is as follows: + +1. Make note of the names of the existing PVs and PVCs: + - Kubernetes uses the following policy for naming PVC: `<pvc-template-name>-<statefulset-name>-<pod index>`, i.e. this would be + `graphdb-node-data-dynamic-pvc-graphdb-node-0` for version 10 of the chart. + - For the new version 11, this depends on the release name or if you'll use name overrides, but it should be something like this: + `storage-<statefulset-name>-<pod-index>`, i.e. `storage-test-graphdb-0` where `test` is the Helm release name. +2. Uninstall the old deployment with `helm uninstall ...` +3. Make sure that the reclaim policy of the existing PVs is set to `Retain`. For each PVC, find the corresponding PV and patch it with: + ```bash + kubectl patch pv <pv-name> -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' + ``` + where: + - `pv-name` is the name of one of the existing persistent volumes +4. Patch the existing PVs with `"claimRef":null` to force them to go from status `Released` to `Available`, use: + ```bash + kubectl patch pv <pv-name> -p '{"spec":{"claimRef":null}}' + ``` + where: + * `pv-name` is the name of one of the existing persistent volumes +5. Update the existing PVs `claimRef` attribute to match the PVC names that will be created by the new PVC template in version 11, use: + ```bash + kubectl patch pv <pv-name> -p '{"spec":{"claimRef":{"name":"storage-<statefulset-name>-<pod-index>","namespace":"<namespace>"}}}' + ``` + where: + * `pv-name` is the name of one of the existing persistent volumes + * `statefulset-name` is the name of the StatefulSet for GraphDB, and it depends on the release name or any name overrides + * `pod-index` is the ordinal index of a concrete pod, i.e. `0`, `1` and `2` for a 3 node cluster + * `namespace` is the Kubernetes namespace where you'll deploy the Helm chart + + If you are not fully sure what are the correct PVCs names, you could first deploy the new version to make note of the PVC naming and patch the + PVs later. + +The downside of this option is that the user that owns the data in the existing PVs is `root` while the new chart runs with a non-root user. +[Fixing Permissions](#fixing-permissions) explains further. + +#### Fixing Permissions + +Version 11 of the chart includes a default security context that avoids running containers with the `root` user. +However, version 10 of the chart have been running containers with the `root` user. +This requires changing ownership of the data when using existing Persistent Volumes. + +Note that if you've selected to use the **Backup and Restore** option for the data migration, these next steps are not needed. + +There are 3 options that you can choose from: + +**Using an initContainer** + +The chart includes a special init container that will change the data to be owned by the configured user in the security context. +Set `initContainerDataPermissions.enabled` to `true` to enable it for GraphDB and `proxy.initContainerDataPermissions.enabled` to `true` for the +proxies. This should be a one time operation, so you can disable them later. + +You can also provide a custom init container with `extraInitContainers` and `proxy.extraInitContainers` + +**Reconfigure the context** + +Alternatively, you can reconfigure the security context configurations to use the `root` user. +This includes the following configurations: + +* `podSecurityContext`, `securityContext` and `initContainerSecurityContext` for GraphDB +* `proxy.podSecurityContext`, `proxy.securityContext` and `proxy.initContainerSecurityContext` for the GraphDB proxies +* `jobs.podSecurityContext` and `jobs.securityContext` for the cluster management Jobs + +**Manually** + +You could mount the persistent volumes to temporary pods and manually update the permissions. +The process is similar to matching PVC claims as described above but to pods that would just update the ownership of the data. + +Consider this option if you would like to avoid the init container approach. + +--- + +You can now install the new Helm chart version. + +## From 9.x to 10 + +**Warning**: Before starting the migration change your master into read only mode. +The process is irreversible and full backup is HIGHLY advisable. +At minimum backup the PV of the worker you are planing to use for migration. + +The Helm chart is completely new and not backwards-compatible. + +1. Make all masters read only, you can use the workbench. + +2. Using the workbench disconnect all repositories of the worker which we are going to use to migrate to 10.0. + If you've used the official GraphDB helm chart you can select any worker. + In case of a custom implementation select one that can easily be scaled down. + + **Note**: Only the repositories that are on the worker will be migrated into the new cluster! + +3. Get the PV information of the worker, noting down the capacity and the access mode: + ```bash + kubectl get pv + ``` + +4. Note down the resource limits of the worker node: + ```bash + kubectl get pod graphdb-worker-<selected-worker> -o yaml | grep -B 2 memory + ``` + +5. Make sure all the important settings saved in the settings.js of the master are present in the workers. Their only difference + should be the lack of locations in the worker's settings. + ```bash + kubectl cp graphdb-master-1-0:/opt/graphdb/home/work/workbench/settings.js settings_m.js + kubectl cp graphdb-worker-<selected-worker>:/opt/graphdb/home/work/workbench/settings.js settings_w.js + diff settings_m.js settings_w.js + ``` + If anything other than the locations is different between the files assume that the master's file is correct and copy it to the worker: + ```bash + kubectl cp settings_m.js graphdb-worker-<selected-worker>:/opt/graphdb/home/work/workbench/settings.js + ``` + +6. During a replication of a node GraphDB 10 can take double the storage which 9.x takes, so you might need to increase your PV size! To do this + we recommend checking the documentation of your cloud service provider but in general the procedure is: + - Make sure `allowVolumeExpansion: true` is set in your used storageClass. + - Request a change in volume capacity by editing your PVC's `spec.resources.requests.storage` + - Verify the change has taken effect with `get pvc <pvc-name> -o yaml` and checking the `status.capacity` field. + +7. Scale down the selected worker. In the official GraphDB chart, every worker has its own statefulset. + List all the stateful sets to find the name of the worker you want to scale down: + ```bash + kubectl get statefulsets + ``` + Then change the number of replicas to 0: + ```bash + kubectl scale statefulsets <stateful-set-name> --replicas=0 + ``` + +8. Once the worker is down, patch the worker's PV with `"persistentVolumeReclaimPolicy":"Retain"`: + ```bash + kubectl patch pv <worker-pv-name> -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' + ``` + +9. Delete the worker's PVC. + ```bash + kubectl delete pvc <worker-pvc-name> + ``` + +10. Patch the PV with `"claimRef":null` so it can go from status Released to Available: + ```bash + kubectl patch pv <worker-pv-name> -p '{"spec":{"claimRef":null}}' + ``` + +11. Patch the PV with `claimRef` matching the PVC that will be generated by the `volumeClaimTemplates`: + ```bash + kubectl patch pv <worker-pv-name> -p '{"spec":{"claimRef":{"name":"graphdb-node-data-dynamic-pvc-graphdb-node-0"}}}' + ``` + +12. Create a namespace for the GraphDB 10 helm chart, so we can deploy it without having to delete our 9.x cluster: + ```bash + kubectl create namespace <new-namespace-name> + ``` + +13. Patch/Move the worker's PV to the new namespace: + ```bash + kubectl patch pv <worker-pv-name> -p '{"spec":{"claimRef":{"namespace":"<namespace-name>"}}}' + ``` + +14. Create a secret with your license in the new namespace: + ```bash + graphdb-license --from-file graphdb.license -n <new-namespace-name> + ``` + +15. Install the 10.0 Helm chart. Remember to edit: + - `graphdb.node.resources.limits.memory` and `graphdb.node.resources.requests.memory` to the ones used by the old workers. + - `graphdb.nodesCount:` The raft protocol recommends an odd amount of nodes. Set to the amount of workers you had in the old cluster. + - `graphdb.node.persistance.volumeClaimTemplateSpec.accessModes` and `graphdb.node.persistance.volumeClaimTemplateSpec.resources.requests.storage` to the ones used by the old PVs. + - `graphdb.clusetConfig.clusterCreationTimeout` high enough so the data from the old worker has time to replicate to all the new nodes. This depends on network speed between the nodes and the read/write performance of the storage. If the replication is expected to take more than 5 minutes add an equivalent `--timeout XXm` to the helm install command. + - `deployment.host` to temporary address where you can test everything is working. + +16. Once you confirm everything has migrated and works as expected you can free up the old `deployment.host` and upgrade the new cluster to it. + +**Note**: If you decide to revert to 9.x and don't have a backup of the worker's PV, you won't be able to use the old PV as GraphDB 10's repositories and settings aren't backward compatible. +Your best course of action would be to make sure it will provision a new clean PV, scale the replica back from 0, recreate the worker repositories and reconnect them to the old master repositories letting GraphDB replicate the data. diff --git a/examples/custom-logback/README.md b/examples/custom-logback/README.md new file mode 100644 index 00000000..5d69eae6 --- /dev/null +++ b/examples/custom-logback/README.md @@ -0,0 +1,28 @@ +# GraphDB with Custom Logback Configuration + +GraphDB comes with a pre-configured Logback XML using sensible configuration defaults. +However, for certain use cases, it might need to be fine-tuned. + +This example shows how to use a custom Logback XML configuration with GraphDB's Helm chart. + +## Usage + +1. Customize [configmap-logback.yaml](configmap-logback.yaml) according to your needs and apply: + + ```bash + kubecttl apply -f configmap-logback.yaml + ``` + +2. Configure the Helm chart to use the custom ConfigMap in [values.yaml](values.yaml) + + ```yaml + configuration: + logback: + existingConfigmap: "graphdb-custom-logback-config" + ``` + +3. Deploy the Helm chart with the custom configurations + + ```bash + helm upgrade --install --values values.yaml graphdb-logback ../../ + ``` diff --git a/examples/custom-logback/configmap-logback.yaml b/examples/custom-logback/configmap-logback.yaml new file mode 100644 index 00000000..5ab95fec --- /dev/null +++ b/examples/custom-logback/configmap-logback.yaml @@ -0,0 +1,194 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: graphdb-custom-logback-config +data: + logback.xml: |- + <configuration debug="false" scan="true" scanPeriod="30 seconds"> + <jmxConfigurator/> + + <!-- Try to guess the logs destination based on the application server or fallback to a default logs directory(embedded mode) + NOTE: We are using a really old version of logback so we have to use p().isEmpty instead of isDefined --> + + <if condition='p("logDestinationDirectory").isEmpty()'> + <then> + <!-- catalina.base if we are running on tomcat --> + <if condition='!p("catalina.base").isEmpty()'> + <then> + <property name="logDestinationDirectory" value="${catalina.base}/logs/graphdb"/> + </then> + <else> + <!-- jetty.base if we are running on tomcat --> + <if condition='!p("jetty.base").isEmpty()'> + <then> + <property name="logDestinationDirectory" value="${jetty.base}/logs/graphdb"/> + </then> + <else> + <!-- we are running in embedded mode --> + <property name="logDestinationDirectory" value="logs"/> + </else> + </if> + </else> + </if> + </then> + </if> + + <property name="defaultPattern" value="[%-5p] %d{ISO8601} [%t | %c{5}]%X{headers} %m%n%ex"/> + <property name="encoding" value="UTF-8"/> + + <!-- Properties for log keeping based on age and size. By default logs will be kept for 30 days with no size limit--> + <!-- Sets the maximum age of kept logs in days. Set to 0 for no limit --> + <property name="keepLogDays" value="30"/> + <!-- Sets the maximum size of every log kept. Accepts values like 500KB, 200MB, 1GB etc. Set to 0 for no limit + NOTE: This sets the size limit per each different log type. If you want more control change the totalSizeCap of each log separately--> + <property name="logMaxSize" value="0"/> + <!-- This attribute sets the maximum size that an individual log file can reach before Logback triggers a rollover. + When a log file surpasses this size, a new log file is created, and the old one may be archived, compressed, or otherwise handled based on the rolling policy. --> + <property name="maxFileSize" value="1GB"/> + + <!-- Audit log. Contains security related things --> + <appender name="AuditLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDestinationDirectory}/audit.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> + <fileNamePattern>${logDestinationDirectory}/audit-%d{yyyy-MM}/audit-%d{yyyy-MM-dd}.%i.zip</fileNamePattern> + <maxFileSize>${maxFileSize}</maxFileSize> + <maxHistory>${keepLogDays}</maxHistory> + <totalSizeCap>${logMaxSize}</totalSizeCap> + <cleanHistoryOnStart>true</cleanHistoryOnStart> + </rollingPolicy> + <encoder> + <pattern>${defaultPattern}</pattern> + <charset>${encoding}</charset> + </encoder> + </appender> + + <appender name="MainLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDestinationDirectory}/main.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> + <fileNamePattern>${logDestinationDirectory}/main-%d{yyyy-MM}/main-%d{yyyy-MM-dd}.%i.zip + </fileNamePattern> + <maxFileSize>${maxFileSize}</maxFileSize> + <maxHistory>${keepLogDays}</maxHistory> + <totalSizeCap>${logMaxSize}</totalSizeCap> + <cleanHistoryOnStart>true</cleanHistoryOnStart> + </rollingPolicy> + <encoder> + <pattern>${defaultPattern}</pattern> + <charset>${encoding} + </charset> + </encoder> + </appender> + + <appender name="ErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDestinationDirectory}/error.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> + <fileNamePattern>${logDestinationDirectory}/errors-%d{yyyy-MM}/error-%d{yyyy-MM-dd}.%i.zip + </fileNamePattern> + <maxFileSize>${maxFileSize}</maxFileSize> + <maxHistory>${keepLogDays}</maxHistory> + <totalSizeCap>${logMaxSize}</totalSizeCap> + <cleanHistoryOnStart>true</cleanHistoryOnStart> + </rollingPolicy> + <encoder> + <pattern>${defaultPattern}</pattern> + <charset>${encoding}</charset> + </encoder> + <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> + <level>ERROR</level> + </filter> + </appender> + + <appender name="QueryLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDestinationDirectory}/query.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> + <fileNamePattern>${logDestinationDirectory}/queries-%d{yyyy-MM}/query-%d{yyyy-MM-dd}.%i.zip</fileNamePattern> + <maxFileSize>${maxFileSize}</maxFileSize> + <maxHistory>${keepLogDays}</maxHistory> + <totalSizeCap>${logMaxSize}</totalSizeCap> + <cleanHistoryOnStart>true</cleanHistoryOnStart> + </rollingPolicy> + <encoder> + <pattern>${defaultPattern}</pattern> + <charset>${encoding}</charset> + </encoder> + </appender> + + <appender name="SlowQueryLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDestinationDirectory}/slow-query.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> + <fileNamePattern>${logDestinationDirectory}/slow-queries-%d{yyyy-MM}/slow-query-%d{yyyy-MM-dd}.%i.zip</fileNamePattern> + <maxFileSize>${maxFileSize}</maxFileSize> + <maxHistory>${keepLogDays}</maxHistory> + <totalSizeCap>${logMaxSize}</totalSizeCap> + <cleanHistoryOnStart>true</cleanHistoryOnStart> + </rollingPolicy> + <encoder> + <pattern>${defaultPattern}</pattern> + <charset>${encoding}</charset> + </encoder> + </appender> + + <if condition='!p("graphdb.foreground").isEmpty()'> + <then> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>${defaultPattern}</pattern> + </encoder> + </appender> + </then> + </if> + + <!-- Log all repository, user creations, modifications and deletions. Also logs successful or not attempts to + login into system. Updates, queries and imports to repository. Set to "INFO" level for logging all former updates. + Will log exceptions on "ERROR" level. Additivity is set to "false" and called first to prevent the messages + from cluttering the other logs. --> + <logger name="com.ontotext.forest.security.audit.AuditLoggingFilter" level="INFO" additivity="false"> + <appender-ref ref="AuditLog"/> + </logger> + + <!-- Log update operations on workers. Set to "INFO" level by default for logging all updates in workers' QueryLog. + Will log exceptions on "ERROR" level. Additivity is set to "false" and called first to prevent the messages + from cluttering the other logs.--> + <logger name="com.ontotext.trree.monitorRepository.MonitorRepositoryConnection" level="INFO" additivity="false"> + <appender-ref ref="QueryLog"/> + </logger> + + <!-- Log querry operations on the repository. Set to "DEBUG" level for logging all querries. Will log exceptions on "ERROR" + level. Additivity is set to "false" to prevent the messages from cluttering the other logs. --> + <logger name="com.ontotext.trree.query.LoggingClosableIteration" level="INFO" additivity="false"> + <appender-ref ref="QueryLog"/> + </logger> + + <!-- Log slow queries on "INFO" level. Queries are deemed "slow" if they take more than "SlowOpThresholdMs" from the + RepositorySettings property. Set the level to "OFF" to stop this log. Additivity is set to "false" to prevent the messages + from cluttering the other logs. --> + <logger name="slow-queries" level="INFO" additivity="false"> + <appender-ref ref="SlowQueryLog"/> + </logger> + + <root> + <level value="${graphdb.logger.root.level:-DEBUG}"/> + <appender-ref ref="MainLog"/> + <appender-ref ref="ErrorLog"/> + <if condition='!p("graphdb.foreground").isEmpty()'> + <then> + <appender-ref ref="STDOUT"/> + </then> + </if> + + </root> + + <!-- Make some of the more verbose loggers less chatty --> + <logger name="org.springframework" level="WARN"/> + <logger name="org.apache" level="WARN"/> + <logger name="com.github.ziplet" level="WARN"/> + <logger name="springfox.documentation" level="WARN"/> + <logger name="org.eclipse.rdf4j.query.algebra.evaluation" level="ERROR"/> + + <!-- GeoSPAQRL related deps be less verbose --> + <logger name="hsqldb.*" level="WARN"/> + <logger name="org.geotoolkit.*" level="WARN"/> + + <!-- SemanticVectors related logger be less verbose --> + <logger name="pitt.search.semanticvectors.DocVectors" level="WARN"/> + </configuration> diff --git a/examples/custom-logback/values.yaml b/examples/custom-logback/values.yaml new file mode 100644 index 00000000..f5c169c4 --- /dev/null +++ b/examples/custom-logback/values.yaml @@ -0,0 +1,9 @@ +configuration: + logback: + existingConfigmap: "graphdb-custom-logback-config" + +# You can use the same Logback configuration for the proxy as well +proxy: + configuration: + logback: + existingConfigmap: "graphdb-custom-logback-config" diff --git a/examples/ingress-nginx/README.md b/examples/ingress-nginx/README.md new file mode 100644 index 00000000..1afccbda --- /dev/null +++ b/examples/ingress-nginx/README.md @@ -0,0 +1,7 @@ +# Nginx Ingress Examples + +This folder contains examples of using GraphDB with the NGINX Ingress controller. + +* [values.yaml](values.yaml) - Example of how to deploy and expose GraphDB with the default Ingress resource using the NGINX Ingress Controller. +* [values_context_path.yaml](values_context_path.yaml) - Example of how to deploy GraphDB behind the context path "/graphdb" and how to properly + configure the Ingress resource. diff --git a/examples/ingress-nginx/values.yaml b/examples/ingress-nginx/values.yaml new file mode 100644 index 00000000..3d4e6069 --- /dev/null +++ b/examples/ingress-nginx/values.yaml @@ -0,0 +1,14 @@ +# +# This example shows how to deploy and expose GraphDB with the default Ingress resource using the NGINX Ingress Controller. +# See https://kubernetes.github.io/ingress-nginx/ +# + +configuration: + externalUrl: http://graphdb.127.0.0.1.nip.io/ + +ingress: + enabled: true + className: nginx + annotations: + # Allows larger payloads to GraphDB, i.e. import from the workbench + nginx.ingress.kubernetes.io/proxy-body-size: 512M diff --git a/examples/ingress-nginx/values_context_path.yaml b/examples/ingress-nginx/values_context_path.yaml new file mode 100644 index 00000000..9506c98d --- /dev/null +++ b/examples/ingress-nginx/values_context_path.yaml @@ -0,0 +1,23 @@ +# +# This example shows how to deploy GraphDB behind the context path "/graphdb" and how to properly configure the Ingress resource to serve GraphDB +# behind that path. +# See https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/ +# + +configuration: + # Note the hostname and the context path + externalUrl: http://127.0.0.1.nip.io/graphdb + +ingress: + enabled: true + className: nginx + annotations: + # Allows larger payloads to GraphDB, i.e. import from the workbench + nginx.ingress.kubernetes.io/proxy-body-size: 512M + # Strips /graphdb from the upstream requests + nginx.ingress.kubernetes.io/rewrite-target: /$2 + nginx.ingress.kubernetes.io/x-forwarded-prefix: /graphdb + # Required to use regex in the path + pathType: ImplementationSpecific + # Matches everything that begins with /graphdb + path: /graphdb(/|$)(.*) diff --git a/examples/openshift-local/README.md b/examples/openshift-local/README.md index 2a21f292..c07dda52 100644 --- a/examples/openshift-local/README.md +++ b/examples/openshift-local/README.md @@ -2,7 +2,7 @@ Example configurations for deploying GraphDB cluster in [OpenShift Local](https://developers.redhat.com/products/openshift-local/overview). -The primary purpose is to show an example of the necessary OpenShift local overrides and the proper `securityContext` configurations so +The primary purpose is to show an example of the necessary OpenShift local overrides and the proper `podSecurityContext` configurations so GraphDB can be deployed without policy violations. Read more about Kubernetes security context and OpenShift security context constraints: @@ -45,7 +45,9 @@ Instances are configured for being accessed at [https://graphdb.apps-crc.testing You'll have to use the `oc` utility provided by `crc` (from step 1): ```bash -oc create route edge --service=graphdb-cluster-proxy --port=7200 --hostname=graphdb.apps-crc.testing --namespace graphdb +oc create route edge --service=graphdb-proxy --port=7200 --hostname=graphdb.apps-crc.testing --namespace graphdb ``` +Note: You might need to update your hosts file to resolve `graphdb.apps-crc.testing` + You can now access GraphDB at [https://graphdb.apps-crc.testing/](https://graphdb.apps-crc.testing/). diff --git a/examples/openshift-local/values.yaml b/examples/openshift-local/values.yaml index 4b713643..d83f7f39 100644 --- a/examples/openshift-local/values.yaml +++ b/examples/openshift-local/values.yaml @@ -1,74 +1,34 @@ -global: - storageClass: "crc-csi-hostpath-provisioner" -deployment: - host: graphdb.apps-crc.testing - protocol: https - ingress: - enabled: false +fullnameOverride: graphdb -graphdb: - clusterConfig: - nodesCount: 3 +# Cluster requires license, you have to provision it before deploying this chart +license: + existingSecret: graphdb-license - workbench: - subpath: / +replicas: 3 - node: - # Cluster requires license, you have to provision it before deploying this chart - license: graphdb-license - securityContext: - runAsNonRoot: true - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - seccompProfile: - type: RuntimeDefault - capabilities: - drop: - - ALL - # Uncomment to disable default resource limits and requests - #resources: - # limits: - # memory: null - # cpu: null - # requests: - # memory: null - # cpu: null - initContainerSecurityContext: - runAsNonRoot: true - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - seccompProfile: - type: RuntimeDefault - capabilities: - drop: - - ALL +configuration: + externalUrl: https://graphdb.apps-crc.testing - clusterProxy: - securityContext: - runAsNonRoot: true - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - seccompProfile: - type: RuntimeDefault - capabilities: - drop: - - ALL - # Uncomment to disable default resource limits and requests - #resources: - # limits: - # memory: null - # cpu: null - # requests: - # memory: null - # cpu: null +ingress: + enabled: false - jobSecurityContext: - runAsNonRoot: true - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - seccompProfile: - type: RuntimeDefault - capabilities: - drop: - - ALL +# OpenShift uses very high uid/gid, override the default with 1000660000 +podSecurityContext: + runAsUser: 1000660000 + runAsGroup: 1000660000 + fsGroup: 1000660000 + +jobs: + podSecurityContext: + runAsUser: 1000660000 + runAsGroup: 1000660000 + fsGroup: 1000660000 + +proxy: + fullnameOverride: graphdb-proxy + + podSecurityContext: + runAsUser: 1000660000 + runAsGroup: 1000660000 + fsGroup: 1000660000 diff --git a/files/config/cluster-config.json b/files/config/cluster-config.json index 488f4b6b..740bebd9 100644 --- a/files/config/cluster-config.json +++ b/files/config/cluster-config.json @@ -1,14 +1,9 @@ { - "electionMinTimeout": {{ .Values.graphdb.clusterConfig.electionMinTimeout | int }}, - "electionRangeTimeout": {{ .Values.graphdb.clusterConfig.electionRangeTimeout | int }}, - "heartbeatInterval": {{ .Values.graphdb.clusterConfig.heartbeatInterval | int }}, - "verificationTimeout": {{ .Values.graphdb.clusterConfig.verificationTimeout | int }}, - "messageSizeKB": {{ .Values.graphdb.clusterConfig.messageSize | int }}, - "transactionLogMaximumSizeGB": {{ .Values.graphdb.clusterConfig.transactionLogMaximumSizeGB | quote }}, - "nodes": [ - {{- range $i, $node_index := until (int .Values.graphdb.clusterConfig.nodesCount) }} - "graphdb-node-{{ $node_index }}.graphdb-node.{{ $.Release.Namespace }}.svc.cluster.local:7300"{{- if gt (sub (int $.Values.graphdb.clusterConfig.nodesCount) 1 ) $node_index }}, - {{- end }} - {{- end }} - ] + "electionMinTimeout": {{ .Values.cluster.config.params.electionMinTimeout | int }}, + "electionRangeTimeout": {{ .Values.cluster.config.params.electionRangeTimeout | int }}, + "heartbeatInterval": {{ .Values.cluster.config.params.heartbeatInterval | int }}, + "verificationTimeout": {{ .Values.cluster.config.params.verificationTimeout | int }}, + "messageSizeKB": {{ .Values.cluster.config.params.messageSizeKB | int }}, + "transactionLogMaximumSizeGB": {{ .Values.cluster.config.params.transactionLogMaximumSizeGB | quote }}, + "nodes": {{- include "graphdb.cluster.nodes.json" . | indent 2 }} } diff --git a/files/config/graphdb.properties b/files/config/graphdb.properties deleted file mode 100644 index eeb8df0b..00000000 --- a/files/config/graphdb.properties +++ /dev/null @@ -1,524 +0,0 @@ -####### PATHS AND DIRECTORIES ###### -# -# GraphDB home directory. Defines the root directory for GraphDB on the file system. -# It acts as a parent for all configurable paths like repository data, configuration, logs and other runtime -# data unless the location for a specific functionality is explicitly set by its corresponding property. -# The default is the same as the GraphDB distribution directory. -# The actual values for graphdb.home and the other graphdb.home.xxx properties will be printed in the log -# when GraphDB starts. -# -# graphdb.home = -# -# -# GraphDB data directory. Defines the directory where the engine stores all repository data. -# This directory must be writable by the GraphDB process. -# The default is ${graphdb.home}/data. -# -# graphdb.home.data = -# -# -# GraphDB logs directory. Defines the directory where the log files are written. -# This directory must be writable by the GraphDB process. -# The default is ${graphdb.home}/logs. -# -# graphdb.home.logs = -# -# -# GraphDB configuration directory. Used for user-editable configuration, including this file. Stores -# provided runtime license through the application, persisted as ${graphdb.home.conf}/graphdb.license. -# This directory and all files within it may be read-only for GraphDB only if no license is set in the way described above. -# The default is ${graphdb.home}/conf. -# -# Since the location of this config file depends on this property, it does not make sense to set it here. -# Instead you can provide is a system property with -D. -# -# graphdb.home.conf = -# -# -# GraphDB work directory. Used for non-user-editable database configurations. -# This directory must be writable by the GraphDB process. -# The default is ${graphdb.home}/work. -# -# graphdb.home.work = -# -# -# GraphDB external plugins directory. This can be used to add -# additional external plugins outside the distribution's lib/plugins directory. -# -# graphdb.extra.plugins = -# -# -# Graphdb global page cache memory parameter. By default the page cache will -# allocate 50% of the maximum Java heap memory (-Xmx) for the JVM process. -# Setting this value too high will cause OME during the execution of memory intensive queries. -# -# graphdb.page.cache.size=10G - - -###### LICENSE ###### -# -# The license can be set through the GraphDB Workbench, through a file graphdb.license -# in the GraphDB configuration directory (see graphdb.home.conf above), or through this -# property that should point to a license file: -# -# graphdb.license.file = - - -###### GraphDB Ontop JDBC Driver Path ###### -# -# GraphDB directory for the JDBC driver used in the creation of Ontop repositories. -# Use it when you want to set it to a directory different from the lib/jdbc one where the driver is normally placed. -# -# graphdb.ontop.jdbc.path = <path-to-jdbc-driver> - - -###### Ontop Properties ###### -# -# Ontop configuration attribute can be passed through a property: -# -# graphdb.ontop.<attribute>=xxx - - -###### NETWORK SETTINGS ###### -# -# HTTP port for running GraphDB in standalone mode. The default is 7200. -# -# graphdb.connector.port = 7200 -# -# Controls whether it is necessary to rewrite the Location header when no proxy is configured. -# Setting this property to true will use the graphdb.external-url when building the transaction URLs. -# Set it to true when the returned URLs are incorrect due to missing or invalid proxy configurations. -# Set it to false when the server can be called on multiple addresses, -# as it will override the returned address to the one defined by the graphdb.external-url. -# Boolean, default is false. -# -# graphdb.external-url.enforce.transactions = false -# -# Enable SSL (uncomment to enable) -# graphdb.connector.SSLEnabled = true -# graphdb.connector.scheme = https -# graphdb.connector.secure = true -# -# GraphDB uses the Java implementation of SSL, which requires a configured key in the Java keystore. -# To setup keystore uncomment the following properties and set keystorePass and keyPass to the actual values. -# -# The default is the file .keystore in the operating system home directory of the user that is running GraphDB -# graphdb.connector.keystoreFile = <path to the keystore file> -# graphdb.connector.keystorePass = <secret> -# graphdb.connector.keyAlias = graphdb -# graphdb.connector.keyPass = <secret> -# -# How to generate a keystore? -# -# Option 1: Generate a self-signed key, which would require to trust the certificate in all clients. -# -# keytool -genkey -alias graphdb -keyalg RSA -# -# Option 2: Convert a third party trusted OpenSSL certificate to PKCS12 key and then import to the Java keystore. -# -# keytool -importkeystore -deststorepass MYPASS -srckeystore mypkcs12.p12 -srcstoretype PKCS12 -# -# For any additional information please refer to https://tomcat.apache.org/tomcat-9.0-doc/ssl-howto.html -# -# In addition to the above settings, you can set any Tomcat Connector attribute through a property: -# graphdb.connector.<attribute> = xxx -# -# See https://tomcat.apache.org/tomcat-9.0-doc/config/http.html#Attributes for more information. -# -# Another option is to use Self Signed SSL Certificate setting following two properties -# -# graphdb.connector.SSLCertificateFile = <path-to-file> -# graphdb.connector.SSLCertificateKeyFile = <path-to-file> - - -###### ENGINE OVERRIDE ###### -# -# The GraphDB Engine can be configured through a set of properties that start with the graphdb.engine. prefix. -# These properties correspond to the properties that can be set when creating a repository through the Workbench -# or through a .ttl file. -# -# Note that properties defined here WILL OVERRIDE the properties for each repository, regardless of whether you created -# the repository before or after you set the global value of an engine property. As such, the global overrides -# should be used only in specific cases while for normal everyday needs you should set the corresponding properties -# when you create a repository. -# -# -# graphdb.engine.<property> = xxx - - -# A global setting that ensures IRI validation in the entity pool. It is performed only when an IRI is seen for the first time -# (i.e., when being created in the entity pool). For consistency reasons, not only IRIs coming from RDF serializations, -# but also all new IRIs (via API or SPARQL), will be validated in the same way. -# This property can be turned off by setting its value to false. -# -# graphdb.engine.entity.validate = true - - -###### AUTHENTICATION TOKEN SECRET ###### -# -# GraphDB authentication token secret could be set by passing it as a configuration parameter -# -# graphdb.auth.token.secret = <my-shared-secret-key> -# -# In case of not explicitly specified, GraphDB will try to obtain one automatically from the SSL -# certificate if present or will randomly generate one - -###### OPENID AUTHENTICATION ###### -# -# OpenId is used for authentication against another authorization database (local or LDAP). -# Password authentication can be disabled in addition. -# -# Enable OpenId authentication. The default value is 'basic, gdb'. -# Provide only 'openid' if password-based login methods (basic and gdb) are not needed. -# graphdb.auth.methods = basic, gdb, openid -# -# OpenID issuer URL, used to derive keys, endpoints and token validation. No default value. -# graphdb.auth.openid.issuer = https://accounts.example.com -# -# OpenID well-known config URL, used to fetch the OpenID configuration of the OpenID provider. -# The default value will be derived by appending /.well-known/openid-configuration to the issuer URL. -# Use this setting if your OpenID does not conform to the specification and the well-known config is -# served on a different URL than the default standard-mandated value. -# graphdb.auth.openid.well_known_config_url = https://openid.example.com/custom/.well-known/openid-configuration -# -# OpenID header types, specifies the allowed values for the field "typ" in the JWT header. -# The value is a comma-delimited list, where 'null' is interpreted as 'no value'. -# The default value is 'jwt, at+jwt, null' and will allow tokens with "typ": "jwt", "typ": "at+jwt", -# as well as tokens with a missing "typ" value. -# graphdb.auth.openid.header_types = jwt, at+jwt, null -# -# OpenID client ID, used to authenticate and validate tokens. No default value. -# graphdb.auth.openid.client_id = my-client-id -# -# OpenID claim to use as the GraphDB username. No default value. -# graphdb.auth.openid.username_claim = email -# -# OpenID authentication flow: code, code_no_pkce or implicit. No default value. -# The recommended value is 'code' if the OpenId provider supports it with PKCE without a client secret. -# graphdb.auth.openid.auth_flow = code -# -# OpenID token type to send to GraphDB. The available values are 'access' and 'id'. No default value. -# Use the access token if it is a JWT token, otherwise use the id token. -# graphdb.auth.openid.token_type = access -# -# OpenID expected issuer URL in tokens, used to validate tokens. The default is the same as the actual issuer URL. -# graphdb.auth.openid.token_issuer = https://accounts.example.com/custom -# -# OpenID expected audience in tokens, used to validate tokens. The default value is the same as the client ID. -# graphdb.auth.openid.token_audience = my-audience -# -# OpenID extra scopes to request. Multiple scopes can be specified by separating them with a space. -# By default GraphDB requests only the 'openid' scope and, if supported, the 'offline_access' scope. -# Scopes are used to request sets of claims, e.g. you might need to set this to a provider-specific value -# in order to obtain the username_name or the roles_claim (if using OAuth as well). The default value is empty. -# graphdb.auth.openid.extra_scopes = profile email -# -# OpenID extra parameters for the authorize endpoint. Some OpenID providers require additional parameters sent -# to the authorize endpoint (e.g. resource=xxx). This is a URL encoded string where each parameter-value pair -# is delimited by &. The string will be appended to the rest of the authorize URL parameters. -# The default value is the empty string. -# graphdb.auth.openid.authorize_parameters = param1=value%201¶m2=value%202 -# -# OpenID Oracle identity domain. Oracle Access Manager has a non-standard OpenID implementation that requires -# an additional parameter: the Oracle identity domain name. If you use OAM set this to your identity domain name. -# graphdb.auth.openid.oracle_domain = my-oracle-domain -# -# OpenID use GraphDB as proxy for the JWKS URL and token endpoints. This can be used to bypass an OpenID provider -# without a proper CORS configuration. The value is a boolean true/false. False by default. -# graphdb.auth.openid.proxy = false - -###### OPENID AUTHENTICATION + OAUTH AUTHORIZATION ###### -# -# OpenId is used for authentication and the authorization is provided via OAuth. -# Password authentication is not available in this mode. -# -# Enable OpenId authentication and disable password-based login. The default value is 'basic, gdb'. -# graphdb.auth.methods = openid -# -# Enable OAuth authorization. The default value is 'local' corresponding to local users. -# graphdb.auth.database = oauth -# -# Set case-insensitive validation for user accounts so that users can log in regardless of the case used at login time. -# The default value is false. -# graphdb.auth.database.case_insensitive = false -# -# OpenID issuer URL, used to derive keys, endpoints and token validation. No default value. -# graphdb.auth.openid.issuer = https://accounts.example.com -# -# OpenID client ID, used to authenticate and validate tokens. No default value. -# graphdb.auth.openid.client_id = my-client-id -# -# OpenID claim to use as the GraphDB username. No default value. -# This will be interpreted as a JSONPath expression, so for example the value "roles.graphdb" -# will first access the object under the "roles" key and then extract the roles from the "graphdb" -# key inside that object. -# graphdb.auth.openid.username_claim = email -# -# OpenID authentication flow: code, code_no_pkce or implicit. No default value. -# The recommended value is 'code' if the OpenId provider supports it with PKCE without a client secret. -# graphdb.auth.openid.auth_flow = code -# -# OpenId token type to send to GraphDB. The available values are 'access' and 'id'. No default value. -# Use the access token if it is a JWT token, otherwise use the id token. -# graphdb.auth.openid.token_type = access -# -# OpenID expected issuer URL in tokens, used to validate tokens. The default is the same as the actual issuer URL. -# graphdb.auth.openid.token_issuer = https://accounts.example.com/custom -# -# OpenID expected audience in tokens, used to validate tokens. The default value is the same as the client ID. -# graphdb.auth.openid.token_audience = my-audience -# -# OpenID extra parameters for the authorize endpoint. Some OpenID providers require additional parameters sent -# to the authorize endpoint (e.g. resource=xxx). This is a URL encoded string where each parameter-value pair -# is delimited by &. The string will be appended to the rest of the authorize URL parameters. -# The default value is the empty string. -# graphdb.auth.openid.authorize_parameters = param1=value%201¶m2=value%202 -# -# OpenID use GraphDB as proxy for the JWKS URL and token endpoints. This can be used to bypass an OpenID provider -# without a proper CORS configuration. The value is a boolean true/false. False by default. -# graphdb.auth.openid.proxy = false -# -# OAuth roles claim. The field from the JWT token that will provide the GraphDB roles. No default value. -# graphdb.auth.oauth.roles_claim = roles -# -# OAuth roles prefix to strip. The roles claim may provide the GraphDB roles with some prefix, e.g. GDB_ROLE_USER. -# The prefix will be stripped when the roles are mapped. The default value is the empty string. -# graphdb.auth.oauth.roles_prefix = GDB_ -# -# OAuth roles suffix to strip. The roles claim may provide the GraphDB roles with some suffix, e.g. ROLE_USER_GDB. -# The suffix will be stripped when the roles are mapped. The default value is the empty string. -# graphdb.auth.oauth.roles_suffix = ROLE_USER_GDB -# -# OAuth default roles to assign. It may be convenient to always assign certain roles without listing them in the roles -# claim. The value is a comma-delimited list of GraphDB roles. The default value is the empty list. -# -# graphdb.auth.oauth.default_roles = ROLE_USER - -###### LDAP AUTHENTICATION AND AUTHORIZATION ###### -# -# Turn on ldap authentication and configure the server. -# -# Note that since GraphDB 9.5 local users will no longer be accessible when using LDAP -# -# graphdb.auth.database = ldap -# graphdb.auth.ldap.url = ldap://localhost:10389/dc=example,dc=org - -# Permit access for all users that are part of the \u201Cpeople\u201D unit of the fictional \u201Cexample.org\u201D organisation. -# -# graphdb.auth.ldap.user.search.base = ou=people -# graphdb.auth.ldap.user.search.filter = (cn={0}) - -# Make all users in the Administration group GraphDB administrators as well. -# -# graphdb.auth.ldap.role.search.base = ou=groups -# graphdb.auth.ldap.role.search.filter = (member={0}) -# graphdb.auth.ldap.role.map.administrator = Administration - -# Make all users in the Management group GraphDB Repository Managers as well. -# -# graphdb.auth.ldap.role.map.repositoryManager = Management - -# Enable all users in the Readers group to read the my_repo repository. -# -# graphdb.auth.ldap.role.map.repository.read.my_repo = Readers - -# Enable all users in the Writers group to write and read the my_repo repository. -# -# graphdb.auth.ldap.role.map.repository.write.my_repo = Writers - -# All entries located under the "groups" organizational unit that have members (i.e., groups), -# will be able to read repositories that share their common name. -# -# graphdb.auth.ldap.repository.read.base = ou=groups -# graphdb.auth.ldap.repository.read.filter = (member={0}) -# graphdb.auth.ldap.repository.read.attribute = cn - -# All entries located under the "groups" organizational unit that have members (i.e., groups), -# will be able to read and write to repositories that share their common name. -# -# graphdb.auth.ldap.repository.write.base = ou=groups -# graphdb.auth.ldap.repository.write.filter = (member={0}) -# graphdb.auth.ldap.repository.write.attribute = cn - -# Required for accessing a LDAP server, that does not allow anonymous binds and anonymous access -# -# graphdb.auth.ldap.bind.userDn = uid=userId,ou=people,dc=example,dc=org -# graphdb.auth.ldap.bind.userDn.password = 123456 - -# Adds to all users in Readers group custom role. -# -# graphdb.auth.ldap.map.role.role_name = Readers - -###### KERBEROS AUTHENTICATION ###### -# -# Enables Kerberos authentication. The default value is 'basic, gdb'. -# -# graphdb.auth.methods = basic, gdb, kerberos -# -# Full or relative (to the GraphDB config directory) path to where the keys -# of the Kerberos service principal are stored. No default value. Required if Kerberos is enabled -# You can find more on how to create a keytab file https://web.mit.edu/kerberos/krb5-devel/doc/basic/keytab_def.html -# -# graphdb.auth.kerberos.keytab = <path-to-keytab-file> -# -# Name of the Kerberos service principal. No default value. Required if Kerberos is enabled. -# -# graphdb.auth.kerberos.principal = HTTP/data.example.com@EXAMPLE.COM -# -# Determines whether to print additional Kerberos-related messages -# in some of the Spring Kerberos classes. Default value is false. -# -# graphdb.auth.kerberos.debug = true/false - -###### X.509 CERTIFICATE AUTHENTICATION + LOCAL or LDAP AUTHORIZATION ###### -# -# X.509 certificate authentication is used for authentication against another authorization database (local or LDAP). -# -# Enable X.509 certificate authentication. The default value is 'basic, gdb'. -# Provide only 'x509' if password-based login methods (basic and gdb) are not needed. -# graphdb.auth.methods = basic, gdb, x509 -# -# Enable local or LDAP authorization. The default value is 'local' corresponding to local users. -# If LDAP is the chosen authorization database, follow the instructions for its enabling. -# graphdb.auth.database = ldap -# -# Provides the regular expression to extract the username from the certificate. -# The default is "CN=(.*?)(?:,|$)". Uncomment to provide a custom expression. -# graphdb.auth.methods.x509.subject.dn.pattern = CN=(.*?)(?:,|$) -# -# To implement server-side X.509 authentication, enable SSL. -# -# To set up a truststore different from the default JRE one, uncomment the following -# properties and set 'truststoreFile' and 'truststorePass' to their actual values. -# -# graphdb.connector.truststoreFile = <path-to-custom-truststore-file> -# graphdb.connector.truststorePass = <secret> -# -##### X.509 CERTIFICATE AUTHENTICATION REVOCATION STATUS CHECK CONFIGURATION ###### -# -# Controls whether OCSP checks are performed, true by default. -# graphdb.auth.methods.x509.ocsp = true -# -# Controls whether CRLDP checks are performed, true by default. -# graphdb.auth.methods.x509.crldp = true -# -# Uncomment the following to set a Certificate Revocation List to Tomcat, -# which will allow revocation checks for certificates that do not provide -# an Authority Information Access (AIA) extension, or as an alternative -# in case of OCSP or CrlDP responders downtime. -# graphdb.auth.methods.x509.crlFile = <path-to-certificate-revocation-list> - -###### Cloud backup and Restore ###### -# -# Enable tls for connections against s3 compatible services. To set up a truststore different from the default JRE one -# set `graphdb.connector.truststoreFile` and `graphdb.connector.truststorePass` -# graphdb.s3.tls.enabled = false -# -# Timeout in seconds for a cloud backup's single part upload. -# graphdb.s3.backup.httpclient.write.timeout = 3600 - -###### AUDIT TRAIL ###### -# -# Enable the detail audit trail for all operations with the minimal access role of: -# USER, REPO_MANAGER, ADMIN, ANY -# -# graphdb.audit.role = USER -# -# and read, write operations with the minimal access of: -# READ, WRITE -# -# graphdb.audit.repository = READ -# -# Audit the specific headers -# -# graphdb.audit.headers = Origin, Host -# -# List headers that should be included into logs in front of client requests. -# -# graphdb.request.id.alternatives = X-Amz-Request-Id -# -# Enable logging of "X-Request-Id" header and listed in graphdb.request.id.alternatives headers into any log. -# "X-Request-Id" header will be included by default. In case "X-Request-Id" is not present in the headers of -# the request it will be generated randomly in UUID type 5 format. -# -# graphdb.append.request.id.headers = true - -###### CLUSTER CONFIGURATIONS ###### - -# Embedded cluster proxy configurations - -# Uncomment to disable the embedded cluster proxy that redirects requests to the leader in cluster deployment. -# Will be disabled automatically if external proxy is used. -#graphdb.cluster.proxy.enabled=false - -# The following configurations represents the defaults of the HTTP client used to redirect requests. -# Uncomment and change any of the default values -# -1 means infinite timeout -# The connection timeout is in seconds -#graphdb.cluster.proxy.socketTimeout=-1 -#graphdb.cluster.proxy.connectionTimeoutS=15 -# This limits the maximum number of concurrent requests send to the leader -#graphdb.cluster.proxy.maxConnectionsPerRoute=30000 -#graphdb.cluster.proxy.maxConnectionsTotal=50000 - -# Dedicated cluster proxy configurations - -# List the addresses of GraphDB HTTP or RPC address to the nodes that are part of a cluster -# Note that all of the addresses need to be from the same cluster -# graphdb.proxy.hosts = -# The number of times a request to be retried to a different node in the cluster, when a node is not reachable, before failing the request. -# If a request could be handled by other node, other than the initial one, then other node from the cluster will be -# asked to handle the request. -# graphdb.proxy.followerRetries=3 - - -###### CHATGPT INTEGRATION ###### -# -# GraphDB has built-in ChatGPT integration. The minimum required configuration is setting the GPT access token. -# -# GPT API access token, none by default. -# graphdb.gpt.token = -# -# GPT model to use, gpt-3.5-turbo by default. -# graphdb.gpt.model = gpt-3.5-turbo -# -# GPT timeout in seconds, 90 by default. -# graphdb.gpt.timeout = 90 -# -# -# GPT advanced options below - setting these may be needed if the integration should use a different API endpoint -# and/or a different authentication method. See the documentation for more details. -# -# GPT chat completions API endpoint, https://api.openai.com/v1/chat/completions by default. -# graphdb.gpt.url = https://api.openai.com/v1/chat/completions -# -# GPT authentication method, bearer by default. -# graphdb.gpt.auth = bearer - - -# Server report in cluster configuration - -# The maximum time to wait for a triggered report is configured with a default value of 120 minutes. -#graphdb.wait.report.minutes=120 - -###### HEAP DUMPS ###### -# -# GraphDB can dump the heap on out of memory errors in order to provide insight to the cause -# for excessive memory usage. -# -# Enable or disable the heap dump (enabled by default) -# graphdb.heapdump.enable = true -# -# File to write the heap dump to, by default this is the file heapdump.hprof in the configured logs directory. -# See also the properties graphdb.home and graphdb.home.logs. -# graphdb.heapdump.path = - -###### JSON-LD WHITELIST ###### -# -# The configuration property 'graphdb.jsonld.whitelist' is used to define a whitelist -# of URLs or file locations that are permitted for JSON-LD processing in GraphDB. -# -# The whitelist is a comma-separated list of URLs or file locations. -# The wildcard (*) in URLs or file paths allows for fine-grained control, enabling administrators to specify entire domains or directories. -# Each entry in the list represents a resource that is considered safe for JSON-LD operations. -# graphdb.jsonld.whitelist = https://my.good_host.com/prop, https://my.good_host.com/*, file:///my/good/jsonld/prop, file:///my/good/jsonld/* diff --git a/files/config/logback.xml b/files/config/logback.xml deleted file mode 100644 index 3d62809f..00000000 --- a/files/config/logback.xml +++ /dev/null @@ -1,170 +0,0 @@ -<configuration debug="false" scan="true" scanPeriod="30 seconds"> - <jmxConfigurator /> - - <!-- Try to guess the logs destination based on the application server or fallback to a default logs directory(embedded mode) - NOTE: We are using a really old version of logback so we have to use p().isEmpty instead of isDefined --> - - <if condition='p("logDestinationDirectory").isEmpty()'> - <then> - <!-- catalina.base if we are running on tomcat --> - <if condition='!p("catalina.base").isEmpty()'> - <then> - <property name="logDestinationDirectory" value="${catalina.base}/logs/graphdb"/> - </then> - <else> - <!-- jetty.base if we are running on tomcat --> - <if condition='!p("jetty.base").isEmpty()'> - <then> - <property name="logDestinationDirectory" value="${jetty.base}/logs/graphdb"/> - </then> - <else> - <!-- we are running in embedded mode --> - <property name="logDestinationDirectory" value="logs"/> - </else> - </if> - </else> - </if> - </then> - </if> - - <property name="defaultPattern" value="[%-5p] %d{ISO8601} [%t | %c{5}]%X{headers} %m%n%ex" /> - <property name="encoding" value="UTF-8" /> - - <!-- Properties for log keeping based on age and size. By default logs will be kept for 30 days with no size limit--> - <!-- Sets the maximum age of kept logs in days. Set to 0 for no limit --> - <property name="keepLogDays" value="30" /> - <!-- Sets the maximum size of every log kept. Accepts values like 500KB, 200MB, 1GB etc. Set to 0 for no limit - NOTE: This sets the size limit per each different log type. If you want more control change the totalSizeCap of each log separately--> - <property name="logMaxSize" value="0" /> - - <!-- Audit log. Contains security related things --> - <appender name="AuditLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> - <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> - <fileNamePattern>${logDestinationDirectory}/audit-log-%d{yyyy-MM-dd}.log</fileNamePattern> - <maxHistory>${keepLogDays}</maxHistory> - <totalSizeCap>${logMaxSize}</totalSizeCap> - <cleanHistoryOnStart>true</cleanHistoryOnStart> - </rollingPolicy> - <encoder> - <pattern>${defaultPattern}</pattern> - <charset>${encoding}</charset> - </encoder> - </appender> - - <appender name="MainLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> - <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> - <fileNamePattern>${logDestinationDirectory}/main-%d{yyyy-MM-dd}.log</fileNamePattern> - <maxHistory>${keepLogDays}</maxHistory> - <totalSizeCap>${logMaxSize}</totalSizeCap> - <cleanHistoryOnStart>true</cleanHistoryOnStart> - </rollingPolicy> - <encoder> - <pattern>${defaultPattern}</pattern> - <charset>${encoding}</charset> - </encoder> - </appender> - - <appender name="ErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> - <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> - <fileNamePattern>${logDestinationDirectory}/error-%d{yyyy-MM-dd}.log</fileNamePattern> - <maxHistory>${keepLogDays}</maxHistory> - <totalSizeCap>${logMaxSize}</totalSizeCap> - <cleanHistoryOnStart>true</cleanHistoryOnStart> - </rollingPolicy> - <encoder> - <pattern>${defaultPattern}</pattern> - <charset>${encoding}</charset> - </encoder> - <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> - <level>ERROR</level> - </filter> - </appender> - - <appender name="QueryLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> - <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> - <fileNamePattern>${logDestinationDirectory}/query-log-%d{yyyy-MM-dd}.log</fileNamePattern> - <maxHistory>${keepLogDays}</maxHistory> - <totalSizeCap>${logMaxSize}</totalSizeCap> - <cleanHistoryOnStart>true</cleanHistoryOnStart> - </rollingPolicy> - <encoder> - <pattern>${defaultPattern}</pattern> - <charset>${encoding}</charset> - </encoder> - </appender> - - <appender name="SlowQueryLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> - <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> - <fileNamePattern>${logDestinationDirectory}/slow-query-log-%d{yyyy-MM-dd}.log</fileNamePattern> - <maxHistory>${keepLogDays}</maxHistory> - <totalSizeCap>${logMaxSize}</totalSizeCap> - <cleanHistoryOnStart>true</cleanHistoryOnStart> - </rollingPolicy> - <encoder> - <pattern>${defaultPattern}</pattern> - <charset>${encoding}</charset> - </encoder> - </appender> - - <if condition='!p("graphdb.foreground").isEmpty()'> - <then> - <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> - <encoder> - <pattern>${defaultPattern}</pattern> - </encoder> - </appender> - </then> - </if> - - <!-- Log all repository, user creations, modifications and deletions. Also logs successful or not attempts to - login into system. Updates, queries and imports to repository. Set to "INFO" level for logging all former updates. - Will log exceptions on "ERROR" level. Additivity is set to "false" and called first to prevent the messages - from cluttering the other logs. --> - <logger name="com.ontotext.forest.security.audit.AuditLoggingFilter" level="INFO" additivity="false"> - <appender-ref ref="AuditLog"/> - </logger> - - <!-- Log update operations on workers. Set to "INFO" level by default for logging all updates in workers' QueryLog. - Will log exceptions on "ERROR" level. Additivity is set to "false" and called first to prevent the messages - from cluttering the other logs.--> - <logger name="com.ontotext.trree.monitorRepository.MonitorRepositoryConnection" level="INFO" additivity="false"> - <appender-ref ref="QueryLog"/> - </logger> - - <!-- Log query operations on the repository. Set to "DEBUG" level for logging all querries. Will log exceptions on "ERROR" - level. Additivity is set to "false" to prevent the messages from cluttering the other logs. --> - <logger name="com.ontotext.trree.query.LoggingClosableIteration" level="INFO" additivity="false"> - <appender-ref ref="QueryLog"/> - </logger> - - <!-- Log slow queries on "INFO" level. Queries are deemed "slow" if they take more than "SlowOpThresholdMs" from the - RepositorySettings property. Set the level to "OFF" to stop this log. Additivity is set to "false" to prevent the messages - from cluttering the other logs. --> - <logger name="slow-queries" level="INFO" additivity="false"> - <appender-ref ref="SlowQueryLog"/> - </logger> - - <root> - <level value="${graphdb.logger.root.level:-INFO}"/> - <appender-ref ref="MainLog"/> - <appender-ref ref="ErrorLog" /> - <if condition='!p("graphdb.foreground").isEmpty()'> - <then> - <appender-ref ref="STDOUT"/> - </then> - </if> - </root> - - <!-- Make some of the more verbose loggers less chatty --> - <logger name="org.springframework" level="WARN"/> - <logger name="org.apache" level="WARN"/> - <logger name="com.github.ziplet" level="WARN"/> - <logger name="springfox.documentation" level="WARN"/> - - <!-- GeoSPAQRL related deps be less verbose --> - <logger name="hsqldb.*" level="WARN"/> - <logger name="org.geotoolkit.*" level="WARN"/> - - <!-- SemanticVectors related logger be less verbose --> - <logger name="pitt.search.semanticvectors.DocVectors" level="WARN"/> -</configuration> diff --git a/files/config/proxy/graphdb.properties b/files/config/proxy/graphdb.properties deleted file mode 100644 index 06398b49..00000000 --- a/files/config/proxy/graphdb.properties +++ /dev/null @@ -1,76 +0,0 @@ -###### NETWORK SETTINGS ###### -# -# HTTP port for running GraphDB in standalone mode. The default is 7200. -# -# graphdb.connector.port = 7200 -# -# Controls whether it is necessary to rewrite the Location header when no proxy is configured. -# Setting this property to true will use the graphdb.external-url when building the transaction URLs. -# Set it to true when the returned URLs are incorrect due to missing or invalid proxy configurations. -# Set it to false when the server can be called on multiple addresses, -# as it will override the returned address to the one defined by the graphdb.external-url. -# Boolean, default is false. -# -# graphdb.external-url.enforce.transactions = false -# -# Enable SSL (uncomment to enable) -# graphdb.connector.SSLEnabled = true -# graphdb.connector.scheme = https -# graphdb.connector.secure = true -# -# GraphDB uses the Java implementation of SSL, which requires a configured key in the Java keystore. -# To setup keystore uncomment the following properties and set keystorePass and keyPass to the actual values. -# -# The default is the file .keystore in the operating system home directory of the user that is running GraphDB -# graphdb.connector.keystoreFile = <path to the keystore file> -# graphdb.connector.keystorePass = <secret> -# graphdb.connector.keyAlias = graphdb -# graphdb.connector.keyPass = <secret> -# -# How to generate a keystore? -# -# Option 1: Generate a self-signed key, which would require to trust the certificate in all clients. -# -# keytool -genkey -alias graphdb -keyalg RSA -# -# Option 2: Convert a third party trusted OpenSSL certificate to PKCS12 key and then import to the Java keystore. -# -# keytool -importkeystore -deststorepass MYPASS -srckeystore mypkcs12.p12 -srcstoretype PKCS12 -# -# For any additional information please refer to https://tomcat.apache.org/tomcat-9.0-doc/ssl-howto.html -# -# In addition to the above settings, you can set any Tomcat Connector attribute through a property: -# graphdb.connector.<attribute> = xxx -# -# See https://tomcat.apache.org/tomcat-9.0-doc/config/http.html#Attributes for more information. -# -# Another option is to use Self Signed SSL Certificate setting following two properties -# -# graphdb.connector.SSLCertificateFile = <path-to-file> -# graphdb.connector.SSLCertificateKeyFile = <path-to-file> - -###### AUTHENTICATION TOKEN SECRET ###### -# -# GraphDB authentication token secret could be set by passing it as a configuration parameter -# -# graphdb.auth.token.secret = <my-shared-secret-key> -# -# In case of not explicitly specified, GraphDB will try to obtain one automatically from the SSL -# certificate if present or will randomly generate one - -###### CLUSTER CONFIGURATIONS ###### - -# Dedicated cluster proxy configurations - -# List the addresses of GraphDB HTTP or RPC address to the nodes that are part of a cluster -# Note that all of the addresses need to be from the same cluster - - -graphdb.proxy.hosts={{- range $i, $node_index := until ( (int $.Values.graphdb.clusterConfig.nodesCount) )}}http://graphdb-node-{{ $node_index }}.graphdb-node.{{ $.Release.Namespace }}.svc.cluster.local:7200{{- if gt (sub (int $.Values.graphdb.clusterConfig.nodesCount) 1 ) $node_index }},{{- end }} -{{- end }} - - -# The number of times a request to be retried to a different node in the cluster, when a node is not reachable, before failing the request. -# If a request could be handled by other node, other than the initial one, then other node from the cluster will be -# asked to handle the request. -# graphdb.proxy.followerRetries=3 diff --git a/files/config/settings.js b/files/config/settings.js index 1fd2365f..68cd9e6c 100644 --- a/files/config/settings.js +++ b/files/config/settings.js @@ -2,7 +2,7 @@ "import.server" : { }, "import.local" : { }, "properties" : { - {{- if .Values.graphdb.security.enabled }} + {{- if .Values.security.enabled }} "security.enabled" : true, {{- end }} "current.location" : "" diff --git a/files/config/users.js b/files/config/users.js index 209f864a..d9e30566 100644 --- a/files/config/users.js +++ b/files/config/users.js @@ -2,7 +2,7 @@ "users" : { "admin" : { "username" : "admin", - "password" : "{bcrypt}$2a$10$H7uekkF1ZFLIV5M1g9tDs.syZGtkMqrfj2Si2SHG1WgwhpNqpZwne", + "password" : {{ .Values.security.admin.initialPassword | default "{bcrypt}$2a$10$H7uekkF1ZFLIV5M1g9tDs.syZGtkMqrfj2Si2SHG1WgwhpNqpZwne" | quote }}, "grantedAuthorities" : [ "ROLE_ADMIN" ], "appSettings" : { "DEFAULT_INFERENCE" : true, @@ -13,9 +13,10 @@ }, "dateCreated" : 1618403171751 }, - "{{ .Values.graphdb.security.provisioningUsername }}" : { - "username" : "{{ .Values.graphdb.security.provisioningUsername }}", - "password" : "{bcrypt}{{ htpasswd .Values.graphdb.security.provisioningUsername .Values.graphdb.security.provisioningPassword | trimPrefix (printf "%s:" .Values.graphdb.security.provisioningUsername) }}", + {{- include "grahdb.security.extra-users.json" . | nindent 4 }} + "{{ .Values.security.provisioner.username }}" : { + "username" : "{{ .Values.security.provisioner.username }}", + "password" : "{bcrypt}{{ htpasswd .Values.security.provisioner.username .Values.security.provisioner.password | trimPrefix (printf "%s:" .Values.security.provisioner.username) }}", "grantedAuthorities" : [ "ROLE_ADMIN" ], "appSettings" : { "DEFAULT_INFERENCE" : true, diff --git a/files/scripts/graphdb.sh b/files/scripts/graphdb.sh index 7cce89d4..ed4afded 100755 --- a/files/scripts/graphdb.sh +++ b/files/scripts/graphdb.sh @@ -1,13 +1,22 @@ #!/usr/bin/env bash -set -eu + +set -o errexit +set -o nounset +set -o pipefail function createCluster { waitAllNodes $1 local configLocation=$2 - local authToken=$PROVISION_USER_AUTH_TOKEN local timeout=$3 + echo "Creating cluster" - curl -o response.json -isSL -m $timeout -X POST --header "Authorization: Basic ${authToken}" --header 'Content-Type: application/json' --header 'Accept: */*' -d @"$configLocation" http://graphdb-node-0.graphdb-node:7200/rest/cluster/config + curl -o response.json -isSL -m "${timeout}" -X POST \ + -d @"$configLocation" \ + --header "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" \ + --header 'Content-Type: application/json' \ + --header 'Accept: */*' \ + "http://${GRAPHDB_POD_NAME}-0.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/cluster/config" + if grep -q 'HTTP/1.1 201' "response.json"; then echo "Cluster creation successful!" elif grep -q 'Cluster already exists.\|HTTP/1.1 409' "response.json" ; then @@ -22,13 +31,12 @@ function createCluster { function waitService { local address=$1 - local authToken=$PROVISION_USER_AUTH_TOKEN local attempt_counter=0 local max_attempts=100 echo "Waiting for ${address}" - until $(curl --output /dev/null -fsSL -m 5 -H "Authorization: Basic ${authToken}" --silent --fail ${address}); do + until curl --output /dev/null -fsSL -m 5 -H "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" --silent --fail "${address}"; do if [[ ${attempt_counter} -eq ${max_attempts} ]];then echo "Max attempts reached" exit 1 @@ -43,25 +51,32 @@ function waitService { function waitAllNodes { local node_count=$1 - for (( c=$node_count; c>0; c )) + for (( c=node_count; c>0; c )) do c=$((c-1)) - local node_address=http://graphdb-node-$c.graphdb-node:7200 - waitService "${node_address}/rest/repositories" + waitService "http://${GRAPHDB_POD_NAME}-$c.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/repositories" done } function createRepositoryFromFile { waitAllNodes $1 local repositoriesConfigsLocation=$2 - local authToken=$PROVISION_USER_AUTH_TOKEN local timeout=60 - echo "Creating repositories" local success=true + + echo "Creating repositories" for filename in ${repositoriesConfigsLocation}/*.ttl; do - repositoryName=$(grep "rep:repositoryID" $filename | sed -ne 's/rep:repositoryID "//p' | sed -ne 's/" ;//p' | sed -ne 's/^[[:space:]]*//p') + repositoryName=$(grep "rep:repositoryID" "${filename}" | sed -ne 's/rep:repositoryID "//p' | sed -ne 's/" ;//p' | sed -ne 's/^[[:space:]]*//p') + echo "Provisioning repository ${repositoryName}" - response=$(curl -X POST --connect-timeout 60 --retry 3 --retry-all-errors --retry-delay 10 -H "Authorization: Basic ${authToken}" -H 'Content-Type: multipart/form-data' -F config=@${filename} http://graphdb-node-0.graphdb-node:7200/rest/repositories) + response=$( + curl -X POST --connect-timeout 60 --retry 3 --retry-all-errors --retry-delay 10 \ + -F config=@"${filename}" \ + -H "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" \ + -H 'Content-Type: multipart/form-data' \ + "http://${GRAPHDB_POD_NAME}-0.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/repositories" + ) + if [ -z "$response" ]; then echo "Successfully created repository ${repositoryName}" else diff --git a/files/scripts/update-cluster.sh b/files/scripts/update-cluster.sh index 8ac00790..fd0400fc 100644 --- a/files/scripts/update-cluster.sh +++ b/files/scripts/update-cluster.sh @@ -1,54 +1,75 @@ #!/usr/bin/env bash -set -eu + +set -o errexit +set -o nounset +set -o pipefail function patchCluster { local configLocation=$1 - local authToken=$PROVISION_USER_AUTH_TOKEN local timeout=$2 + echo "Patching cluster" - waitService "http://graphdb-cluster-proxy:7200/proxy/ready" - curl -o patchResponse.json -isSL -m "$timeout" -X PATCH --header "Authorization: Basic ${authToken}" --header 'Content-Type: application/json' --header 'Accept: application/json' -d @"$configLocation" 'http://graphdb-cluster-proxy:7200/rest/cluster/config' - if grep -q 'HTTP/1.1 200' "patchResponse.json"; then - echo "Patch successful" - elif grep -q 'Cluster does not exist.\|HTTP/1.1 412' "patchResponse.json" ; then - echo "Cluster does not exist" - else - echo "Cluster patch failed, received response:" - cat patchResponse.json - echo - exit 1 - fi + waitService "http://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/proxy/ready" + curl -o patchResponse.json -isSL -m "$timeout" -X PATCH \ + --header "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" \ + --header 'Content-Type: application/json' \ + --header 'Accept: application/json' \ + -d @"$configLocation" \ + "http://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/rest/cluster/config" + + if grep -q 'HTTP/1.1 200' "patchResponse.json"; then + echo "Patch successful" + elif grep -q 'Cluster does not exist.\|HTTP/1.1 412' "patchResponse.json" ; then + echo "Cluster does not exist" + else + echo "Cluster patch failed, received response:" + cat patchResponse.json + echo + exit 1 + fi } function removeNodes { local expectedNodes=$1 - local authToken=$PROVISION_USER_AUTH_TOKEN - local namespace=$2 local currentNodes=$(getNodeCountInCurrentCluster) local nodes="" + # DNS suffix in the form of namespace.svc.cluster.local + local dns_suffix + dns_suffix=$(awk '/search/{print $2}' /etc/resolv.conf) + echo "Cluster reported: $currentNodes current nodes" echo "Cluster is expected to have: $expectedNodes nodes" -# if there is no cluster or current nodes are less or equal to expected so no need to remove more, exit + + # if there is no cluster or current nodes are less or equal to expected so no need to remove more, exit if [ "$currentNodes" -lt 2 ] || [ "$currentNodes" -le "$expectedNodes" ]; then echo "No scaling down of the cluster required" exit 0 fi -# if there is a cluster and we wanna scale to 1 node, delete it (we would have exit on the last if in case on no cluster) + + # if there is a cluster and we wanna scale to 1 node, delete it (we would have exit on the last if in case on no cluster) if [ "$expectedNodes" -lt 2 ]; then echo "Scaling down to 1 node. Deleting cluster" deleteCluster exit 0 fi + echo "Scaling the cluster down" for ((i = expectedNodes; i < currentNodes; i++)) do - nodes=${nodes}\"graphdb-node-$i.graphdb-node.${namespace}.svc.cluster.local:7300\" + nodes=${nodes}\"${GRAPHDB_POD_NAME}-$i.${GRAPHDB_SERVICE_NAME}.${dns_suffix}:${GRAPHDB_SERVICE_RPC_PORT}\" if [ $i -lt $(expr $currentNodes - 1) ]; then nodes=${nodes}\, fi done + nodes=\{\"nodes\":\[${nodes}\]\} - waitService "http://graphdb-cluster-proxy:7200/proxy/ready" - curl -o clusterRemove.json -isSL -m 15 -X DELETE --header 'Content-Type: application/json' --header 'Accept: application/json' --header "Authorization: Basic ${authToken}" -d "${nodes}" 'http://graphdb-cluster-proxy:7200/rest/cluster/config/node' + waitService "http://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/proxy/ready" + curl -o clusterRemove.json -isSL -m 15 -X DELETE \ + --header 'Content-Type: application/json' \ + --header 'Accept: application/json' \ + --header "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" \ + -d "${nodes}" \ + "http://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/rest/cluster/config/node" + if grep -q 'HTTP/1.1 200' "clusterRemove.json"; then echo "Scaling down successful." else @@ -61,28 +82,39 @@ function removeNodes { function addNodes { local expectedNodes=$1 - local authToken=$PROVISION_USER_AUTH_TOKEN - local namespace=$2 - local timeout=$3 + local timeout=$2 local currentNodes=$(getNodeCountInCurrentCluster) local nodes="" + # DNS suffix in the form of namespace.svc.cluster.local + local dns_suffix + dns_suffix=$(awk '/search/{print $2}' /etc/resolv.conf) + echo "Cluster reported: $currentNodes current nodes" echo "Cluster is expected to have: $expectedNodes nodes" -# if there is no cluster or current nodes are more or equal to expected so no need to add more, exit + + # if there is no cluster or current nodes are more or equal to expected so no need to add more, exit if [ "$currentNodes" -lt 2 ] || [ "$currentNodes" -ge "$expectedNodes" ]; then echo "No scaling up of the cluster required" exit 0 fi + echo "Scaling the cluster up" for ((i = currentNodes; i < expectedNodes; i++)) do - nodes=${nodes}\"graphdb-node-$i.graphdb-node.${namespace}.svc.cluster.local:7300\" + nodes=${nodes}\"${GRAPHDB_POD_NAME}-$i.${GRAPHDB_SERVICE_NAME}.${dns_suffix}:${GRAPHDB_SERVICE_RPC_PORT}\" if [ $i -lt $(expr $expectedNodes - 1) ]; then nodes=${nodes}\, fi done + nodes=\{\"nodes\":\[${nodes}\]\} - waitService "http://graphdb-cluster-proxy:7200/proxy/ready" - curl -o clusterAdd.json -isSL -m ${timeout} -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header "Authorization: Basic ${authToken}" -d "${nodes}" 'http://graphdb-cluster-proxy:7200/rest/cluster/config/node' + waitService "http://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/proxy/ready" + curl -o clusterAdd.json -isSL -m "${timeout}" -X POST \ + --header 'Content-Type: application/json' \ + --header 'Accept: application/json' \ + --header "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" \ + -d "${nodes}" \ + "http://${GRAPHDB_PROXY_SERVICE_NAME}:${GRAPHDB_PROXY_SERVICE_PORT}/rest/cluster/config/node" + if grep -q 'HTTP/1.1 200' "clusterAdd.json"; then echo "Scaling successful." elif grep -q 'Mismatching fingerprints\|HTTP/1.1 412' "clusterAdd.json"; then @@ -100,9 +132,13 @@ function addNodes { } function deleteCluster { - local authToken=$PROVISION_USER_AUTH_TOKEN - waitService "http://graphdb-node-0.graphdb-node:7200/rest/repositories" - curl -o response.json -isSL -m 15 -X DELETE --header "Authorization: Basic ${authToken}" --header 'Accept: */*' 'http://graphdb-node-0.graphdb-node:7200/rest/cluster/config?force=false' + waitService "http://${GRAPHDB_POD_NAME}-0.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/repositories" + + curl -o response.json -isSL -m 15 -X DELETE \ + --header "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" \ + --header 'Accept: */*' \ + "http://${GRAPHDB_POD_NAME}-0.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}/rest/cluster/config?force=false" + if grep -q 'HTTP/1.1 200' "response.json"; then echo "Cluster deletion successful!" elif grep -q 'Node is not part of the cluster.\|HTTP/1.1 412' "response.json" ; then @@ -116,21 +152,23 @@ function deleteCluster { } function getNodeCountInCurrentCluster { - local authToken=$PROVISION_USER_AUTH_TOKEN - local node_address=http://graphdb-node-0.graphdb-node:7200 + local node_address="http://${GRAPHDB_POD_NAME}-0.${GRAPHDB_SERVICE_NAME}:${GRAPHDB_SERVICE_PORT}" waitService "${node_address}/rest/repositories" - curl -o clusterResponse.json -isSL -m 15 -X GET --header 'Content-Type: application/json' --header "Authorization: Basic ${authToken}" --header 'Accept: */*' "${node_address}/rest/cluster/config" - grep -o 'graphdb-node-' "clusterResponse.json" | grep -c "" + curl -o clusterResponse.json -isSL -m 15 -X GET \ + --header 'Content-Type: application/json' \ + --header "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" \ + --header 'Accept: */*' \ + "${node_address}/rest/cluster/config" + grep -o "${GRAPHDB_SERVICE_NAME}" "clusterResponse.json" | grep -c "" } function waitService { local address=$1 - local authToken=$PROVISION_USER_AUTH_TOKEN local attempt_counter=0 local max_attempts=100 - until $(curl --output /dev/null -fsSL -m 5 -H "Authorization: Basic ${authToken}" --silent --fail ${address}); do + until curl --output /dev/null -fsSL -m 5 -H "Authorization: Basic ${GRAPHDB_AUTH_TOKEN}" --silent --fail "${address}"; do if [[ ${attempt_counter} -eq ${max_attempts} ]];then echo "Max attempts reached" exit 1 diff --git a/templates/NOTES.txt b/templates/NOTES.txt index 013cb49c..b5dc954e 100644 --- a/templates/NOTES.txt +++ b/templates/NOTES.txt @@ -1,23 +1,26 @@ -{{/* - A welcome screen showing useful information after installing/upgrading the chart. -*/}} -------------------------------------------------------------------------------- - ____ _ ____ ____ - / ___|_ __ __ _ _ __ | |__ | _ \| __ ) - | | _| '__/ _` | '_ \| '_ \| | | | _ \ - | |_| | | | (_| | |_) | | | | |_| | |_) | - \____|_| \__,_| .__/|_| |_|____/|____/ - |_| -------------------------------------------------------------------------------- -version: {{ .Chart.AppVersion }} -GDB cluster: {{ gt (int .Values.graphdb.clusterConfig.nodesCount) 1 }} +----------------------------------------------------------------------------------------- + ____ _ ____ ____ + / ___|_ __ __ _ _ __ | |__ | _ \| __ ) + | | _| '__/ _` | '_ \| '_ \| | | | _ \ + | |_| | | | (_| | |_) | | | | |_| | |_) | + \____|_| \__,_| .__/|_| |_|____/|____/ + |_| +----------------------------------------------------------------------------------------- + +Chart version: {{ .Chart.Version }} +GraphDB version: {{ coalesce .Values.image.tag .Chart.AppVersion }} +{{- if gt (int .Values.replicas) 1 }} +GraphDB cluster: {{ .Values.replicas }} replicas +{{- else }} +GraphDB cluster: disabled +{{- end }} +GraphDB workbench: {{ include "graphdb.external-url" . }} ** Please be patient while the chart is being deployed and services are available ** -You can check their status with kubectl get pods +You can check their status with kubectl --namespace {{ include "graphdb.namespace" . }} get pods -{{- if and (gt (int .Values.graphdb.clusterConfig.nodesCount) 1) (not .Values.graphdb.node.license) }} +{{- include "graphdb.notes.warnings" . }} -WARNING: You are attempting to make a cluster without providing a license secret! -{{ end }} -Endpoints: -* GraphDB workbench: {{ .Values.deployment.protocol }}://{{ include "graphdb.resolveDeploymentHost" . }}{{ .Values.graphdb.workbench.subpath }} +------------------------------------------------------------------------------------------ +For more information on running GraphDB, visit https://graphdb.ontotext.com/documentation/ +------------------------------------------------------------------------------------------ diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl new file mode 100644 index 00000000..f856502a --- /dev/null +++ b/templates/_helpers.tpl @@ -0,0 +1,99 @@ +{{/* +Combined image pull secrets +*/}} +{{- define "graphdb.combinedImagePullSecrets" -}} + {{- $secrets := concat .Values.global.imagePullSecrets .Values.image.pullSecrets }} + {{- tpl (toYaml $secrets) . -}} +{{- end -}} + +{{/* +Renders the container image for GraphDB +*/}} +{{- define "graphdb.image" -}} + {{- $repository := .Values.image.repository -}} + {{- $tag := .Values.image.tag | default .Chart.AppVersion | toString -}} + {{- $image := printf "%s:%s" $repository $tag -}} + {{/* Add registry if present */}} + {{- $registry := .Values.global.imageRegistry | default .Values.image.registry -}} + {{- if $registry -}} + {{- $image = printf "%s/%s" $registry $image -}} + {{- end -}} + {{/* Add SHA digest if provided */}} + {{- if .Values.image.digest -}} + {{- $image = printf "%s@%s" $image .Values.image.digest -}} + {{- end -}} + {{- $image -}} +{{- end -}} + +{{/* +Renders the external URL for GraphDB. +*/}} +{{- define "graphdb.external-url" -}} +{{- tpl .Values.configuration.externalUrl . -}} +{{- end -}} + +{{/* +Renders the gRPC address of each GraphDB node that is part of the cluster as a JSON array. Used in the cluster JSON config. +*/}} +{{- define "graphdb.cluster.nodes.json" -}} + {{- $pod_name := include "graphdb.fullname" . -}} + {{- $service_name := include "graphdb.fullname.service.headless" . -}} + {{- $namespace := include "graphdb.namespace" . -}} + {{- $cluster_domain := .Values.global.clusterDomain -}} + {{- $service_rpc_port := .Values.headlessService.ports.rpc -}} + {{- $nodes := list -}} + {{- range $i, $node_index := until (int .Values.replicas) -}} + {{- $nodes = append $nodes (printf "%s-%s.%s.%s.svc.%s:%s" $pod_name (toString $node_index) $service_name $namespace $cluster_domain (toString $service_rpc_port)) -}} + {{- end -}} + {{- toPrettyJson $nodes -}} +{{- end -}} + +{{/* +Renders the HTTP address of each GraphDB node that is part of the cluster, joined by a comma. +*/}} +{{- define "graphdb-proxy.cluster.nodes" -}} + {{- $pod_name := include "graphdb.fullname" . -}} + {{- $service_name := include "graphdb.fullname.service.headless" . -}} + {{- $namespace := include "graphdb.namespace" . -}} + {{- $cluster_domain := .Values.global.clusterDomain -}} + {{- $service_http_port := .Values.headlessService.ports.http -}} + {{- range $i, $node_index := until (int .Values.replicas) -}} + http://{{ $pod_name }}-{{ $node_index }}.{{ $service_name }}.{{ $namespace }}.svc.{{ $cluster_domain }}:{{ $service_http_port }} + {{- if gt (sub (int $.Values.replicas) 1) $node_index -}} + {{- ", " -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* +Checks for potential issues and prints warning messages. +*/}} +{{- define "graphdb.notes.warnings" -}} + {{- $warnings := list -}} + {{- if and (gt (int .Values.replicas) 1) (not .Values.license.existingSecret) -}} + {{- $warnings = append $warnings "WARNING: You are attempting to make a cluster without providing a secret for GraphDB Enterprise Edition license!" -}} + {{- end -}} + {{- if not .Values.persistence.enabled -}} + {{- $warnings = append $warnings "WARNING: Persistence is disabled! You will lose your data when GraphDB pods are restarted or terminated!" -}} + {{- end -}} + {{- if and (gt (int .Values.replicas) 1) (eq (mod (int .Values.replicas) 2) 0) -}} + {{- $warnings = append $warnings "WARNING: You are deploying a GraphDB cluster with an even amount of replicas! You should be using an odd amount of replicas." -}} + {{- end -}} + {{- if gt (len $warnings) 0 }} + {{- print "\n" }} + {{- range $warning, $index := $warnings }} +{{ print $index }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Converts custom users YAML to a pretty JSON for insertion in users.js +*/}} +{{- define "grahdb.security.extra-users.json" -}} +{{- if .Values.security.initialUsers.users -}} + {{- range $user, $data := .Values.security.initialUsers.users -}} + {{- $user | quote }}: {{ $data | mustToPrettyJson }}, + {{- end -}} +{{- end -}} +{{- end -}} diff --git a/templates/_helpers.yaml b/templates/_helpers.yaml deleted file mode 100644 index 38d4c09f..00000000 --- a/templates/_helpers.yaml +++ /dev/null @@ -1,55 +0,0 @@ - -{{- define "graphdb.resolveDeploymentHost" -}} - {{- $global := .Values.global | default dict -}} - {{- $globalDeployment := $global.deployment | default dict -}} - {{- print (index $globalDeployment "host" | default (index $global "ingressHost") | default .Values.deployment.host) -}} -{{- end }} - -{{/* -Combined image pull secrets -*/}} -{{- define "graphdb.combinedImagePullSecrets" -}} - {{- $secrets := list -}} - - {{- if .Values.deployment.imagePullSecret -}} - {{- $secret := dict "name" .Values.deployment.imagePullSecret -}} - {{- $secrets = append $secrets $secret -}} - {{- end -}} - - {{- if and .Values.global .Values.global.imagePullSecrets -}} - {{- $secrets = concat $secrets .Values.global.imagePullSecrets -}} - {{- end -}} - - {{- toYaml $secrets -}} -{{- end -}} - -{{/* -Rendenders a volumeClaimTemplate as yaml. -If the storage class name is not specified - 'global.storageClass' is checked and if set it is used as the storageClassName for the template. -Otherwise it is left blank and cluster default will be used. -*/}} -{{- define "graphdb.renderVolumeClaimTemplateSpec" }} - {{- if and .globalStorageClassName (not .spec.storageClassName) }} - {{- $spec := set .spec "storageClassName" .globalStorageClassName }} - {{- $spec | toYaml }} - {{- else }} - {{- .spec | toYaml }} - {{- end }} -{{- end }} - -{{/* -Render the container image for GraphDB -*/}} -{{- define "graphdb.image" -}} - {{- $registry := .Values.images.graphdb.registry -}} - {{- $repository := .Values.images.graphdb.repository -}} - {{- $tag := .Values.images.graphdb.tag | default .Chart.AppVersion | toString -}} - {{- if and .Values.global .Values.global.imageRegistry -}} - {{- $registry = .Values.global.imageRegistry -}} - {{- end -}} - {{- if $registry -}} - {{- printf "%s/%s:%s" $registry $repository $tag -}} - {{- else -}} - {{- printf "%s:%s" $repository $tag -}} - {{- end -}} -{{- end }} diff --git a/templates/_labels.yaml b/templates/_labels.tpl similarity index 69% rename from templates/_labels.yaml rename to templates/_labels.tpl index ce419826..9f89c6c3 100644 --- a/templates/_labels.yaml +++ b/templates/_labels.tpl @@ -36,12 +36,12 @@ Common labels {{- define "graphdb.labels" -}} helm.sh/chart: {{ include "graphdb.chart" . }} {{ include "graphdb.selectorLabels" . }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +app.kubernetes.io/version: {{ coalesce .Values.image.tag .Chart.AppVersion | quote }} app.kubernetes.io/managed-by: {{ .Release.Service }} app.kubernetes.io/component: graphdb app.kubernetes.io/part-of: graphdb -{{- if .Values.extraLabels }} -{{ toYaml .Values.extraLabels }} +{{- if .Values.labels }} +{{ tpl (toYaml .Values.labels) . }} {{- end }} {{- end }} @@ -52,3 +52,21 @@ Selector labels app.kubernetes.io/name: {{ include "graphdb.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "graphdb.serviceAccountName" -}} + {{- if .Values.serviceAccount.create }} + {{- default (include "graphdb.fullname" .) .Values.serviceAccount.name }} + {{- else }} + {{- default "default" .Values.serviceAccount.name }} + {{- end }} +{{- end }} + +{{/* +Returns the namespace of the release. +*/}} +{{- define "graphdb.namespace" -}} +{{- .Values.namespaceOverride | default .Release.Namespace | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/templates/configuration/graphdb-cluster-config-configmap.yaml b/templates/configuration/graphdb-cluster-config-configmap.yaml deleted file mode 100644 index cc8af758..00000000 --- a/templates/configuration/graphdb-cluster-config-configmap.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if and (gt (int $.Values.graphdb.clusterConfig.nodesCount) 1) (not .Values.graphdb.clusterConfig.existingClusterConfig) }} -# Default configuration map for provisioning the GraphDB cluster configuration. -# To change it, prepare another configuration map and update "graphdb.configs.clusterConfig" -apiVersion: v1 -kind: ConfigMap -metadata: - name: graphdb-cluster-config-configmap - labels: - {{- include "graphdb.labels" . | nindent 4 }} -data: - cluster-config.json: |- -{{ tpl (.Files.Get "files/config/cluster-config.json" | indent 4) . }} -{{- end }} diff --git a/templates/configuration/graphdb-cluster-proxy-configmap.yaml b/templates/configuration/graphdb-cluster-proxy-configmap.yaml deleted file mode 100644 index 614fc1c0..00000000 --- a/templates/configuration/graphdb-cluster-proxy-configmap.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if gt (int $.Values.graphdb.clusterConfig.nodesCount) 1 }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: graphdb-cluster-proxy-configmap - labels: - {{- include "graphdb.labels" . | nindent 4 }} -data: - # >- means replace new line with space and no new lines at the end - GDB_JAVA_OPTS: >- - -Dgraphdb.vhosts={{ $.Values.deployment.protocol }}://{{ include "graphdb.resolveDeploymentHost" $ }}{{ $.Values.graphdb.workbench.subpath }} - -Dgraphdb.external-url={{ $.Values.deployment.protocol }}://{{ include "graphdb.resolveDeploymentHost" $ }}{{ $.Values.graphdb.workbench.subpath }} - -Dgraphdb.auth.token.secret={{ $.Values.graphdb.clusterConfig.clusterSecret | quote }} - -Dgraphdb.home=/opt/graphdb/home - {{ $.Values.graphdb.clusterProxy.java_args }} -{{- end }} diff --git a/templates/configuration/graphdb-logback-configmap.yaml b/templates/configuration/graphdb-logback-configmap.yaml deleted file mode 100644 index e5cea857..00000000 --- a/templates/configuration/graphdb-logback-configmap.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- $configs := (.Values.graphdb.configs | default dict) }} -{{- if $configs.logbackConfigMap }} -{{- if eq $configs.logbackConfigMap "graphdb-logback-configmap" }} -# Default configuration map for provisioning GraphDB logback settings. -# To change it, prepare another configuration map and update "graphdb.configs.logbackConfigMap" -apiVersion: v1 -kind: ConfigMap -metadata: - name: graphdb-logback-configmap - labels: - {{- include "graphdb.labels" . | nindent 4 }} -data: - logback.xml: |- -{{ tpl (.Files.Get "files/config/logback.xml" | indent 4) . }} -{{- end }} -{{- end }} diff --git a/templates/configuration/graphdb-node-configmap.yaml b/templates/configuration/graphdb-node-configmap.yaml deleted file mode 100644 index 4680adcf..00000000 --- a/templates/configuration/graphdb-node-configmap.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: graphdb-node-configmap - labels: - {{- include "graphdb.labels" . | nindent 4 }} -data: - # >- means replace new line with space and no new lines at the end - GDB_JAVA_OPTS: >- - -Denable-context-index=true - -Dentity-pool-implementation=transactional - -Dhealth.max.query.time.seconds=60 - -Dgraphdb.vhosts={{ $.Values.deployment.protocol }}://{{ include "graphdb.resolveDeploymentHost" $ }}{{ $.Values.graphdb.workbench.subpath }} - -Dgraphdb.append.request.id.headers=true - -Dgraphdb.workbench.importDirectory=/opt/graphdb/home/graphdb-import - -Dgraphdb.home=/opt/graphdb/home - -Dgraphdb.ontop.jdbc.path=/opt/graphdb/home/jdbc-driver -{{- if gt (int $.Values.graphdb.clusterConfig.nodesCount) 1 }} - -Dgraphdb.auth.token.secret={{ $.Values.graphdb.clusterConfig.clusterSecret | quote }} -{{- else }} - -Dgraphdb.external-url={{ $.Values.deployment.protocol }}://{{ include "graphdb.resolveDeploymentHost" $ }}{{ $.Values.graphdb.workbench.subpath }} -{{- end }} - {{ default $.Values.graphdb.node.java_args}} diff --git a/templates/configuration/graphdb-properties-configmap.yaml b/templates/configuration/graphdb-properties-configmap.yaml deleted file mode 100644 index 1af03cdd..00000000 --- a/templates/configuration/graphdb-properties-configmap.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- $configs := (.Values.graphdb.configs | default dict) }} -{{- if $configs.propertiesConfigMap}} -{{- if eq $configs.propertiesConfigMap "graphdb-properties-configmap" }} -# Default configuration map for provisioning GraphDB properties. -# To change it, prepare another configuration map and update "graphdb.configs.propertiesConfigMap" -apiVersion: v1 -kind: ConfigMap -metadata: - name: graphdb-properties-configmap - labels: - {{- include "graphdb.labels" . | nindent 4 }} -data: - graphdb.properties: |- -{{ tpl (.Files.Get "files/config/graphdb.properties" | indent 4) . }} -{{- end }} -{{- end }} diff --git a/templates/configuration/graphdb-proxy-properties-configmap.yaml b/templates/configuration/graphdb-proxy-properties-configmap.yaml deleted file mode 100644 index 62ee0d81..00000000 --- a/templates/configuration/graphdb-proxy-properties-configmap.yaml +++ /dev/null @@ -1,11 +0,0 @@ -{{- if gt (int $.Values.graphdb.clusterConfig.nodesCount) 1 }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: graphdb-proxy-properties-configmap - labels: - {{- include "graphdb.labels" . | nindent 4 }} -data: - graphdb.properties: |- -{{ tpl (.Files.Get "files/config/proxy/graphdb.properties" | indent 4) . }} -{{- end }} diff --git a/templates/configuration/graphdb-settings-configmap.yaml b/templates/configuration/graphdb-settings-configmap.yaml deleted file mode 100644 index ee86adda..00000000 --- a/templates/configuration/graphdb-settings-configmap.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- $configs := (.Values.graphdb.configs | default dict) }} -{{- $settingsConfigMap := $configs.settingsConfigMap | default "" }} -{{- if or (eq $settingsConfigMap "graphdb-settings-configmap") (and (not $settingsConfigMap ) (.Values.graphdb.security.enabled)) }} -# Default configuration map for provisioning GraphDB settings.js file. -# To change it, prepare another configuration map and update "graphdb.configs.settingsConfigMap" -apiVersion: v1 -kind: ConfigMap -metadata: - name: graphdb-settings-configmap - labels: - {{- include "graphdb.labels" . | nindent 4 }} -data: - settings.js: |- -{{ tpl (.Files.Get "files/config/settings.js" | indent 4) . }} -{{- end }} diff --git a/templates/configuration/graphdb-users-configmap.yaml b/templates/configuration/graphdb-users-configmap.yaml deleted file mode 100644 index 38821588..00000000 --- a/templates/configuration/graphdb-users-configmap.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- $configs := (.Values.graphdb.configs | default dict) }} -{{- $usersConfigMap := $configs.usersConfigMap | default ""}} -{{- if or (eq $usersConfigMap "graphdb-users-configmap") (and (not $usersConfigMap) (.Values.graphdb.security.enabled)) }} -# Default configuration map for provisioning GraphDB users.js file. -# To change it, prepare another configuration map and update "graphdb.configs.usersConfigMap" -apiVersion: v1 -kind: ConfigMap -metadata: - name: graphdb-users-configmap - labels: - {{- include "graphdb.labels" . | nindent 4 }} -data: - users.js: |- -{{ tpl (.Files.Get "files/config/users.js" | indent 4) . }} -{{- end }} diff --git a/templates/extra-objects.yaml b/templates/extra-objects.yaml new file mode 100644 index 00000000..a9bb3b6b --- /dev/null +++ b/templates/extra-objects.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraObjects }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/templates/gateway/ingress.yaml b/templates/gateway/ingress.yaml deleted file mode 100644 index 5da4d2ed..00000000 --- a/templates/gateway/ingress.yaml +++ /dev/null @@ -1,52 +0,0 @@ -{{- if .Values.deployment.ingress.enabled }} -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: ingress - labels: - {{- include "graphdb.labels" . | nindent 4 }} - annotations: - {{- if .Values.deployment.tls.enabled }} - ingress.kubernetes.io/force-ssl-redirect: "true" - {{- end }} - nginx.ingress.kubernetes.io/proxy-body-size: {{ .Values.deployment.ingress.maxRequestSize }} - nginx.ingress.kubernetes.io/proxy-connect-timeout: {{ .Values.deployment.ingress.timeout.connect | quote }} - nginx.ingress.kubernetes.io/proxy-read-timeout: {{ .Values.deployment.ingress.timeout.read | quote }} - nginx.ingress.kubernetes.io/proxy-send-timeout: {{ .Values.deployment.ingress.timeout.send | quote }} - {{- if eq $.Values.graphdb.workbench.subpath "/" }} - nginx.ingress.kubernetes.io/rewrite-target: /$1 - {{- else }} - nginx.ingress.kubernetes.io/rewrite-target: /$2 - {{- end }} - nginx.ingress.kubernetes.io/x-forwarded-prefix: {{ $.Values.graphdb.workbench.subpath | quote }} - {{- with .Values.deployment.ingress.annotations }} - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - ingressClassName: {{ .Values.deployment.ingress.class }} - {{- if .Values.deployment.tls.enabled }} - tls: - - hosts: - - {{ include "graphdb.resolveDeploymentHost" . | quote }} - secretName: {{ required "TLS secret is required!" .Values.deployment.tls.secretName }} - {{- end }} - rules: - - host: {{ include "graphdb.resolveDeploymentHost" . | quote }} - http: - paths: - {{- if eq $.Values.graphdb.workbench.subpath "/" }} - - path: /(.*) - {{- else }} - - path: {{ $.Values.graphdb.workbench.subpath }}(/|$)(.*) - {{- end }} - pathType: ImplementationSpecific - backend: - service: - {{- if gt (int $.Values.graphdb.clusterConfig.nodesCount) 1 }} - name: graphdb-cluster-proxy - {{- else }} - name: graphdb-node - {{- end }} - port: - number: 7200 -{{- end }} diff --git a/templates/graphdb-cluster-proxy.yaml b/templates/graphdb-cluster-proxy.yaml deleted file mode 100644 index da443c53..00000000 --- a/templates/graphdb-cluster-proxy.yaml +++ /dev/null @@ -1,156 +0,0 @@ -{{- if gt (int $.Values.graphdb.clusterConfig.nodesCount) 1 }} -{{- $configs := ($.Values.graphdb.configs | default dict) }} ---- -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: gdb-proxy - labels: - app: graphdb-cluster-proxy - {{- include "graphdb.labels" . | nindent 4 }} -spec: - replicas: {{ $.Values.graphdb.clusterProxy.replicas }} - serviceName: graphdb-proxy - podManagementPolicy: Parallel - revisionHistoryLimit: {{ .Values.graphdb.clusterProxy.revisionHistoryLimit }} - selector: - matchLabels: - app: graphdb-cluster-proxy - volumeClaimTemplates: - {{- if $.Values.graphdb.clusterProxy.persistence.enablePersistence }} - - metadata: - name: graphdb-cluster-proxy-data-dynamic-pvc - {{- $spec := dict "globalStorageClassName" $.Values.global.storageClass "spec" $.Values.graphdb.clusterProxy.persistence.volumeClaimTemplateSpec }} - spec: {{ include "graphdb.renderVolumeClaimTemplateSpec" $spec | nindent 8 }} - {{- end }} - template: - metadata: - labels: - app: graphdb-cluster-proxy - {{- with .Values.graphdb.clusterProxy.podLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - annotations: - checksum/configmap: {{ include (print $.Template.BasePath "/configuration/graphdb-cluster-proxy-configmap.yaml") . | sha256sum }} - {{- with .Values.graphdb.clusterProxy.podAnnotations }} - {{- toYaml . | nindent 8 }} - {{- end }} - spec: - terminationGracePeriodSeconds: {{ .Values.graphdb.clusterProxy.terminationGracePeriodSeconds }} - setHostnameAsFQDN: true - volumes: - - name: graphdb-properties - configMap: - name: graphdb-proxy-properties-configmap - {{- with $.Values.graphdb.clusterProxy.extraVolumes }} - {{- tpl ( toYaml . ) $ | nindent 8 }} - {{- end }} - {{- with .Values.graphdb.clusterProxy.nodeSelector }} - nodeSelector: {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.graphdb.clusterProxy.affinity }} - affinity: {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.graphdb.clusterProxy.tolerations }} - tolerations: {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.graphdb.clusterProxy.topologySpreadConstraints }} - topologySpreadConstraints: {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.graphdb.clusterProxy.podSecurityContext }} - securityContext: {{- toYaml . | nindent 8 }} - {{- end }} - imagePullSecrets: - {{- include "graphdb.combinedImagePullSecrets" $ | nindent 8 }} - {{- with .Values.graphdb.clusterProxy.extraInitContainers }} - initContainers: - {{- toYaml . | nindent 8 }} - {{- end }} - containers: - - name: graphdb-proxy - image: {{ include "graphdb.image" . }} - imagePullPolicy: {{ $.Values.deployment.imagePullPolicy }} - command: ["/opt/graphdb/dist/bin/cluster-proxy"] - envFrom: - - configMapRef: - name: graphdb-cluster-proxy-configmap - {{- with $.Values.graphdb.clusterProxy.extraEnvFrom }} - {{- tpl ( toYaml . ) $ | nindent 12 }} - {{- end }} - {{- with .Values.graphdb.clusterProxy.extraEnv }} - env: {{- tpl ( toYaml . ) $ | nindent 12 }} - {{- end }} - ports: - - name: gdb-proxy-port - containerPort: 7200 - - name: gdb-proxy-rpc - containerPort: 7300 - volumeMounts: - - name: graphdb-properties - mountPath: /opt/graphdb/home/conf/graphdb.properties - subPath: graphdb.properties - {{- if $.Values.graphdb.clusterProxy.persistence.enablePersistence }} - - name: graphdb-cluster-proxy-data-dynamic-pvc - mountPath: /opt/graphdb/home - {{- end }} - {{- with $.Values.graphdb.clusterProxy.extraVolumeMounts }} - {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.graphdb.clusterProxy.resources }} - resources: {{ toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.graphdb.clusterProxy.securityContext }} - securityContext: {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.graphdb.clusterProxy.startupProbe }} - startupProbe: {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.graphdb.clusterProxy.readinessProbe }} - readinessProbe: {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.graphdb.clusterProxy.livenessProbe }} - livenessProbe: {{- toYaml . | nindent 12 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: graphdb-cluster-proxy - labels: - app: graphdb-cluster-proxy - {{- include "graphdb.labels" . | nindent 4 }} - {{- with .Values.graphdb.clusterProxy.service.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - type: {{ $.Values.graphdb.clusterProxy.serviceType }} - selector: - app: graphdb-cluster-proxy - ports: - - name: gdb-proxy-port - port: 7200 - targetPort: 7200 - protocol: TCP ---- -apiVersion: v1 -kind: Service -metadata: - name: graphdb-proxy - labels: - app: graphdb-cluster-proxy - {{- include "graphdb.labels" . | nindent 4 }} - {{- with .Values.graphdb.clusterProxy.headlessService.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - clusterIP: None - selector: - app: graphdb-cluster-proxy - ports: - - name: gdb-proxy-rpc - port: 7300 - targetPort: 7300 - protocol: TCP -{{- end }} diff --git a/templates/graphdb-node.yaml b/templates/graphdb-node.yaml deleted file mode 100644 index 97b9d200..00000000 --- a/templates/graphdb-node.yaml +++ /dev/null @@ -1,261 +0,0 @@ -{{- $configs := ($.Values.graphdb.configs | default dict) }} ---- -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: graphdb-node - labels: - app: graphdb-node - {{- include "graphdb.labels" . | nindent 4 }} -spec: - replicas: {{ $.Values.graphdb.clusterConfig.nodesCount }} - serviceName: graphdb-node - updateStrategy: - type: RollingUpdate - podManagementPolicy: Parallel - revisionHistoryLimit: {{ .Values.graphdb.node.revisionHistoryLimit }} - selector: - matchLabels: - app: graphdb-node - {{- if or (hasKey $.Values.graphdb.node.persistence "volumeClaimTemplateSpec") ($.Values.graphdb.import_directory_mount.enabled)}} - volumeClaimTemplates: - {{- if hasKey $.Values.graphdb.node.persistence "volumeClaimTemplateSpec" }} - - metadata: - name: graphdb-node-data-dynamic-pvc - {{- $spec := dict "globalStorageClassName" $.Values.global.storageClass "spec" $.Values.graphdb.node.persistence.volumeClaimTemplateSpec }} - spec: {{ include "graphdb.renderVolumeClaimTemplateSpec" $spec | nindent 8 }} - {{- end }} - {{- if $.Values.graphdb.import_directory_mount.enabled }} - - metadata: - name: graphdb-server-import-dir - {{- $spec := dict "globalStorageClassName" $.Values.global.storageClass "spec" $.Values.graphdb.import_directory_mount.volumeClaimTemplateSpec }} - spec: {{ include "graphdb.renderVolumeClaimTemplateSpec" $spec | nindent 8 }} - {{- end }} - {{- end }} - template: - metadata: - labels: - app: graphdb-node - {{- with .Values.graphdb.node.podLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - annotations: - checksum/configmap: {{ include (print $.Template.BasePath "/configuration/graphdb-node-configmap.yaml") . | sha256sum }} - {{- with .Values.graphdb.node.podAnnotations }} - {{- toYaml . | nindent 8 }} - {{- end }} - spec: - setHostnameAsFQDN: true - terminationGracePeriodSeconds: {{ .Values.graphdb.node.terminationGracePeriodSeconds }} - volumes: - {{- if .Values.graphdb.node.license }} - - name: graphdb-license - secret: - secretName: {{ .Values.graphdb.node.license }} - {{- end }} - {{- if or $configs.settingsConfigMap $.Values.graphdb.security.enabled }} - - name: graphdb-settings-config - configMap: - name: {{ $configs.settingsConfigMap | default "graphdb-settings-configmap" }} - {{- end }} - {{- if or $configs.usersConfigMap $.Values.graphdb.security.enabled }} - - name: graphdb-users-config - configMap: - name: {{ $configs.usersConfigMap | default "graphdb-users-configmap" }} - {{- end }} - {{- if $configs.propertiesConfigMap }} - - name: graphdb-properties-config - configMap: - name: {{ $configs.propertiesConfigMap }} - {{- end }} - {{- if $configs.logbackConfigMap }} - - name: graphdb-logback-config - configMap: - name: {{ $configs.logbackConfigMap }} - {{- end }} - {{- with $.Values.graphdb.node.extraVolumes }} - {{- tpl ( toYaml . ) $ | nindent 8 }} - {{- end }} - {{- with .Values.graphdb.node.nodeSelector }} - nodeSelector: {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.graphdb.node.affinity }} - affinity: {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.graphdb.node.tolerations }} - tolerations: {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.graphdb.node.topologySpreadConstraints }} - topologySpreadConstraints: {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.graphdb.node.podSecurityContext }} - securityContext: {{- toYaml . | nindent 8 }} - {{- end }} - imagePullSecrets: - {{- include "graphdb.combinedImagePullSecrets" $ | nindent 8 }} - containers: - - name: graphdb-node - image: {{ include "graphdb.image" . }} - imagePullPolicy: {{ $.Values.deployment.imagePullPolicy }} - {{- with .Values.graphdb.node.command }} - command: {{ toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.graphdb.node.args }} - args: {{ toYaml . | nindent 12 }} - {{- end }} - ports: - - name: graphdb - containerPort: 7200 - {{- if gt (int (.Values.graphdb.clusterConfig.nodesCount)) 1 }} - - name: graphdb-rpc - containerPort: 7300 - {{- end }} - envFrom: - - configMapRef: - name: graphdb-node-configmap - {{- with $.Values.graphdb.node.extraEnvFrom }} - {{- tpl ( toYaml . ) $ | nindent 12 }} - {{- end }} - {{- with .Values.graphdb.node.extraEnv }} - env: {{- tpl ( toYaml . ) $ | nindent 12 }} - {{- end }} - volumeMounts: - {{- if hasKey $.Values.graphdb.node.persistence "volumeClaimTemplateSpec" }} - - name: graphdb-node-data-dynamic-pvc - mountPath: /opt/graphdb/home - {{- end }} - {{- if .Values.graphdb.node.license }} - - name: graphdb-license - mountPath: /opt/graphdb/home/conf/graphdb.license - subPath: {{ .Values.graphdb.node.licenseFilename }} - {{- end }} - {{- if $.Values.graphdb.import_directory_mount.enabled }} - - name: graphdb-server-import-dir - mountPath: /opt/graphdb/home/graphdb-import - {{- end }} - {{- with $.Values.graphdb.node.extraVolumeMounts }} - {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.graphdb.node.resources }} - resources: {{ toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.graphdb.node.securityContext }} - securityContext: {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.graphdb.node.startupProbe }} - startupProbe: {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.graphdb.node.readinessProbe }} - readinessProbe: {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.graphdb.node.livenessProbe }} - livenessProbe: {{- toYaml . | nindent 12 }} - {{- end }} - initContainers: - # PROVISION SETTINGS AND SECURITY - - name: provision-settings - image: {{ include "graphdb.image" . }} - imagePullPolicy: {{ $.Values.deployment.imagePullPolicy }} - volumeMounts: - {{- if hasKey $.Values.graphdb.node.persistence "volumeClaimTemplateSpec" }} - - name: graphdb-node-data-dynamic-pvc - mountPath: /opt/graphdb/home - {{- end }} - {{- if or $configs.settingsConfigMap $.Values.graphdb.security.enabled }} - - name: graphdb-settings-config - mountPath: /tmp/graphdb-settings-configmap - {{- end }} - {{- if or $configs.usersConfigMap $.Values.graphdb.security.enabled }} - - name: graphdb-users-config - mountPath: /tmp/graphdb-users-configmap - {{- end }} - {{- if $configs.propertiesConfigMap }} - - name: graphdb-properties-config - mountPath: /tmp/graphdb-properties-configmap - {{- end }} - {{- if $configs.logbackConfigMap }} - - name: graphdb-logback-config - mountPath: /tmp/graphdb-logback-configmap - {{- end }} - {{- with .Values.graphdb.node.initContainerSecurityContext }} - securityContext: {{- toYaml . | nindent 12 }} - {{- end }} - {{- with .Values.graphdb.node.initContainerResources }} - resources: {{ toYaml . | nindent 12 }} - {{- end }} - command: ['bash', '-c'] - args: - - | - set -eu - if [[ ! -f /opt/graphdb/home/work/workbench/settings.js && ! -f /opt/graphdb/home/data/users.js && -f /tmp/graphdb-users-configmap/users.js ]]; then - echo "Provisioning users with users.js file..." - mkdir -p /opt/graphdb/home/data ; - cp /tmp/graphdb-users-configmap/users.js /opt/graphdb/home/data/users.js - fi - if [[ ! -f /opt/graphdb/home/work/workbench/settings.js && ! -f /opt/graphdb/home/data/settings.js && -f /tmp/graphdb-settings-configmap/settings.js ]]; then - echo "Provisioning settings with settings.js file..." - mkdir -p /opt/graphdb/home/data ; - cp /tmp/graphdb-settings-configmap/settings.js /opt/graphdb/home/data/settings.js - fi - if [[ -f /tmp/graphdb-properties-configmap/graphdb.properties ]]; then - echo "Provisioning graphdb properties file..." - mkdir -p /opt/graphdb/home/conf ; - cp /tmp/graphdb-properties-configmap/graphdb.properties /opt/graphdb/home/conf/graphdb.properties - fi - if [[ -f /tmp/graphdb-logback-configmap/logback.xml ]]; then - echo "Provisioning logging config file..." - mkdir -p /opt/graphdb/home/conf ; - cp /tmp/graphdb-logback-configmap/logback.xml /opt/graphdb/home/conf/logback.xml - fi - mkdir -p /opt/graphdb/home/jdbc-driver - echo 'Done' - {{- with .Values.graphdb.node.extraInitContainers }} - {{- toYaml . | nindent 8 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: graphdb-node - labels: - app: graphdb-node - {{- include "graphdb.labels" . | nindent 4 }} - {{- with .Values.graphdb.node.service.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - clusterIP: None - selector: - app: graphdb-node - ports: - - name: graphdb - port: 7200 - targetPort: 7200 - protocol: TCP - {{- if gt (int $.Values.graphdb.clusterConfig.nodesCount) 1 }} - - name: rpc - port: 7300 - targetPort: 7300 - protocol: TCP - {{- end }} - -{{- if .Values.graphdb.pdb.create }} ---- -apiVersion: policy/v1 -kind: PodDisruptionBudget -metadata: - name: graphdb-node - labels: - {{- include "graphdb.labels" . | nindent 4 }} -spec: - {{- if .Values.graphdb.pdb.minAvailable }} - minAvailable: {{ .Values.graphdb.pdb.minAvailable }} - {{- end }} - {{- if .Values.graphdb.pdb.maxUnavailable }} - maxUnavailable: {{ .Values.graphdb.pdb.maxUnavailable }} - {{- end }} - selector: - matchLabels: - app: graphdb-node -{{- end }} diff --git a/templates/graphdb-provision-user-secret.yaml b/templates/graphdb-provision-user-secret.yaml deleted file mode 100644 index 764aa1c2..00000000 --- a/templates/graphdb-provision-user-secret.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# Secret used from the jobs to authenticate to running GraphDB instances -apiVersion: v1 -kind: Secret -metadata: - name: graphdb-provision-user - labels: - {{- include "graphdb.labels" . | nindent 4 }} - annotations: - "helm.sh/hook": pre-install, pre-upgrade, pre-rollback, post-install, post-upgrade, post-rollback - "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed - "helm.sh/hook-weight": "-9" -type: Opaque -data: - provisioningUsername: {{ .Values.graphdb.security.provisioningUsername | b64enc | quote }} - provisioningPassword: {{ .Values.graphdb.security.provisioningPassword | b64enc | quote }} - PROVISION_USER_AUTH_TOKEN: {{ printf "%s:%s" .Values.graphdb.security.provisioningUsername .Values.graphdb.security.provisioningPassword | b64enc | b64enc | quote }} diff --git a/templates/graphdb/_labels.tpl b/templates/graphdb/_labels.tpl new file mode 100644 index 00000000..809071e9 --- /dev/null +++ b/templates/graphdb/_labels.tpl @@ -0,0 +1,27 @@ +{{/* +Helper functions for labels related to GraphDB resources +*/}} + +{{- define "graphdb.fullname.configmap.environment" -}} + {{- printf "%s-%s" (include "graphdb.fullname" .) "environment" -}} +{{- end -}} + +{{- define "graphdb.fullname.configmap.properties" -}} + {{- printf "%s-%s" (include "graphdb.fullname" .) "properties" -}} +{{- end -}} + +{{- define "graphdb.fullname.secret.properties" -}} + {{- printf "%s-%s" (include "graphdb.fullname" .) "properties" -}} +{{- end -}} + +{{- define "graphdb.fullname.configmap.initial-settings" -}} + {{- printf "%s-%s" (include "graphdb.fullname" .) "initial-settings" -}} +{{- end -}} + +{{- define "graphdb.fullname.secret.initial-users" -}} + {{- printf "%s-%s" (include "graphdb.fullname" .) "initial-users" -}} +{{- end -}} + +{{- define "graphdb.fullname.service.headless" -}} + {{- printf "%s-%s" (include "graphdb.fullname" .) "headless" -}} +{{- end -}} diff --git a/templates/graphdb/configmap-environment.yaml b/templates/graphdb/configmap-environment.yaml new file mode 100644 index 00000000..af4afbc4 --- /dev/null +++ b/templates/graphdb/configmap-environment.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "graphdb.fullname.configmap.environment" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +data: + GDB_JAVA_OPTS: >- + -Dgraphdb.home=/opt/graphdb/home + -Dhttp.socket.keepalive=true + {{ tpl .Values.configuration.defaultJavaArguments . }} + {{ tpl .Values.configuration.javaArguments . }} diff --git a/templates/graphdb/configmap-initial-settings.yaml b/templates/graphdb/configmap-initial-settings.yaml new file mode 100644 index 00000000..8ae1305a --- /dev/null +++ b/templates/graphdb/configmap-initial-settings.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.security.enabled (not .Values.configuration.initialSettings.existingConfigmap) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "graphdb.fullname.configmap.initial-settings" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +data: + {{ .Values.configuration.initialSettings.configmapKey }}: |- + {{- tpl (.Files.Get "files/config/settings.js" | trim) . | nindent 4 }} +{{- end }} diff --git a/templates/graphdb/configmap-properties.yaml b/templates/graphdb/configmap-properties.yaml new file mode 100644 index 00000000..597c68ce --- /dev/null +++ b/templates/graphdb/configmap-properties.yaml @@ -0,0 +1,30 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "graphdb.fullname.configmap.properties" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +data: + graphdb.properties: |- + ##### GraphDB configurations ##### + # See https://graphdb.ontotext.com/documentation/ for supported properties + graphdb.connector.port={{ .Values.containerPorts.http }} + graphdb.append.request.id.headers=true + graphdb.workbench.importDirectory=/opt/graphdb/home/graphdb-import + graphdb.ontop.jdbc.path=/opt/graphdb/home/jdbc-driver + {{- if eq (int .Values.replicas) 1}} + graphdb.external-url={{ include "graphdb.external-url" . }} + {{- end }} + {{- if .Values.configuration.properties }} + ##### Overrides from values.yaml ##### + {{- range $key, $val := .Values.configuration.properties -}} + {{- if ne $val nil }} + {{ $key }}={{ tpl ($val | toString) $ | quote }} + {{- end }} + {{- end -}} + {{- end -}} diff --git a/templates/graphdb/pdb.yaml b/templates/graphdb/pdb.yaml new file mode 100644 index 00000000..efdf505e --- /dev/null +++ b/templates/graphdb/pdb.yaml @@ -0,0 +1,23 @@ +{{- if .Values.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "graphdb.fullname" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +spec: + {{- if .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "graphdb.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/templates/graphdb/secret-initial-users.yaml b/templates/graphdb/secret-initial-users.yaml new file mode 100644 index 00000000..1b8012d7 --- /dev/null +++ b/templates/graphdb/secret-initial-users.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.security.enabled (not .Values.security.initialUsers.existingSecret) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "graphdb.fullname.secret.initial-users" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +type: Opaque +data: + {{ .Values.security.initialUsers.secretKey }}: {{ tpl (.Files.Get "files/config/users.js" | trim) . | b64enc | quote }} +{{- end }} diff --git a/templates/graphdb/secret-properties.yaml b/templates/graphdb/secret-properties.yaml new file mode 100644 index 00000000..54e13ba5 --- /dev/null +++ b/templates/graphdb/secret-properties.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "graphdb.fullname.secret.properties" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +type: Opaque +stringData: + graphdb-secrets.properties: |- + ##### GraphDB sensitive configurations ##### + {{- if and (gt (int .Values.replicas) 1) (not .Values.cluster.token.existingSecret) }} + graphdb.auth.token.secret={{ .Values.cluster.token.secret | quote }} + {{- end }} + {{- if .Values.configuration.secretProperties }} + ##### Secrets overrides from values.yaml ##### + {{- range $key, $val := .Values.configuration.secretProperties -}} + {{- if ne $val nil }} + {{ $key }}={{ tpl ($val | toString) $ | quote }} + {{- end }} + {{- end -}} + {{- end -}} diff --git a/templates/graphdb/service-headless.yaml b/templates/graphdb/service-headless.yaml new file mode 100644 index 00000000..b5ebc54a --- /dev/null +++ b/templates/graphdb/service-headless.yaml @@ -0,0 +1,34 @@ +{{- if .Values.headlessService.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "graphdb.fullname.service.headless" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + {{- with .Values.headlessService.labels }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} + {{- with (mergeOverwrite (deepCopy .Values.annotations) .Values.headlessService.annotations) }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +spec: + clusterIP: None + selector: + {{- include "graphdb.selectorLabels" . | nindent 4 }} + ports: + - name: http + port: {{ .Values.headlessService.ports.http }} + targetPort: http + protocol: TCP + {{- if gt (int .Values.replicas) 1 }} + - name: rpc + port: {{ .Values.headlessService.ports.rpc }} + targetPort: rpc + protocol: TCP + {{- end }} + {{- with .Values.headlessService.extraPorts -}} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/templates/graphdb/service.yaml b/templates/graphdb/service.yaml new file mode 100644 index 00000000..06045bd5 --- /dev/null +++ b/templates/graphdb/service.yaml @@ -0,0 +1,46 @@ +{{- if and .Values.service.enabled (eq (int .Values.replicas) 1) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "graphdb.fullname" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + {{- with .Values.service.labels }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} + {{- with (mergeOverwrite (deepCopy .Values.annotations) .Values.service.annotations) }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.service.type }} + selector: + {{- include "graphdb.selectorLabels" . | nindent 4 }} + {{- if .Values.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }} + {{- end }} + {{- if .Values.service.healthCheckNodePort }} + healthCheckNodePort: {{ .Values.service.healthCheckNodePort }} + {{- end }} + {{- if .Values.service.loadBalancerClass }} + loadBalancerClass: {{ .Values.service.loadBalancerClass }} + {{- end }} + {{- if .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{ .Values.service.loadBalancerSourceRanges | toYaml | nindent 4 }} + {{- end }} + {{- if .Values.service.externalIPs }} + externalIPs: {{ .Values.service.externalIPs | toYaml | nindent 4 }} + {{- end }} + ports: + - name: http + port: {{ .Values.service.ports.http }} + targetPort: http + protocol: TCP + {{- if .Values.service.nodePort }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + {{- with .Values.service.extraPorts -}} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/templates/graphdb/serviceaccount.yaml b/templates/graphdb/serviceaccount.yaml new file mode 100644 index 00000000..15f66bca --- /dev/null +++ b/templates/graphdb/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "graphdb.serviceAccountName" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + {{- with (mergeOverwrite (deepCopy .Values.annotations) .Values.serviceAccount.annotations) }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +{{- end }} diff --git a/templates/graphdb/statefulset.yaml b/templates/graphdb/statefulset.yaml new file mode 100644 index 00000000..e291aafc --- /dev/null +++ b/templates/graphdb/statefulset.yaml @@ -0,0 +1,353 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "graphdb.fullname" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.replicas }} + serviceName: {{ include "graphdb.fullname.service.headless" . }} + updateStrategy: {{ .Values.updateStrategy | toYaml | nindent 4 }} + podManagementPolicy: {{ .Values.podManagementPolicy }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "graphdb.selectorLabels" . | nindent 6 }} + {{- if or .Values.persistence.enabled .Values.import.volumeMount.enabled .Values.extraVolumeClaimTemplates }} + volumeClaimTemplates: + {{- if .Values.persistence.enabled }} + - metadata: + name: {{ .Values.persistence.volumeClaimTemplate.name }} + {{- with .Values.persistence.volumeClaimTemplate.labels }} + labels: {{ tpl (toYaml .) $ | nindent 10 }} + {{- end }} + {{- with .Values.persistence.volumeClaimTemplate.annotations }} + annotations: {{ tpl (toYaml .) $ | nindent 10 }} + {{- end }} + spec: + {{- toYaml .Values.persistence.volumeClaimTemplate.spec | nindent 8 }} + {{- end }} + {{- if .Values.import.volumeMount.enabled }} + - metadata: + name: {{ .Values.import.volumeMount.volumeClaimTemplate.name }} + {{- with .Values.import.volumeMount.volumeClaimTemplate.labels }} + labels: {{ tpl (toYaml .) $ | nindent 10 }} + {{- end }} + {{- with .Values.import.volumeMount.volumeClaimTemplate.annotations }} + annotations: {{ tpl (toYaml .) $ | nindent 10 }} + {{- end }} + spec: + {{- toYaml .Values.import.volumeMount.volumeClaimTemplate.spec | nindent 8 }} + {{- end }} + {{- if .Values.extraVolumeClaimTemplates }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} + {{- end }} + template: + metadata: + labels: + {{- include "graphdb.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + annotations: + checksum/configmap-environment: {{ include (print .Template.BasePath "/graphdb/configmap-environment.yaml") . | sha256sum }} + checksum/configmap-properties: {{ include (print .Template.BasePath "/graphdb/configmap-properties.yaml") . | sha256sum }} + checksum/secret-properties: {{ include (print .Template.BasePath "/graphdb/secret-properties.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + spec: + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + serviceAccountName: {{ include "graphdb.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + {{- with .Values.dnsConfig }} + dnsConfig: {{ toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.dnsPolicy }} + dnsPolicy: {{ .Values.dnsPolicy }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + volumes: + {{- if not .Values.persistence.enabled }} + - name: {{ .Values.persistence.volumeClaimTemplate.name }} + emptyDir: {{ .Values.persistence.emptyDir | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.tempVolume.enabled }} + - name: temp-dir + emptyDir: {{ .Values.tempVolume.emptyDir | toYaml | nindent 12 }} + {{- end }} + - name: graphdb-properties + configMap: + name: {{ include "graphdb.fullname.configmap.properties" . }} + - name: graphdb-secret-properties + secret: + secretName: {{ include "graphdb.fullname.secret.properties" . }} + {{- if .Values.configuration.extraProperties.existingConfigmap }} + - name: graphdb-extra-properties + configMap: + name: {{ tpl .Values.configuration.extraProperties.existingConfigmap . }} + {{- end }} + {{- if .Values.configuration.extraProperties.existingSecret }} + - name: graphdb-extra-secret-properties + secret: + secretName: {{ tpl .Values.configuration.extraProperties.existingSecret . }} + {{- end }} + {{- if .Values.configuration.logback.existingConfigmap }} + - name: graphdb-logback-config + configMap: + name: {{ tpl .Values.configuration.logback.existingConfigmap . }} + {{- end }} + {{- if .Values.license.existingSecret }} + - name: graphdb-license + secret: + secretName: {{ tpl .Values.license.existingSecret . }} + {{- end }} + {{- if or .Values.security.enabled .Values.configuration.initialSettings.existingConfigmap }} + - name: graphdb-initial-settings-config + configMap: + name: {{ (tpl .Values.configuration.initialSettings.existingConfigmap .) | default (include "graphdb.fullname.configmap.initial-settings" .) }} + {{- end }} + {{- if or .Values.security.enabled .Values.security.initialUsers.existingSecret }} + - name: graphdb-initial-users-config + secret: + secretName: {{ (tpl .Values.security.initialUsers.existingSecret .) | default (include "graphdb.fullname.secret.initial-users" .) }} + {{- end }} + {{- with .Values.extraVolumes }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.podSecurityContext }} + securityContext: {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.global.imagePullSecrets .Values.image.pullSecrets }} + imagePullSecrets: + {{- include "graphdb.combinedImagePullSecrets" . | nindent 8 }} + {{- end }} + initContainers: + {{- if and .Values.persistence.enabled .Values.initContainerDataPermissions.enabled }} + # Fixes the permissions in the storage volume to match the security context settings + - name: {{ .Chart.Name }}-fix-permissions + image: {{ include "graphdb.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: GRAPHDB_USER_ID + value: {{ coalesce .Values.securityContext.runAsUser .Values.podSecurityContext.runAsUser | quote }} + - name: GRAPHDB_GROUP_ID + value: {{ coalesce .Values.securityContext.runAsGroup .Values.podSecurityContext.runAsGroup | quote }} + volumeMounts: + - name: {{ .Values.persistence.volumeClaimTemplate.name }} + mountPath: /opt/graphdb/home + {{- with .Values.initContainerResources }} + resources: {{ toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.initContainerDataPermissions.securityContext }} + securityContext: {{- toYaml . | nindent 12 }} + {{- end }} + command: [ "bash", "-c" ] + args: + - | + set -eu + echo "Changing ownership to ${GRAPHDB_USER_ID}:${GRAPHDB_GROUP_ID}" + chown -R ${GRAPHDB_USER_ID}:${GRAPHDB_GROUP_ID} /opt/graphdb/home + {{- end }} + # PROVISION SETTINGS AND SECURITY + - name: {{ .Chart.Name }}-provision-settings + image: {{ include "graphdb.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: GRAPHDB_PUBLIC_URL + value: {{ include "graphdb.external-url" . }} + - name: GRAPHDB_HTTP_PORT + value: {{ .Values.containerPorts.http | quote }} + - name: GRAPHDB_RPC_PORT + value: {{ .Values.containerPorts.rpc | quote }} + {{- if .Values.cluster.token.existingSecret }} + - name: GRAPHDB_CLUSTER_SECRET + valueFrom: + secretKeyRef: + name: {{ .Values.cluster.token.existingSecret }} + key: {{ .Values.cluster.token.secretKey }} + {{- end }} + volumeMounts: + - name: {{ .Values.persistence.volumeClaimTemplate.name }} + mountPath: /opt/graphdb/home + - name: graphdb-properties + mountPath: /tmp/graphdb/graphdb.properties + subPath: graphdb.properties + - name: graphdb-secret-properties + mountPath: /tmp/graphdb/graphdb-secrets.properties + subPath: graphdb-secrets.properties + {{- if .Values.configuration.extraProperties.existingConfigmap }} + - name: graphdb-extra-properties + mountPath: /tmp/graphdb/graphdb-extra.properties + subPath: {{ .Values.configuration.extraProperties.configmapKey }} + {{- end }} + {{- if .Values.configuration.extraProperties.existingSecret }} + - name: graphdb-extra-secret-properties + mountPath: /tmp/graphdb/graphdb-extra-secret.properties + subPath: {{ .Values.configuration.extraProperties.secretKey }} + {{- end }} + {{- if or .Values.security.enabled .Values.configuration.initialSettings.existingConfigmap }} + - name: graphdb-initial-settings-config + mountPath: /tmp/graphdb/settings.js + subPath: {{ .Values.configuration.initialSettings.configmapKey }} + {{- end }} + {{- if or .Values.security.enabled .Values.security.initialUsers.existingSecret }} + - name: graphdb-initial-users-config + mountPath: /tmp/graphdb/users.js + subPath: {{ .Values.security.initialUsers.secretKey }} + {{- end }} + {{- with .Values.initContainerSecurityContext }} + securityContext: {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.initContainerResources }} + resources: {{ toYaml . | nindent 12 }} + {{- end }} + command: [ "bash", "-c" ] + args: + - | + set -eu + set +x + mkdir -p /opt/graphdb/home/conf/ /opt/graphdb/home/data/ /opt/graphdb/home/jdbc-driver/ + + echo 'Configuring graphdb.properties' + echo "" > /opt/graphdb/home/conf/graphdb.properties + + echo "Configuring GraphDB hostname: $(hostname --fqdn)" + cat << EOF >> /opt/graphdb/home/conf/graphdb.properties + ##### Configurations from initContainer #####" + graphdb.hostname=$(hostname --fqdn) + graphdb.rpc.address=$(hostname --fqdn):${GRAPHDB_RPC_PORT} + graphdb.vhosts=$(hostname --fqdn):${GRAPHDB_HTTP_PORT}, ${GRAPHDB_PUBLIC_URL} + EOF + echo "" >> /opt/graphdb/home/conf/graphdb.properties + + cat /tmp/graphdb/graphdb.properties >> /opt/graphdb/home/conf/graphdb.properties + echo "" >> /opt/graphdb/home/conf/graphdb.properties + + cat /tmp/graphdb/graphdb-secrets.properties >> /opt/graphdb/home/conf/graphdb.properties + echo "" >> /opt/graphdb/home/conf/graphdb.properties + + if [[ -n ${GRAPHDB_CLUSTER_SECRET:-""} ]]; then + echo "##### Override from existing cluster secret #####" >> /opt/graphdb/home/conf/graphdb.properties + (echo "graphdb.auth.token.secret=${GRAPHDB_CLUSTER_SECRET}" >> /opt/graphdb/home/conf/graphdb.properties) >/dev/null 2>&1 + echo "" >> /opt/graphdb/home/conf/graphdb.properties + fi + + if [[ -f /tmp/graphdb/graphdb-extra.properties ]]; then + echo "##### Overrides from extra properties configmap #####" >> /opt/graphdb/home/conf/graphdb.properties + cat /tmp/graphdb/graphdb-extra.properties >> /opt/graphdb/home/conf/graphdb.properties + echo "" >> /opt/graphdb/home/conf/graphdb.properties + fi + + if [[ -f /tmp/graphdb/graphdb-extra-secret.properties ]]; then + echo "##### Overrides from extra secret properties #####" >> /opt/graphdb/home/conf/graphdb.properties + cat /tmp/graphdb/graphdb-extra-secret.properties >> /opt/graphdb/home/conf/graphdb.properties + echo "" >> /opt/graphdb/home/conf/graphdb.properties + fi + + if [[ ! -f /opt/graphdb/home/work/workbench/settings.js && ! -f /opt/graphdb/home/data/users.js && -f /tmp/graphdb/users.js ]]; then + echo "Provisioning users with users.js file..." + cp /tmp/graphdb/users.js /opt/graphdb/home/data/users.js + fi + + if [[ ! -f /opt/graphdb/home/work/workbench/settings.js && ! -f /opt/graphdb/home/data/settings.js && -f /tmp/graphdb/settings.js ]]; then + echo "Provisioning settings with settings.js file..." + cp /tmp/graphdb/settings.js /opt/graphdb/home/data/settings.js + fi + + echo 'Done' + {{- with .Values.extraInitContainers }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: {{ include "graphdb.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- with .Values.command }} + command: {{ toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.args }} + args: {{ toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.containerPorts.http }} + {{- if gt (int (.Values.replicas)) 1 }} + - name: rpc + containerPort: {{ .Values.containerPorts.rpc }} + {{- end }} + {{- with .Values.extraContainerPorts }} + {{- toYaml . | nindent 12 }} + {{- end }} + envFrom: + - configMapRef: + name: {{ include "graphdb.fullname.configmap.environment" . }} + {{- with .Values.extraEnvFrom }} + {{- tpl (toYaml .) $ | nindent 12 }} + {{- end }} + {{- with .Values.extraEnv }} + env: {{- tpl (toYaml .) $ | nindent 12 }} + {{- end }} + volumeMounts: + - name: {{ .Values.persistence.volumeClaimTemplate.name }} + mountPath: /opt/graphdb/home + - name: temp-dir + mountPath: /tmp + {{- if .Values.license.existingSecret }} + - name: graphdb-license + mountPath: /opt/graphdb/home/conf/graphdb.license + subPath: {{ .Values.license.licenseFilename }} + {{- end }} + {{- if .Values.configuration.logback.existingConfigmap }} + - name: graphdb-logback-config + mountPath: /opt/graphdb/home/conf/logback.xml + subPath: {{ .Values.configuration.logback.configmapKey }} + {{- end }} + {{- if .Values.import.volumeMount.enabled }} + - name: {{ .Values.import.volumeMount.volumeClaimTemplate.name }} + mountPath: /opt/graphdb/home/graphdb-import + {{- end }} + {{- with .Values.extraVolumeMounts }} + {{- tpl (toYaml .) $ | nindent 12 }} + {{- end }} + {{- with .Values.resources }} + resources: {{ toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.securityContext }} + securityContext: {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.startupProbe }} + startupProbe: {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.livenessProbe }} + livenessProbe: {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.extraContainers }} + {{ tpl (toYaml .) $ | nindent 8 }} + {{- end }} diff --git a/templates/ingress.yaml b/templates/ingress.yaml new file mode 100644 index 00000000..55588308 --- /dev/null +++ b/templates/ingress.yaml @@ -0,0 +1,52 @@ +{{- if .Values.ingress.enabled }} +{{- $external_url := urlParse (include "graphdb.external-url" .) -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "graphdb.fullname" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + {{- with .Values.ingress.labels }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} + {{- with (mergeOverwrite (deepCopy .Values.annotations) .Values.ingress.annotations) }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +spec: + {{- with .Values.ingress.className }} + ingressClassName: {{ . }} + {{- end }} + {{- if or .Values.ingress.tls.enabled .Values.ingress.extraTLS }} + tls: + {{- if .Values.ingress.tls.enabled }} + - hosts: + - {{ coalesce .Values.ingress.host $external_url.host }} + secretName: {{ required "TLS secret is required!" .Values.ingress.tls.secretName }} + {{- end }} + {{- with .Values.ingress.extraTLS }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} + {{- end }} + rules: + - host: {{ coalesce .Values.ingress.host $external_url.host }} + http: + paths: + - path: {{ coalesce .Values.ingress.path $external_url.path "/" }} + pathType: {{ .Values.ingress.pathType }} + backend: + service: + {{- if gt (int .Values.replicas) 1 }} + name: {{ include "graphdb-proxy.fullname" . }} + port: + number: {{ .Values.proxy.service.ports.http }} + {{- else }} + name: {{ include "graphdb.fullname" . }} + port: + number: {{ .Values.headlessService.ports.http }} + {{- end }} + {{- with .Values.ingress.extraHosts }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +{{- end }} diff --git a/templates/jobs/_labels.tpl b/templates/jobs/_labels.tpl new file mode 100644 index 00000000..1f37db49 --- /dev/null +++ b/templates/jobs/_labels.tpl @@ -0,0 +1,36 @@ +{{/* +Helper functions for labels related to Job and provisioning resources +*/}} + +{{- define "graphdb.fullname.configmap.cluster" -}} + {{- printf "%s-%s" (include "graphdb.fullname" .) "cluster" -}} +{{- end -}} + +{{- define "graphdb.fullname.configmap.utils" -}} + {{- printf "%s-%s" (include "graphdb.fullname" .) "utils" -}} +{{- end -}} + +{{- define "graphdb.fullname.secret.provisioning-user" -}} + {{- printf "%s-%s" (include "graphdb.fullname" .) "provisioning-user" -}} +{{- end -}} + +{{- define "graphdb.fullname.job.create-cluster" -}} + {{- printf "%s-%s" (include "graphdb.fullname" .) "create-cluster" -}} +{{- end -}} + +{{- define "graphdb.fullname.job.patch-cluster" -}} + {{- printf "%s-%s" (include "graphdb.fullname" .) "patch-cluster" -}} +{{- end -}} + +{{- define "graphdb.fullname.job.provision-repositories" -}} + {{- printf "%s-%s" (include "graphdb.fullname" .) "provision-repositories" -}} +{{- end -}} + +{{- define "graphdb.fullname.job.scale-down-cluster" -}} + {{- printf "%s-%s" (include "graphdb.fullname" .) "scale-down-cluster" -}} +{{- end -}} + +{{- define "graphdb.fullname.job.scale-up-cluster" -}} + {{- printf "%s-%s" (include "graphdb.fullname" .) "scale-up-cluster" -}} +{{- end -}} + diff --git a/templates/jobs/configmap-cluster-config.yaml b/templates/jobs/configmap-cluster-config.yaml new file mode 100644 index 00000000..04018646 --- /dev/null +++ b/templates/jobs/configmap-cluster-config.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.cluster.jobs.createCluster.enabled (gt (int .Values.replicas) 1) (not .Values.cluster.config.existingConfigmap) }} +# Default configuration map for provisioning the GraphDB cluster configuration. +# To change it, prepare another configuration map and update "graphdb.configs.clusterConfig" +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "graphdb.fullname.configmap.cluster" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +data: + {{ .Values.cluster.config.configmapKey }}: |- + {{- tpl (.Files.Get "files/config/cluster-config.json" | trim) . | nindent 4 }} +{{- end }} diff --git a/templates/graphdb-utils-configmap.yaml b/templates/jobs/configmap-utils.yaml similarity index 51% rename from templates/graphdb-utils-configmap.yaml rename to templates/jobs/configmap-utils.yaml index fccbaf60..30f54e20 100644 --- a/templates/graphdb-utils-configmap.yaml +++ b/templates/jobs/configmap-utils.yaml @@ -1,16 +1,19 @@ apiVersion: v1 kind: ConfigMap metadata: - name: graphdb-utils-configmap + name: {{ include "graphdb.fullname.configmap.utils" . }} + namespace: {{ include "graphdb.namespace" . }} labels: - name: graphdb-utils-configmap {{- include "graphdb.labels" . | nindent 4 }} annotations: "helm.sh/hook": pre-install, pre-upgrade, pre-rollback, post-install, post-upgrade, post-rollback "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed "helm.sh/hook-weight": "-10" + {{- with .Values.annotations }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} data: graphdb.sh: |- -{{ tpl (.Files.Get "files/scripts/graphdb.sh" | indent 4) . }} + {{- tpl (.Files.Get "files/scripts/graphdb.sh" | trim) . | nindent 4 }} update-cluster.sh: |- -{{ tpl (.Files.Get "files/scripts/update-cluster.sh" | indent 4) . }} + {{- tpl (.Files.Get "files/scripts/update-cluster.sh" | trim) . | nindent 4 }} diff --git a/templates/jobs/job-create-cluster.yaml b/templates/jobs/job-create-cluster.yaml new file mode 100644 index 00000000..7e20dc0c --- /dev/null +++ b/templates/jobs/job-create-cluster.yaml @@ -0,0 +1,76 @@ +{{- if and .Values.cluster.jobs.createCluster.enabled (gt (int .Values.replicas) 1) }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "graphdb.fullname.job.create-cluster" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-install, post-upgrade, post-rollback + "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed + "helm.sh/hook-weight": "-1" + {{- with .Values.annotations }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +spec: + backoffLimit: {{ .Values.jobs.backoffLimit }} + ttlSecondsAfterFinished: {{ .Values.jobs.ttlSecondsAfterFinished }} + template: + spec: + restartPolicy: Never + automountServiceAccountToken: false + {{- if or .Values.global.imagePullSecrets .Values.image.pullSecrets }} + imagePullSecrets: + {{- include "graphdb.combinedImagePullSecrets" . | nindent 8 }} + {{- end }} + {{- with .Values.jobs.podSecurityContext }} + securityContext: {{ toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: job-temp + emptyDir: {{ .Values.jobs.persistence.emptyDir | toYaml | nindent 12 }} + - name: cluster-config + configMap: + name: {{ (tpl .Values.cluster.config.existingConfigmap .) | default (include "graphdb.fullname.configmap.cluster" .) }} + - name: graphdb-utils + configMap: + name: {{ include "graphdb.fullname.configmap.utils" . }} + containers: + - name: create-graphdb-cluster + image: {{ include "graphdb.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: GRAPHDB_POD_NAME + value: {{ include "graphdb.fullname" . }} + - name: GRAPHDB_SERVICE_NAME + value: {{ include "graphdb.fullname.service.headless" . }} + - name: GRAPHDB_SERVICE_PORT + value: {{ .Values.headlessService.ports.http | quote }} + - name: GRAPHDB_AUTH_TOKEN + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.security.provisioner.existingSecret .) | default (include "graphdb.fullname.secret.provisioning-user" .) }} + key: {{ .Values.security.provisioner.tokenKey }} + {{- with .Values.jobs.securityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.jobs.resources }} + resources: {{ toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: job-temp + mountPath: /tmp + - name: graphdb-utils + mountPath: /tmp/utils + - name: cluster-config + mountPath: /tmp/cluster-config/cluster-config.json + subPath: {{ .Values.cluster.config.configmapKey }} + command: ["bash"] + args: + - "/tmp/utils/graphdb.sh" + - createCluster + - "{{ .Values.replicas }}" + - "/tmp/cluster-config/cluster-config.json" + - "{{ .Values.cluster.clusterCreationTimeout }}" +{{- end }} diff --git a/templates/jobs/job-patch-cluster.yaml b/templates/jobs/job-patch-cluster.yaml new file mode 100644 index 00000000..897c300b --- /dev/null +++ b/templates/jobs/job-patch-cluster.yaml @@ -0,0 +1,79 @@ +{{- if and .Values.cluster.jobs.patchCluster.enabled (gt (int .Values.replicas) 1) }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "graphdb.fullname.job.patch-cluster" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-upgrade, post-rollback + "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed + "helm.sh/hook-weight": "2" + {{- with .Values.annotations }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +spec: + backoffLimit: {{ .Values.jobs.backoffLimit }} + ttlSecondsAfterFinished: {{ .Values.jobs.ttlSecondsAfterFinished }} + template: + spec: + restartPolicy: Never + automountServiceAccountToken: false + {{- if or .Values.global.imagePullSecrets .Values.image.pullSecrets }} + imagePullSecrets: + {{- include "graphdb.combinedImagePullSecrets" . | nindent 8 }} + {{- end }} + {{- with .Values.jobs.podSecurityContext }} + securityContext: {{ toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: job-temp + emptyDir: {{ .Values.jobs.persistence.emptyDir | toYaml | nindent 12 }} + - name: cluster-config + configMap: + name: {{ (tpl .Values.cluster.config.existingConfigmap .) | default (printf "%s-cluster" (include "graphdb.fullname" .)) }} + - name: graphdb-utils + configMap: + name: {{ include "graphdb.fullname.configmap.utils" . }} + containers: + - name: patch-cluster + image: {{ include "graphdb.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: GRAPHDB_POD_NAME + value: {{ include "graphdb.fullname" . }} + - name: GRAPHDB_SERVICE_NAME + value: {{ include "graphdb.fullname.service.headless" . }} + - name: GRAPHDB_SERVICE_PORT + value: {{ .Values.headlessService.ports.http | quote }} + - name: GRAPHDB_PROXY_SERVICE_NAME + value: {{ include "graphdb-proxy.fullname" . }} + - name: GRAPHDB_PROXY_SERVICE_PORT + value: {{ .Values.proxy.headlessService.ports.http | quote }} + - name: GRAPHDB_AUTH_TOKEN + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.security.provisioner.existingSecret .) | default (include "graphdb.fullname.secret.provisioning-user" .) }} + key: {{ .Values.security.provisioner.tokenKey }} + {{- with .Values.jobs.securityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.jobs.resources }} + resources: {{ toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: job-temp + mountPath: /tmp + - name: graphdb-utils + mountPath: /tmp/utils + - name: cluster-config + mountPath: /tmp/cluster-config/cluster-config.json + subPath: {{ .Values.cluster.config.configmapKey }} + command: ["bash"] + args: + - "/tmp/utils/update-cluster.sh" + - "patchCluster" + - "/tmp/cluster-config/cluster-config.json" + - "{{ .Values.cluster.clusterCreationTimeout }}" +{{- end }} diff --git a/templates/jobs/job-provision-repositories.yaml b/templates/jobs/job-provision-repositories.yaml new file mode 100644 index 00000000..1762b016 --- /dev/null +++ b/templates/jobs/job-provision-repositories.yaml @@ -0,0 +1,74 @@ +{{- if .Values.repositories.existingConfigmap }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "graphdb.fullname.job.provision-repositories" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-install, post-upgrade, post-rollback + "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed + "helm.sh/hook-weight": "4" + {{- with .Values.annotations }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +spec: + backoffLimit: {{ .Values.jobs.backoffLimit }} + ttlSecondsAfterFinished: {{ .Values.jobs.ttlSecondsAfterFinished }} + template: + spec: + restartPolicy: Never + automountServiceAccountToken: false + {{- if or .Values.global.imagePullSecrets .Values.image.pullSecrets }} + imagePullSecrets: + {{- include "graphdb.combinedImagePullSecrets" . | nindent 8 }} + {{- end }} + {{- with .Values.jobs.podSecurityContext }} + securityContext: {{ toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: job-temp + emptyDir: {{ .Values.jobs.persistence.emptyDir | toYaml | nindent 12 }} + - name: repositories-config + configMap: + name: {{ .Values.repositories.existingConfigmap }} + - name: graphdb-utils + configMap: + name: {{ include "graphdb.fullname.configmap.utils" . }} + containers: + - name: provision-repositories + image: {{ include "graphdb.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: GRAPHDB_POD_NAME + value: {{ include "graphdb.fullname" . }} + - name: GRAPHDB_SERVICE_NAME + value: {{ include "graphdb.fullname.service.headless" . }} + - name: GRAPHDB_SERVICE_PORT + value: {{ .Values.headlessService.ports.http | quote }} + - name: GRAPHDB_AUTH_TOKEN + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.security.provisioner.existingSecret .) | default (include "graphdb.fullname.secret.provisioning-user" .) }} + key: {{ .Values.security.provisioner.tokenKey }} + {{- with .Values.jobs.securityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.jobs.resources }} + resources: {{ toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: job-temp + mountPath: /tmp + - name: graphdb-utils + mountPath: /tmp/utils + - name: repositories-config + mountPath: /tmp/repositories-config + command: ["bash"] + args: + - "/tmp/utils/graphdb.sh" + - "createRepositoryFromFile" + - "{{ .Values.replicas }}" + - "/tmp/repositories-config" +{{- end }} diff --git a/templates/jobs/job-scale-down-cluster.yaml b/templates/jobs/job-scale-down-cluster.yaml new file mode 100644 index 00000000..0476c724 --- /dev/null +++ b/templates/jobs/job-scale-down-cluster.yaml @@ -0,0 +1,73 @@ +{{- if .Values.cluster.jobs.scaleCluster.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "graphdb.fullname.job.scale-down-cluster" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-upgrade, pre-rollback + "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed + {{- with .Values.annotations }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +spec: + backoffLimit: {{ .Values.jobs.backoffLimit }} + ttlSecondsAfterFinished: {{ .Values.jobs.ttlSecondsAfterFinished }} + template: + spec: + restartPolicy: Never + automountServiceAccountToken: false + {{- if or .Values.global.imagePullSecrets .Values.image.pullSecrets }} + imagePullSecrets: + {{- include "graphdb.combinedImagePullSecrets" . | nindent 8 }} + {{- end }} + {{- with .Values.jobs.podSecurityContext }} + securityContext: {{ toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: job-temp + emptyDir: {{ .Values.jobs.persistence.emptyDir | toYaml | nindent 12 }} + - name: graphdb-utils + configMap: + name: {{ include "graphdb.fullname.configmap.utils" . }} + containers: + - name: scale-down-cluster + image: {{ include "graphdb.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: GRAPHDB_POD_NAME + value: {{ include "graphdb.fullname" . }} + - name: GRAPHDB_SERVICE_NAME + value: {{ include "graphdb.fullname.service.headless" . }} + - name: GRAPHDB_SERVICE_PORT + value: {{ .Values.headlessService.ports.http | quote }} + - name: GRAPHDB_SERVICE_RPC_PORT + value: {{ .Values.headlessService.ports.rpc | quote }} + - name: GRAPHDB_PROXY_SERVICE_NAME + value: {{ include "graphdb-proxy.fullname" . }} + - name: GRAPHDB_PROXY_SERVICE_PORT + value: {{ .Values.proxy.headlessService.ports.http | quote }} + - name: GRAPHDB_AUTH_TOKEN + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.security.provisioner.existingSecret .) | default (include "graphdb.fullname.secret.provisioning-user" .) }} + key: {{ .Values.security.provisioner.tokenKey }} + {{- with .Values.jobs.securityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.jobs.resources }} + resources: {{ toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: job-temp + mountPath: /tmp + - name: graphdb-utils + mountPath: /tmp/utils + command: ["bash"] + args: + - "/tmp/utils/update-cluster.sh" + - "removeNodes" + - "{{ .Values.replicas }}" +{{- end }} diff --git a/templates/jobs/job-scale-up-cluster.yaml b/templates/jobs/job-scale-up-cluster.yaml new file mode 100644 index 00000000..693b05d7 --- /dev/null +++ b/templates/jobs/job-scale-up-cluster.yaml @@ -0,0 +1,75 @@ +{{- if and .Values.cluster.jobs.scaleCluster.enabled (gt (int .Values.replicas) 1) }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "graphdb.fullname.job.scale-up-cluster" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-upgrade, post-rollback + "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed + "helm.sh/hook-weight": "1" + {{- with .Values.annotations }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +spec: + backoffLimit: {{ .Values.jobs.backoffLimit }} + ttlSecondsAfterFinished: {{ .Values.jobs.ttlSecondsAfterFinished }} + template: + spec: + restartPolicy: Never + automountServiceAccountToken: false + {{- if or .Values.global.imagePullSecrets .Values.image.pullSecrets }} + imagePullSecrets: + {{- include "graphdb.combinedImagePullSecrets" . | nindent 8 }} + {{- end }} + {{- with .Values.jobs.podSecurityContext }} + securityContext: {{ toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: job-temp + emptyDir: {{ .Values.jobs.persistence.emptyDir | toYaml | nindent 12 }} + - name: graphdb-utils + configMap: + name: {{ include "graphdb.fullname.configmap.utils" . }} + containers: + - name: scale-up-cluster + image: {{ include "graphdb.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: GRAPHDB_POD_NAME + value: {{ include "graphdb.fullname" . }} + - name: GRAPHDB_SERVICE_NAME + value: {{ include "graphdb.fullname.service.headless" . }} + - name: GRAPHDB_SERVICE_PORT + value: {{ .Values.headlessService.ports.http | quote }} + - name: GRAPHDB_SERVICE_RPC_PORT + value: {{ .Values.headlessService.ports.rpc | quote }} + - name: GRAPHDB_PROXY_SERVICE_NAME + value: {{ include "graphdb-proxy.fullname" . }} + - name: GRAPHDB_PROXY_SERVICE_PORT + value: {{ .Values.proxy.headlessService.ports.http | quote }} + - name: GRAPHDB_AUTH_TOKEN + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.security.provisioner.existingSecret .) | default (include "graphdb.fullname.secret.provisioning-user" .) }} + key: {{ .Values.security.provisioner.tokenKey }} + {{- with .Values.jobs.securityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.jobs.resources }} + resources: {{ toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: job-temp + mountPath: /tmp + - name: graphdb-utils + mountPath: /tmp/utils + command: ["bash"] + args: + - "/tmp/utils/update-cluster.sh" + - "addNodes" + - "{{ .Values.replicas }}" + - "{{ .Values.cluster.clusterCreationTimeout }}" +{{- end }} diff --git a/templates/jobs/patch-cluster-job.yaml b/templates/jobs/patch-cluster-job.yaml deleted file mode 100644 index f0a93b10..00000000 --- a/templates/jobs/patch-cluster-job.yaml +++ /dev/null @@ -1,55 +0,0 @@ -{{- if gt (int .Values.graphdb.clusterConfig.nodesCount) 1 }} -apiVersion: batch/v1 -kind: Job -metadata: - name: patch-cluster-job - labels: - {{- include "graphdb.labels" . | nindent 4 }} - annotations: - "helm.sh/hook": post-upgrade, post-rollback - "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed - "helm.sh/hook-weight": "2" -spec: - ttlSecondsAfterFinished: 300 - backoffLimit: 4 - template: - spec: - restartPolicy: Never - imagePullSecrets: - {{- include "graphdb.combinedImagePullSecrets" $ | nindent 8 }} - securityContext: - {{- $.Values.graphdb.jobPodSecurityContext | toYaml | nindent 8 }} - containers: - - name: patch-cluster - image: {{ include "graphdb.image" . }} - envFrom: - - secretRef: - name: graphdb-provision-user - securityContext: {{- $.Values.graphdb.jobSecurityContext | toYaml | nindent 12 }} - {{- with .Values.graphdb.jobResources }} - resources: {{ toYaml . | nindent 12 }} - {{- end }} - volumeMounts: - - name: job-temp - mountPath: /tmp - - name: graphdb-utils - mountPath: /tmp/utils - - name: cluster-config - mountPath: /tmp/cluster-config - command: ['bash'] - args: - - "/tmp/utils/update-cluster.sh" - - "patchCluster" - - "/tmp/cluster-config/cluster-config.json" - - "{{ .Values.graphdb.clusterConfig.clusterCreationTimeout }}" - volumes: - - name: job-temp - emptyDir: - sizeLimit: 10Mi - - name: cluster-config - configMap: - name: {{ .Values.graphdb.clusterConfig.existingClusterConfig | default "graphdb-cluster-config-configmap" }} - - name: graphdb-utils - configMap: - name: graphdb-utils-configmap -{{- end }} diff --git a/templates/jobs/post-start-job.yaml b/templates/jobs/post-start-job.yaml deleted file mode 100644 index cfd88861..00000000 --- a/templates/jobs/post-start-job.yaml +++ /dev/null @@ -1,56 +0,0 @@ -{{- if gt (int .Values.graphdb.clusterConfig.nodesCount) 1 }} -apiVersion: batch/v1 -kind: Job -metadata: - name: create-graphdb-cluster-job - labels: - {{- include "graphdb.labels" . | nindent 4 }} - annotations: - "helm.sh/hook": post-install, post-upgrade, post-rollback - "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed - "helm.sh/hook-weight": "-1" -spec: - ttlSecondsAfterFinished: 300 - backoffLimit: 9 - template: - spec: - restartPolicy: Never - imagePullSecrets: - {{- include "graphdb.combinedImagePullSecrets" $ | nindent 8 }} - securityContext: - {{- $.Values.graphdb.jobPodSecurityContext | toYaml | nindent 8 }} - containers: - - name: create-graphdb-cluster - image: {{ include "graphdb.image" . }} - envFrom: - - secretRef: - name: graphdb-provision-user - securityContext: {{- $.Values.graphdb.jobSecurityContext | toYaml | nindent 12 }} - {{- with .Values.graphdb.jobResources }} - resources: {{ toYaml . | nindent 12 }} - {{- end }} - volumeMounts: - - name: job-temp - mountPath: /tmp - - name: graphdb-utils - mountPath: /tmp/utils - - name: cluster-config - mountPath: /tmp/cluster-config - command: ['bash'] - args: - - "/tmp/utils/graphdb.sh" - - createCluster - - "{{ .Values.graphdb.clusterConfig.nodesCount }}" - - "/tmp/cluster-config/cluster-config.json" - - "{{ .Values.graphdb.clusterConfig.clusterCreationTimeout }}" - volumes: - - name: job-temp - emptyDir: - sizeLimit: 10Mi - - name: cluster-config - configMap: - name: {{ .Values.graphdb.clusterConfig.existingClusterConfig | default "graphdb-cluster-config-configmap" }} - - name: graphdb-utils - configMap: - name: graphdb-utils-configmap -{{- end }} diff --git a/templates/jobs/provision-repositories-job.yaml b/templates/jobs/provision-repositories-job.yaml deleted file mode 100644 index ed7cfc69..00000000 --- a/templates/jobs/provision-repositories-job.yaml +++ /dev/null @@ -1,56 +0,0 @@ -{{- $configs := (.Values.graphdb.configs | default dict) }} -{{- if $configs.provisionRepositoriesConfigMap }} -apiVersion: batch/v1 -kind: Job -metadata: - name: provision-repositories-job - labels: - {{- include "graphdb.labels" . | nindent 4 }} - annotations: - "helm.sh/hook": post-install, post-upgrade, post-rollback - "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed - "helm.sh/hook-weight": "4" -spec: - ttlSecondsAfterFinished: 300 - backoffLimit: 3 - template: - spec: - restartPolicy: Never - imagePullSecrets: - {{- include "graphdb.combinedImagePullSecrets" $ | nindent 8 }} - securityContext: - {{- $.Values.graphdb.jobPodSecurityContext | toYaml | nindent 8 }} - containers: - - name: provision-repositories - image: {{ include "graphdb.image" . }} - envFrom: - - secretRef: - name: graphdb-provision-user - securityContext: {{- $.Values.graphdb.jobSecurityContext | toYaml | nindent 12 }} - {{- with .Values.graphdb.jobResources }} - resources: {{ toYaml . | nindent 12 }} - {{- end }} - volumeMounts: - - name: job-temp - mountPath: /tmp - - name: graphdb-utils - mountPath: /tmp/utils - - name: repositories-config - mountPath: /tmp/repositories-config - command: ['bash'] - args: - - "/tmp/utils/graphdb.sh" - - "createRepositoryFromFile" - - "{{ .Values.graphdb.clusterConfig.nodesCount }}" - - "/tmp/repositories-config" - volumes: - - name: job-temp - emptyDir: - sizeLimit: 10Mi - - name: repositories-config - configMap: - name: {{ .Values.graphdb.configs.provisionRepositoriesConfigMap }} - - name: graphdb-utils - configMap: - name: graphdb-utils-configmap -{{- end }} diff --git a/templates/jobs/scale-down-cluster-job.yaml b/templates/jobs/scale-down-cluster-job.yaml deleted file mode 100644 index f7fe85b7..00000000 --- a/templates/jobs/scale-down-cluster-job.yaml +++ /dev/null @@ -1,47 +0,0 @@ -apiVersion: batch/v1 -kind: Job -metadata: - name: scale-down-cluster-job - labels: - {{- include "graphdb.labels" . | nindent 4 }} - annotations: - "helm.sh/hook": pre-upgrade, pre-rollback - "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed -spec: - ttlSecondsAfterFinished: 300 - backoffLimit: 4 - template: - spec: - restartPolicy: Never - imagePullSecrets: - {{- include "graphdb.combinedImagePullSecrets" $ | nindent 8 }} - securityContext: - {{- $.Values.graphdb.jobPodSecurityContext | toYaml | nindent 8 }} - containers: - - name: scale-down-cluster - image: {{ include "graphdb.image" . }} - envFrom: - - secretRef: - name: graphdb-provision-user - securityContext: {{- $.Values.graphdb.jobSecurityContext | toYaml | nindent 12 }} - {{- with .Values.graphdb.jobResources }} - resources: {{ toYaml . | nindent 12 }} - {{- end }} - volumeMounts: - - name: job-temp - mountPath: /tmp - - name: graphdb-utils - mountPath: /tmp/utils - command: ['bash'] - args: - - "/tmp/utils/update-cluster.sh" - - "removeNodes" - - "{{ .Values.graphdb.clusterConfig.nodesCount }}" - - "{{ $.Release.Namespace }}" - volumes: - - name: job-temp - emptyDir: - sizeLimit: 10Mi - - name: graphdb-utils - configMap: - name: graphdb-utils-configmap diff --git a/templates/jobs/scale-up-cluster-job.yaml b/templates/jobs/scale-up-cluster-job.yaml deleted file mode 100644 index 76d4aab3..00000000 --- a/templates/jobs/scale-up-cluster-job.yaml +++ /dev/null @@ -1,51 +0,0 @@ -{{- if gt (int .Values.graphdb.clusterConfig.nodesCount) 1 }} -apiVersion: batch/v1 -kind: Job -metadata: - name: scale-up-cluster-job - labels: - {{- include "graphdb.labels" . | nindent 4 }} - annotations: - "helm.sh/hook": post-upgrade, post-rollback - "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed - "helm.sh/hook-weight": "1" -spec: - ttlSecondsAfterFinished: 300 - backoffLimit: 4 - template: - spec: - restartPolicy: Never - imagePullSecrets: - {{- include "graphdb.combinedImagePullSecrets" $ | nindent 8 }} - securityContext: - {{- $.Values.graphdb.jobPodSecurityContext | toYaml | nindent 8 }} - containers: - - name: scale-up-cluster - image: {{ include "graphdb.image" . }} - envFrom: - - secretRef: - name: graphdb-provision-user - securityContext: {{- $.Values.graphdb.jobSecurityContext | toYaml | nindent 12 }} - {{- with .Values.graphdb.jobResources }} - resources: {{ toYaml . | nindent 12 }} - {{- end }} - volumeMounts: - - name: job-temp - mountPath: /tmp - - name: graphdb-utils - mountPath: /tmp/utils - command: ['bash'] - args: - - "/tmp/utils/update-cluster.sh" - - "addNodes" - - "{{ .Values.graphdb.clusterConfig.nodesCount }}" - - "{{ $.Release.Namespace }}" - - "{{ .Values.graphdb.clusterConfig.clusterCreationTimeout }}" - volumes: - - name: job-temp - emptyDir: - sizeLimit: 10Mi - - name: graphdb-utils - configMap: - name: graphdb-utils-configmap -{{- end }} diff --git a/templates/jobs/secret-provision-user.yaml b/templates/jobs/secret-provision-user.yaml new file mode 100644 index 00000000..a273382d --- /dev/null +++ b/templates/jobs/secret-provision-user.yaml @@ -0,0 +1,21 @@ +{{- if not .Values.security.provisioner.existingSecret }} +# Secret used from the jobs to authenticate to running GraphDB instances +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "graphdb.fullname.secret.provisioning-user" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install, pre-upgrade, pre-rollback, post-install, post-upgrade, post-rollback + "helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed + "helm.sh/hook-weight": "-9" + {{- with .Values.annotations }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +type: Opaque +data: + {{ .Values.security.provisioner.tokenKey }}: {{ printf "%s:%s" .Values.security.provisioner.username .Values.security.provisioner.password | b64enc | b64enc | quote }} +{{- end }} diff --git a/templates/proxy/_labels.tpl b/templates/proxy/_labels.tpl new file mode 100644 index 00000000..2ac56169 --- /dev/null +++ b/templates/proxy/_labels.tpl @@ -0,0 +1,73 @@ +{{/* +Creates another chart name for the proxy service to distinguish it from GraphDB. +*/}} +{{- define "graphdb-proxy.chartName" -}} +{{- printf "%s-proxy" .Chart.Name -}} +{{- end }} + +{{/* +Expand the name of the proxy service. +*/}} +{{- define "graphdb-proxy.name" -}} +{{- default (include "graphdb-proxy.chartName" .) .Values.proxy.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name for the proxy service. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "graphdb-proxy.fullname" -}} +{{- if .Values.proxy.fullnameOverride }} +{{- .Values.proxy.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default (include "graphdb-proxy.chartName" .) .Values.proxy.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Common labels for the proxy service. +*/}} +{{- define "graphdb-proxy.labels" -}} +helm.sh/chart: {{ include "graphdb.chart" . }} +{{ include "graphdb-proxy.selectorLabels" . }} +app.kubernetes.io/version: {{ coalesce .Values.image.tag .Chart.AppVersion | quote }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: graphdb-proxy +app.kubernetes.io/part-of: graphdb +{{- if .Values.labels }} +{{ tpl (toYaml .Values.labels) . }} +{{- end }} +{{- if .Values.proxy.labels }} +{{ tpl (toYaml .Values.proxy.labels) . }} +{{- end }} +{{- end }} + +{{/* +Selector labels for the proxy service. +*/}} +{{- define "graphdb-proxy.selectorLabels" -}} +app.kubernetes.io/name: {{ include "graphdb-proxy.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{- define "graphdb-proxy.fullname.configmap.environment" -}} + {{- printf "%s-%s" (include "graphdb-proxy.fullname" .) "environment" -}} +{{- end -}} + +{{- define "graphdb-proxy.fullname.configmap.properties" -}} + {{- printf "%s-%s" (include "graphdb-proxy.fullname" .) "properties" -}} +{{- end -}} + +{{- define "graphdb-proxy.fullname.secret.properties" -}} + {{- printf "%s-%s" (include "graphdb-proxy.fullname" .) "properties" -}} +{{- end -}} + +{{- define "graphdb-proxy.fullname.service.headless" -}} + {{- printf "%s-%s" (include "graphdb-proxy.fullname" .) "headless" -}} +{{- end -}} diff --git a/templates/proxy/configmap-environment.yaml b/templates/proxy/configmap-environment.yaml new file mode 100644 index 00000000..ffb1d159 --- /dev/null +++ b/templates/proxy/configmap-environment.yaml @@ -0,0 +1,19 @@ +{{- if gt (int .Values.replicas) 1 }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "graphdb-proxy.fullname.configmap.environment" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb-proxy.labels" . | nindent 4 }} + {{- with (mergeOverwrite (deepCopy .Values.annotations) .Values.proxy.annotations) }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +data: + GDB_JAVA_OPTS: >- + -Dgraphdb.home=/opt/graphdb/home + -Dhttp.socket.keepalive=true + {{ tpl .Values.proxy.configuration.defaultJavaArguments . }} + {{ tpl .Values.proxy.configuration.javaArguments . }} +{{- end }} diff --git a/templates/proxy/configmap-properties.yaml b/templates/proxy/configmap-properties.yaml new file mode 100644 index 00000000..8f572855 --- /dev/null +++ b/templates/proxy/configmap-properties.yaml @@ -0,0 +1,27 @@ +{{- if gt (int .Values.replicas) 1 }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "graphdb-proxy.fullname.configmap.properties" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb-proxy.labels" . | nindent 4 }} + {{- with (mergeOverwrite (deepCopy .Values.annotations) .Values.proxy.annotations) }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +data: + graphdb.properties: |- + ##### GraphDB configurations ##### + # See https://graphdb.ontotext.com/documentation/ for supported properties + graphdb.connector.port={{ .Values.proxy.containerPorts.http }} + graphdb.proxy.hosts={{ include "graphdb-proxy.cluster.nodes" . }} + {{- if .Values.proxy.configuration.properties }} + ##### Overrides from values.yaml ##### + {{- range $key, $val := .Values.proxy.configuration.properties -}} + {{- if ne $val nil }} + {{ $key }}={{ tpl ($val | toString) $ | quote }} + {{- end }} + {{- end -}} + {{- end -}} +{{- end }} diff --git a/templates/proxy/pdb.yaml b/templates/proxy/pdb.yaml new file mode 100644 index 00000000..933acd20 --- /dev/null +++ b/templates/proxy/pdb.yaml @@ -0,0 +1,23 @@ +{{- if .Values.proxy.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "graphdb-proxy.fullname" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb-proxy.labels" . | nindent 4 }} + {{- with (mergeOverwrite (deepCopy .Values.annotations) .Values.proxy.annotations) }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +spec: + {{- if .Values.proxy.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.proxy.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.proxy.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.proxy.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "graphdb-proxy.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/templates/proxy/secret-properties.yaml b/templates/proxy/secret-properties.yaml new file mode 100644 index 00000000..f2c079c5 --- /dev/null +++ b/templates/proxy/secret-properties.yaml @@ -0,0 +1,28 @@ +{{- if gt (int .Values.replicas) 1 }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "graphdb-proxy.fullname.secret.properties" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb-proxy.labels" . | nindent 4 }} + {{- with (mergeOverwrite (deepCopy .Values.annotations) .Values.proxy.annotations) }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +type: Opaque +stringData: + graphdb-secrets.properties: |- + ##### GraphDB sensitive configurations ##### + {{- if not .Values.cluster.token.existingSecret }} + graphdb.auth.token.secret={{ .Values.cluster.token.secret | quote }} + {{- end }} + {{- if .Values.proxy.configuration.secretProperties }} + ##### Secrets overrides from values.yaml ##### + {{- range $key, $val := .Values.proxy.configuration.secretProperties -}} + {{- if ne $val nil }} + {{ $key }}={{ tpl ($val | toString) $ | quote }} + {{- end }} + {{- end -}} + {{- end -}} +{{- end }} diff --git a/templates/proxy/service-headless.yaml b/templates/proxy/service-headless.yaml new file mode 100644 index 00000000..f6b080d0 --- /dev/null +++ b/templates/proxy/service-headless.yaml @@ -0,0 +1,32 @@ +{{- if and .Values.proxy.headlessService.enabled (gt (int .Values.replicas) 1) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "graphdb-proxy.fullname.service.headless" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb-proxy.labels" . | nindent 4 }} + {{- with .Values.proxy.headlessService.labels }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} + {{- with (mergeOverwrite (deepCopy .Values.annotations) .Values.proxy.annotations .Values.proxy.headlessService.annotations) }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +spec: + clusterIP: None + selector: + {{- include "graphdb-proxy.selectorLabels" . | nindent 4 }} + ports: + - name: http + port: {{ .Values.proxy.headlessService.ports.http }} + targetPort: http + protocol: TCP + - name: rpc + port: {{ .Values.proxy.headlessService.ports.rpc }} + targetPort: rpc + protocol: TCP + {{- with .Values.proxy.headlessService.extraPorts -}} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/templates/proxy/service.yaml b/templates/proxy/service.yaml new file mode 100644 index 00000000..cb62b511 --- /dev/null +++ b/templates/proxy/service.yaml @@ -0,0 +1,46 @@ +{{- if and .Values.proxy.service.enabled (gt (int .Values.replicas) 1) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "graphdb-proxy.fullname" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb-proxy.labels" . | nindent 4 }} + {{- with .Values.proxy.service.labels }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} + {{- with (mergeOverwrite (deepCopy .Values.annotations) .Values.proxy.annotations .Values.proxy.service.annotations) }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.proxy.service.type }} + selector: + {{- include "graphdb-proxy.selectorLabels" . | nindent 4 }} + {{- if .Values.proxy.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.proxy.service.externalTrafficPolicy }} + {{- end }} + {{- if .Values.proxy.service.healthCheckNodePort }} + healthCheckNodePort: {{ .Values.proxy.service.healthCheckNodePort }} + {{- end }} + {{- if .Values.proxy.service.loadBalancerClass }} + loadBalancerClass: {{ .Values.proxy.service.loadBalancerClass }} + {{- end }} + {{- if .Values.proxy.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{ .Values.proxy.service.loadBalancerSourceRanges | toYaml | nindent 4 }} + {{- end }} + {{- if .Values.proxy.service.externalIPs }} + externalIPs: {{ .Values.proxy.service.externalIPs | toYaml | nindent 4 }} + {{- end }} + ports: + - name: http + port: {{ .Values.proxy.service.ports.http }} + targetPort: http + protocol: TCP + {{- if .Values.proxy.service.nodePort }} + nodePort: {{ .Values.proxy.service.nodePort }} + {{- end }} + {{- with .Values.proxy.service.extraPorts -}} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/templates/proxy/statefulset.yaml b/templates/proxy/statefulset.yaml new file mode 100644 index 00000000..dd553a4a --- /dev/null +++ b/templates/proxy/statefulset.yaml @@ -0,0 +1,292 @@ +{{- if gt (int .Values.replicas) 1 }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "graphdb-proxy.fullname" . }} + namespace: {{ include "graphdb.namespace" . }} + labels: + {{- include "graphdb-proxy.labels" . | nindent 4 }} + {{- with (mergeOverwrite (deepCopy .Values.annotations) .Values.proxy.annotations) }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.proxy.replicas }} + serviceName: {{ include "graphdb-proxy.fullname.service.headless" . }} + updateStrategy: {{ .Values.proxy.updateStrategy | toYaml | nindent 4 }} + podManagementPolicy: {{ .Values.proxy.podManagementPolicy }} + revisionHistoryLimit: {{ .Values.proxy.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "graphdb-proxy.selectorLabels" . | nindent 6 }} + {{- if or .Values.proxy.persistence.enabled .Values.proxy.extraVolumeClaimTemplates }} + volumeClaimTemplates: + {{- if .Values.proxy.persistence.enabled }} + - metadata: + name: {{ .Values.proxy.persistence.volumeClaimTemplate.name }} + {{- with .Values.proxy.persistence.volumeClaimTemplate.labels }} + labels: {{ tpl (toYaml .) $ | nindent 10 }} + {{- end }} + {{- with .Values.proxy.persistence.volumeClaimTemplate.annotations }} + annotations: {{ tpl (toYaml .) $ | nindent 10 }} + {{- end }} + spec: + {{- toYaml .Values.proxy.persistence.volumeClaimTemplate.spec | nindent 8 }} + {{- end }} + {{- if .Values.proxy.extraVolumeClaimTemplates }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} + {{- end }} + template: + metadata: + labels: + {{- include "graphdb-proxy.selectorLabels" . | nindent 8 }} + {{- with .Values.proxy.podLabels }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + annotations: + checksum/configmap-environment: {{ include (print .Template.BasePath "/proxy/configmap-environment.yaml") . | sha256sum }} + checksum/configmap-properties: {{ include (print .Template.BasePath "/proxy/configmap-properties.yaml") . | sha256sum }} + checksum/secret-properties: {{ include (print .Template.BasePath "/proxy/secret-properties.yaml") . | sha256sum }} + {{- with .Values.proxy.podAnnotations }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + spec: + terminationGracePeriodSeconds: {{ .Values.proxy.terminationGracePeriodSeconds }} + automountServiceAccountToken: false + {{- if .Values.proxy.schedulerName }} + schedulerName: {{ .Values.proxy.schedulerName }} + {{- end }} + {{- with .Values.proxy.dnsConfig }} + dnsConfig: {{ toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.proxy.dnsPolicy }} + dnsPolicy: {{ .Values.proxy.dnsPolicy }} + {{- end }} + {{- if .Values.proxy.priorityClassName }} + priorityClassName: {{ .Values.proxy.priorityClassName }} + {{- end }} + volumes: + {{- if not .Values.proxy.persistence.enabled }} + - name: {{ .Values.proxy.persistence.volumeClaimTemplate.name }} + emptyDir: {{ .Values.proxy.persistence.emptyDir | toYaml | nindent 12 }} + {{- end }} + - name: graphdb-proxy-properties + configMap: + name: {{ include "graphdb-proxy.fullname.configmap.properties" . }} + - name: graphdb-proxy-secret-properties + secret: + secretName: {{ include "graphdb-proxy.fullname.secret.properties" . }} + {{- if .Values.proxy.configuration.extraProperties.existingConfigmap }} + - name: graphdb-proxy-extra-properties + configMap: + name: {{ tpl .Values.proxy.configuration.extraProperties.existingConfigmap . }} + {{- end }} + {{- if .Values.proxy.configuration.extraProperties.existingSecret }} + - name: graphdb-proxy-extra-secret-properties + secret: + secretName: {{ tpl .Values.proxy.configuration.extraProperties.existingSecret . }} + {{- end }} + {{- if .Values.proxy.configuration.logback.existingConfigmap }} + - name: graphdb-proxy-logback-config + configMap: + name: {{ tpl .Values.proxy.configuration.logback.existingConfigmap . }} + {{- end }} + {{- with .Values.proxy.extraVolumes }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.proxy.nodeSelector }} + nodeSelector: {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.proxy.affinity }} + affinity: {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.proxy.tolerations }} + tolerations: {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.proxy.topologySpreadConstraints }} + topologySpreadConstraints: {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.proxy.podSecurityContext }} + securityContext: {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.global.imagePullSecrets .Values.image.pullSecrets }} + imagePullSecrets: + {{- include "graphdb.combinedImagePullSecrets" . | nindent 8 }} + {{- end }} + initContainers: + {{- if and .Values.proxy.persistence.enabled .Values.proxy.initContainerDataPermissions.enabled }} + # Fixes the permissions in the storage volume to match the security context settings + - name: {{ .Chart.Name }}-fix-permissions + image: {{ include "graphdb.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: GRAPHDB_USER_ID + value: {{ coalesce .Values.proxy.securityContext.runAsUser .Values.proxy.podSecurityContext.runAsUser | quote }} + - name: GRAPHDB_GROUP_ID + value: {{ coalesce .Values.proxy.securityContext.runAsGroup .Values.proxy.podSecurityContext.runAsGroup | quote }} + volumeMounts: + - name: {{ .Values.proxy.persistence.volumeClaimTemplate.name }} + mountPath: /opt/graphdb/home + {{- with .Values.proxy.initContainerResources }} + resources: {{ toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.proxy.initContainerDataPermissions.securityContext }} + securityContext: {{- toYaml . | nindent 12 }} + {{- end }} + command: [ "bash", "-c" ] + args: + - | + set -eu + echo "Changing ownership to ${GRAPHDB_USER_ID}:${GRAPHDB_GROUP_ID}" + chown -R ${GRAPHDB_USER_ID}:${GRAPHDB_GROUP_ID} /opt/graphdb/home + {{- end }} + - name: {{ include "graphdb-proxy.chartName" . }}-provision-settings + image: {{ include "graphdb.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: GRAPHDB_PUBLIC_URL + value: {{ include "graphdb.external-url" . }} + - name: GRAPHDB_PROXY_HTTP_PORT + value: {{ .Values.proxy.containerPorts.http | quote }} + - name: GRAPHDB_PROXY_RPC_PORT + value: {{ .Values.proxy.containerPorts.rpc | quote }} + {{- if .Values.cluster.token.existingSecret }} + - name: GRAPHDB_CLUSTER_SECRET + valueFrom: + secretKeyRef: + name: {{ .Values.cluster.token.existingSecret }} + key: {{ .Values.cluster.token.secretKey }} + {{- end }} + {{- with .Values.proxy.initContainerSecurityContext }} + securityContext: {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.proxy.initContainerResources }} + resources: {{ toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: {{ .Values.proxy.persistence.volumeClaimTemplate.name }} + mountPath: /opt/graphdb/home + - name: graphdb-proxy-properties + mountPath: /tmp/graphdb.properties + subPath: graphdb.properties + - name: graphdb-proxy-secret-properties + mountPath: /tmp/graphdb/graphdb-secrets.properties + subPath: graphdb-secrets.properties + {{- if .Values.proxy.configuration.extraProperties.existingConfigmap }} + - name: graphdb-proxy-extra-properties + mountPath: /tmp/graphdb/graphdb-extra.properties + subPath: {{ .Values.proxy.configuration.extraProperties.configmapKey }} + {{- end }} + {{- if .Values.proxy.configuration.extraProperties.existingSecret }} + - name: graphdb-proxy-extra-secret-properties + mountPath: /tmp/graphdb/graphdb-extra-secret.properties + subPath: {{ .Values.proxy.configuration.extraProperties.secretKey }} + {{- end }} + command: [ "bash", "-c" ] + args: + - | + set -eu + set +x + mkdir -p /opt/graphdb/home/conf/ + + echo 'Configuring graphdb.properties' + echo "" > /opt/graphdb/home/conf/graphdb.properties + + echo 'Configuring GraphDB cluster proxy hostnames' + cat << EOF >> /opt/graphdb/home/conf/graphdb.properties + ##### Configurations from initContainer ##### + graphdb.hostname=$(hostname --fqdn) + graphdb.rpc.address=$(hostname --fqdn):${GRAPHDB_PROXY_RPC_PORT} + graphdb.vhosts=$(hostname --fqdn):${GRAPHDB_PROXY_HTTP_PORT}, ${GRAPHDB_PUBLIC_URL} + graphdb.external-url=${GRAPHDB_PUBLIC_URL} + EOF + echo "" >> /opt/graphdb/home/conf/graphdb.properties + + cat /tmp/graphdb.properties >> /opt/graphdb/home/conf/graphdb.properties + echo "" >> /opt/graphdb/home/conf/graphdb.properties + + cat /tmp/graphdb/graphdb-secrets.properties >> /opt/graphdb/home/conf/graphdb.properties + echo "" >> /opt/graphdb/home/conf/graphdb.properties + + if [[ -n ${GRAPHDB_CLUSTER_SECRET:-""} ]]; then + echo "##### Override from existing cluster secret #####" >> /opt/graphdb/home/conf/graphdb.properties + (echo "graphdb.auth.token.secret=${GRAPHDB_CLUSTER_SECRET}" >> /opt/graphdb/home/conf/graphdb.properties) >/dev/null 2>&1 + echo "" >> /opt/graphdb/home/conf/graphdb.properties + fi + + if [[ -f /tmp/graphdb/graphdb-extra.properties ]]; then + echo "##### Overrides from extra properties configmap #####" >> /opt/graphdb/home/conf/graphdb.properties + cat /tmp/graphdb/graphdb-extra.properties >> /opt/graphdb/home/conf/graphdb.properties + echo "" >> /opt/graphdb/home/conf/graphdb.properties + fi + + if [[ -f /tmp/graphdb/graphdb-extra-secret.properties ]]; then + echo "##### Overrides from extra secret properties #####" >> /opt/graphdb/home/conf/graphdb.properties + cat /tmp/graphdb/graphdb-extra-secret.properties >> /opt/graphdb/home/conf/graphdb.properties + echo "" >> /opt/graphdb/home/conf/graphdb.properties + fi + + echo 'Done' + {{- with .Values.proxy.extraInitContainers }} + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ include "graphdb-proxy.chartName" . }} + image: {{ include "graphdb.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.proxy.command }} + command: {{ toYaml .Values.proxy.command | nindent 12 }} + {{- else }} + command: ["/opt/graphdb/dist/bin/cluster-proxy"] + {{- end }} + {{- with .Values.proxy.args }} + args: {{ toYaml . | nindent 12 }} + {{- end }} + envFrom: + - configMapRef: + name: {{ include "graphdb-proxy.fullname.configmap.environment" . }} + {{- with .Values.proxy.extraEnvFrom }} + {{- tpl (toYaml .) $ | nindent 12 }} + {{- end }} + {{- with .Values.proxy.extraEnv }} + env: {{- tpl (toYaml .) $ | nindent 12 }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.proxy.containerPorts.http }} + - name: rpc + containerPort: {{ .Values.proxy.containerPorts.rpc }} + {{- with .Values.proxy.extraContainerPorts }} + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: {{ .Values.proxy.persistence.volumeClaimTemplate.name }} + mountPath: /opt/graphdb/home + {{- if .Values.proxy.configuration.logback.existingConfigmap }} + - name: graphdb-proxy-logback-config + mountPath: /opt/graphdb/home/conf/logback.xml + subPath: {{ .Values.proxy.configuration.logback.configmapKey }} + {{- end }} + {{- with .Values.proxy.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.proxy.resources }} + resources: {{ toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.proxy.securityContext }} + securityContext: {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.proxy.startupProbe }} + startupProbe: {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.proxy.readinessProbe }} + readinessProbe: {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.proxy.livenessProbe }} + livenessProbe: {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.proxy.extraContainers }} + {{ tpl (toYaml .) $ | nindent 8 }} + {{- end }} +{{- end }} diff --git a/values.yaml b/values.yaml index 7e841fb5..f6bb71da 100644 --- a/values.yaml +++ b/values.yaml @@ -1,325 +1,1328 @@ -# -# Main configuration file -# -# To override single property use --set -# To override multiple, provide another values-override.yaml with the -f flag -# See https://helm.sh/docs/chart_template_guide/values_files/ +############################################################################### +# Main configuration file # +# To override single property use --set # +# To override multiple, provide another values-override.yaml with the -f flag # +# See https://helm.sh/docs/chart_template_guide/values_files/ # +############################################################################### + +######################### +# Global Configurations # +######################### global: + # Overrides image.registry + # Can be used to override it globally when using umbrella charts. + imageRegistry: "" + + # Inserts additional pull secret references together along with any from .Values.image.pullSecrets + # Can be used to override it globally when using umbrella charts. + # Values are processed as Helm templates. + # Ref: https://kubernetes.io/docs/concepts/configuration/secret/#using-imagepullsecrets + # + # Example: + # imagePullSecrets: + # - name: my-pull-secret imagePullSecrets: [] - storageClass: "standard" - imageRegistry: docker.io - -# Top lvl flat for easier maintenance -images: - graphdb: - registry: docker.io - repository: ontotext/graphdb - # If specified, overrides Chart.AppVersion - tag: "" - busybox: - repository: busybox - tag: "1.36.1" - -# Extra labels for the deployed resources -extraLabels: {} - -####### DEPLOYMENT CONFIGURATIONS ####### -deployment: - # -- Defines the policy with which components will request their image. - imagePullPolicy: IfNotPresent - # Secret used to pull Docker images. Uncomment to use it. - # Important: Must be created beforehand - # imagePullSecret: ontotext - - # -- The hostname and protocol at which the graphdb will be accessible. - # Needed to configure ingress as well as some components require it to properly render their UIs - protocol: http - # Important: This should be a resolvable hostname, not an IP address! - host: localhost - - # Configures SSL termination on ingress level. - # See https://kubernetes.github.io/ingress-nginx/examples/tls-termination/ + + # The default domain suffix of the Kubernetes cluster + # Ref: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/ + clusterDomain: cluster.local + +############################### +# Metadata Configurations # +# Naming and labels overrides # +############################### + +# Overrides the name of the chart affecting the names of GraphDB resources. +# Note: To override the GraphDB proxy's resource names, use .Values.proxy.nameOverride +nameOverride: "" + +# Overrides the naming of all GraphDB resources, effectively removing the chart's name and the release name prefix. +# This override takes precedence over anything in .Values.nameOverride +# Note: To override the GraphDB proxy's full name, use .Values.proxy.fullnameOverride +fullnameOverride: "" + +# Overrides the deployment namespace in case of multi-namespace deployments, for example when using umbrella charts where some sub-charts should be +# deployed in different namespaces. +# This affects every resource deployed by this chart. +# The default value is .Release.Namespace if this is left unspecified. +namespaceOverride: "" + +# Additional common labels to add to all resources for both GraphDB and the GraphDB proxy. +# Values are processed as Helm templates. +# Ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +# +# Example: +# labels: +# foo: bar +# some-label: {{ .Values.someValue }} +labels: {} + +# Additional common annotations to add to all resources for both GraphDB and the GraphDB proxy. +# Values are processed as Helm templates. +# Ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +# +# Example: +# annotations: +# foo: bar +# some-annotation: {{ .Values.someValue }} +annotations: {} + +################################ +# GraphDB Image Configurations # +################################ + +# Image configurations for GraphDB. +# All containers in this chart use the GraphDB image, this includes the proxy, all init containers and any Jobs as well. +# Ref: https://kubernetes.io/docs/concepts/containers/images/ +image: + # The registry that hosts the GraphDB image. + # The default is to pull it from the official Docker registry, but this can be overridden to pull from other public or private registries. + registry: docker.io + + # The repository name of the GraphDB image. + repository: ontotext/graphdb + + # Image tag that corresponds to the version of GraphDB. + # By default, the chart uses .Chart.AppVersion to construct the full image name. + # Use this to override the value from .Chart.AppVersion and effectively deploy a custom GraphDB version. + tag: "" + + # Expected SHA256 digest of the used GraphDB image, e.g. "sha256@abc" + # Use the digest to make sure you are always deploying the exact same GraphDB image. + # Defining this would override .Chart.AppVersion and image.tag + digest: "" + + # Defines the policy for pulling images + # Ref: https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy + pullPolicy: IfNotPresent + + # Secrets for pulling GraphDB's Docker image from secured registries. + # Values are processed as Helm templates. + # Ref: https://kubernetes.io/docs/concepts/configuration/secret/#using-imagepullsecrets + # + # Example: + # pullSecrets: + # - name: my-pull-secret + pullSecrets: [] + +########################## +# Scaling Configurations # +########################## + +# Number of GraphDB nodes to be deployed as part of the StatefulSet. +# Set value to 1 to run a standalone GraphDB instance +# Set value to more than 1 to form a GraphDB cluster with GraphDB cluster proxies. +# This setting control the deployment of the cluster proxies and cluster jobs as well. +# Ref: https://graphdb.ontotext.com/documentation/10.6/creating-a-cluster.html +replicas: 1 + +########################## +# GraphDB Configurations # +########################## + +# Commercial license is required for using GraphDB Enterprise Edition features. +license: + # Reference to a secret containing 'graphdb.license' file that will be mounted in the GraphDB pod. + # The value is processed as a Helm template. + existingSecret: "" + # File name of the GraphDB license file in the existing license secret. + # The default is graphdb.license, but it can be changed to map to a different secret key. + licenseFilename: graphdb.license + +# GraphDB runtime configuration settings. +# For reference, see https://graphdb.ontotext.com/documentation/10.6/directories-and-config-properties.html +configuration: + # The external URL at which GraphDB should be accessible. + # This can be a publicly available domain name, an internal one or even a Kubernetes service address. + # + # This configures the address resolving in GraphDB and the GraphDB proxy as well, if enabled. + # It also configures the hostname in the default Ingress resource, if enabled. + # The value is processed as a Helm template. + # + # Note: If the external URL uses HTTPS and the default Ingress is enabled, you have to configure .Values.ingress.tls + # + # Note: When deploying on a context path different from /, you need to properly configure the Ingress according to the requirements of the + # Ingress controller implementation. + externalUrl: http://graphdb.127.0.0.1.nip.io/ + + # GraphDB properties to insert in the default graphdb.properties ConfigMap. + # Values are processed as Helm templates. + # + # Example: + # properties: + # graphdb.append.request.id.headers: "true" + properties: {} + + # Sensitive GraphDB properties to insert in the default graphdb.properties Secret. + # Values defined here will be merged with the values from the default graphdb.properties ConfigMap. + # Values are processed as Helm templates. + # Note: Consider mounting existing Secret objects as environment variables or files + # + # Example: + # secretProperties: + # graphdb.connector.keystorePass: "xxxx" + secretProperties: {} + + # Additional GraphDB configurations that will be appended to graphdb.properties, effectively overriding anything configured + # in the default graphdb.properties ConfigMap and Secret resources. + # Note: The exact processing and order of precedence is visible in the initContainers. + # + # Example: + # extraProperties: + # existingConfigmap: my-graphdb-properties + # existingSecret: my-secret-graphdb-properties + extraProperties: + # Reference to an existing ConfigMap resource containing GraphDB configurations under a graphdb.properties file. + # The value is processed as a Helm template. + existingConfigmap: "" + # Key in the existing ConfigMap that holds the properties for GraphDB. + configmapKey: graphdb.properties + + # Reference to an existing Secret resource containing sensitive GraphDB configurations under a graphdb.properties file. + # The value is processed as a Helm template. + existingSecret: "" + # Key in the existing Secret that holds the properties for GraphDB. + secretKey: graphdb.properties + + # Default Java arguments with which GraphDB instances will be launched. + # GraphDB configuration properties can also be passed here in the format -Dproperty=value + # Takes precedence over any configurations provided in graphdb.properties + # The value is processed as a Helm template. + # Ref: https://graphdb.ontotext.com/documentation/10.6/directories-and-config-properties.html#configuration + defaultJavaArguments: -XX:+UseContainerSupport -XX:MaxRAMPercentage=70 -XX:-UseCompressedOops -Ddefault.min.distinct.threshold=100m + + # Java arguments to append after .Values.configuration.defaultJavaArguments + # Use this one in order to avoid overriding the default values. + # The value is processed as a Helm template. + javaArguments: "" + + # Configurations for GraphDB's Logback + # Ref: https://graphdb.ontotext.com/documentation/10.6/diagnosing-and-reporting-critical-errors.html#logs + # + # Example: + # logback: + # existingConfigmap: custom-logback-config + logback: + # Reference to an existing ConfigMap containing a Logback XML configuration. + # The value is processed as a Helm template. + existingConfigmap: "" + # Key in the existing ConfigMap that maps to the Logback XML configuration. + configmapKey: logback.xml + + # Configurations for provisioning an initial settings.js to GraphDB. + # Note: Once provisioned, changes made to settings.js won't be re-applied! + # + # There are three cases to be aware of: + # - By default, no settings.js configuration is provisioned initially, so GraphDB will initialize its default one. + # - If the security is enabled, a default initial settings.js will be provided to GraphDB, see files/config/settings.js + # - If a custom existing settings.js is provided, it will be used no matter if the security is enabled or not. + # + # Example: + # initialSettings: + # existingConfigmap: custom-initial-settings + initialSettings: + # Reference to an existing ConfigMap with initial GraphDB settings.js to provision. + # The value is processed as a Helm template. + existingConfigmap: "" + # Key in the existing ConfigMap that maps to the settings.js file + configmapKey: settings.js + +################################### +# GraphDB Security Configurations # +################################### + +security: + # Toggles the security in GraphDB. + # + # This setting controls the initial setup of the security and the provisioning of the default initial users.js and settings.js files from this chart. + # If the security has been enabled after the initial start, changing this flag won't provision anything in order to protect from overriding changes. + # This setting also controls the authentication in the cluster provisioning jobs. + # Ref: https://graphdb.ontotext.com/documentation/10.6/enabling-security.html + enabled: false + + # Administrator user with ROLE_ADMIN authority. + # Provisioned as part of the default initial users.js if no custom Secret has been provided, see files/config/users.js + admin: + # Define an initial password for the administrator user. + # If the password is not specified, it will use the default one for GraphDB which is "root" + # Important: This value must be a bcrypt encrypted hash, not a plaintext string. The format is "{bcrypt}<the-encrypted-hash>" + initialPassword: "" + + # Provisioning user with ROLE_ADMIN authority + # Provisioned as part of the default initial users.js if no custom Secret has been provided, see files/config/users.js + # If the security is enabled, it's mandatory to have a provisioning user, so the cluster provisioning jobs can work properly. + provisioner: + # The following user will be created in the default initial users.js and used in the cluster provisioning. + # Note: The user is created regardless of if the existingSecret is provided or not. + username: provisioner + password: iHaveSuperpowers + # Reference to Secret with a basic authentication token of an existing user to use for provisioning tasks instead of the default user in the initial + # user.js that is created using the plaintext username and password configurations from above. + # Note that the user must already exist in GraphDB for this to work properly. + existingSecret: "" + # Key in the existing Secret holding the authentication token. + tokenKey: GRAPHDB_AUTH_TOKEN + + # Initial users to provision to GraphDB before starting for the first time. + # Note: If the security has already been enabled and is not the initial provisioning, this won't be applied. + # + # There are three cases to be aware of: + # - By default, no users.js configuration is provisioned initially, so GraphDB will initialize its default one. + # - If the security is enabled, a default initial users.js will be provided to GraphDB, see files/config/users.js + # - If a custom existing users.js is provided, it will be used no matter if the security is enabled or not. + initialUsers: + # Additional users to insert in the default users.js (see files/config/users.js) when the security is enabled for the first time. + # Check the default user.js syntax for details. + # Note that this won't be applied if you provide a custom Secret object with user.js via existingSecret below. + # + # Example: + # users: + # tester: + # username: tester + # password: {bcrypt}xxxxxx + # grantedAuthorities: [ROLE_USER] + users: {} + # Existing initial users.js to provision to GraphDB. Overrides any users configured in users above. + # Note that this is provisioned just once and any updates on the Secret won't be re-applied on consecutive upgrades. + # The value is processed as a Helm template. + existingSecret: "" + # Key in the Secret object mapping to users.js + secretKey: users.js + +################################## +# GraphDB Cluster Configurations # +################################## + +# Configurations for creating and configuring the GraphDB cluster. +# Ref: https://graphdb.ontotext.com/documentation/10.6/creating-a-cluster.html +cluster: + # Configurations for shared token authentication in the cluster. + # The secret token is used to encrypt and decrypt the communication between GraphDB nodes in the cluster. + # Ref: https://graphdb.ontotext.com/documentation/10.6/creating-a-cluster.html#prerequisites + token: + # Defines the secret token as plaintext. + # Note: Consider providing an existing Secret object with the token via .Values.cluster.token.existingSecret + secret: s3cr37 + # Reference to an existing Secret that contains the cluster secret token. + # This overrides any value defined under .Values.cluster.token.secret + # The value is processed as a Helm template. + existingSecret: "" + # Key in the existing Secret that holds the secret cluster token for GraphDB + secretKey: "" + + # Timeout for cURL queries used for the cluster creation and update. + clusterCreationTimeout: 60 + + # Cluster configuration parameters. + # Changing the parameters would trigger a Job that patches the configuration. + # Ref: https://graphdb.ontotext.com/documentation/10.6/creating-a-cluster.html#creation-parameters + config: + # Reference to a ConfigMap with a custom JSON configuration to use when creating the cluster. + # This setting overrides any other values specified under .Values.cluster.config.params + # The value is processed as a Helm template. + existingConfigmap: "" + # The key in the cluster config configmap that contains the cluster configuration JSON + configmapKey: cluster-config.json + + # Inline cluster configuration parameters. + # Note that the "nodes" parameter is calculated based on the final GraphDB pods names. Check the "graphdb.cluster.nodes.json" template function. + params: + # The minimum wait time in milliseconds for a heartbeat from a leader. + electionMinTimeout: 8000 + # The variable portion of each waiting period in milliseconds for a heartbeat. + electionRangeTimeout: 6000 + # The interval in milliseconds between each heartbeat that is sent to follower nodes by the leader. + heartbeatInterval: 2000 + # The size in KB of the data blocks transferred during data replication streaming through the RPC protocol. + messageSizeKB: 64 + # Maximum size of the transaction log in GBs. The transaction log will be automatically truncated if it becomes bigger than this value. + transactionLogMaximumSizeGB: 50 + # The amount of time in milliseconds a follower node would wait before attempting to verify the last committed entry when the first verification is unsuccessful. + verificationTimeout: 1500 + + # Configurations for the cluster automation Jobs. + # Note that there are common configurations under jobs.<> as well. + jobs: + # Job for creating the GraphDB cluster. + createCluster: + # Enables or disables the cluster creation Job + enabled: true + # Job for patching the GraphDB cluster configuration. + patchCluster: + # Enables or disables the Job for patching the cluster configuration + enabled: true + # Jobs for scaling up or down the GraphDB cluster, depending on the .Values.replica value. + scaleCluster: + # Enables or disables the Jobs for scaling up or down the cluster + enabled: true + +########################## +# Ingress Configurations # +########################## + +# Configurations for the default Ingress resource for GraphDB. +# +# The default Ingress in this chart makes no assumptions of what Ingress controller is being used, it's up to you to define any specific annotations +# required by the controller implementation in your cluster. +# +# There are two modes to be aware of: +# - If .Values.replicas is set to 1, meaning single GraphDB node: the Ingress uses the GraphDB ClusterIP service. +# - If .Values.replicas is set to more than 1, meaning GraphDB cluster: the Ingress uses the GraphDB proxy ClusterIP service. +# +# Ref: https://kubernetes.io/docs/concepts/services-networking/ingress/ +ingress: + # Toggles the deployment of the default Ingress resource. + enabled: true + # Specifies the ingress controller implementation that will control this Ingress resource. + # Not defining this would result in using the default ingress controller in the cluster, if there is one. + className: "" + # Additional labels to append to the Ingress resource. + # Values are processed as Helm templates. + labels: {} + # Additional annotations to append to the Ingress resource. + # Values are processed as Helm templates. + annotations: {} + # If set, overrides the host from .Values.configuration.externalUrl + host: "" + # If set, overrides the context path from .Values.configuration.externalUrl + path: "" + # Sets the ingress path type. + # If you need to use ImplementationSpecific, make sure to set any annotations needed by the controller implementation. + pathType: Prefix + # Configures SSL termination on Ingress level. + # Ref: https://kubernetes.github.io/ingress-nginx/examples/tls-termination/ tls: - # -- Feature toggle for SSL termination. Disabled by default. - # If TLS is enabled, the protocol should also be updated (https) + # Feature toggle for SSL termination. Disabled by default. + # If TLS is enabled, the .Values.configuration.externalUrl should also be updated to use HTTPS. enabled: false - # -- Name of a Kubernetes secret object with the key and certificate. + # Name of a Kubernetes Secret object with the key and certificate. # If TLS is enabled, it's required to be provided, depending on the deployment. + # This could be an existing Secret or one that is not yet created. secretName: + # List of additional hostnames to append to the Ingress resource. + # Values are processed as Helm templates. + extraHosts: [] + # List of additional TLS records to append to the Ingress resource. + # Values are processed as Helm templates. + extraTLS: [] - # -- Ingress related configurations - ingress: - enabled: true - class: nginx - # -- Sets extra ingress annotations +########################## +# Service Configurations # +########################## + +# Configurations for GraphDB Service. +# This Service is deployed only when the .Values.replicas are set to 1. +# In cluster mode (replicas > 1), this Service is not created. +# Ref: https://kubernetes.io/docs/concepts/services-networking/service/ +service: + # Enables or disables the Service deployment + enabled: true + # Additional labels to append to the Service resource. + # Values are processed as Helm templates. + labels: {} + # Additional annotations to append to the Service resource. + # Values are processed as Helm templates. + annotations: {} + # Service type + # Ref: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: ClusterIP + # Ports exposed by the Service. + # Note: If you want to add additional ports, use .Values.service.extraPorts. + ports: + # Port mapped to GraphDB's HTTP API. + http: 7200 + # Exposes the Service on a specific node port on the host machine when "serviceType: NodePort" + # If left undefined, K8S will pick a random port from the node port range of the cluster. + nodePort: "" + # Defines the policy for treating external ingress traffic. + # By default, Cluster does not preserve client IPs. Change to Local to preserve them. + # See https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + externalTrafficPolicy: "" + # NodePort used by external load balancers when the external traffic policy is set to Local. + # By default, Kubernetes will assign a random port, use this to override it. + healthCheckNodePort: "" + # Defines the class that should select a particular load balancer implementation. + # By default, Kubernetes will assign the cluster default implementation, use this to override it. + # Ref: https://kubernetes.io/docs/concepts/services-networking/service/#load-balancer-class + loadBalancerClass: "" + # Source IP ranges for restricting external ingress traffic + loadBalancerSourceRanges: [] + # External IP addresses at which the Service will be exposed + # Ref: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips + externalIPs: [] + # Additional ports to expose with the Service. + extraPorts: [] + +# Configurations for GraphDB headless Service. +# This Service is deployed regardless of the amount of .Values.replicas, so it exists for both single node and for cluster mode. +# Ref: https://kubernetes.io/docs/concepts/services-networking/service/ +headlessService: + # Enables or disables the headless Service deployment. + enabled: true + # Additional labels to append to the headless Service + # Values are processed as Helm templates. + labels: {} + # Additional annotations to append to the Service + # Values are processed as Helm templates. + annotations: {} + # Ports exposed by the Service + # Note: If you want to add additional ports, use .Values.headlessService.extraPorts. + ports: + # Port mapped to GraphDB's HTTP API. + http: 7200 + # Port mapped to GraphDB's gRPC API. + rpc: 7300 + # Additional ports to expose with the Service. + extraPorts: [] + +############################## +# Persistence Configurations # +############################## + +persistence: + # Toggles the persistence of GraphDB data. + # - If enabled, the StatefulSet will use a PVC template and rely on the CSI to dynamically provision Persistent Volumes. + # - If disabled, it falls back to an emptyDir volume. + enabled: true + + # Configurations for PVC based persistence. + # Ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#volume-claim-templates + # Ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/ + volumeClaimTemplate: + # Prefix used when naming the PVCs for the StatefulSet + name: "storage" + # Additional labels to add to the PVC template. + # Values are processed as Helm templates. + labels: {} + # Additional annotations to add to the PVC template. + # Values are processed as Helm templates. annotations: {} - # -- Sets the maximum size for all requests to the underlying Nginx - maxRequestSize: 512M - # -- Default timeouts in seconds for the underlying Nginx. - timeout: - connect: 5 - read: 600 - send: 600 - -# GraphDB database configurations -graphdb: - clusterConfig: - # -- Number of GraphDB nodes to be used in the cluster. - # Set value to 1 to run a standalone GraphDB instance. - nodesCount: 1 - # -- A secret used for secure communication amongst the nodes in the cluster. - clusterSecret: s3cr37 - # -- Timeout for the cluster creation CURL query. - # Note: By default helm waits for Kubernetes commands to complete for 5 minutes. You can increase that by adding "--timeout 10m" to the helm command. - clusterCreationTimeout: 60 - # -- Use a custom JSON configuration when creating the cluster, see https://graphdb.ontotext.com/documentation/10.6/creating-a-cluster.html#creation-parameters - # The resources expect a configmap containing a key "cluster-config.json" with the JSON for cluster creation - existingClusterConfig: - # -- Cluster configuration parameters: - # Refer to https://graphdb.ontotext.com/documentation/10.6/creating-a-cluster.html#creation-parameters - # The minimum wait time in milliseconds for a heartbeat from a leader. - electionMinTimeout: 8000 - # The variable portion of each waiting period in milliseconds for a heartbeat. - electionRangeTimeout: 6000 - # The interval in milliseconds between each heartbeat that is sent to follower nodes by the leader. - heartbeatInterval: 2000 - # The size in KB of the data blocks transferred during data replication streaming through the RPC protocol. - messageSize: 64 - # Maximum size of the transaction log in GBs. The transaction log will be automatically truncated if it becomes bigger than this value. - transactionLogMaximumSizeGB: 50 - # The amount of time in milliseconds a follower node would wait before attempting to verify the last committed entry when the first verification is unsuccessful. - verificationTimeout: 1500 - - # -- References to configuration maps containing settings.js, users.js, graphdb.properties, and logback.xml files to overwrite - # the default GraphDB configuration. For reference see https://graphdb.ontotext.com/documentation/10.6/directories-and-config-properties.html - configs: - # Override default settings configuration - #settingsConfigMap: graphdb-settings-configmap - # Override default users configuration - #usersConfigMap: graphdb-users-configmap - # Override default properties configuration - #propertiesConfigMap: graphdb-properties-configmap - # Override default logback configuration - #logbackConfigMap: graphdb-logback-configmap - # Optional configmap containing repository configuration ttl file(s). GraphDB will automatically create repositories with the provided repositories configuration files - # provisionRepositoriesConfigMap: graphdb-repositories-configmap - - security: - # If the security is enabled, it's mandatory to have a provisioning user, so the health-checks and cluster linking can work properly + # Specification for a PVC to be created by the StatefulSet. + # Tune according to your needs. + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 5Gi + + # Configurations for an emptyDir volume to be used for data storage by the StatefulSet. + # Used when the persistence is disabled with .Values.persistence.enabled + # Ref: https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/ + emptyDir: + # Default emptyDir limit, override to your needs. + sizeLimit: 1Gi + +# Configurations for an emptyDir volume for the /tmp folder in each GraphDB container. +# Because the default security context in .Values.securityContext configures the root filesystem to be in read-only mode, certain GraphDB features +# cannot create and write files in /tmp. If you don't use a read-only root filesystem, you can disable this with .Values.tempPersistence.enabled +tempVolume: + # Toggles the temp folder emptyDir volume creation. + # - If enabled, the StatefulSet will use an emptyDir volume for /tmp. + # - If disabled, the chart won't create and mount ephemeral volumes for /tmp. + enabled: true + + # Configurations for an emptyDir volume to be used for /tmp. + # Ref: https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/ + emptyDir: + # Default emptyDir limit, override to your needs. + sizeLimit: 128Mi + +############################## +# StatefulSet Configurations # +############################## + +# Configures the strategy of updating StatefulSet Pods. +# The default type of RollingUpdate ensures that there will always be .Values.replicas amount of running nodes at the same time. +# Ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies +updateStrategy: + type: RollingUpdate + +# Configures how Pods are created and scaled. +# Ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies +podManagementPolicy: Parallel + +# Changes the maximum amount of revisions that are kept. +revisionHistoryLimit: 10 + +# Grace period in seconds before terminating the Pods. +# Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination +terminationGracePeriodSeconds: 120 + +# Toggles the auto mounting of API credentials token into the Pods. +# Enable this if you need to contact either the API server or need web identity credentials for federated authentication in cloud APIs. +# Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#opt-out-of-api-credential-automounting +automountServiceAccountToken: false + +# Overrides the default Kubernetes scheduler. +# See https://kubernetes.io/docs/tasks/extend-kubernetes/configure-multiple-schedulers/#specify-schedulers-for-pods +schedulerName: "" + +# Overrides the Pod's DNS settings. +# Ref: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-dns-config +dnsConfig: {} + +# Defines the Pod's policy for DNS resolution. +# Ref: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy +dnsPolicy: "" + +# Name of an existing PriorityClass to assign, defining the importance of the pods compared to other pods in the cluster. +# Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/ +priorityClassName: "" + +# Overrides the default GraphDB container command. +# Use only for troubleshooting! +# See https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/ +command: [] + +# Overrides the default GraphDB container command's arguments. +# Use only for troubleshooting! +# See https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/ +args: [] + +# Ports used by the GraphDB container +# Note: If you want to add additional ports, use .Values.extraContainerPorts. +containerPorts: + # Port mapped to GraphDB's HTTP API. + http: 7200 + # Port mapped to GraphDB's gRPC API. + rpc: 7300 + +# Additional labels to append to the Pod definition. +# Values are processed as Helm templates. +# Ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +podLabels: {} + +# Additional annotations to append to the Pod definition. +# Values are processed as Helm templates. +# Ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +podAnnotations: {} + +################################### +# Security Context Configurations # +################################### + +# Defines privilege and access control settings for all containers in the GraphDB Pod. +# See https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod +podSecurityContext: + runAsNonRoot: true + runAsUser: 10001 + runAsGroup: 10001 + fsGroup: 10001 + fsGroupChangePolicy: OnRootMismatch + seccompProfile: + type: RuntimeDefault + +# Defines privilege and access control settings for the container running GraphDB. +# See https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container +securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: [ "ALL" ] + seccompProfile: + type: RuntimeDefault + +# Defines privilege and access control settings for the init containers provisioning configurations for GraphDB. +# See https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container +initContainerSecurityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: [ "ALL" ] + seccompProfile: + type: RuntimeDefault + +############################# +# Scheduling Configurations # +############################# + +# Selector labels to match when selecting nodes. +# Values are processed as Helm templates. +# Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector +# See https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/ +nodeSelector: {} + +# Node and pod affinity & anti affinity configurations for constraining the Pod scheduling. +# Values are processed as Helm templates. +# Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity +affinity: {} + +# List of taint tolerations. +# Values are processed as Helm templates. +# Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ +tolerations: [] + +# Configurations for spreading Pods across different failure domains. +# Values are processed as Helm templates. +# Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#pod-topology-spread-constraints +# Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ +topologySpreadConstraints: [] + +########################## +# Resource Configuration # +########################## + +# Resource configurations for the GraphDB containers. +# For resizing to your needs, refer to the GraphDB documentation https://graphdb.ontotext.com/documentation/10.6/requirements.html +# Ref: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/ +resources: + limits: + memory: 4Gi + requests: + memory: 4Gi + cpu: 500m + +# Resource configurations for the init containers in the GraphDB Pod. +initContainerResources: + limits: + memory: 16Mi + cpu: 50m + requests: + memory: 16Mi + cpu: 50m + +######################### +# Probes Configurations # +######################### + +# Configurations for the GraphDB container startup probe. +# Note: A misconfigured probe can lead to a failing GraphDB cluster! +startupProbe: + httpGet: + path: /protocol + port: http + failureThreshold: 30 + timeoutSeconds: 5 + periodSeconds: 10 + +# Configurations for the GraphDB container readiness probe. +# Note: A misconfigured probe can lead to a failing GraphDB cluster! +readinessProbe: + httpGet: + path: /protocol + port: http + initialDelaySeconds: 5 + timeoutSeconds: 5 + periodSeconds: 10 + +# Configurations for the GraphDB container liveness probe. +# Note: A misconfigured probe can lead to a failing GraphDB cluster! +livenessProbe: + httpGet: + path: /protocol + port: http + initialDelaySeconds: 60 + timeoutSeconds: 5 + periodSeconds: 10 + +######################################### +# Additional Statefulset Configurations # +######################################### + +# Additional environment variables to be set for the GraphDB containers. +# Values are processed as Helm templates. +extraEnvFrom: [] + +# Additional environment variables to be set for the GraphDB containers. +# Values are processed as Helm templates. +extraEnv: [] + +# Additional volumes to be set for the GraphDB Pod. +# Values are processed as Helm templates. +extraVolumes: [] + +# Additional volume mounts to be set for the GraphDB containers. +# Values are processed as Helm templates. +extraVolumeMounts: [] + +# Additional volume claim templates to be set in GraphDB's StatefulSet. +# Values are processed as Helm templates. +extraVolumeClaimTemplates: [] + +# Additional init containers to be inserted after the provisioning init containers. +# Values are processed as Helm templates. +extraInitContainers: [] + +# Additional GraphDB container ports to expose. +extraContainerPorts: {} + +# Additional containers to insert into the GraphDB Pod, e.g. sidecar containers +# Values are processed as Helm templates. +extraContainers: [] + +######################################## +# Pod Disruption Budget Configurations # +######################################## + +# Configurations for GraphDB's default Pod Disruption Budget. +# The GraphDB cluster requires a quorum of replicas/2 + 1 amount of GraphDB nodes (>50%) in order to work properly. +# The default configuration protects against losing quorum in the GraphDB cluster. +# Ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/#pod-disruption-budgets +podDisruptionBudget: + enabled: true + minAvailable: 51% + maxUnavailable: "" + +################################## +# Service Account Configurations # +################################## + +# Configurations for the default ServiceAccount for GraphDB. +# GraphDB by itself has no need to communicate with the Kubernetes API but the service account tokens can be used +# as ODIC federated web identity tokens for authentication in cloud APIs. +# Ref: https://kubernetes.io/docs/concepts/security/service-accounts/ +serviceAccount: + # Specifies whether a ServiceAccount should be created for GraphDB. + create: false + + # The name of the ServiceAccount to use. + # + # There are three cases to be aware of when using this: + # - If not set and create is true, a name is generated using the fullname template + # - If set and create is true, it will use the provided name when creating the ServiceAccount + # - If set but create is false, it will use the provided ServiceAccount. + name: "" + + # If .Values.serviceAccount.create is true, insert additional annotations to the created ServiceAccount. + # Values are processed as Helm templates. + annotations: {} + +################################# +# GraphDB Import Configurations # +################################# + +# Settings for importing data into GraphDB +import: + # Attach additional PV which will be used as an import directory + # See https://graphdb.ontotext.com/documentation/10.6/loading-data-using-the-workbench.html#importing-server-files + volumeMount: + # Toggles the attachment of the additional PV via StatefulSet's PVC templates. enabled: false - provisioningUsername: provisioner - # bcrypt encrypted password. default: iHaveSuperpowers - provisioningPassword: iHaveSuperpowers - - # jobSecurityContext defines privilege and access control settings for all the job pods - jobPodSecurityContext: {} - # jobContainerSecurityContext defines privilege and access control settings for all the job containers - jobSecurityContext: {} - # jobResources defines resource requests and limits for all the job containers - jobResources: {} - - # Settings for the GraphDB cluster nodes - node: - # -- Reference to a secret containing 'graphdb.license' file to be used by the nodes. - # Important: Must be created beforehand - license: - # -- File name of the GraphDB license file in the existing license secret. Default is graphdb.license - licenseFilename: graphdb.license - # -- Java arguments with which node instances will be launched. GraphDB configuration properties can also be passed here in the format -Dprop=value - java_args: "-XX:MaxRAMPercentage=70 -Ddefault.min.distinct.threshold=100m -XX:+UseContainerSupport" - # Node scheduling options such as nodeSelector, affinity, tolerations, topologySpreadConstraints can be set here for ALL nodes. - # By default, no restrictions are applied. - nodeSelector: {} - affinity: {} - tolerations: [] - topologySpreadConstraints: [] - # Extra pod labels and annotations - podLabels: {} - podAnnotations: {} - # -- GraphDB node service configurations - service: - # Extra annotations to append to the service + # Ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#volume-claim-templates + # Ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/ + volumeClaimTemplate: + # Prefix used when naming the PVCs for the StatefulSet + name: "import" + # Additional labels to add to the PVC template. + # Values are processed as Helm templates. + labels: {} + # Additional annotations to add to the PVC template. + # Values are processed as Helm templates. annotations: {} - # -- Persistence configurations. - # By default, Helm will use a PV that reads and writes to the host file system. - persistence: - # use dynamic volume provisioning - volumeClaimTemplateSpec: - accessModes: - - "ReadWriteOnce" + spec: + accessModes: [ "ReadWriteOnce" ] resources: requests: - storage: "5Gi" - # -- Below are minimum requirements for data sets of up to 50 million RDF triples - # For resizing, refer according to the GraphDB documentation - # https://graphdb.ontotext.com/documentation/10.6/requirements.html - resources: - limits: - memory: 2Gi - requests: - memory: 2Gi - cpu: 0.5 - # -- Configurations for the GraphDB node startup probe. Misconfigured probe can lead to a failing cluster. - startupProbe: - httpGet: - path: /protocol - port: graphdb - failureThreshold: 30 - timeoutSeconds: 5 - periodSeconds: 10 - # -- Configurations for the GraphDB node readiness probe. Misconfigured probe can lead to a failing cluster. - readinessProbe: - httpGet: - path: /protocol - port: graphdb - initialDelaySeconds: 5 - timeoutSeconds: 5 - periodSeconds: 10 - # -- Configurations for the GraphDB node liveness probe. Misconfigured probe can lead to a failing cluster. - livenessProbe: - httpGet: - path: /protocol - port: graphdb - initialDelaySeconds: 60 - timeoutSeconds: 5 - periodSeconds: 10 - # additional environment variables to be set for the graphdb nodes - extraEnvFrom: [] - # additional environment variables to be set for the graphdb nodes - extraEnv: [] - # additional volumes to be set for the graphdb nodes - extraVolumes: [] - # additional volume mounts to be set for the graphdb nodes - extraVolumeMounts: [] - # additional init containers inserted after the provisioning init containers - extraInitContainers: [] - # podSecurityContext defines privilege and access control settings for the node pods. - podSecurityContext: {} - # securityContext defines privilege and access control settings for the node container running graphdb. - securityContext: {} - # provisionSecurityContext defines privilege and access control settings for the node containers provisioning configurations for graphdb. - initContainerSecurityContext: {} - # initContainerResources defines resource requests and limits for the node containers provisioning configurations for graphdb. - initContainerResources: {} - # changes the maximum amount of kept revisions - revisionHistoryLimit: 10 - # grace period in seconds before terminating the pods - terminationGracePeriodSeconds: 120 - # overrides the default container command, use only for troubleshooting! - command: - # overrides the default container command's arguments, use only for troubleshooting! - args: - - # Settings for the GraphDB cluster proxy used to communicate with the GraphDB cluster - # Note: If there is no cluster (graphdb.clusterConfig.nodesCount is set to 1) no proxy will be deployed - clusterProxy: - # -- Number of cluster proxies used to access the GraphDB cluster - replicas: 1 - # -- Java arguments with which the cluster proxy instances will be launched. GraphDB configuration properties can also be passed here in the format -Dprop=value - java_args: "-XX:MaxRAMPercentage=70 -Ddefault.min.distinct.threshold=100m -XX:+UseContainerSupport" - # -- Service type used by the graphdb-cluster-proxy service - # Note: If using ALB in AWS EKS this will default to being on the public internet - serviceType: LoadBalancer - # Node scheduling options such as nodeSelector, affinity, tolerations, topologySpreadConstraints can be set here for ALL nodes. - # By default, no restrictions are applied. - nodeSelector: {} - affinity: {} - tolerations: [] - topologySpreadConstraints: [] - # Extra pod labels and annotations - podLabels: {} - podAnnotations: {} - # -- GraphDB cluster proxy service configurations - service: - # Extra annotations to append to the service - annotations: {} - # -- GraphDB cluster proxy headless service configurations - headlessService: - # Extra annotations to append to the service + storage: 10Gi + +###################################### +# Custom Repositories Configurations # +###################################### + +repositories: + # Optional configmap containing repository configuration .ttl file(s). + # GraphDB will automatically create repositories with the provided repositories configuration files. + # Each key in the existing configmap will be treated as the config.ttl of a repository. + existingConfigmap: "" + +################################################ +# Persistent Volume Permissions Configurations # +################################################ + +# Optional init container that can change the permissions in the PV for GraphDB to match the security context settings. +# Use when you have existing persistent volumes with mismatching permissions. +# Note that the container has to run as root to be able to change the permissions, hence the different security context. +initContainerDataPermissions: + enabled: false + securityContext: + runAsNonRoot: false + runAsUser: 0 + +###################### +# Job Configurations # +###################### + +# Common settings for Job resources servicing and automating GraphDB and the cluster. +# Ref: https://kubernetes.io/docs/concepts/workloads/controllers/job/ +jobs: + # Number of retries before considering the jobs failed + backoffLimit: 10 + + # Time in seconds before deleting finished pods + ttlSecondsAfterFinished: 300 + + # Defines privilege and access control settings for all containers in the Jobs. + # See https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + podSecurityContext: + runAsNonRoot: true + runAsUser: 10001 + runAsGroup: 10001 + fsGroup: 10001 + fsGroupChangePolicy: OnRootMismatch + seccompProfile: + type: RuntimeDefault + + # Defines privilege and access control settings for Jobs containers. + # See https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: [ "ALL" ] + seccompProfile: + type: RuntimeDefault + + # Resource configurations for the Jobs containers. + # Ref: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/ + resources: + limits: + memory: 16Mi + cpu: 50m + ephemeral-storage: 10Mi + requests: + memory: 16Mi + cpu: 50m + ephemeral-storage: 10Mi + + # Persistence configurations for all Jobs. + persistence: + # Empty directory volume for temporary file storage and execution of scripts + emptyDir: + sizeLimit: 10Mi + +############################################################################### +# GraphDB Cluster Proxy Configurations # +# Settings for the cluster proxy used to communicate with the GraphDB cluster # +############################################################################### + +# The GraphDB Cluster Proxy is a separate StatefulSet that is enabled when the main GraphDB StatefulSet is deployed in cluster mode, i.e. replicas > 1. +# The proxy takes care of always routing traffic to the GraphDB leader node, reducing needless network hops by the internal proxy mechanism in GraphDB. +# See https://graphdb.ontotext.com/documentation/10.6/creating-a-cluster.html#configure-external-cluster-proxy +proxy: + # Overrides the name of the GraphDB proxy component. + nameOverride: "" + + # Overrides the naming of all GraphDB proxy resources, effectively removing the release name prefix and the proxy name. + # Takes precedence over .Values.proxy.nameOverride + fullnameOverride: "" + + # Additional common labels to add to all GraphDB proxy resources. + # Values are processed as Helm templates. + # Ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + labels: {} + + # Additional common annotations to add to all GraphDB proxy resources. + # Values are processed as Helm templates. + # Ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + annotations: {} + + ################################ + # GraphDB Proxy Configurations # + ################################ + + # GraphDB proxy runtime configuration settings. + # For reference, see https://graphdb.ontotext.com/documentation/10.6/directories-and-config-properties.html + configuration: + # GraphDB proxy properties to insert in the default graphdb.properties ConfigMap for the proxy. + # Values are processed as Helm templates. + properties: {} + + # Sensitive GraphDB proxy properties to insert in the default graphdb.properties Secret for the proxy. + # Values defined here will be merged with the values from the default graphdb.properties ConfigMap for the proxy. + # Values are processed as Helm templates. + # Note: Consider mounting existing Secret objects as environment variables or files + secretProperties: {} + + # Additional GraphDB configurations that will be appended to graphdb.properties, effectively overriding anything configured + # in the default graphdb.properties ConfigMap and Secret resources for the proxy. + extraProperties: + # Reference to an existing ConfigMap resource containing GraphDB configurations under a graphdb.properties file. + # The value is processed as a Helm template. + existingConfigmap: "" + # Key in the existing ConfigMap that holds the properties for GraphDB + configmapKey: graphdb.properties + + # Reference to an existing Secret resource containing sensitive GraphDB configurations under a graphdb.properties file. + # The value is processed as a Helm template. + existingSecret: "" + # Key in the existing Secret that holds the properties for GraphDB + secretKey: graphdb.properties + + # Default Java arguments with which the GraphDB proxy instances will be launched. + # GraphDB configuration properties can also be passed here in the format -Dprop=value + # Takes precedence over any configurations in graphdb.properties + # The value is processed as a Helm template. + # Ref: https://graphdb.ontotext.com/documentation/10.6/directories-and-config-properties.html#configuration + defaultJavaArguments: -XX:+UseContainerSupport -XX:MaxRAMPercentage=70 + + # Java arguments to append after .Values.proxy.configuration.defaultJavaArguments + # Use this one in order to avoid overriding the default values. + # The value is processed as a Helm template. + javaArguments: "" + + # Configurations for GraphDB's Logback + # Ref: https://graphdb.ontotext.com/documentation/10.6/diagnosing-and-reporting-critical-errors.html#logs + logback: + # Reference to an existing ConfigMap containing a Logback XML configuration. + # The value is processed as a Helm template. + existingConfigmap: "" + # Key in the existing ConfigMap that maps to the Logback XML configuration. + configmapKey: logback.xml + + ########################## + # Service Configurations # + ########################## + + # GraphDB cluster proxy Service configurations. + service: + # Enables or disables the Service deployment + enabled: true + # Additional labels to append to the Service resource. + # Values are processed as Helm templates. + labels: {} + # Additional annotations to append to the Service resource. + # Values are processed as Helm templates. + annotations: {} + # Service type + # Ref: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: ClusterIP + # Ports exposed by the Service. + # Note: If you want to add additional ports, use .Values.proxy.service.extraPorts. + ports: + # Port mapped to GraphDB proxy's HTTP API. + http: 7200 + # Exposes the Service on a specific node port on the host machine when "serviceType: NodePort" + # If left undefined, K8S will pick a random port from the node port range of the cluster. + nodePort: "" + # Defines the policy for treating external ingress traffic. + # By default, Cluster does not preserve client IPs. Change to Local to preserve them. + # See https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + externalTrafficPolicy: "" + # NodePort used by external load balancers when the external traffic policy is set to Local. + # By default, Kubernetes will assign a random port, use this to override it. + healthCheckNodePort: "" + # Defines the class that should select a particular load balancer implementation. + # By default, Kubernetes will assign the cluster default implementation, use this to override it. + # See https://kubernetes.io/docs/concepts/services-networking/service/#load-balancer-class + loadBalancerClass: "" + # Source IP ranges for restricting external ingress traffic + loadBalancerSourceRanges: [] + # External IP addresses at which the service will be exposed + # See https://kubernetes.io/docs/concepts/services-networking/service/#external-ips + externalIPs: [] + # Additional proxy ports to expose with the Service. + extraPorts: [] + + # GraphDB cluster proxy headless Service configurations. + # Ref: https://kubernetes.io/docs/concepts/services-networking/service/ + headlessService: + # Enables or disables the headless Service deployment. + enabled: true + # Additional labels to append to the headless Service + # Values are processed as Helm templates. + labels: {} + # Additional annotations to append to the Service + # Values are processed as Helm templates. + annotations: {} + # Ports exposed by the Service + # Note: If you want to add additional ports, use .Values.proxy.headlessService.extraPorts. + ports: + # Port mapped to GraphDB's HTTP API. + http: 7200 + # Port mapped to GraphDB's gRPC API. + rpc: 7300 + # Additional proxy ports to expose with the Service. + extraPorts: [] + + ############################## + # Persistence Configurations # + ############################## + + # Persistence configurations for storing GraphDB proxy log and temp files. + persistence: + # Toggles the persistence of GraphDB proxy data. + # - If enabled, the StatefulSet will use a PVC template and rely on the CSI to dynamically provision Persistent Volumes. + # - If disabled, it falls back to an emptyDir volume. + enabled: true + + # Configurations for PVC based persistence. + # Ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#volume-claim-templates + # Ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/ + volumeClaimTemplate: + # Prefix used when naming the PVCs for the StatefulSet + name: "storage" + # Additional labels to add to the PVC template. + # Values are processed as Helm templates. + labels: {} + # Additional annotations to add to the PVC template. + # Values are processed as Helm templates. annotations: {} - # -- Minimum requirements for a successfully running GraphDB cluster proxy - resources: - limits: - memory: 1500Mi - requests: - memory: 1500Mi - cpu: 100m - # -- Persistence configurations. - # By default, Helm will use a PV that reads and writes to the host file system. - persistence: - # enable or disable proxy persistence - enablePersistence: true - # use dynamic volume provisioning - volumeClaimTemplateSpec: - accessModes: - - "ReadWriteOnce" + # Specification for a PVC to be created by the StatefulSet. + # Tune according to your needs. + spec: + accessModes: [ "ReadWriteOnce" ] resources: requests: - storage: "500Mi" - # -- Configurations for the GraphDB cluster proxy startup probe. Misconfigured probe can lead to a failing cluster. - startupProbe: - httpGet: - path: /proxy/ready - port: gdb-proxy-port - failureThreshold: 60 - timeoutSeconds: 3 - periodSeconds: 5 - # -- Configurations for the GraphDB cluster proxy readiness probe. Misconfigured probe can lead to a failing cluster. - readinessProbe: - httpGet: - path: /proxy/ready - port: gdb-proxy-port - timeoutSeconds: 5 - periodSeconds: 10 - # -- Configurations for the GraphDB cluster proxy liveness probe. Misconfigured probe can lead to a failing cluster. - livenessProbe: - httpGet: - path: /proxy/health - port: gdb-proxy-port - initialDelaySeconds: 120 - timeoutSeconds: 5 - periodSeconds: 10 - # additional environment variables to be set for each cluster proxy - extraEnvFrom: [] - # additional environment variables to be set for each cluster proxy - extraEnv: [] - # additional volumes to be set for each cluster proxy - extraVolumes: [] - # additional volume mounts to be set for each cluster proxy - extraVolumeMounts: [] - # additional init containers - extraInitContainers: [] - # podSecurityContext defines privilege and access control settings for the proxy pods. - podSecurityContext: {} - # securityContext defines privilege and access control settings for the proxy containers. - securityContext: {} - # changes the maximum amount of kept revisions - revisionHistoryLimit: 10 - # grace period in seconds before terminating the pods - terminationGracePeriodSeconds: 30 - - # GraphDB workbench configurations - workbench: - # -- This is the sub path at which GraphDB workbench can be opened. - # Should be configured in the API gateway (or any other proxy in front) - subpath: /graphdb - - # WARNING: Setting enabled to true in most cloud providers will result in an error - # Attach additional PV which will be used as an import directory - # https://graphdb.ontotext.com/documentation/10.6/loading-data-using-the-workbench.html#importing-server-files - import_directory_mount: - enabled: false - volumeClaimTemplateSpec: - accessModes: - - "ReadWriteOnce" - resources: - requests: - storage: "10Gi" + storage: 500Mi + + # Configurations for an emptyDir volume to be used for data storage by the StatefulSet. + # Used when the persistence is disabled with .Values.proxy.persistence.enabled + # Ref: https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/ + emptyDir: + # Default emptyDir limit, override to your needs. + sizeLimit: 500Mi + + ############################## + # Statefulset Configurations # + ############################## + + # Number of cluster proxies used to access the GraphDB cluster. + # It is recommended to use more than 1 replicas of the proxies as to avoid single point of failure. + replicas: 3 + + # Configures the strategy of updating the proxy's StatefulSet Pods. + # The default type of RollingUpdate ensures that there will always be .Values.replicas amount of running nodes at the same time. + # Ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies + updateStrategy: + type: RollingUpdate + + # Configures how proxy Pods are created and scaled. + # Ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies + podManagementPolicy: Parallel + + # Changes the maximum amount of revisions that are kept. + revisionHistoryLimit: 10 + + # Grace period in seconds before terminating the proxy Pods. + # Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination + terminationGracePeriodSeconds: 30 + + # Overrides the default Kubernetes scheduler. + # See https://kubernetes.io/docs/tasks/extend-kubernetes/configure-multiple-schedulers/#specify-schedulers-for-pods + schedulerName: "" + + # Overrides the proxy Pod's DNS settings. + # Ref: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-dns-config + dnsConfig: {} + + # Defines the proxy Pod's policy for DNS resolution. + # Ref: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy + dnsPolicy: "" + + # Name of an existing PriorityClass to assign, defining the importance of the pods compared to other pods in the cluster. + # Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/ + priorityClassName: "" + + # Overrides the default GraphDB proxy container command. + # Use only for troubleshooting! + # See https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/ + command: [] + + # Overrides the default GraphDB proxy container command's arguments. + # Use only for troubleshooting! + # See https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/ + args: [] + + # Ports used by the GraphDB proxy container + # Note: If you want to add additional ports, use .Values.proxy.extraContainerPorts. + containerPorts: + # Port mapped to GraphDB's HTTP API. + http: 7200 + # Port mapped to GraphDB's gRPC API. + rpc: 7300 + + # Additional labels to append to the proxy Pod definition. + # Values are processed as Helm templates. + # Ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + podLabels: {} + + # Additional annotations to append to the proxy Pod definition. + # Values are processed as Helm templates. + # Ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + podAnnotations: {} + + ################################### + # Security Context Configurations # + ################################### + + # Defines privilege and access control settings for all containers in the GraphDB proxy Pod. + # See https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + podSecurityContext: + runAsNonRoot: true + runAsUser: 10001 + runAsGroup: 10001 + fsGroup: 10001 + fsGroupChangePolicy: OnRootMismatch + seccompProfile: + type: RuntimeDefault + + # Defines privilege and access control settings for the container running the GraphDB proxy. + # See https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: [ "ALL" ] + seccompProfile: + type: RuntimeDefault + + # Defines privilege and access control settings for the init containers provisioning configurations for the GraphDB proxy. + # See https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + initContainerSecurityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: [ "ALL" ] + seccompProfile: + type: RuntimeDefault + + ############################# + # Scheduling Configurations # + ############################# + + # Selector labels to match when selecting nodes. + # Values are processed as Helm templates. + # Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector + # See https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/ + nodeSelector: {} + + # Node and pod affinity & anti affinity configurations for constraining the Pod scheduling. + # Values are processed as Helm templates. + # Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity + affinity: {} + + # List of taint tolerations. + # Values are processed as Helm templates. + # Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ + tolerations: [] - # Pod Disruption Budget for GraphDB nodes + # Configurations for spreading Pods across different failure domains. + # Values are processed as Helm templates. + # Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#pod-topology-spread-constraints + # Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ + topologySpreadConstraints: [] + + ########################## + # Resource Configuration # + ########################## + + # Resource configurations for the GraphDB proxy containers. + # For resizing to your needs, refer to the GraphDB documentation https://graphdb.ontotext.com/documentation/10.6/requirements.html + # Ref: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/ + resources: + limits: + memory: 1500Mi + requests: + memory: 1500Mi + cpu: 100m + + # Resource configurations for the init containers in the GraphDB proxy Pod. + initContainerResources: + limits: + memory: 16Mi + cpu: 50m + requests: + memory: 16Mi + cpu: 50m + + ######################### + # Probes Configurations # + ######################### + + # Configurations for the GraphDB proxy container startup probe. + # Note: A misconfigured probe can lead to a failing GraphDB cluster! + startupProbe: + httpGet: + path: /proxy/ready + port: http + failureThreshold: 60 + timeoutSeconds: 3 + periodSeconds: 5 + + # Configurations for the GraphDB proxy container readiness probe. + # Note: A misconfigured probe can lead to a failing GraphDB cluster! + readinessProbe: + httpGet: + path: /proxy/ready + port: http + timeoutSeconds: 5 + periodSeconds: 10 + + # Configurations for the GraphDB proxy container liveness probe. + # Note: A misconfigured probe can lead to a failing GraphDB cluster! + livenessProbe: + httpGet: + path: /proxy/health + port: http + initialDelaySeconds: 120 + timeoutSeconds: 5 + periodSeconds: 10 + + ######################################### + # Additional Statefulset Configurations # + ######################################### + + # Additional environment variables to be set for the GraphDB proxy containers. + # Values are processed as Helm templates. + extraEnvFrom: [] + + # Additional environment variables to be set for the GraphDB proxy containers. + # Values are processed as Helm templates. + extraEnv: [] + + # Additional volumes to be set for the GraphDB proxy Pod. + # Values are processed as Helm templates. + extraVolumes: [] + + # Additional volume mounts to be set for the GraphDB proxy containers. + # Values are processed as Helm templates. + extraVolumeMounts: [] + + # Additional volume claim templates to be set in GraphDB proxy's StatefulSet. + # Values are processed as Helm templates. + extraVolumeClaimTemplates: [] + + # Additional init containers to be inserted after the provisioning init containers for the GraphDB proxy. + # Values are processed as Helm templates. + extraInitContainers: [] + + # Additional GraphDB proxy container ports to expose. + extraContainerPorts: {} + + # Additional containers to insert into the GraphDB proxy Pod, e.g. sidecar containers + # Values are processed as Helm templates. + extraContainers: [] + + ######################################## + # Pod Disruption Budget Configurations # + ######################################## + + # Configurations for GraphDB proxy's default Pod Disruption Budget. + # The default configuration ensures that replicas/2 + 1 amount of proxies will not be disrupted. # See https://kubernetes.io/docs/concepts/workloads/pods/disruptions/#pod-disruption-budgets - pdb: - create: false - minAvailable: "51%" - maxUnavailable: + podDisruptionBudget: + enabled: true + minAvailable: 51% + maxUnavailable: "" + + ################################################ + # Persistent Volume Permissions Configurations # + ################################################ + + # Optional init container that can change the permissions in the PV for the GraphDB proxy to match the security context settings. + # Use when you have existing persistent volumes with mismatching permissions. + # Note that the container has to run as root to be able to change the permissions, hence the different security context. + initContainerDataPermissions: + enabled: false + securityContext: + runAsNonRoot: false + runAsUser: 0 + +################################# +# Additional Kubernetes Objects # +################################# + +# Additional objects to insert along with the release. +# Values are processed as Helm templates. +extraObjects: []