Skip to content

Commit

Permalink
SLI-1812 Support for Ansible files
Browse files Browse the repository at this point in the history
  • Loading branch information
eray-felek-sonarsource committed Jan 28, 2025
1 parent aa01d8a commit c16b3af
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
- name: Create a Pod
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Pod
metadata:
name: example
spec:
hostNetwork: true # Noncompliant {{Make sure it is safe to use host operating system namespaces here.}}
# ^^^^
- name: Create a Pod
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Pod
metadata:
name: example-2
spec:
hostPID: true # Noncompliant {{Make sure it is safe to use host operating system namespaces here.}}
# ^^^^
hostIPC: true # Noncompliant {{Make sure it is safe to use host operating system namespaces here.}}
# ^^^^
hostNetwork: true # Noncompliant
# ^^^^
- name: Create a Pod
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Pod
metadata:
name: example-3
spec:
hostPID: true # Noncompliant {{Make sure it is safe to use host operating system namespaces here.}}
hostIPC: false
hostNetwork: false
- name: Create a Pod
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Pod
metadata:
name: example-4
spec:
hostPID: false
hostIPC: false
hostNetwork: false
---
- name: Create a Deployment
kubernetes.core.k8s:
state: present
definition:
apiVersion: apps/v1
kind: Deployment
metadata:
name: s6431-explicitlynoncompliant-network
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
protocol: TCP
hostNetwork: true # Noncompliant {{Make sure it is safe to use host operating system namespaces here.}}
# ^^^^
hostPID: false
hostIPC: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* SonarLint for IntelliJ IDEA
* Copyright (C) 2015-2025 SonarSource
* [email protected]
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonarlint.intellij.its.tests.flavor

import com.intellij.remoterobot.utils.waitFor
import com.sonar.orchestrator.container.Edition
import com.sonar.orchestrator.junit5.OrchestratorExtension
import com.sonar.orchestrator.locator.FileLocation
import java.time.Duration
import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.condition.EnabledIf
import org.sonarlint.intellij.its.BaseUiTest
import org.sonarlint.intellij.its.fixtures.idea
import org.sonarlint.intellij.its.fixtures.tool.window.toolWindow
import org.sonarlint.intellij.its.tests.domain.CurrentFileTabTests.Companion.enableConnectedModeFromCurrentFilePanel
import org.sonarlint.intellij.its.tests.domain.CurrentFileTabTests.Companion.verifyCurrentFileTabContainsMessages
import org.sonarlint.intellij.its.utils.OpeningUtils.Companion.openExistingProject
import org.sonarlint.intellij.its.utils.OpeningUtils.Companion.openFile
import org.sonarlint.intellij.its.utils.OrchestratorUtils.Companion.defaultBuilderEnv
import org.sonarlint.intellij.its.utils.OrchestratorUtils.Companion.executeBuildWithSonarScanner
import org.sonarlint.intellij.its.utils.OrchestratorUtils.Companion.generateTokenNameAndValue
import org.sonarlint.intellij.its.utils.OrchestratorUtils.Companion.newAdminWsClientWithUser
import org.sonarlint.intellij.its.utils.SettingsUtils.Companion.clearConnectionsAndAddSonarQubeConnection

const val ANSIBLE_PROJECT_KEY = "sample-ansible"

@Tag("ConnectedAnalysisTests")
@EnabledIf("isIdeaCommunity")
class AnsibleTests : BaseUiTest() {

@Test
fun should_display_issue() = uiTest {
openExistingProject("sample-ansible")
openFile("HostNamespacesCheck/tasks/HostNamespacesCheck.yaml")
verifyCurrentFileTabContainsMessages("No issues to display")

enableConnectedModeFromCurrentFilePanel(ANSIBLE_PROJECT_KEY, true, "Orchestrator")

idea {
waitBackgroundTasksFinished()
}

verifyIssueTreeContainsMessages()
}

private fun verifyIssueTreeContainsMessages() {
with(remoteRobot) {
idea {
toolWindow("SonarQube for IDE") {
ensureOpen()
tabTitleContains("Current File") { select() }
// the synchronization can take a while to happen
waitFor(duration = Duration.ofMinutes(1)) {
hasText("Use a specific version tag for the image.")
}
}
}
}
}

companion object {
private val ORCHESTRATOR: OrchestratorExtension = defaultBuilderEnv()
.setEdition(Edition.ENTERPRISE)
.activateLicense()
.keepBundledPlugins()
.restoreProfileAtStartup(FileLocation.ofClasspath("/ansible-issue.xml"))
.build()

@JvmStatic
@BeforeAll
fun createSonarLintUser() {
ORCHESTRATOR.start()

val adminWsClient = newAdminWsClientWithUser(ORCHESTRATOR.server)
val response = generateTokenNameAndValue(adminWsClient, "sonarlintUser")
val token = response.second

ORCHESTRATOR.server.provisionProject(ANSIBLE_PROJECT_KEY, "Sample Ansible Issues")
ORCHESTRATOR.server.associateProjectToQualityProfile(
ANSIBLE_PROJECT_KEY,
"ansible",
"SonarLint IT Ansible Issue"
)

// Build and analyze project to raise issue
executeBuildWithSonarScanner("projects/sample-ansible/", ORCHESTRATOR, ANSIBLE_PROJECT_KEY)

clearConnectionsAndAddSonarQubeConnection(ORCHESTRATOR.server.url, token)
}

@AfterAll
@JvmStatic
fun teardown() {
ORCHESTRATOR.stop()
}
}

}
13 changes: 13 additions & 0 deletions its/src/test/resources/ansible-issue.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version='1.0' encoding='UTF-8'?>
<profile>
<name>SonarLint IT Ansible Issue</name>
<language>ansible</language>
<rules>
<!-- Remove this commented out code -->
<rule>
<repositoryKey>ansible</repositoryKey>
<key>S6596</key>
<priority>MAJOR</priority>
</rule>
</rules>
</profile>
6 changes: 4 additions & 2 deletions src/main/java/org/sonarlint/intellij/core/EnabledLanguages.kt
Original file line number Diff line number Diff line change
Expand Up @@ -114,20 +114,22 @@ object EnabledLanguages {
@JvmStatic
val extraEnabledLanguagesInConnectedMode: Set<Language>
get() {
val extraEnabledLanguages = EnumSet.of(Language.ANSIBLE)

return when {
isIdeModuleEnabled(RIDER_MODULE_ID) -> {
EnumSet.noneOf(Language::class.java)
extraEnabledLanguages
}

else -> {
val extraEnabledLanguages = EnumSet.noneOf(Language::class.java)
if (isIdeModuleEnabled(DATABASE_PLUGIN_ID)) {
extraEnabledLanguages.add(Language.PLSQL)
}
if (!isIdeModuleEnabled(CLION_MODULE_ID)) {
// all other IDEs
extraEnabledLanguages.addAll(EnumSet.of(Language.SCALA, Language.SWIFT))
}

extraEnabledLanguages
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ private val typescriptFileTypesByPriority = arrayOf("TypeScript", "JavaScript")

enum class RuleLanguages(private val language: Language, private vararg val fileTypesByPriorityOrder: String) {

ANSIBLE(Language.ANSIBLE, "YAML"),
C(Language.C, *cFamilyLanguagesFileTypesByPriority),
// for now most code examples are written in YAML for CloudFormation
CLOUD_FORMATION(Language.CLOUDFORMATION, "YAML"),
Expand Down

0 comments on commit c16b3af

Please sign in to comment.