From 555abeb7d7c38477b11f7b3f18f35d7c668b5cff Mon Sep 17 00:00:00 2001 From: Eric Giffon Date: Fri, 9 Jun 2023 14:10:45 +0200 Subject: [PATCH] SONAR-19425 Update telemetry with official helm chart and image usage --- .../sonar/server/telemetry/TelemetryData.java | 2 +- .../telemetry/TelemetryDataJsonWriter.java | 2 ++ .../TelemetryDataJsonWriterTest.java | 6 ++-- .../telemetry/CloudUsageDataProvider.java | 24 ++++++++++++-- .../telemetry/CloudUsageDataProviderTest.java | 32 +++++++++++++++++++ .../TelemetryDataLoaderImplTest.java | 3 +- 6 files changed, 63 insertions(+), 6 deletions(-) diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryData.java b/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryData.java index 44a1a473096..c4938050f15 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryData.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryData.java @@ -353,7 +353,7 @@ public class TelemetryData { } record CloudUsage(boolean kubernetes, @Nullable String kubernetesVersion, @Nullable String kubernetesPlatform, - @Nullable String kubernetesProvider) { + @Nullable String kubernetesProvider, @Nullable String officialHelmChart, boolean officialImage) { } public static class ProjectStatistics { diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataJsonWriter.java b/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataJsonWriter.java index f802d1ba1a8..f28b8cdbb22 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataJsonWriter.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataJsonWriter.java @@ -239,6 +239,8 @@ public class TelemetryDataJsonWriter { json.prop("kubernetesVersion", cloudUsage.kubernetesVersion()); json.prop("kubernetesPlatform", cloudUsage.kubernetesPlatform()); json.prop("kubernetesProvider", cloudUsage.kubernetesProvider()); + json.prop("officialHelmChart", cloudUsage.officialHelmChart()); + json.prop("officialImage", cloudUsage.officialImage()); json.endObject(); } diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/telemetry/TelemetryDataJsonWriterTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/telemetry/TelemetryDataJsonWriterTest.java index 2d035ca8918..27d803053d1 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/telemetry/TelemetryDataJsonWriterTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/telemetry/TelemetryDataJsonWriterTest.java @@ -290,7 +290,9 @@ public class TelemetryDataJsonWriterTest { "kubernetes": true, "kubernetesVersion": "1.27", "kubernetesPlatform": "linux/amd64", - "kubernetesProvider": "5.4.181-99.354.amzn2.x86_64" + "kubernetesProvider": "5.4.181-99.354.amzn2.x86_64", + "officialHelmChart": "10.1.0", + "officialImage": false } } """); @@ -602,7 +604,7 @@ public class TelemetryDataJsonWriterTest { .setMessageSequenceNumber(1L) .setPlugins(Collections.emptyMap()) .setManagedInstanceInformation(new TelemetryData.ManagedInstanceInformation(false, null)) - .setCloudUsage(new TelemetryData.CloudUsage(true, "1.27", "linux/amd64", "5.4.181-99.354.amzn2.x86_64")) + .setCloudUsage(new TelemetryData.CloudUsage(true, "1.27", "linux/amd64", "5.4.181-99.354.amzn2.x86_64", "10.1.0", false)) .setDatabase(new TelemetryData.Database("H2", "11")) .setNcdId(NCD_ID); } diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/CloudUsageDataProvider.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/CloudUsageDataProvider.java index 6fe36fcbbcd..f35f1f026f2 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/CloudUsageDataProvider.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/CloudUsageDataProvider.java @@ -61,10 +61,13 @@ public class CloudUsageDataProvider { private static final String SERVICEACCOUNT_CA_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"; static final String KUBERNETES_SERVICE_HOST = "KUBERNETES_SERVICE_HOST"; static final String KUBERNETES_SERVICE_PORT = "KUBERNETES_SERVICE_PORT"; + static final String SONAR_HELM_CHART_VERSION = "SONAR_HELM_CHART_VERSION"; + static final String DOCKER_RUNNING = "DOCKER_RUNNING"; private static final String[] KUBERNETES_PROVIDER_COMMAND = {"bash", "-c", "uname -r"}; private final System2 system2; private final Paths2 paths2; private OkHttpClient httpClient; + private TelemetryData.CloudUsage cloudUsageData; @Inject public CloudUsageDataProvider(System2 system2, Paths2 paths2) { @@ -83,6 +86,10 @@ public class CloudUsageDataProvider { } public TelemetryData.CloudUsage getCloudUsage() { + if (cloudUsageData != null) { + return cloudUsageData; + } + String kubernetesVersion = null; String kubernetesPlatform = null; @@ -94,17 +101,30 @@ public class CloudUsageDataProvider { } } - return new TelemetryData.CloudUsage( + cloudUsageData = new TelemetryData.CloudUsage( isOnKubernetes(), kubernetesVersion, kubernetesPlatform, - getKubernetesProvider()); + getKubernetesProvider(), + getOfficialHelmChartVersion(), + isOfficialImageUsed()); + + return cloudUsageData; } private boolean isOnKubernetes() { return StringUtils.isNotBlank(system2.envVariable(KUBERNETES_SERVICE_HOST)); } + @CheckForNull + private String getOfficialHelmChartVersion() { + return system2.envVariable(SONAR_HELM_CHART_VERSION); + } + + private boolean isOfficialImageUsed() { + return Boolean.parseBoolean(system2.envVariable(DOCKER_RUNNING)); + } + /** * Create a http client to call the Kubernetes API. * This is based on the client creation in the official Kubernetes Java client. diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/CloudUsageDataProviderTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/CloudUsageDataProviderTest.java index cb6aba86d97..ccefc0cae3c 100644 --- a/server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/CloudUsageDataProviderTest.java +++ b/server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/CloudUsageDataProviderTest.java @@ -43,8 +43,10 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static org.sonar.server.telemetry.CloudUsageDataProvider.DOCKER_RUNNING; import static org.sonar.server.telemetry.CloudUsageDataProvider.KUBERNETES_SERVICE_HOST; import static org.sonar.server.telemetry.CloudUsageDataProvider.KUBERNETES_SERVICE_PORT; +import static org.sonar.server.telemetry.CloudUsageDataProvider.SONAR_HELM_CHART_VERSION; public class CloudUsageDataProviderTest { @@ -135,6 +137,36 @@ public class CloudUsageDataProviderTest { assertThat(underTest.getCloudUsage().kubernetesProvider()).isNotBlank(); } + @Test + public void officialHelmChart_whenEnvVarExists_shouldReturnValue() { + when(system2.envVariable(SONAR_HELM_CHART_VERSION)).thenReturn("10.1.0"); + assertThat(underTest.getCloudUsage().officialHelmChart()).isEqualTo("10.1.0"); + } + + @Test + public void officialHelmChart_whenEnvVarDoesNotExist_shouldReturnNull() { + when(system2.envVariable(SONAR_HELM_CHART_VERSION)).thenReturn(null); + assertThat(underTest.getCloudUsage().officialHelmChart()).isNull(); + } + + @Test + public void officialImage_whenEnvVarTrue_shouldReturnTrue() { + when(system2.envVariable(DOCKER_RUNNING)).thenReturn("True"); + assertThat(underTest.getCloudUsage().officialImage()).isTrue(); + } + + @Test + public void officialImage_whenEnvVarFalse_shouldReturnFalse() { + when(system2.envVariable(DOCKER_RUNNING)).thenReturn("False"); + assertThat(underTest.getCloudUsage().officialImage()).isFalse(); + } + + @Test + public void officialImage_whenEnvVarDoesNotExist_shouldReturnFalse() { + when(system2.envVariable(DOCKER_RUNNING)).thenReturn(null); + assertThat(underTest.getCloudUsage().officialImage()).isFalse(); + } + @Test public void initHttpClient_whenValidCertificate_shouldCreateClient() throws URISyntaxException { when(paths2.get(anyString())).thenReturn(Paths.get(requireNonNull(getClass().getResource("dummy.crt")).toURI())); diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/TelemetryDataLoaderImplTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/TelemetryDataLoaderImplTest.java index ea81a4451aa..53e1ab87e28 100644 --- a/server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/TelemetryDataLoaderImplTest.java +++ b/server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/TelemetryDataLoaderImplTest.java @@ -63,6 +63,7 @@ import org.sonar.server.property.MapInternalProperties; import org.sonar.server.qualitygate.QualityGateCaycChecker; import org.sonar.server.qualitygate.QualityGateFinder; import org.sonar.server.telemetry.TelemetryData.Branch; +import org.sonar.server.telemetry.TelemetryData.CloudUsage; import org.sonar.server.telemetry.TelemetryData.NewCodeDefinition; import org.sonar.server.telemetry.TelemetryData.ProjectStatistics; import org.sonar.updatecenter.common.Version; @@ -556,7 +557,7 @@ public class TelemetryDataLoaderImplTest { @Test public void load_shouldContainCloudUsage() { - TelemetryData.CloudUsage cloudUsage = new TelemetryData.CloudUsage(true, "1.27", "linux/amd64", "5.4.181-99.354.amzn2.x86_64"); + CloudUsage cloudUsage = new CloudUsage(true, "1.27", "linux/amd64", "5.4.181-99.354.amzn2.x86_64", "10.1.0", false); when(cloudUsageDataProvider.getCloudUsage()).thenReturn(cloudUsage); TelemetryData data = commercialUnderTest.load(); -- 2.39.5