From 2cbc496ccae18a7d603f432cadd3571b95ef3815 Mon Sep 17 00:00:00 2001 From: Sophio Japharidze Date: Wed, 18 Dec 2024 12:10:39 +0100 Subject: [PATCH] SLCORE-1097 download iac along with iacenterprise when available --- .../core/commons/api/SonarLanguage.java | 2 +- .../sonarlint/core/plugin/PluginsService.java | 24 ++++++++++++++----- .../LocalStorageSynchronizer.java | 6 ++--- .../serverconnection/PluginsSynchronizer.java | 9 +++++-- .../PluginsSynchronizerTests.java | 4 ++-- 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/backend/commons/src/main/java/org/sonarsource/sonarlint/core/commons/api/SonarLanguage.java b/backend/commons/src/main/java/org/sonarsource/sonarlint/core/commons/api/SonarLanguage.java index 02f98469b2..b1c8c9f4a9 100644 --- a/backend/commons/src/main/java/org/sonarsource/sonarlint/core/commons/api/SonarLanguage.java +++ b/backend/commons/src/main/java/org/sonarsource/sonarlint/core/commons/api/SonarLanguage.java @@ -68,7 +68,7 @@ public enum SonarLanguage { KUBERNETES("kubernetes", "iac", new String[0], "sonar.kubernetes.file.suffixes"), TERRAFORM("terraform", "iac", new String[]{".tf"}, "sonar.terraform.file.suffixes"), AZURERESOURCEMANAGER("azureresourcemanager", "iac", new String[]{".bicep"}, Constants.NO_PUBLIC_PROPERTY_PROVIDED_FOR_THIS_LANGUAGE), - ANSIBLE("ansible", "iac", new String[0], "sonar.ansible.file.suffixes"); + ANSIBLE("ansible", "iacenterprise", new String[0], "sonar.ansible.file.suffixes"); private final String sonarLanguageKey; /** diff --git a/backend/core/src/main/java/org/sonarsource/sonarlint/core/plugin/PluginsService.java b/backend/core/src/main/java/org/sonarsource/sonarlint/core/plugin/PluginsService.java index d36a3834b6..5865c488e5 100644 --- a/backend/core/src/main/java/org/sonarsource/sonarlint/core/plugin/PluginsService.java +++ b/backend/core/src/main/java/org/sonarsource/sonarlint/core/plugin/PluginsService.java @@ -52,6 +52,7 @@ import org.springframework.context.event.EventListener; import static org.sonarsource.sonarlint.core.serverconnection.PluginsSynchronizer.CUSTOM_SECRETS_MIN_SQ_VERSION; +import static org.sonarsource.sonarlint.core.serverconnection.PluginsSynchronizer.ENTERPRISE_IAC_MIN_SQ_VERSION; @Named @Singleton @@ -164,23 +165,34 @@ private Set getPluginPathsForConnection(String connectionId) { } private Map getEmbeddedPluginPathsByKey(String connectionId) { + var embeddedPlugins = new HashMap<>(connectedModeEmbeddedPluginPathsByKey); if (supportsCustomSecrets(connectionId)) { - var embeddedPluginsExceptSecrets = new HashMap<>(connectedModeEmbeddedPluginPathsByKey); - embeddedPluginsExceptSecrets.remove(SonarLanguage.SECRETS.getPluginKey()); - return embeddedPluginsExceptSecrets; + embeddedPlugins.remove(SonarLanguage.SECRETS.getPluginKey()); } - return connectedModeEmbeddedPluginPathsByKey; + if (supportsIaCEnterprise(connectionId)) { + // if iacenterprise is there on the server, download both, iac and iacenterprise + embeddedPlugins.remove(SonarLanguage.AZURERESOURCEMANAGER.getPluginKey()); + } + return embeddedPlugins; + } + + public boolean supportsIaCEnterprise(String connectionId) { + return isSonarQubeCloudOrVersionOlderThan(ENTERPRISE_IAC_MIN_SQ_VERSION, connectionId); } public boolean supportsCustomSecrets(String connectionId) { + return isSonarQubeCloudOrVersionOlderThan(CUSTOM_SECRETS_MIN_SQ_VERSION, connectionId); + } + + private boolean isSonarQubeCloudOrVersionOlderThan(Version version, String connectionId) { var connection = connectionConfigurationRepository.getConnectionById(connectionId); if (connection == null) { // Connection is gone return false; } - // when storage is not present, assume that secrets are not supported by server + // when storage is not present, assume that iac enterprise is not supported by server return connection.getKind() == ConnectionKind.SONARCLOUD || storageService.connection(connectionId).serverInfo().read() - .map(serverInfo -> serverInfo.getVersion().compareToIgnoreQualifier(CUSTOM_SECRETS_MIN_SQ_VERSION) >= 0) + .map(serverInfo -> serverInfo.getVersion().compareToIgnoreQualifier(version) >= 0) .orElse(false); } diff --git a/backend/server-connection/src/main/java/org/sonarsource/sonarlint/core/serverconnection/LocalStorageSynchronizer.java b/backend/server-connection/src/main/java/org/sonarsource/sonarlint/core/serverconnection/LocalStorageSynchronizer.java index 6ac3084392..1ffb949d08 100644 --- a/backend/server-connection/src/main/java/org/sonarsource/sonarlint/core/serverconnection/LocalStorageSynchronizer.java +++ b/backend/server-connection/src/main/java/org/sonarsource/sonarlint/core/serverconnection/LocalStorageSynchronizer.java @@ -54,9 +54,9 @@ public PluginSynchronizationSummary synchronizeServerInfosAndPlugins(ServerApi s var version = storage.serverInfo().read().orElseThrow().getVersion(); // On SonarQube server 10.4+ and SonarQube Cloud, we need to use the server's text analyzer // to support commercial rules (SQC and SQS 10.8+ DE+) and custom secrets (SQS 10.4+ EE+) - var useSecretsFromServer = serverApi.isSonarCloud() - || version.compareToIgnoreQualifier(CUSTOM_SECRETS_MIN_SQ_VERSION) >= 0; - return pluginsSynchronizer.synchronize(serverApi, useSecretsFromServer, cancelMonitor); + var useSecretsFromServer = serverApi.isSonarCloud() || version.compareToIgnoreQualifier(CUSTOM_SECRETS_MIN_SQ_VERSION) >= 0; + var usesIaCEnterprise = serverApi.isSonarCloud() || version.compareToIgnoreQualifier(PluginsSynchronizer.ENTERPRISE_IAC_MIN_SQ_VERSION) >= 0; + return pluginsSynchronizer.synchronize(serverApi, useSecretsFromServer, usesIaCEnterprise, cancelMonitor); } private static AnalyzerSettingsUpdateSummary diffAnalyzerConfiguration(AnalyzerConfiguration original, AnalyzerConfiguration updated) { diff --git a/backend/server-connection/src/main/java/org/sonarsource/sonarlint/core/serverconnection/PluginsSynchronizer.java b/backend/server-connection/src/main/java/org/sonarsource/sonarlint/core/serverconnection/PluginsSynchronizer.java index a0c356a66d..bcaafa1dc5 100644 --- a/backend/server-connection/src/main/java/org/sonarsource/sonarlint/core/serverconnection/PluginsSynchronizer.java +++ b/backend/server-connection/src/main/java/org/sonarsource/sonarlint/core/serverconnection/PluginsSynchronizer.java @@ -37,6 +37,7 @@ public class PluginsSynchronizer { public static final Version CUSTOM_SECRETS_MIN_SQ_VERSION = Version.create("10.4"); + public static final Version ENTERPRISE_IAC_MIN_SQ_VERSION = Version.create("2025.1"); private static final SonarLintLogger LOG = SonarLintLogger.get(); private final Set sonarSourceDisabledPluginKeys; @@ -49,9 +50,13 @@ public PluginsSynchronizer(Set enabledLanguages, ConnectionStorag this.embeddedPluginKeys = embeddedPluginKeys; } - public PluginSynchronizationSummary synchronize(ServerApi serverApi, boolean useSecretsFromServer, SonarLintCancelMonitor cancelMonitor) { + public PluginSynchronizationSummary synchronize(ServerApi serverApi, boolean useSecretsFromServer, boolean usesIaCEnterprise, SonarLintCancelMonitor cancelMonitor) { + var embeddedPluginKeysCopy = new HashSet<>(embeddedPluginKeys); + if (usesIaCEnterprise) { + embeddedPluginKeysCopy.remove(SonarLanguage.TERRAFORM.getPluginKey()); + embeddedPluginKeys = embeddedPluginKeysCopy; + } if (useSecretsFromServer) { - var embeddedPluginKeysCopy = new HashSet<>(embeddedPluginKeys); embeddedPluginKeysCopy.remove(SonarLanguage.SECRETS.getPluginKey()); embeddedPluginKeys = embeddedPluginKeysCopy; } diff --git a/backend/server-connection/src/test/java/org/sonarsource/sonarlint/core/serverconnection/PluginsSynchronizerTests.java b/backend/server-connection/src/test/java/org/sonarsource/sonarlint/core/serverconnection/PluginsSynchronizerTests.java index f6c754ecab..8a2a6cb5bb 100644 --- a/backend/server-connection/src/test/java/org/sonarsource/sonarlint/core/serverconnection/PluginsSynchronizerTests.java +++ b/backend/server-connection/src/test/java/org/sonarsource/sonarlint/core/serverconnection/PluginsSynchronizerTests.java @@ -53,7 +53,7 @@ void should_not_synchronize_sonar_text_pre_104(@TempDir Path dest) { "]}"); underTest = new PluginsSynchronizer(Set.of(SonarLanguage.SECRETS), new ConnectionStorage(dest, dest, "connectionId"), Set.of("text")); - underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), false, new SonarLintCancelMonitor()); + underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), false, false, new SonarLintCancelMonitor()); assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/plugin_references.pb")).exists(); assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/sonar-text-plugin-1.2.3.4.jar")).doesNotExist(); @@ -73,7 +73,7 @@ void should_not_synchronize_sonar_text_post_103(@TempDir Path dest) { mockServer.addStringResponse("/api/plugins/download?plugin=textenterprise", "content-textenterprise"); underTest = new PluginsSynchronizer(Set.of(SonarLanguage.SECRETS), new ConnectionStorage(dest, dest, "connectionId"), Set.of("text")); - underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), true, new SonarLintCancelMonitor()); + underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), true, false, new SonarLintCancelMonitor()); assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/plugin_references.pb")).exists(); assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/sonar-text-plugin-2.3.4.5.jar")).exists();