diff --git a/chart/CHANGELOG.md b/chart/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..6bfa7ee25082751f64ce2b6be8995ee6b4565964 --- /dev/null +++ b/chart/CHANGELOG.md @@ -0,0 +1,88 @@ +# SonarQube Chart Changelog +All changes to this chart will be documented in this file. + +## [1.0.8] +* fix typo in initfs +* fix plugin installation init container permissions +* fix duplicated mount point for conf when sonar.properties are defined + +## [1.0.7] +* fix invalid yaml render in `secret.yaml` when using external postgresql + +## [1.0.6] +* added `prometheusExporter.downloadURL` (custom download URL for the agent jar) + +## [1.0.5] +* replace `rjkernick/alpine-wget` with `curlimages/curl` +* update `install-plugins` script +* fix possible issue with prometheus init container and `env` set in the `values.yaml` + +## [1.0.4] +* fix for missing `serviceAccountName` in STS deployment kind + +## [1.0.3] +* fixed prometheus config volume mount if disabled +* switched from wget to curl image per default for downloading agent +* added support for proxy envs + +## [1.0.2] +* added option to configure CE java opts separately + +## [1.0.1] +* fixed missing conditional that was introduced in 0.9.2.2 to sonarqube-sts.yaml +* updated default application version to 8.9 + +## [1.0.0] +* changed default deployment from replica set to statefull set +* added default support for prometheus jmx exporter +* added init filesystem container +* added nginx-ingress as optional dependency +* updated application version to 8.8-community +* improved readiness/startup and liveness probes +* improved documentation + +## [0.9.6.2] +* Change order of env variables to better support 7.9-lts + +## [0.9.6.1] +* Add support for setting custom annotations in admin hook job. + +## [0.9.6.0] +* Add the possibility of definining the secret key name of the postgres password. + +## [0.9.5.0] +* Add Ingress default backend for GCE class + +## [0.9.2.3] +* Added namespace to port-foward command in notes. + +## [0.9.2.2] +* Added a condition to deployment.yaml so that `wait-for-db` initContainer is only created if `postgresql.enabled=true` + +## [0.9.2.1] +* Updated the configuration table to include the additional keys added in release 9.2.0. + +## [0.9.2.0] +* Added functionality for deployments to OpenShift clusters. + * .Values.OpenShift flag to signify if deploying to OpenShift. + * Ability to have chart generate an SCC allowing the init-sysctl container to run as privileged. + * Setting of a seperate securityContext section for the main SonarQube container to avoid running as root. + * Exposing additional `postreSQL` keys in values.yaml to support configuring postgres to run under standard "restricted" or "anyuid"/"nonroot" SCCs on OpenShift. +* Added initContainer `wait-for-db` to await postgreSQL successful startup before starting SonarQube, to avoid race conditions. + +## [0.9.1.1] +* Update SonarQube to 8.5.1. +* **Fix:** Purge plugins directory before download. + +## [0.9.0.0] +* Update SonarQube to 8.5. +* **Breaking change:** Rework init containers. + * Move global defaults from `plugins` section to `initContainers`. + * Update container images. +* **Deprecation:** `elasticsearch.configureNode` in favor of `initSysctl.enabled`. +* Rework sysctl with support for custom values. +* Rework plugins installation via `opt/sonarqube/extensions/downloads` folder that is handled by SonarQube itself. + * **Breaking change:** remove `plugins.deleteDefaultPlugins` as SonarQube stores bundled plugins out of `opt/sonarqube/extensions`. +* Rename deprecated `SONARQUBE_` environment variables to `SONAR_` ones. +* **Breaking change:** Rename `enabledTests` to `tests.enabled`. +* Add `terminationGracePeriodSeconds`. diff --git a/chart/Chart.yaml b/chart/Chart.yaml index 162b12128c52d9455c4fca67048cabe5bea7f61e..d5f7c9c03bd1214e1adbdd2ca6888d1a17bfe63d 100644 --- a/chart/Chart.yaml +++ b/chart/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 -appVersion: 8.7.1-community name: sonarqube description: SonarQube is an open sourced code quality scanning tool -version: 9.2.6-bb.12 +version: 1.0.8-bb.0 +appVersion: 8.9-community keywords: - coverage - security @@ -13,11 +13,5 @@ icon: https://www.sonarqube.org/assets/logo-31ad3115b1b4b120f3d1efd63e6b13ac9f1f sources: - https://github.com/SonarSource/docker-sonarqube maintainers: - - name: rjkernick - email: rjkernick@gmail.com - - name: tsiddique - email: tsiddique@live.com -dependencies: - - name: gluon - version: "0.1.1" - repository: "oci://registry.dso.mil/platform-one/big-bang/apps/library-charts/gluon" + - name: tobias-trabelsi-sonarsource + email: tobias.trabelsi+helm@sonarsource.com \ No newline at end of file diff --git a/chart/Kptfile b/chart/Kptfile new file mode 100644 index 0000000000000000000000000000000000000000..988a88cb8eda3fcf89d630f1afdc900fc938fcbb --- /dev/null +++ b/chart/Kptfile @@ -0,0 +1,11 @@ +apiVersion: kpt.dev/v1alpha1 +kind: Kptfile +metadata: + name: sonarqube +upstream: + type: git + git: + commit: af0ae8e5ea1bc7d635a048c1507556948c1a0fe0 + repo: https://github.com/SonarSource/helm-chart-sonarqube + directory: /charts/sonarqube + ref: master diff --git a/chart/OWNERS b/chart/OWNERS new file mode 100644 index 0000000000000000000000000000000000000000..dc80d0d78aab88cd72cb00e6b4ab2444aa092429 --- /dev/null +++ b/chart/OWNERS @@ -0,0 +1,4 @@ +approvers: +- tobias-trabelsi-sonarsource +reviewers: +- tobias-trabelsi-sonarsource diff --git a/chart/README.md b/chart/README.md index 4b9415feeb8cb033ad0bba2dd870042dc437c088..fe3ad6580c9aca399f5d09a4a2af23df25e6f1d1 100644 --- a/chart/README.md +++ b/chart/README.md @@ -2,176 +2,223 @@ [SonarQube](https://www.sonarqube.org/) is an open sourced code quality scanning tool. -This chart was pulled from: https://github.com/Oteemo/charts/tree/master/charts/sonarqube - ## Introduction This chart bootstraps a SonarQube instance with a PostgreSQL database. -## Prerequisites +Please note that this chart only supports SonarQube Community, Developer, and Enterprise Editions. + +## Compatibility -- Kubernetes 1.10+ +| SonarQube Version | Kubernetes Version | Helm Chart Version | +|-------------------|--------------------|--------------------| +| 8.8, 8.9 | 1.19, 1.20, 1.21 | 1.0 | ## Installing the chart To install the chart: ```bash -helm repo add oteemocharts https://oteemo.github.io/charts -helm install oteemocharts/sonarqube +git clone https://github.com/SonarSource/helm-chart-sonarqube.git +cd helm-chart-sonarqube/charts/sonarqube +helm dependency update +kubectl create namespace sonarqube +helm upgrade --install -f values.yaml -n sonarqube sonarqube ./ ``` -The above command deploys Sonarqube on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. - -For OpenShift installations; if you wish for the chart to create the required SCC for the privileged initContainer, and run PostgreSQL under the restricted SCC use the following `set` statements: -```bash -helm repo add oteemocharts https://oteemo.github.io/charts -helm install oteemocharts/sonarqube --set OpenShift.enabled=true,\ - serviceAccount.create=true,\ - postgresql.serviceAccount.enabled=true,\ - postgresql.securityContext.enabled=false,\ - postgresql.volumePermissions.enabled=true,\ - postgresql.volumePermissions.securityContext.runAsUser="auto" -``` +The above command deploys Sonarqube on the Kubernetes cluster in the default configuration in the sonarqube namespace. The [configuration](#configuration) section lists the parameters that can be configured during installation. The default login is admin/admin. +## How to use it + +Take some time to read the Deploy on [SonarQube on Kubernetes](https://docs.sonarqube.org/latest/setup/sonarqube-on-kubernetes/) page. +SonarQube deployment on Kubernetes has been tested with the recommendations and constraints documented there, and deployment has some limitations. + ## Uninstalling the chart To uninstall/delete the deployment: ```bash $ helm list -NAME REVISION UPDATED STATUS CHART NAMESPACE -kindly-newt 1 Mon Oct 2 15:05:44 2017 DEPLOYED sonarqube-0.1.0 default +NAME REVISION UPDATED STATUS CHART NAMESPACE +kindly-newt 1 Mon Oct 2 15:05:44 2017 DEPLOYED sonarqube-0.1.0 sonarqube $ helm delete kindly-newt ``` -## Ingress Paths +## Ingress + +### Path + +Some cloud may need the path to be `/*` instead of `/.` Try this first if you are having issues getting traffic through the ingress. + +### Default Backend + +if you use GCP as a cloud provider you need to set a default backend to avoid useless default backend created by the gce controller. To add this default backend you must set "ingress.class" annotation with "gce" or "gce-internal" value. -Some cloud may need the path to be /* instead of /. Try this first if you are having issues getting traffic through the ingress. +Example: + +```yaml +--- +ingress: + enabled: true + hosts: + - name: sonarqube.example.com + path: "/*" + annotations: + kubernetes.io/ingress.class: "gce-internal" + kubernetes.io/ingress.allow-http: "false" +``` ## Configuration The following table lists the configurable parameters of the Sonarqube chart and their default values. -| Parameter | Description | Default | -| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | -| `replicaCount` | Number of replicas deployed | `1` | -| `deploymentStrategy` | Deployment strategy | `{}` | -| `priorityClassName` | Schedule pods on priority (commented out) | `"high-priority"` | -| `schedulerName` | Kubernetes scheduler name | None | -| `OpenShift.enabled` | Define if this deployment is for OpenShift | `false` | -| `OpenShift.createSCC` | If this deployment is for OpenShift, define if SCC should be created for sonarqube pod | `true` | -| `image.repository` | image repository | `sonarqube` | -| `image.tag` | `sonarqube` image tag. | `8.5.1-community` | -| `image.pullPolicy` | Image pull policy | `IfNotPresent` | -| `image.pullSecret` | imagePullSecret to use for private repository (commented out) | `my-repo-secret` | -| `securityContext.fsGroup` | Group applied to mounted directories/files | `1000` | -| `containerSecurityContext.runAsUser` | User to run containers in sonarqube pod as, unless overwritten (such as for init-sysctl container) | `1000` | -| `elasticsearch.configureNode` | [DEPRECATED] Use initSysctl.enabled instead. | `true` | -| `elasticsearch.bootstrapChecks` | Enables/disables Elasticsearch bootstrap checks | `true` | -| `service.type` | Kubernetes service type | `ClusterIP` | -| `service.externalPort` | Kubernetes service port | `9000` | -| `service.internalPort` | Kubernetes container port | `9000` | -| `service.labels` | Kubernetes service labels | None | -| `service.annotations` | Kubernetes service annotations | None | -| `service.loadBalancerSourceRanges` | Kubernetes service LB Allowed inbound IP addresses | None | -| `service.loadBalancerIP` | Kubernetes service LB Optional fixed external IP | None | -| `ingress.enabled` | Flag for enabling ingress | false | -| `ingress.labels` | Ingress additional labels | `{}` | -| `ingress.hosts[0].name` | Hostname to your SonarQube installation | `sonar.organization.com` | -| `ingress.hosts[0].path` | Path within the URL structure | / | -| `ingress.hosts[0].serviceName` | Optional field to override the default serviceName of a path | None | -| `ingress.hosts[0].servicePort` | Optional field to override the default servicePort of a path | None | -| `ingress.tls` | Ingress secrets for TLS certificates | `[]` | -| `affinity` | Node / Pod affinities | `{}` | -| `tolerations` | List of node taints to tolerate | `[]` | -| `nodeSelector` | Node labels for pod assignment | `{}` | -| `hostAliases` | Aliases for IPs in /etc/hosts | `[]` | -| `readinessProbe.initialDelaySecond` | ReadinessProbe initial delay for SonarQube checking | `60` | -| `readinessProbe.periodSeconds` | ReadinessProbe period between checking SonarQube | `30` | -| `readinessProbe.failureThreshold` | ReadinessProbe thresold for marking as failed | `6` | -| `readinessProbe.sonarWebContext` | SonarQube web context for readinessProbe | / | -| `livenessProbe.initialDelaySecond` | LivenessProbe initial delay for SonarQube checking | `60` | -| `livenessProbe.periodSeconds` | LivenessProbe period between checking SonarQube | `30` | -| `livenessProbe.sonarWebContext` | SonarQube web context for livenessProbe | / | -| `initContainers.image` | Change init container image | `busybox:1.32` | -| `initContainers.securityContext` | SecurityContext for init containers | `nil` | -| `initContainers.resources` | Resources for init containers | `{}` | -| `caCerts.image` | Change init CA certificates container image | `adoptopenjdk/openjdk11:alpine` | -| `caCerts.secret` | Name of the secret containing additional CA certificates | `nil` | -| `initSysctl.enabled` | Modify k8s worker to conform to system requirements | `true` | -| `initSysctl.vmMaxMapCount` | Set init sysctl container vm.max_map_count | `524288` | -| `initSysctl.fsFileMax` | Set init sysctl container fs.file-max | `131072` | -| `initSysctl.nofile` | Set init sysctl container open file descriptors limit | `131072` | -| `initSysctl.nproc` | Set init sysctl container open threads limit | `8192 ` | -| `initSysctl.image` | Change init sysctl container image | `busybox:1.32` | -| `initSysctl.securityContext` | InitSysctl container security context | `{privileged: true}` | -| `initSysctl.resources` | InitSysctl container resource requests & limits | `{}` | -| `plugins.install` | List of plugins to install | `[]` | -| `plugins.lib` | Plugins libray | `[]` | -| `plugins.resources` | Plugin Pod resource requests & limits | `{}` | -| `plugins.httpProxy` | For use behind a corporate proxy when downloading plugins | "" | -| `plugins.httpsProxy` | For use behind a corporate proxy when downloading plugins | "" | -| `plugins.noProxy` | For use behind a corporate proxy when downloading plugins | "" | -| `plugins.image` | Image for plugins container | "" | -| `plugins.resources` | Resources for plugins container | "" | -| `plugins.netrcCreds` | Name of the secret containing .netrc file to use creds when downloading plugins | "" | -| `jvmOpts` | Values to add to SONARQUBE_WEB_JVM_OPTS | `""` | -| `env` | Environment variables to attach to the pods | `nil` | -| `annotations` | Sonarqube Pod annotations | `{}` | -| `resources` | Sonarqube Pod resource requests & limits | `{}` | -| `persistence.enabled` | Flag for enabling persistent storage | false | -| `persistence.annotations` | Kubernetes pvc annotations | `{}` | -| `persistence.existingClaim` | Do not create a new PVC but use this one | None | -| `persistence.storageClass` | Storage class to be used | "" | -| `persistence.accessMode` | Volumes access mode to be set | `ReadWriteOnce` | -| `persistence.size` | Size of the volume | 10Gi | -| `persistence.volumes` | Specify extra volumes. Refer to ".spec.volumes" specification | [] | -| `persistence.mounts` | Specify extra mounts. Refer to ".spec.containers.volumeMounts" specification | [] | -| `emptyDir` | Configuration of resources for `emptyDir` | `{}` | -| `sonarProperties` | Custom `sonar.properties` file | None | -| `sonarSecretProperties` | Additional `sonar.properties` file to load from a secret | None | -| `sonarSecretKey` | Name of existing secret used for settings encryption | None | -| `jdbcDatabaseType` | Type of the JDBC Database driver | `postgreql` | -| `jdbcUrlOverride` | Overrides default JDBC URL creation | None | -| `postgresql.enabled` | Set to `false` to use external server | `true` | -| `postgresql.existingSecret` | Secret containing the password of the external Postgresql server | `null` | -| `postgresql.postgresqlServer` | Hostname of the external Postgresql server | `null` | -| `postgresql.postgresqlUsername` | Postgresql database user | `sonarUser` | -| `postgresql.postgresqlPassword` | Postgresql database password | `sonarPass` | -| `postgresql.postgresqlDatabase` | Postgresql database name | `sonarDB` | -| `postgresql.service.port` | Postgresql port | `5432` | -| `postgresql.resources.requests.memory`| Postgresql memory request | `256Mi` | -| `postgresql.resources.requests.cpu` | Postgresql cpu request | `250m` | -| `postgresql.resources.limits.memory` | Postgresql memory limit | `2Gi` | -| `postgresql.resources.limits.cpu` | Postgresql cpu limit | `2` | -| `postgresql.persistence.enabled` | Postgresql persistence en/disabled | `true` | -| `postgresql.persistence.accessMode` | Postgresql persistence accessMode | `ReadWriteOnce` | -| `postgresql.persistence.size` | Postgresql persistence size | `20Gi` | -| `postgresql.persistence.storageClass` | Postgresql persistence storageClass | `""` | -| `postgresql.securityContext.enabled` | Postgresql securityContext en/disabled | `true` | -| `postgresql.securityContext.fsGroup` | Postgresql securityContext fsGroup | `1001` | -| `postgresql.securityContext.runAsUser`| Postgresql securityContext runAsUser | `1001` | -| `postgresql.volumePermissions.enabled`| Postgres vol permissions en/disabled | `false` | -| `postgresql.volumePermissions.securityContext.runAsUser`| Postgres vol permissions secContext runAsUser | `0` | -| `postgresql.shmVolume.chmod.enabled` | Postgresql shared memory vol en/disabled | `false` | -| `postgresql.serivceAccount.enabled` | Postgresql service Account creation en/disabled | `false` | -| `postgresql.serivceAccount.name` | Postgresql service Account name (commented out) | `""` | -| `podLabels` | Map of labels to add to the pods | `{}` | -| `sonarqubeFolder` | Directory name of Sonarqube | `/opt/sonarqube` | -| `tests.enabled` | Flag that allows tests to be excluded from generated yaml | true | -| `tests.image` | Change init test container image | `dduportal/bats:0.4.0` | -| `serviceAccount.create` | If set to true, create a serviceAccount | false | -| `serviceAccount.name` | Name of the serviceAccount to create/use | `sonarqube-sonarqube` | -| `serviceAccount.annotations` | Additional serviceAccount annotations | `{}` | -| `extraConfig.secrets` | A list of `Secret`s (which must contain key/value pairs) which may be loaded into the Scanner as environment variables | `[]` | -| `extraConfig.configmaps` | A list of `ConfigMap`s (which must contain key/value pairs) which may be loaded into the Scanner as environment variables | `[]` | -| `account.adminPassword` | Custom admin password | `"admin"` | -| `account.currentAdminPassword` | Current admin password | `"admin"` | -| `curlContainerImage` | Curl container image | `"curlimages/curl:latest"` | -| `terminationGracePeriodSeconds` | Configuration of `terminationGracePeriodSeconds` | `60` | +| Parameter | Description | Default | +| -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | +| `deploymentType` | Deployment Type | `StatefulSet` | +| `replicaCount` | Number of replicas deployed | `1` | +| `deploymentStrategy` | Deployment strategy | `{}` | +| `priorityClassName` | Schedule pods on priority (commented out) | `"high-priority"` | +| `schedulerName` | Kubernetes scheduler name | None | +| `OpenShift.enabled` | Define if this deployment is for OpenShift | `false` | +| `OpenShift.createSCC` | If this deployment is for OpenShift, define if SCC should be created for sonarqube pod | `true` | +| `image.repository` | image repository | `sonarqube` | +| `image.tag` | `sonarqube` image tag. | `8.8-community` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `image.pullSecret` | imagePullSecret to use for private repository (commented out) | `my-repo-secret` | +| `securityContext.fsGroup` | Group applied to mounted directories/files | `1000` | +| `containerSecurityContext.runAsUser` | User to run containers in sonarqube pod as, unless overwritten (such as for init-sysctl container) | `1000` | +| `elasticsearch.configureNode` | [DEPRECATED] Use initSysctl.enabled instead. | `true` | +| `elasticsearch.bootstrapChecks` | Enables/disables Elasticsearch bootstrap checks | `true` | +| `nginx.enabled` | Also install Nginx Ingress Helm | `false` | +| `service.type` | Kubernetes service type | `ClusterIP` | +| `service.externalPort` | Kubernetes service port | `9000` | +| `service.internalPort` | Kubernetes container port | `9000` | +| `service.labels` | Kubernetes service labels | None | +| `service.annotations` | Kubernetes service annotations | None | +| `service.loadBalancerSourceRanges` | Kubernetes service LB Allowed inbound IP addresses | None | +| `service.loadBalancerIP` | Kubernetes service LB Optional fixed external IP | None | +| `ingress.enabled` | Flag for enabling ingress | false | +| `ingress.labels` | Ingress additional labels | `{}` | +| `ingress.hosts[0].name` | Hostname to your SonarQube installation | `sonarqube.your-org.com` | +| `ingress.hosts[0].path` | Path within the URL structure | / | +| `ingress.hosts[0].serviceName` | Optional field to override the default serviceName of a path | None | +| `ingress.hosts[0].servicePort` | Optional field to override the default servicePort of a path | None | +| `ingress.tls` | Ingress secrets for TLS certificates | `[]` | +| `affinity` | Node / Pod affinities | `{}` | +| `tolerations` | List of node taints to tolerate | `[]` | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `hostAliases` | Aliases for IPs in /etc/hosts | `[]` | +| `readinessProbe.initialDelaySecond` | ReadinessProbe initial delay for SonarQube checking | `60` | +| `readinessProbe.periodSeconds` | ReadinessProbe period between checking SonarQube | `30` | +| `readinessProbe.failureThreshold` | ReadinessProbe thresold for marking as failed | `6` | +| `readinessProbe.sonarWebContext` | SonarQube web context for readinessProbe | / | +| `livenessProbe.initialDelaySecond` | LivenessProbe initial delay for SonarQube checking | `60` | +| `livenessProbe.periodSeconds` | LivenessProbe period between checking SonarQube | `30` | +| `livenessProbe.sonarWebContext` | SonarQube web context for livenessProbe | / | +| `livenessProbe.failureThreshold` | LivenessProbe thresold for marking as dead | `6` | +| `startupProbe.initialDelaySecond` | StartupProbe initial delay for SonarQube checking | `30` | +| `startupProbe.periodSeconds` | StartupProbe period between checking SonarQube | `10` | +| `startupProbe.sonarWebContext` | SonarQube web context for StartupProbe | / | +| `startupProbe.failureThreshold` | StartupProbe thresold for marking as failed | `24` | +| `initContainers.image` | Change init container image | `busybox:1.32` | +| `initContainers.securityContext` | SecurityContext for init containers | `nil` | +| `initContainers.resources` | Resources for init containers | `{}` | +| `extraInitContainers` | Extra init containers to e.g. download required artifacts | `{}` | +| `caCerts.image` | Change init CA certificates container image | `adoptopenjdk/openjdk11:alpine` | +| `caCerts.secret` | Name of the secret containing additional CA certificates | `nil` | +| `initSysctl.enabled` | Modify k8s worker to conform to system requirements | `true` | +| `initSysctl.vmMaxMapCount` | Set init sysctl container vm.max_map_count | `524288` | +| `initSysctl.fsFileMax` | Set init sysctl container fs.file-max | `131072` | +| `initSysctl.nofile` | Set init sysctl container open file descriptors limit | `131072` | +| `initSysctl.nproc` | Set init sysctl container open threads limit | `8192 ` | +| `initSysctl.image` | Change init sysctl container image | `busybox:1.32` | +| `initSysctl.securityContext` | InitSysctl container security context | `{privileged: true}` | +| `initSysctl.resources` | InitSysctl container resource requests & limits | `{}` | +| `initFs.enabled` | Enable file permission change with init container | true | +| `initFs.image` | InitFS container image | `busybox:1.32` | +| `initFs.securityContext.privileged` | InitFS container needs to run privileged | true | +| `prometheusExporter.enabled` | Use the Prometheus JMX exporter | true | +| `prometheusExporter.version` | jmx_prometheus_javaagent version to download from Maven Central | `0.15.0` | +| `prometheusExporter.downloadURL` | Alternative full download URL for the jmx_prometheus_javaagent.jar (overrides `prometheusExporter.version`) | "" | +| `prometheusExporter.config` | Prometheus JMX exporter config yaml | see `values.yaml` | +| `prometheusExporter.httpProxy` | HTTP proxy for downloading JMX agent | `""` | +| `prometheusExporter.httpsProxy` | HTTPS proxy for downloading JMX agent | `""` | +| `prometheusExporter.noProxy` | No proxy for downloading JMX agent | `""` | +| `prometheusExporter.securityContext` | Security context for downloading the jmx agent | see `values.yaml` | +| `plugins.install` | List of plugins to install | `[]` | +| `plugins.lib` | Plugins libray | `[]` | +| `plugins.resources` | Plugin Pod resource requests & limits | `{}` | +| `plugins.httpProxy` | For use behind a corporate proxy when downloading plugins | "" | +| `plugins.httpsProxy` | For use behind a corporate proxy when downloading plugins | "" | +| `plugins.noProxy` | For use behind a corporate proxy when downloading plugins | "" | +| `plugins.image` | Image for plugins container | "" | +| `plugins.resources` | Resources for plugins container | "" | +| `plugins.netrcCreds` | Name of the secret containing .netrc file to use creds when downloading plugins | "" | +| `plugins.noCheckCertificate` | Flag to not check server's certificate when downloading plugins | `false` | +| `plugins.securityContext` | Security context for the container to download plugins | see `values.yaml` | +| `jvmOpts` | Values to add to SONARQUBE_WEB_JVM_OPTS | `""` | +| `jvmCEOpts` | Values to add to SONAR_CE_JAVAOPTS | `""` | +| `monitoringPasscode` | Value for sonar.web.systemPasscode. needed for liveness probes | `"define_it"` | +| `env` | Environment variables to attach to the pods | `nil` | +| `annotations` | Sonarqube Pod annotations | `{}` | +| `resources.requests.memory` | Sonarqube memory request | `2Gi` | +| `resources.requests.cpu` | Sonarqube cpu request | `400m` | +| `resources.limits.memory` | Sonarqube memory limit | `4096M` | +| `resources.limits.cpu` | Sonarqube cpu limit | `800m` | +| `persistence.enabled` | Flag for enabling persistent storage | false | +| `persistence.annotations` | Kubernetes pvc annotations | `{}` | +| `persistence.existingClaim` | Do not create a new PVC but use this one | None | +| `persistence.storageClass` | Storage class to be used | "" | +| `persistence.accessMode` | Volumes access mode to be set | `ReadWriteOnce` | +| `persistence.size` | Size of the volume | 5Gi | +| `persistence.volumes` | Specify extra volumes. Refer to ".spec.volumes" specification | [] | +| `persistence.mounts` | Specify extra mounts. Refer to ".spec.containers.volumeMounts" specification | [] | +| `emptyDir` | Configuration of resources for `emptyDir` | `{}` | +| `sonarProperties` | Custom `sonar.properties` file | None | +| `sonarSecretProperties` | Additional `sonar.properties` file to load from a secret | None | +| `sonarSecretKey` | Name of existing secret used for settings encryption | None | +| `jdbcDatabaseType` | Type of the JDBC Database driver | `postgreql` | +| `jdbcUrlOverride` | Overrides default JDBC URL creation | None | +| `postgresql.enabled` | Set to `false` to use external server | `true` | +| `postgresql.existingSecret` | Secret containing the password of the external Postgresql server | `null` | +| `postgresql.existingSecretPasswordKey` | Secret Key containing the password of the external Postgresql server | `postgresql-password` | +| `postgresql.postgresqlServer` | Hostname of the external Postgresql server | `null` | +| `postgresql.postgresqlUsername` | Postgresql database user | `sonarUser` | +| `postgresql.postgresqlPassword` | Postgresql database password | `sonarPass` | +| `postgresql.postgresqlDatabase` | Postgresql database name | `sonarDB` | +| `postgresql.service.port` | Postgresql port | `5432` | +| `postgresql.resources.requests.memory` | Postgresql memory request | `256Mi` | +| `postgresql.resources.requests.cpu` | Postgresql cpu request | `250m` | +| `postgresql.resources.limits.memory` | Postgresql memory limit | `2Gi` | +| `postgresql.resources.limits.cpu` | Postgresql cpu limit | `2` | +| `postgresql.persistence.enabled` | Postgresql persistence en/disabled | `true` | +| `postgresql.persistence.accessMode` | Postgresql persistence accessMode | `ReadWriteOnce` | +| `postgresql.persistence.size` | Postgresql persistence size | `20Gi` | +| `postgresql.persistence.storageClass` | Postgresql persistence storageClass | `""` | +| `postgresql.securityContext.enabled` | Postgresql securityContext en/disabled | `true` | +| `postgresql.securityContext.fsGroup` | Postgresql securityContext fsGroup | `1001` | +| `postgresql.securityContext.runAsUser` | Postgresql securityContext runAsUser | `1001` | +| `postgresql.volumePermissions.enabled` | Postgres vol permissions en/disabled | `false` | +| `postgresql.volumePermissions.securityContext.runAsUser` | Postgres vol permissions secContext runAsUser | `0` | +| `postgresql.shmVolume.chmod.enabled` | Postgresql shared memory vol en/disabled | `false` | +| `postgresql.serivceAccount.enabled` | Postgresql service Account creation en/disabled | `false` | +| `postgresql.serivceAccount.name` | Postgresql service Account name (commented out) | `""` | +| `podLabels` | Map of labels to add to the pods | `{}` | +| `sonarqubeFolder` | Directory name of Sonarqube | `/opt/sonarqube` | +| `tests.enabled` | Flag that allows tests to be excluded from generated yaml | true | +| `tests.image` | Change init test container image | `dduportal/bats:0.4.0` | +| `serviceAccount.create` | If set to true, create a serviceAccount | false | +| `serviceAccount.name` | Name of the serviceAccount to create/use | `sonarqube-sonarqube` | +| `serviceAccount.annotations` | Additional serviceAccount annotations | `{}` | +| `extraConfig.secrets` | A list of `Secret`s (which must contain key/value pairs) which may be loaded into the Scanner as environment variables | `[]` | +| `extraConfig.configmaps` | A list of `ConfigMap`s (which must contain key/value pairs) which may be loaded into the Scanner as environment variables | `[]` | +| `account.adminPassword` | Custom admin password | `"admin"` | +| `account.currentAdminPassword` | Current admin password | `"admin"` | +| `curlContainerImage` | Curl container image | `"curlimages/curl:latest"` | +| `adminJobAnnotations` | Custom annotations for admin hook Job | `{}` | +| `terminationGracePeriodSeconds` | Configuration of `terminationGracePeriodSeconds` | `60` | You can also configure values for the PostgreSQL database via the Postgresql [Chart](https://hub.helm.sh/charts/bitnami/postgresql) @@ -213,13 +260,11 @@ Since SonarQube comes bundled with an Elasticsearch instance, some [bootstrap ch This chart offers the option to use an initContainer in privilaged mode to automatically set certain kernel settings on the kube worker. While this can ensure proper functionality of Elasticsearch, modifying the underlying kernel settings on the Kubernetes node can impact other users. It may be best to work with your cluster administrator to either provide specific nodes with the proper kernel settings, or ensure they are set cluster wide. -To enable auto-configuration of the kube worker node, set `elasticsearch.configureNode` to `true`. This is the default behavior, so you do not need to explicitly set this. +To enable auto-configuration of the kube worker node, set `elasticsearch.configureNode` to `true`. This is the default behavior, so you do not need to explicitly set this. This will run `sysctl -w vm.max_map_count=262144` on the worker where the sonarqube pod(s) get scheduled. This needs to be set to `262144` but normally defaults to `65530`. Other kernel settings are recommended by the [docker image](https://hub.docker.com/_/sonarqube/#requirements), but the defaults work fine in most cases. -To disable worker node configuration, set `elasticsearch.configureNode` to `false`. Note that if node configuration is not enabled, then you will likely need to also disable the Elasticsearch bootstrap checks. These can be explicitly disabled by setting `elasticsearch.bootstrapChecks` to `false`. - -### As of 7.9 Mysql is no longer supported, so it has been removed from the chart +To disable worker node configuration, set `elasticsearch.configureNode` to `false`. Note that if node configuration is not enabled, then you will likely need to also disable the Elasticsearch bootstrap checks. These can be explicitly disabled by setting `elasticsearch.bootstrapChecks` to `false`. ### Extra Config @@ -229,20 +274,20 @@ In such environments, configuration may be read, via environment variables, from 1. Create a `ConfigMap` (or `Secret`) containing key/value pairs, as expected by Sonarqube - ```yaml - apiVersion: v1 - kind: ConfigMap - metadata: - name: external-sonarqube-opts - data: - SONARQUBE_JDBC_USERNAME: foo - SONARQUBE_JDBC_URL: jdbc:postgresql://db.example.com:5432/sonar - ``` + ```yaml + apiVersion: v1 + kind: ConfigMap + metadata: + name: external-sonarqube-opts + data: + SONARQUBE_JDBC_USERNAME: foo + SONARQUBE_JDBC_URL: jdbc:postgresql://db.example.com:5432/sonar + ``` 2. Set the following in your `values.yaml` (using the key `extraConfig.secrets` to reference `Secret`s) - ```yaml - extraConfig: - configmaps: - - external-sonarqube-opts - ``` + ```yaml + extraConfig: + configmaps: + - external-sonarqube-opts + ``` diff --git a/chart/charts/ingress-nginx-3.29.0.tgz b/chart/charts/ingress-nginx-3.29.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..791f8fe6bf54b35032434eed21388d693e0f9f9b Binary files /dev/null and b/chart/charts/ingress-nginx-3.29.0.tgz differ diff --git a/chart/requirements.lock b/chart/requirements.lock index f7b92aa528c3cda8b174093f53d621e1e112a8ff..4e98a2f3a85dab011754d77aed359e4f23571adb 100644 --- a/chart/requirements.lock +++ b/chart/requirements.lock @@ -1,6 +1,9 @@ dependencies: +- name: ingress-nginx + repository: https://kubernetes.github.io/ingress-nginx + version: 3.29.0 - name: gluon repository: oci://registry.dso.mil/platform-one/big-bang/apps/library-charts/gluon version: 0.1.1 -digest: sha256:cf1107c00a11cde8074a39624643312fe85ee11250bb7d9380e3787bde0af0f7 -generated: "2021-05-25T13:09:48.372995-06:00" +digest: sha256:1ff95a59506ab376f44593d141fd1472b248f30d2a8b151ee041bb6a4ff319d1 +generated: "2021-06-07T16:19:44.1121955-06:00" diff --git a/chart/requirements.yaml b/chart/requirements.yaml index db53d78925e452e39dd827990828a133d7c2acb5..c47ac94eff7243f0a60b173daf8d2ae9e23aa17d 100644 --- a/chart/requirements.yaml +++ b/chart/requirements.yaml @@ -1,5 +1,12 @@ dependencies: - - name: postgresql - version: 8.6.4 - repository: file://./deps/postgresql - condition: postgresql.enabled +- name: postgresql + version: 8.6.4 + repository: file://./deps/postgresql + condition: postgresql.enabled +- name: ingress-nginx + version: 3.29.0 + repository: https://kubernetes.github.io/ingress-nginx + condition: nginx.enabled +- name: gluon + version: "0.1.1" + repository: "oci://registry.dso.mil/platform-one/big-bang/apps/library-charts/gluon" \ No newline at end of file diff --git a/chart/templates/NOTES.txt b/chart/templates/NOTES.txt index 1633b453bbd55ee0f6c33cd7718a670f1a17a537..571015fce9db99177c0690e1cbfeb3f9f780c7a3 100644 --- a/chart/templates/NOTES.txt +++ b/chart/templates/NOTES.txt @@ -1,9 +1,10 @@ -{{- if not .Values.istio.enabled }} 1. Get the application URL by running these commands: {{- if .Values.ingress.enabled }} {{- range .Values.ingress.hosts }} http://{{ .name }} {{- end }} +{{- else if .Values.istio.enabled }} + https://sonarqube.{{ .Values.hostname }} {{- else if contains "NodePort" .Values.service.type }} export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "sonarqube.fullname" . }}) export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") @@ -18,4 +19,3 @@ echo "Visit http://127.0.0.1:8080 to use your application" kubectl port-forward $POD_NAME 8080:{{ .Values.service.externalPort }} -n {{ .Release.Namespace }} {{- end }} -{{- end }} \ No newline at end of file diff --git a/chart/templates/_helpers.tpl b/chart/templates/_helpers.tpl index 8059ff8c2ce3c005f62a79cac98fc74a883f9746..157d41d721ab7116cb62ef4ce051b4350b6dd13f 100644 --- a/chart/templates/_helpers.tpl +++ b/chart/templates/_helpers.tpl @@ -43,13 +43,24 @@ Set postgresql.secret {{- define "postgresql.secret" -}} {{- if .Values.postgresql.existingSecret -}} {{- .Values.postgresql.existingSecret -}} -{{- else if .Values.postgresql.enabled -}} -{{- template "postgresql.fullname" . -}} -{{- else -}} +{{- else if .Values.postgresql.enabled -}} +{{- template "postgresql.fullname" . -}} +{{- else -}} {{- template "sonarqube.fullname" . -}} {{- end -}} {{- end -}} +{{/* +Set postgresql.secretKey +*/}} +{{- define "postgresql.secretPasswordKey" -}} +{{- if and .Values.postgresql.existingSecretPasswordKey .Values.postgresql.existingSecret -}} +{{- .Values.postgresql.existingSecretPasswordKey -}} +{{- else -}} +{{- "postgresql-password" -}} +{{- end -}} +{{- end -}} + {{/* Set postgresql.useInternalSecret */}} @@ -61,6 +72,43 @@ true {{- end -}} {{- end -}} +{{/* +Set sonarqube.jvmOpts +*/}} +{{- define "sonarqube.jvmOpts" -}} +{{- if and .Values.caCerts .Values.prometheusExporter.enabled -}} +{{ printf "-javaagent:%s/data/jmx_prometheus_javaagent.jar=8000:%s/conf/prometheus-config.yaml -Djavax.net.ssl.trustStore=%s/certs/cacerts %s" .Values.sonarqubeFolder .Values.sonarqubeFolder .Values.sonarqubeFolder .Values.jvmOpts | trim | quote }} +{{- else if .Values.caCerts -}} +{{ printf "-Djavax.net.ssl.trustStore=%s/certs/cacerts %s" .Values.sonarqubeFolder .Values.jvmOpts | trim | quote }} +{{- else if .Values.prometheusExporter.enabled -}} +{{ printf "-javaagent:%s/data/jmx_prometheus_javaagent.jar=8000:%s/conf/prometheus-config.yaml %s" .Values.sonarqubeFolder .Values.sonarqubeFolder .Values.jvmOpts | trim | quote }} +{{- else -}} +{{ printf "%s" .Values.jvmOpts }} +{{- end -}} +{{- end -}} + +{{/* +Set sonarqube.jvmCEOpts +*/}} +{{- define "sonarqube.jvmCEOpts" -}} +{{- if .Values.caCerts -}} +{{ printf "-Djavax.net.ssl.trustStore=%s/certs/cacerts %s" .Values.sonarqubeFolder .Values.jvmCeOpts | trim | quote }} +{{- else -}} +{{ printf "%s" .Values.jvmCeOpts }} +{{- end -}} +{{- end -}} + +{{/* +Set prometheusExporter.downloadURL +*/}} +{{- define "prometheusExporter.downloadURL" -}} +{{- if .Values.prometheusExporter.downloadURL -}} +{{ printf "%s" .Values.prometheusExporter.downloadURL }} +{{- else -}} +{{ printf "https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/%s/jmx_prometheus_javaagent-%s.jar" .Values.prometheusExporter.version .Values.prometheusExporter.version }} +{{- end -}} +{{- end -}} + {{/* Create chart name and version as used by the chart label. */}} diff --git a/chart/templates/change-admin-password-hook.yml b/chart/templates/change-admin-password-hook.yml index f3010b84f3d52278b4855f6c2498188173e50b4c..6cfae7d395d1f8a51939272dfdf68d0c13dc6eeb 100644 --- a/chart/templates/change-admin-password-hook.yml +++ b/chart/templates/change-admin-password-hook.yml @@ -15,6 +15,9 @@ metadata: annotations: "helm.sh/hook": post-install "helm.sh/hook-delete-policy": hook-succeeded + {{- range $key, $value := .Values.adminJobAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} spec: template: metadata: @@ -31,6 +34,6 @@ spec: containers: - name: {{ template "sonarqube.fullname" . }}-change-default-admin-password image: {{ default "curlimages/curl:latest" .Values.curlContainerImage }} - command: ["sh", "-c", 'until curl -v --connect-timeout 100 {{ template "sonarqube.fullname" . }}:{{ default 9000 .Values.service.internalPort }}/api/system/status | grep -w UP; do sleep 10; done; curl -v --connect-timeout 100 -u admin:{{ default "admin" .Values.account.currentAdminPassword }} -X POST "{{ template "sonarqube.fullname" . }}:{{ default 9000 .Values.service.internalPort }}/api/users/change_password?login=admin&previousPassword={{ default "admin" .Values.account.currentAdminPassword }}&password={{ default "admin" .Values.account.adminPassword }}"'] + command: ["sh", "-c", 'until curl -v --connect-timeout 100 {{ template "sonarqube.fullname" . }}:{{ default 9000 .Values.service.internalPort }}/api/system/status | grep -w UP; do sleep 10; done; curl -v --connect-timeout 100 -u admin:{{ default "admin" .Values.account.currentAdminPassword }} -X POST "{{ template "sonarqube.fullname" . }}:{{ default 9000 .Values.service.internalPort }}/api/users/change_password?login=admin&previousPassword={{ .Values.account.currentAdminPassword | default "admin" | urlquery }}&password={{ .Values.account.adminPassword | default "admin" | urlquery }}"'] {{- end }} {{- end }} diff --git a/chart/templates/deployment.yaml b/chart/templates/deployment.yaml index da69ad2e28746c2f848c3e4b16d92adab7b3f8c3..860ce975432bb37595cee8b4dd5566bbe3e5936e 100644 --- a/chart/templates/deployment.yaml +++ b/chart/templates/deployment.yaml @@ -1,3 +1,4 @@ +{{- if eq .Values.deploymentType "Deployment"}} apiVersion: apps/v1 kind: Deployment metadata: @@ -58,11 +59,13 @@ spec: imagePullSecrets: - name: {{ .Values.image.pullSecret }} {{- end }} - {{- if or .Values.caCerts .Values.initSysctl.enabled .Values.elasticsearch.configureNode .Values.plugins.install .Values.postgresql.enabled (and .Values.sonarProperties .Values.sonarSecretProperties) }} initContainers: + {{- if .Values.extraInitContainers }} +{{ toYaml .Values.extraInitContainers | indent 8 }} + {{- end }} {{- if .Values.caCerts }} - name: ca-certs - image: {{ default "adoptopenjdk/openjdk11:alpine" .Values.caCerts.image }} + image: {{ default "registry1.dso.mil/ironbank/redhat/openjdk/openjdk11:1.11" .Values.caCerts.image }} imagePullPolicy: {{ .Values.image.pullPolicy }} command: ["sh"] args: ["-c", "cp -f \"${JAVA_HOME}/lib/security/cacerts\" /tmp/certs/cacerts; if [ \"$(ls /tmp/secrets/ca-certs)\" ]; then for f in /tmp/secrets/ca-certs/*; do keytool -importcert -file \"${f}\" -alias \"$(basename \"${f}\")\" -keystore /tmp/certs/cacerts -storepass changeit -trustcacerts -noprompt; done; fi;"] @@ -106,7 +109,7 @@ spec: {{- end }} {{- if .Values.plugins.install }} - name: install-plugins - image: {{ default "registry.dso.mil/platform-one/big-bang/apps/developer-tools/sonarqube/alpine-wget:latest" .Values.plugins.image }} + image: {{ default "registry1.dso.mil/ironbank/sonarsource/sonarqube/sonarqube8-community:8.9-community" .Values.plugins.image }} imagePullPolicy: {{ .Values.image.pullPolicy }} command: ["sh", "-e", @@ -130,8 +133,14 @@ spec: {{- end }} resources: {{ toYaml (default .Values.initContainers.resources .Values.plugins.resource) | indent 12 }} - {{- with .Values.env }} env: + - name: http_proxy + value: {{ default "" .Values.plugins.httpProxy }} + - name: https_proxy + value: {{ default "" .Values.plugins.httpsProxy }} + - name: no_proxy + value: {{ default "" .Values.plugins.noProxy }} + {{- with .Values.env }} {{- . | toYaml | trim | nindent 12 }} {{- end }} {{- end }} @@ -164,16 +173,12 @@ spec: {{- end }} {{- if .Values.postgresql.enabled }} - name: "wait-for-db" - image: registry1.dso.mil/ironbank/opensource/postgres/postgresql96:9.6.20 + image: {{ default "registry.dso.mil/platform-one/big-bang/apps/developer-tools/sonarqube/busybox:1.32" .Values.initContainers.image }} imagePullPolicy: {{ .Values.image.pullPolicy }} resources: {{ toYaml .Values.initContainers.resources | indent 12 }} - command: ["/bin/sh", "-c", "until pg_isready -h {{ .Release.Name}}-postgresql -p 5432 -U {{ .Values.postgresql.postgresqlUsername }}; do sleep 2; done"] - env: - - name: POSTGRES_HOST_AUTH_METHOD - value: "trust" - {{- end }} - {{- end }} + command: ["/bin/sh", "-c", "for i in $(seq 1 200); do nc -z -w3 {{ .Release.Name}}-postgresql 5432 && exit 0 || sleep 2; done; exit 1"] + {{- end }} {{- if .Values.priorityClassName }} priorityClassName: {{ .Values.priorityClassName }} {{- end }} @@ -202,24 +207,18 @@ spec: containerPort: {{ .Values.service.internalPort }} protocol: TCP env: - {{- with .Values.env }} - {{- . | toYaml | trim | nindent 12 }} - {{- end }} - name: SONAR_WEB_JAVAOPTS - {{- if .Values.caCerts }} - value: {{ printf "-Djavax.net.ssl.trustStore=%s/certs/cacerts %s" .Values.sonarqubeFolder .Values.jvmOpts | trim | quote }} - {{- else }} - value: "{{ .Values.jvmOpts }}" - {{- end }} - {{- if .Values.caCerts }} + value: {{ template "sonarqube.jvmOpts" . }} - name: SONAR_CE_JAVAOPTS - value: {{ printf "-Djavax.net.ssl.trustStore=%s/certs/cacerts" .Values.sonarqubeFolder | trim | quote }} - {{- end }} + value: {{ template "sonarqube.jvmCEOpts" . }} - name: SONAR_JDBC_PASSWORD valueFrom: secretKeyRef: name: {{ template "postgresql.secret" . }} - key: postgresql-password + key: {{ template "postgresql.secretPasswordKey" . }} + {{- with .Values.env }} + {{- . | toYaml | trim | nindent 12 }} + {{- end }} envFrom: - configMapRef: name: {{ template "sonarqube.fullname" . }}-postgres-config @@ -271,7 +270,11 @@ spec: - mountPath: {{ .Values.sonarqubeFolder }}/data name: sonarqube subPath: data - {{- if .Values.plugins.install }} + {{- if .Values.persistence.enabled }} + - mountPath: {{ .Values.sonarqubeFolder }}/extensions + name: sonarqube + subPath: extensions + {{- else if .Values.plugins.install }} - mountPath: {{ .Values.sonarqubeFolder }}/extensions/downloads name: sonarqube subPath: extensions/downloads @@ -371,3 +374,4 @@ spec: - name : concat-dir emptyDir: {{- toYaml .Values.emptyDir | nindent 10 -}} {{- end }} +{{- end }} diff --git a/chart/templates/ingress.yaml b/chart/templates/ingress.yaml index 11d8c2b944d15e577cfea0d3023efc1d3899326e..fe6dc93c75fe3126d64b0f198f6e920a4c215f65 100644 --- a/chart/templates/ingress.yaml +++ b/chart/templates/ingress.yaml @@ -1,7 +1,9 @@ {{- if .Values.ingress.enabled -}} {{- $serviceName := include "sonarqube.fullname" . -}} {{- $servicePort := .Values.service.externalPort -}} -{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} +{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} +apiVersion: networking.k8s.io/v1 +{{ else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} apiVersion: networking.k8s.io/v1beta1 {{ else }} apiVersion: extensions/v1beta1 @@ -23,7 +25,32 @@ metadata: {{ $key }}: {{ $value | quote }} {{- end }} {{- end }} +{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} spec: + rules: + {{- range .Values.ingress.hosts }} + - host: {{ printf "%s" .name }} + http: + paths: + - backend: + service: + name: {{ default $serviceName .serviceName }} + port: + number: {{ default $servicePort .servicePort }} + path: {{ .path}} + pathType: ImplementationSpecific + {{- end }} +{{ else }} +spec: + {{- if .Values.ingress.annotations }} + {{- range $key, $value := .Values.ingress.annotations }} + {{- if and (eq $key "kubernetes.io/ingress.class") (contains $value "gce") }} + backend: + serviceName: {{ default $serviceName .serviceName }} + servicePort: {{ default $servicePort .servicePort }} + {{- end }} + {{- end }} + {{- end }} rules: {{- range .Values.ingress.hosts }} - host: {{ .name }} @@ -34,6 +61,7 @@ spec: serviceName: {{ default $serviceName .serviceName }} servicePort: {{ default $servicePort .servicePort }} {{- end -}} +{{ end -}} {{- if .Values.ingress.tls }} tls: {{ toYaml .Values.ingress.tls | indent 4 }} diff --git a/chart/templates/init-fs.yaml b/chart/templates/init-fs.yaml new file mode 100644 index 0000000000000000000000000000000000000000..bb5026ff6d844f01dfd46d344d41cff998047ffa --- /dev/null +++ b/chart/templates/init-fs.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "sonarqube.fullname" . }}-init-fs + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + init_fs.sh: |- + {{- if .Values.persistence.enabled }} + chown -R {{ .Values.persistence.uid }}: {{ .Values.sonarqubeFolder }} + {{- end }} diff --git a/chart/templates/install-plugins.yaml b/chart/templates/install-plugins.yaml index 618653ae317f9a6740a8731f5356e20368e41551..eefc4b96db56a0e7bff9911d76ec038c8ddc0272 100644 --- a/chart/templates/install-plugins.yaml +++ b/chart/templates/install-plugins.yaml @@ -9,21 +9,12 @@ metadata: heritage: {{ .Release.Service }} data: install_plugins.sh: |- - {{- if .Values.plugins.httpProxy }} - export http_proxy={{ .Values.plugins.httpProxy }} - {{- end }} - {{- if .Values.plugins.httpsProxy }} - export https_proxy={{ .Values.plugins.httpsProxy }} - {{- end }} - {{- if .Values.plugins.noProxy }} - export no_proxy={{ .Values.plugins.noProxy }} - {{- end }} {{- if .Values.plugins.install }} [ -e {{ .Values.sonarqubeFolder }}/extensions/downloads/* ] && rm {{ .Values.sonarqubeFolder }}/extensions/downloads/* - {{ range $index, $val := .Values.plugins.install }} - echo {{ $val | quote }} >> {{ $.Values.sonarqubeFolder }}/extensions/downloads/list{{ end }} - cat {{ .Values.sonarqubeFolder }}/extensions/downloads/list | xargs -n 1 -P 8 wget --directory-prefix {{ .Values.sonarqubeFolder }}/extensions/downloads --no-verbose - rm {{ .Values.sonarqubeFolder }}/extensions/downloads/list + cd {{ .Values.sonarqubeFolder }}/extensions/downloads + {{- range $index, $val := .Values.plugins.install }} + curl {{ if $.Values.plugins.noCheckCertificate }}--insecure{{ end }} -fsSLO {{ $val | quote }} + {{- end }} {{- end }} {{- if .Values.plugins.lib }} {{- range $index, $val := .Values.plugins.lib }} diff --git a/chart/templates/prometheus-config.yaml b/chart/templates/prometheus-config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..84481d517dcede7a65722fdb37706902477ad1b3 --- /dev/null +++ b/chart/templates/prometheus-config.yaml @@ -0,0 +1,14 @@ +{{- if .Values.prometheusExporter.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "sonarqube.fullname" . }}-prometheus-config + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + prometheus-config.yaml: |- +{{ toYaml .Values.prometheusExporter.config | indent 8 }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/secret.yaml b/chart/templates/secret.yaml index 220be8e4a0507b80851033c6ae4853f7e3cda937..0df976acbd713066830c11fb7d47667fc9fc5f61 100644 --- a/chart/templates/secret.yaml +++ b/chart/templates/secret.yaml @@ -10,5 +10,19 @@ metadata: heritage: {{ .Release.Service }} type: Opaque data: - postgresql-password: {{ .Values.postgresql.postgresqlPassword | b64enc | quote }} -{{- end -}} + {{ template "postgresql.secretPasswordKey" . }}: {{ .Values.postgresql.postgresqlPassword | b64enc | quote }} +{{- end }} + +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "sonarqube.fullname" . }}-monitoring-passcode + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +type: Opaque +data: + SONAR_WEB_SYSTEMPASSCODE: {{ .Values.monitoringPasscode | b64enc | quote }} \ No newline at end of file diff --git a/chart/templates/service.yaml b/chart/templates/service.yaml old mode 100644 new mode 100755 index c61fe09b87ce919a66a2fc7654ac0c3762d872a6..3824edf5e67fee5265b697f731e89c4b08ad1cd7 --- a/chart/templates/service.yaml +++ b/chart/templates/service.yaml @@ -23,6 +23,9 @@ spec: targetPort: http protocol: TCP name: http + {{- if .Values.service.nodePort }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} selector: app: {{ template "sonarqube.name" . }} release: {{ .Release.Name }} diff --git a/chart/templates/sonarqube-scc.yaml b/chart/templates/sonarqube-scc.yaml index 151dff343c65d00da915e4e47b6b9f29cac30c62..7f5ed6d8614dfdbaa9cc2c664fe330524edfe383 100644 --- a/chart/templates/sonarqube-scc.yaml +++ b/chart/templates/sonarqube-scc.yaml @@ -60,4 +60,4 @@ users: - system:serviceaccount:{{ .Release.Namespace }}:{{ .Release.Name }}-postgresql {{- end }} -{{- end }} +{{- end }} \ No newline at end of file diff --git a/chart/templates/sonarqube-sts.yaml b/chart/templates/sonarqube-sts.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8f1ec43d62147936cb617fa0baf7a68a7e111def --- /dev/null +++ b/chart/templates/sonarqube-sts.yaml @@ -0,0 +1,437 @@ +{{- if eq .Values.deploymentType "StatefulSet"}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "sonarqube.fullname" . }} + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + app.kubernetes.io/name: {{ template "sonarqube.name" . }}-{{ template "sonarqube.fullname" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/part-of: sonarqube + app.kubernetes.io/component: {{ template "sonarqube.fullname" . }} + app.kubernetes.io/version: {{ .Values.image.tag | quote }} +spec: + replicas: 1 + serviceName: {{ template "sonarqube.fullname" . }} + selector: + matchLabels: + app: {{ template "sonarqube.name" . }} + release: {{ .Release.Name }} + template: + metadata: + labels: + app: {{ template "sonarqube.name" . }} + release: {{ .Release.Name }} +{{- with .Values.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} + annotations: + checksum/init-sysctl: {{ include (print $.Template.BasePath "/init-sysctl.yaml") . | sha256sum }} + checksum/init-fs: {{ include (print $.Template.BasePath "/init-fs.yaml") . | sha256sum }} + checksum/plugins: {{ include (print $.Template.BasePath "/install-plugins.yaml") . | sha256sum }} + checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} +{{- if .Values.annotations}} + {{- range $key, $value := .Values.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + spec: + {{- if .Values.image.pullSecret }} + imagePullSecrets: + - name: {{ .Values.image.pullSecret }} + {{- end }} + initContainers: + {{- if .Values.extraInitContainers }} +{{ toYaml .Values.extraInitContainers | indent 8 }} + {{- end }} + {{- if .Values.postgresql.enabled }} + - name: "wait-for-db" + image: {{ default "registry.dso.mil/platform-one/big-bang/apps/developer-tools/sonarqube/busybox:1.32" .Values.initContainers.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + resources: +{{ toYaml .Values.initContainers.resources | indent 12 }} + command: ["/bin/sh", "-c", "for i in $(seq 1 200); do nc -z -w3 {{ .Release.Name}}-postgresql 5432 && exit 0 || sleep 2; done; exit 1"] + {{- end }} + {{- if or .Values.initSysctl.enabled .Values.elasticsearch.configureNode }} + {{- if .Values.caCerts }} + - name: ca-certs + image: {{ default "registry1.dso.mil/ironbank/redhat/openjdk/openjdk11:1.11" .Values.caCerts.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["sh"] + args: ["-c", "cp -f \"${JAVA_HOME}/lib/security/cacerts\" /tmp/certs/cacerts; if [ \"$(ls /tmp/secrets/ca-certs)\" ]; then for f in /tmp/secrets/ca-certs/*; do keytool -importcert -file \"${f}\" -alias \"$(basename \"${f}\")\" -keystore /tmp/certs/cacerts -storepass changeit -trustcacerts -noprompt; done; fi;"] + {{- if $securityContext := .Values.initContainers.securityContext }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml .Values.initContainers.resources | indent 12 }} + volumeMounts: + - mountPath: /tmp/certs + name: sonarqube + subPath: certs + - mountPath: /tmp/secrets/ca-certs + name: ca-certs + {{- with .Values.env }} + env: + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + {{- end }} + - name: init-sysctl + image: {{ default "registry.dso.mil/platform-one/big-bang/apps/developer-tools/sonarqube/busybox:1.32" .Values.initSysctl.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if $securityContext := (default .Values.initContainers.securityContext .Values.initSysctl.securityContext) }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml (default .Values.initContainers.resources .Values.initSysctl.resources) | indent 12 }} + command: ["sh", + "-e", + "/tmp/scripts/init_sysctl.sh"] + volumeMounts: + - name: init-sysctl + mountPath: /tmp/scripts/ + {{- with .Values.env }} + env: + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.prometheusExporter.enabled }} + - name: inject-prometheus-exporter + image: {{ default "registry1.dso.mil/ironbank/sonarsource/sonarqube/sonarqube8-community:8.9-community" .Values.prometheusExporter.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if $securityContext := (default .Values.initContainers.securityContext .Values.prometheusExporter.securityContext) }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml (default .Values.initContainers.resources .Values.prometheusExporter.resources) | indent 12 }} + command: ["/bin/sh","-c"] + args: ["curl -s {{ template "prometheusExporter.downloadURL" . }} --output /data/jmx_prometheus_javaagent.jar -v"] + volumeMounts: + - mountPath: /data + name: sonarqube + subPath: data + env: + - name: http_proxy + value: {{ default "" .Values.prometheusExporter.httpProxy }} + - name: https_proxy + value: {{ default "" .Values.prometheusExporter.httpsProxy }} + - name: no_proxy + value: {{ default "" .Values.prometheusExporter.noProxy }} + {{- with .Values.env }} + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + {{- end }} + {{- if and .Values.persistence.enabled .Values.initFs.enabled }} + - name: init-fs + image: {{ default "registry.dso.mil/platform-one/big-bang/apps/developer-tools/sonarqube/busybox:1.32" .Values.initFs.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if $securityContext := (default .Values.initContainers.securityContext .Values.initFs.securityContext) }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml (default .Values.initContainers.resources .Values.initFs.resources) | indent 12 }} + command: ["sh", + "-e", + "/tmp/scripts/init_fs.sh"] + volumeMounts: + - name: init-fs + mountPath: /tmp/scripts/ +{{- if .Values.persistence.mounts }} +{{ toYaml .Values.persistence.mounts | indent 12 }} +{{- end }} + {{- if .Values.caCerts }} + - mountPath: {{ .Values.sonarqubeFolder }}/certs + name: sonarqube + subPath: certs + {{- end }} + - mountPath: {{ .Values.sonarqubeFolder }}/data + name: sonarqube + subPath: data + {{- if .Values.persistence.enabled }} + - mountPath: {{ .Values.sonarqubeFolder }}/extensions + name: sonarqube + subPath: extensions + {{- else if .Values.plugins.install }} + - mountPath: {{ .Values.sonarqubeFolder }}/extensions/downloads + name: sonarqube + subPath: extensions/downloads + {{- end }} + {{- if .Values.plugins.lib }} + {{- range $index, $val := .Values.plugins.lib }} + - mountPath: {{ $.Values.sonarqubeFolder }}/lib/common/{{ $val }} + name: sonarqube + subPath: lib/common/{{ $val }} + {{- end }} + {{- end }} + - mountPath: {{ .Values.sonarqubeFolder }}/temp + name: sonarqube + subPath: temp + - mountPath: {{ .Values.sonarqubeFolder }}/logs + name: sonarqube + subPath: logs + - mountPath: /tmp + name: tmp-dir + {{- end }} + {{- if .Values.plugins.install }} + - name: install-plugins + image: {{ default "registry1.dso.mil/ironbank/sonarsource/sonarqube/sonarqube8-community:8.9-community" .Values.plugins.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["sh", + "-e", + "/tmp/scripts/install_plugins.sh"] + volumeMounts: + - mountPath: {{ .Values.sonarqubeFolder }}/extensions/downloads + name: sonarqube + subPath: extensions/downloads + - mountPath: {{ .Values.sonarqubeFolder }}/lib/common + name: sonarqube + subPath: lib/common + - name: install-plugins + mountPath: /tmp/scripts/ + {{- if .Values.plugins.netrcCreds }} + - name: plugins-netrc-file + mountPath: /root + {{- end }} + {{- if $securityContext := (default .Values.initContainers.securityContext .Values.plugins.securityContext) }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml (default .Values.initContainers.resources .Values.plugins.resource) | indent 12 }} + env: + - name: http_proxy + value: {{ default "" .Values.plugins.httpProxy }} + - name: https_proxy + value: {{ default "" .Values.plugins.httpsProxy }} + - name: no_proxy + value: {{ default "" .Values.plugins.noProxy }} + {{- with .Values.env }} + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.service.internalPort }} + protocol: TCP + resources: +{{ toYaml (default .Values.resources .Values.resource) | indent 12 }} + env: + - name: SONAR_WEB_JAVAOPTS + value: {{ template "sonarqube.jvmOpts" . }} + - name: SONAR_CE_JAVAOPTS + value: {{ template "sonarqube.jvmCEOpts" . }} + - name: SONAR_JDBC_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secret" . }} + key: {{ template "postgresql.secretPasswordKey" . }} + - name: SONAR_WEB_SYSTEMPASSCODE + valueFrom: + secretKeyRef: + name: {{ template "sonarqube.fullname" . }}-monitoring-passcode + key: SONAR_WEB_SYSTEMPASSCODE + {{- with .Values.env }} + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + envFrom: + - configMapRef: + name: {{ template "sonarqube.fullname" . }}-postgres-config +{{- range .Values.extraConfig.secrets }} + - secretRef: + name: {{ . }} +{{- end }} +{{- range .Values.extraConfig.configmaps }} + - configMapRef: + name: {{ . }} +{{- end }} + livenessProbe: + httpGet: + path: {{ .Values.livenessProbe.sonarWebContext }}api/system/status + port: http + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + readinessProbe: + httpGet: + path: {{ .Values.readinessProbe.sonarWebContext }}api/system/status + port: http + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + startupProbe: + httpGet: + scheme: HTTP + path: {{ .Values.readinessProbe.sonarWebContext }}api/system/status + port: 9000 + initialDelaySeconds: {{ .Values.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.startupProbe.periodSeconds }} + failureThreshold: {{ .Values.startupProbe.failureThreshold }} + {{- if .Values.containerSecurityContext }} + securityContext: +{{- toYaml .Values.containerSecurityContext | nindent 12 }} + {{- end }} + volumeMounts: +{{- if .Values.persistence.mounts }} +{{ toYaml .Values.persistence.mounts | indent 12 }} +{{- end }} + {{- if and .Values.sonarProperties .Values.sonarSecretProperties }} + - mountPath: {{ .Values.sonarqubeFolder }}/conf/sonar.properties + subPath: sonar.properties + name: concat-dir + {{- else if or .Values.sonarProperties (not .Values.elasticsearch.bootstrapChecks) }} + - mountPath: {{ .Values.sonarqubeFolder }}/conf/sonar.properties + subPath: sonar.properties + name: config + {{- end }} + {{- if .Values.sonarSecretKey }} + - mountPath: {{ .Values.sonarqubeFolder }}/secret/ + name: secret + {{- end }} + {{- if .Values.caCerts }} + - mountPath: {{ .Values.sonarqubeFolder }}/certs + name: sonarqube + subPath: certs + {{- end }} + - mountPath: {{ .Values.sonarqubeFolder }}/data + name: sonarqube + subPath: data + {{- if .Values.persistence.enabled }} + - mountPath: {{ .Values.sonarqubeFolder }}/extensions + name: sonarqube + subPath: extensions + {{- else if .Values.plugins.install }} + - mountPath: {{ .Values.sonarqubeFolder }}/extensions/downloads + name: sonarqube + subPath: extensions/downloads + {{- end }} + {{- if .Values.plugins.lib }} + {{- range $index, $val := .Values.plugins.lib }} + - mountPath: {{ $.Values.sonarqubeFolder }}/lib/common/{{ $val }} + name: sonarqube + subPath: lib/common/{{ $val }} + {{- end }} + {{- end }} + - mountPath: {{ .Values.sonarqubeFolder }}/temp + name: sonarqube + subPath: temp + - mountPath: {{ .Values.sonarqubeFolder }}/logs + name: sonarqube + subPath: logs + - mountPath: /tmp + name: tmp-dir + {{- if .Values.prometheusExporter.enabled }} + - mountPath: {{ .Values.sonarqubeFolder }}/conf/prometheus-config.yaml + subPath: prometheus-config.yaml + name: prometheus-config + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: +{{ toYaml .Values.tolerations | indent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: +{{ toYaml .Values.affinity | indent 8 }} + {{- end }} + {{- if .Values.serviceAccount.create }} + {{- if .Values.serviceAccount.name }} + serviceAccountName: {{ .Values.serviceAccount.name }} + {{- else }} + serviceAccountName: {{ include "sonarqube.fullname" . }} + {{- end }} + {{- end }} + volumes: +{{- if .Values.persistence.volumes }} +{{ tpl (toYaml .Values.persistence.volumes | indent 6) . }} +{{- end }} + {{- if or .Values.sonarProperties (not .Values.elasticsearch.bootstrapChecks) }} + - name: config + configMap: + name: {{ template "sonarqube.fullname" . }}-config + items: + - key: sonar.properties + path: sonar.properties + {{- end }} + {{- if .Values.sonarSecretProperties }} + - name: secret-config + secret: + secretName: {{ .Values.sonarSecretProperties }} + items: + - key: secret.properties + path: secret.properties + {{- end }} + {{- if .Values.sonarSecretKey }} + - name: secret + secret: + secretName: {{ .Values.sonarSecretKey }} + items: + - key: sonar-secret.txt + path: sonar-secret.txt + {{- end }} + {{- if .Values.caCerts }} + - name: ca-certs + secret: + secretName: {{ .Values.caCerts.secret }} + {{- end }} + {{- if .Values.plugins.netrcCreds }} + - name: plugins-netrc-file + secret: + secretName: {{ .Values.plugins.netrcCreds }} + items: + - key: netrc + path: .netrc + {{- end }} + - name: init-sysctl + configMap: + name: {{ template "sonarqube.fullname" . }}-init-sysctl + items: + - key: init_sysctl.sh + path: init_sysctl.sh + - name: init-fs + configMap: + name: {{ template "sonarqube.fullname" . }}-init-fs + items: + - key: init_fs.sh + path: init_fs.sh + - name: install-plugins + configMap: + name: {{ template "sonarqube.fullname" . }}-install-plugins + items: + - key: install_plugins.sh + path: install_plugins.sh + {{- if .Values.prometheusExporter.enabled }} + - name: prometheus-config + configMap: + name: {{ template "sonarqube.fullname" . }}-prometheus-config + items: + - key: prometheus-config.yaml + path: prometheus-config.yaml + {{- end }} + - name: sonarqube + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ if .Values.persistence.existingClaim }}{{ .Values.persistence.existingClaim }}{{- else }}{{ template "sonarqube.fullname" . }}{{- end }} + {{- else }} + emptyDir: {{- toYaml .Values.emptyDir | nindent 10 }} + {{- end }} + - name : tmp-dir + emptyDir: {{- toYaml .Values.emptyDir | nindent 10 }} + {{- if .Values.sonarSecretProperties }} + - name : concat-dir + emptyDir: {{- toYaml .Values.emptyDir | nindent 10 -}} + {{- end }} +{{- end }} diff --git a/chart/templates/tests/sonarqube-test.yaml b/chart/templates/tests/sonarqube-test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9ecef43edb490f256c0b7a2e8d52922867d296aa --- /dev/null +++ b/chart/templates/tests/sonarqube-test.yaml @@ -0,0 +1,47 @@ +{{- if .Values.tests.enabled -}} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ .Release.Name }}-ui-test" + annotations: + "helm.sh/hook": test-success + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + initContainers: + - name: "bats" + image: "bats/bats:1.2.1" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["bash", "-c"] + args: + - |- + set -ex + cp -R /opt/bats /tools/bats/ + volumeMounts: + - mountPath: /tools + name: tools + containers: + - name: {{ .Release.Name }}-ui-test + image: {{ default "bitnami/minideb-extras" .Values.tests.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: [ + "/tools/bats/bin/bats", + "--tap", + "/tests/run.sh"] + volumeMounts: + - mountPath: /tests + name: tests + readOnly: true + - mountPath: /tools + name: tools + volumes: + - name: tests + configMap: + name: {{ template "sonarqube.fullname" . }}-tests + - name: tools + emptyDir: {{ toYaml .Values.emptyDir | nindent 6 }} + restartPolicy: Never +{{- end -}} diff --git a/chart/tests/cypress/sonarqube-health.spec.js b/chart/tests/cypress/sonarqube-health.spec.js index 91dcead3d6ebac709bec13eaf891b59122fdd099..5325684b1c05598810be52bf94775788c8298aee 100644 --- a/chart/tests/cypress/sonarqube-health.spec.js +++ b/chart/tests/cypress/sonarqube-health.spec.js @@ -10,6 +10,7 @@ describe('Basic Sonarqube', function() { cy.get('input[name="password"]').type(Cypress.env('newpassword')) cy.get('input[name="password_confirmation"]').type(Cypress.env('newpassword')) cy.get('button[id="change-password"]').click() + cy.contains("I understand the risk").click() cy.scrollTo('topRight') cy.get('a[class="dropdown-toggle navbar-avatar"]').click() cy.contains("My Account").click() diff --git a/chart/values.yaml b/chart/values.yaml index 7bb5d87f8be4caec78668f3fb6f6e6cba3120310..28a1aa08505cdf166410e3f93ba2397e8522c842 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -1,6 +1,11 @@ # Default values for sonarqube. # This is a YAML-formatted file. # Declare variables to be passed into your templates. + +deploymentType: "StatefulSet" + +# If the deployment Type is set to Deployment sonarqube is deployed as a replica set +# There should not be more than 1 sonarqube instance connected to the same database replicaCount: 1 # This will use the default deployment strategy unless it is overriden @@ -20,12 +25,11 @@ OpenShift: image: repository: registry.dso.mil/platform-one/big-bang/apps/developer-tools/sonarqube/sonarqube8-community-bb - tag: 8.7.1-community-bb + tag: 8.9-community-bb pullPolicy: IfNotPresent # If using a private repository, the name of the imagePullSecret to use pullSecret: private-registry - # Set security context for sonarqube pod securityContext: fsGroup: 1000 @@ -41,6 +45,10 @@ elasticsearch: configureNode: false bootstrapChecks: true +# also install the nginx ingress helm chart +nginx: + enabled: false + service: type: ClusterIP externalPort: 9000 @@ -56,7 +64,7 @@ ingress: enabled: false # Used to create an Ingress record. hosts: - - name: sonar.example.com + - name: sonarqube.your-org.com # Different clouds or configurations might need /* as the default path path: / # For additional control over serviceName and servicePort @@ -84,11 +92,21 @@ affinity: {} # Tolerations for pod assignment # Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +# taint a node with the following command to mark it as not schedulable for new pods +# kubectl taint nodes sonarqube=true:NoSchedule +# The following statement will tolerate this taint and as such reverse a node for sonarqube tolerations: [] +# - key: "sonarqube" +# operator: "Equal" +# value: "true" +# effect: "NoSchedule" # Node labels for pod assignment # Ref: https://kubernetes.io/docs/user-guide/node-selection/ +# add a label to a node with the following command +# kubectl label node sonarqube=true nodeSelector: {} +# sonarqube: "true" # hostAliases allows the modification of the hosts file inside a container hostAliases: [] @@ -108,15 +126,24 @@ readinessProbe: livenessProbe: initialDelaySeconds: 60 periodSeconds: 30 + failureThreshold: 6 # If an ingress *path* other than the root (/) is defined, it should be reflected here # A trailing "/" must be included sonarWebContext: / # sonarWebContext: /sonarqube/ # If an ingress *path* is defined, it should be reflected here # sonar.web.context: /sonarqube +startupProbe: + initialDelaySeconds: 30 + periodSeconds: 10 + failureThreshold: 24 + # If an ingress *path* other than the root (/) is defined, it should be reflected here + # A trailing "/" must be included + sonarWebContext: / + # sonarWebContext: /sonarqube/ initContainers: - # image: registry.dso.mil/platform-one/big-bang/apps/developer-tools/sonarqube/busybox:1.32 + # image: busybox:1.32 # We allow the init containers to have a separate security context declaration because # the initContainer may not require the same as SonarQube. # securityContext: {} @@ -124,12 +151,15 @@ initContainers: # the initContainer does not take as much resources. resources: {} +extraInitContainers: {} +# Extra init containers to e.g. download required artifacts + ## Provide a secret containing one or more certificate files in the keys that will be added to cacerts ## The cacerts file will be set via SONARQUBE_WEB_JVM_OPTS and SONAR_CE_JAVAOPTS ## -# caCerts: +## caCerts: # image: adoptopenjdk/openjdk11:alpine - # secret: my-secret + # secret: your-secret initSysctl: enabled: false @@ -137,11 +167,36 @@ initSysctl: fsFileMax: 131072 nofile: 131072 nproc: 8192 - # image: registry.dso.mil/platform-one/big-bang/apps/developer-tools/sonarqube/busybox:1.32 + # image: busybox:1.32 securityContext: privileged: true # resources: {} +initFs: + enabled: false + # image: busybox:1.32 + securityContext: + privileged: true + +prometheusExporter: + enabled: false + # jmx_prometheus_javaagent version to download from Maven Central + version: "0.15.0" + # Alternative full download URL for the jmx_prometheus_javaagent.jar (overrides prometheusExporter.version) + # downloadURL: "" + config: + rules: + - pattern: ".*" + # image: curlimages/curl:7.76.1 + # For use behind a corporate proxy when downloading prometheus + # httpProxy: "" + # httpsProxy: "" + # noProxy: "" + # Setting the security context to root as the /data volume is owned by root at this stage + securityContext: + runAsUser: 0 + runAsGroup: 0 + # List of plugins to install. # For example: # plugins: @@ -149,11 +204,7 @@ initSysctl: # - "https://github.com/AmadeusITGroup/sonar-stash/releases/download/1.3.0/sonar-stash-plugin-1.3.0.jar" # - "https://github.com/SonarSource/sonar-ldap/releases/download/2.2-RC3/sonar-ldap-plugin-2.2.0.601.jar" plugins: - install: -# - https://github.com/dependency-check/dependency-check-sonar-plugin/releases/download/1.2.6/sonar-dependency-check-plugin-1.2.6.jar -# - https://github.com/SonarOpenCommunity/sonar-cxx/releases/download/cxx-1.3.2/sonar-c-plugin-1.3.2.1853.jar -# - https://github.com/SonarOpenCommunity/sonar-cxx/releases/download/cxx-1.3.2/sonar-cxx-plugin-1.3.2.1853.jar -# - https://github.com/dmeiners88/sonarqube-prometheus-exporter/releases/download/v1.0.0-SNAPSHOT-2018-07-04/sonar-prometheus-exporter-1.0.0-SNAPSHOT.jar + install: [] lib: [] # For use behind a corporate proxy when downloading plugins @@ -161,17 +212,30 @@ plugins: # httpsProxy: "" # noProxy: "" - # image: registry.dso.mil/platform-one/big-bang/apps/developer-tools/sonarqube/alpine-wget:latest + # image: curlimages/curl:7.76.1 # resources: {} # .netrc secret file with a key "netrc" to use basic auth while downloading plugins # netrcCreds: "" + # Set to true to not validate the server's certificate to download plugin + noCheckCertificate: false + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + ## Values to add to SONARQUBE_WEB_JVM_OPTS ## # jvmOpts: "-Djava.net.preferIPv4Stack=true" jvmOpts: "" +## Values to add to SONAR_CE_JAVAOPTS +jvmCeOpts: "" + +## a monitoring passcode needs to be defined in order to get reasonable probe results +# not setting the monitoring passcode will result in a deployment that will never be ready +monitoringPasscode: "define_it" + ## Environment variables to attach to the pods ## # env: @@ -181,17 +245,16 @@ jvmOpts: "" # Set annotations for pods annotations: {} -resources: {} -# We usually recommend not to specify default resources and to leave this as a conscious -# choice for the user. This also increases chances charts run on environments with little -# resources, such as Minikube. If you do want to specify resources, uncomment the following -# lines, adjust them as necessary, and remove the curly braces after 'resources:'. -# limits: -# cpu: 100m -# memory: 128Mi -# requests: -# cpu: 100m -# memory: 128Mi +## We usually don't make specific ressource recommandations, as they are heavily dependend on +## The usage of SonarQube and the surrounding infrastructure. +## Adjust these values to your needs, but make sure that the memory limit is never under 4 GB +resources: + limits: + cpu: 800m + memory: 4096M + requests: + cpu: 400m + memory: 2Gi persistence: enabled: false ## Set annotations on pvc @@ -209,7 +272,8 @@ persistence: ## storageClass: accessMode: ReadWriteOnce - size: 10Gi + size: 5Gi + uid: 1000 ## Specify extra volumes. Refer to ".spec.volumes" specification : https://kubernetes.io/fr/docs/concepts/storage/volumes/ volumes: [] @@ -224,20 +288,10 @@ emptyDir: {} # A custom sonar.properties file can be provided via dictionary. # For example: -sonarProperties: - sonar.forceAuthentication: true -# SAML SSO config -# sonar.core.serverBaseURL: -# sonar.auth.saml.enabled: false -# sonar.auth.saml.applicationId: -# sonar.auth.saml.providerName: -# sonar.auth.saml.providerId: -# sonar.auth.saml.loginUrl: -# sonar.auth.saml.certificate.secured: -# sonar.auth.saml.user.login: -# sonar.auth.saml.user.name: -# sonar.auth.saml.user.email: -# sonar.auth.saml.group.name: +# sonarProperties: +# sonar.forceAuthentication: true +# sonar.security.realm: LDAP +# ldap.url: ldaps://organization.com # Additional sonar properties to load from a secret with a key "secret.properties" (must be a string) # sonarSecretProperties: @@ -265,6 +319,7 @@ postgresql: # instance, set enabled to false and provide the name of the secret on the # line below: # existingSecret: "" + # existingSecretPasswordKey: "postgresql-password" postgresqlUsername: "sonarUser" postgresqlPassword: "sonarPass" postgresqlDatabase: "sonarDB" @@ -316,7 +371,7 @@ sonarqubeFolder: /opt/sonarqube tests: enabled: false - # image: registry.dso.mil/platform-one/big-bang/apps/developer-tools/sonarqube/minideb-extras:latest + # image: bitnami/minideb-extras serviceAccount: create: false @@ -351,6 +406,7 @@ extraConfig: # adminPassword: admin # currentAdminPassword: admin # curlContainerImage: curlimages/curl:latest +# adminJobAnnotations: {} terminationGracePeriodSeconds: 60 @@ -369,6 +425,7 @@ istio: - istio-system/main hosts: - sonarqube.{{ .Values.hostname }} + monitoring: enabled: false