@@ -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 { |
@@ -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(); | |||
} | |||
@@ -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); | |||
} |
@@ -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. |
@@ -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())); |
@@ -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(); |