Sonarqube
Introduction
SonarQube is an open sourced code quality scanning tool. SonarQube provides the capability to not only show health of an application but also to highlight issues newly introduced. With a Quality Gate in place, you can fix the leak and therefore improve code quality systematically.
Chart
We use public helm charts to deploy sonarqube on our cluster. Here is the public chart that we use and 0.10.3
is the public chart version that is used in our cluster. We use umbrella charts to deploy sonarqube on our cluster. Currently we are using this repository for sonarqube deployment.
Image
Currently we are using this sonarqube:7.4-community
public image for sonarqube in stakater.
Cherry Pickable
Yes
Single Sign-on
Yes, we use Open id connect plugin for sonarqube to achieve this.
Installation
Installation Steps
Most of the times sonarqube will be deployed from pipeline of this repository. It will have updated configurations and dependencies for sonarqube. But we can also install it manually (not recommended). To install sonarqube manually, clone this repo and you can run the make targets of repo containing latest implementation of sonarqube. This will install all dependencies and sonarqube as well.
- Clone this repository
- Update the hardcoded values mentioned in the here
- Run this command.
make install CHART_NAME=release
- Verify from UI that cerebro pod is running and accessible.
Known Issues
There are 2 known issues with latest public helm chart:
- It doesn’t install custom plugins with current version of sonarqube used in the public chart. It doesn’t work even with the latest sonarqube image, but only works with the version 7.1
- It doesn’t read & apply custom sonar.properties file
1st issue is resolved currently by using 7.1 version of sonarqube docker image. For 2nd issue we contacted the chart owner, and he has identified the issue. He confirmed that he will fix the issue soon. Till then we are configuring custom sonar properties manually.
Dependencies
Sonarqube required a database to persist its results. With the public chart we can either use mysql or postgres
- name: sonarqube
version: 0.12.2
repository: https://kubernetes-charts.storage.googleapis.com
alias: sonarqube
Hard-coded-values
Service annotations and labels are hard coded.
sonarqube:
service:
type: ClusterIP
labels:
expose: "true"
annotations:
config.xposer.stakater.com/Domain: stakater.com
config.xposer.stakater.com/IngressNameTemplate: '{{.Service}}-{{.Namespace}}'
config.xposer.stakater.com/IngressURLTemplate: 'sonarqube.{{.Namespace}}.{{.Domain}}'
xposer.stakater.com/annotations: |-
kubernetes.io/ingress.class: internal-ingress
ingress.kubernetes.io/force-ssl-redirect: true
Persistence and postgresql values are hard coded.
sonarqube:
persistence:
enabled: true
storageClass: "default"
accessMode: ReadWriteOnce
size: 10Gi
postgresql:
persistence:
storageClass: "default"
We have an extra oauth plugin
sonarqube:
plugins:
install:
- "https://github.com/vaulttec/sonar-auth-oidc/releases/download/v1.0.4/sonar-auth-oidc-plugin-1.0.4.jar"
Add sonarProperties file containing keycloak configuration for SSO. Update sonar.auth.oidc.clientSecret.secured=testsecret
with the real client secret.
sonarqube:
sonarProperties: |
sonar.forceAuthentication=true
sonar.auth.oidc.enabled=true
sonar.core.serverBaseURL=https://sonarqube.release.stakater.com
sonar.auth.oidc.providerConfiguration={"issuer":"https://keycloak.global.stakater.com/auth/realms/stakater","authorization_endpoint":"https://keycloak.global.stakater.com/auth/realms/stakater/protocol/openid-connect/auth","token_endpoint":"https://keycloak.global.stakater.com/auth/realms/stakater/protocol/openid-connect/token","token_introspection_endpoint":"https://keycloak.global.stakater.com/auth/realms/stakater/protocol/openid-connect/token/introspect","userinfo_endpoint":"https://keycloak.global.stakater.com/auth/realms/stakater/protocol/openid-connect/userinfo","end_session_endpoint":"https://keycloak.global.stakater.com/auth/realms/stakater/protocol/openid-connect/logout","jwks_uri":"https://keycloak.global.stakater.com/auth/realms/stakater/protocol/openid-connect/certs","check_session_iframe":"https://keycloak.global.stakater.com/auth/realms/stakater/protocol/openid-connect/login-status-iframe.html","grant_types_supported":["authorization_code","implicit","refresh_token","password","client_credentials"],"response_types_supported":["code","none","id_token","token","id_token token","code id_token","code token","code id_token token"],"subject_types_supported":["public","pairwise"],"id_token_signing_alg_values_supported":["ES384","RS384","HS256","HS512","ES256","RS256","HS384","ES512","RS512"],"userinfo_signing_alg_values_supported":["ES384","RS384","HS256","HS512","ES256","RS256","HS384","ES512","RS512","none"],"request_object_signing_alg_values_supported":["none","RS256"],"response_modes_supported":["query","fragment","form_post"],"registration_endpoint":"https://keycloak.global.stakater.com/auth/realms/stakater/clients-registrations/openid-connect","token_endpoint_auth_methods_supported":["private_key_jwt","client_secret_basic","client_secret_post","client_secret_jwt"],"token_endpoint_auth_signing_alg_values_supported":["RS256"],"claims_supported":["sub","iss","auth_time","name","given_name","family_name","preferred_username","email"],"claim_types_supported":["normal"],"claims_parameter_supported":false,"scopes_supported":["openid","phone","address","email","profile","offline_access"],"request_parameter_supported":true,"request_uri_parameter_supported":true,"code_challenge_methods_supported":["plain","S256"],"tls_client_certificate_bound_access_tokens":true,"introspection_endpoint":"https://keycloak.global.stakater.com/auth/realms/stakater/protocol/openid-connect/token/introspect"}
sonar.auth.oidc.clientId.secured=stakater-online-platform
sonar.auth.oidc.clientSecret.secured=testsecret