Chapter 3. Providers and rule conditions
The providers are the modular components in charge of analyzing a given language. Providers are able to analyze code by leveraging the Language Server Protocol (LSP). Through the LSP, all code analysis is abstracted away from the analysis engine and left to the specific LSP server to run the search query defined in the rule on the source code.
Additionally, MTA provides a built-in provider with abilities such as XML parsing, running regular expressions on files, and so on.
Currently, MTA supports the following providers:
- Builtin
- Java
- Go
-
External providers (for
Python,DotnetandNode.jsapplications) initialized by the generic provider binary
You can use the generic provider binary to create an external provider for any language that is compliant with LSP 3.17 specifications.
Using the provider capability in custom rules
In a rule, the when block is where the conditions for matching the rule are specified. Each provider offers a series of capabilities to do matching.. The search query in the rule condition can contain patterns, code locations, specific dependencies to be found, and so on, to evaluate the source code and dependencies. The provider sends the LSP server a request to check the search query against the application being analyzed. When the LSP server returns a match for the search in the source code, the analyzer triggers a violation.
The syntax for the when block is as follows: contains one condition, but that condition can have multiple conditions nested under it.
when:
<condition>
<nested-condition>
when:
<condition>
<nested-condition>
3.1. Provider condition Copy linkLink copied to clipboard!
The analyzer engine enables multi-language source code analysis by using providers. The source code of a technology is analyzed by the provider.
The provider publishes what they can do with the source code in terms of capabilities.
The provider condition instructs the analyzer to use a specific provider and one of its capabilities. In general, it follows the <provider_name>.<capability> pattern.
when:
<provider_name>.<capability>
<input_fields>
when:
<provider_name>.<capability>
<input_fields>
The analyzer currently supports the following provider conditions:
-
builtin -
java -
go -
nodejs -
python -
dotnet
Dotnet provider is a Developer Preview feature only. Developer Preview features are not supported by Red Hat in any way and are not functionally complete or production-ready. Do not use Developer Preview features for production or business-critical workloads. Developer Preview features provide early access to upcoming product features in advance of their possible inclusion in a Red Hat product offering, enabling customers to test functionality and provide feedback during the development process. These features might not have any documentation, are subject to change or removal at any time, and testing is limited. Red Hat might provide ways to submit feedback on Developer Preview features without an associated SLA.
| Provider rule conditions | Provider name |
|---|---|
| Providers that are fully supported and included in the product |
|
| Providers that have rules already defined in the product |
|
| Providers that require custom rulesets for analysis |
|
The following table summarizes all the providers and their capabilities:
| Provider Name | Capabilities | Description |
|---|---|---|
|
| referenced | Find references of a pattern with an optional code location for detailed searches. For example, when:
java.referenced:
<fields>
|
| dependency | Check whether the application has a given dependency. For example, when:
java.dependency:
<fields>
| |
|
| xml | Search XML files using xpath queries. |
|
|
Search JSON files using when:
builtin.json:
<fields>
| |
| filecontent | Search content in regular files using regular expression patterns. For example, when:
builtin.filecontent:
<fields>
| |
| file | Find files with names matching a given pattern. For example, when:
builtin.file:
<fields>
| |
| hasTags | Check whether a tag is created for the application using a tagging rule. For example, when:
builtin.hasTags:
<fields>
| |
|
| referenced | Find references to a pattern. For example, when:
go.referenced:
<fields>
|
| dependency | Check whether the application has a given dependency. For example, when:
go.dependency:
<fields>
|
Following the example in the previous table, you can create the first part of the condition that does not contain any of the condition fields.
Example
To create a java provider condition that uses the referenced capability:
when:
java.referenced:
<fields>
when:
java.referenced:
<fields>
Depending on the provider and the capability, there will be different <fields> in the condition.
The following table summarizes available providers, their capabilities and all of their fields:
| Provider | Capability | Fields | Required | Description |
|---|---|---|---|---|
| referenced | pattern | Yes | Regular expression pattern. For example, when:
java.referenced:
location: PACKAGE
pattern: org.jboss.*
| |
| location | No | Source code location. See Java locations. For example, when:
java.referenced:
pattern: org.kubernetes*
location: IMPORT
| ||
| annotated | No | Additional query to inspect annotations. See Annotation inspection. For example, when:
java.referenced:
location: ANNOTATION
pattern: javax.ejb.Singleton
| ||
| dependency | name | Yes | Name of the dependency. For example, when:
java.dependency:
name: junit.junit
| |
| nameregex | No | Regular expression pattern to match the name. | ||
| upperbound | No | Match versions lower than or equal to. For example, when:
java.dependency:
name: junit.junit
upperbound: 4.12.2
| ||
| lowerbound | No | Match versions greater than or equal to. For example, when:
java.dependency:
name: junit.junit
upperbound: 4.12.2
lowerbound: 4.4.0
| ||
| xml | xpath | Yes | Xpath query when:
builtin.xml:
xpath: "//dependencies/dependency"
| |
| namespaces | No | A map to scope down query to namespaces. | ||
| filepaths | No | Optional list of files to scope down search. | ||
| json | xpath | Yes | Xpath query For example, when:
and:
- builtin.json:
xpath: //inclusionTestNode
| |
| filepaths | No | Optional list of files to scope down search. For example, when:
and:
- builtin.json:
xpath: //inclusionTestNode
filepaths: "{{incTest.filepaths}}"
| ||
| filecontent | pattern | Yes | Regular expression pattern to match in content. For example, when:
builtin.filecontent:
pattern: "import.*React"
| |
| filePattern | No | Only search in files with names matching this pattern. For example, when:
builtin.filecontent:
pattern: "import.*React"
filePattern: "\\.tsx$"
| ||
| file | pattern | Yes | Find files with names matching this pattern. For example, when:
builtin.file:
pattern: "*.go"
| |
| hasTags | This is an inline list of string tags. See Tag action For example, when:
or:
- builtin.hasTags:
- Golang
- Kubernetes
| |||
| referenced | pattern | Yes | Regular expression pattern. For example, when:
go.referenced:
pattern: "v1beta1.CustomResourceDefinition"
| |
| dependency | name | Yes | Name of the dependency. For example, when:
- go.dependency:
name: sigs.k8s.io/structured-merge-diff/v4
| |
| nameregex | No | Regular expression pattern to match the name. | ||
| upperbound | No | Match versions lower than or equal to. For example, when:
- go.dependency:
name: sigs.k8s.io/structured-merge-diff/v4
upperbound: v4.2.2
| ||
| lowerbound | No | Match versions greater than or equal to. For example, when:
- go.dependency:
name: sigs.k8s.io/structured-merge-diff/v4
lowerbound: v4.2.0
| ||
| referenced | pattern | Yes |
Regular expression to match a reference in the source code. For example, | |
| namespace | Yes |
Specify the namespace within which the search query must be run. For example, |
3.2. Builtin provider Copy linkLink copied to clipboard!
The builtin is an internal provider that can analyze various files and internal metadata generated by the engine. This provider has the following capabilities:
-
file -
filecontent -
xml -
json -
hasTags
file
By using the file capability, the provider searches for files in the source code that match a given pattern.
when:
builtin.file:
pattern: "<regular_expression_to_match_filenames>"
when:
builtin.file:
pattern: "<regular_expression_to_match_filenames>"
filecontent
By using the filecontent capability, the provider searches for content that matches a given pattern.
when:
builtin.filecontent:
filePattern: "<regular_expression_to_match_filenames_to_scope_search>"
pattern: "<regular_expression_to_match_content_in_the_matching_files>"
when:
builtin.filecontent:
filePattern: "<regular_expression_to_match_filenames_to_scope_search>"
pattern: "<regular_expression_to_match_content_in_the_matching_files>"
xml
The xml capability enables the provider to query XPath expressions on a list of provided XML files. This capability takes 2 input parameters, xpath and filepaths.
where:
xpath- must be a valid XPath expression.
filepaths- is a list of files to apply the XPath query to.
namespaces-
define namespaces and assign them to variables. You can use the variable in the
xpath.
json
By using the json capability, the provider queries XPath expressions on a list of provided JSON files. Currently, json only takes XPath as input and performs the search on all JSON files in the codebase.
when:
builtin.json:
xpath: "<xpath_expressions>"
when:
builtin.json:
xpath: "<xpath_expressions>"
where:
xpath- must be a valid XPath expression.
hasTags
By using the hasTags capability, the provider queries application tags. It queries the internal data structure to check whether the application has the given tags.
when:
# when more than one tag is given, a logical AND is implied
hasTags:
- "tag1"
- "tag2"
when:
# when more than one tag is given, a logical AND is implied
hasTags:
- "tag1"
- "tag2"
where:
hasTags- When more than one tag is given, a logical AND is implied.
3.3. Java provider Copy linkLink copied to clipboard!
The java provider analyzes Java source code.
This provider has the following capabilities:
-
referenced -
dependency
referenced
By using the referenced capability, the provider finds references in the source code. This capability takes three input parameters: pattern, location, and annotated.
when:
java.referenced:
pattern: "<pattern>"
location: "<location>"
annotated: "<annotated>"
when:
java.referenced:
pattern: "<pattern>"
location: "<location>"
annotated: "<annotated>"
where:
pattern- A regular expression pattern to match.
location-
Specifies the exact location where the pattern needs to be matched, for example,
IMPORT. annotated-
Checks for specific annotations and their elements, such as name and value, in the Java code using a query. For example, the following query matches the
Bean(url = “http://www.example.com”) annotation in the method.
annotated:
pattern: org.framework.Bean
elements:
- name: url
value: "http://www.example.com"
annotated:
pattern: org.framework.Bean
elements:
- name: url
value: "http://www.example.com"
See Java condition and capabilities for a detailed explanation on java.referenced capabilities.
dependency
The Java provider has dependency capability. The dependency capability enables the provider to generate a list of dependencies for a given application. You can use a dependency condition to query this list and check whether a certain dependency, with a version range, exists for the application. The dependency can be internal or external/open source. For example, to check if a Java application has a certain dependency, you create a java.dependency condition:
when:
java.dependency:
name: junit.junit
upperbound: 4.12.2
lowerbound: 4.4.0
when:
java.dependency:
name: junit.junit
upperbound: 4.12.2
lowerbound: 4.4.0
You can use the dependency capability to check if a Java application has Fabric8 Kubernetes client of version 5.0.100 or lower:
- java.dependency:
name: io.fabric8.kubernetes-client
lowerbound: 5.0.100
- java.dependency:
name: io.fabric8.kubernetes-client
lowerbound: 5.0.100
When you use the java provider for an analysis, the analysis results have lower precision for projects that cannot be built. For example, when MTA is unable to build a Maven project, it falls back to parsing the pom file to get the list of dependencies.
3.4. Go provider Copy linkLink copied to clipboard!
The go provider analyzes Go source code. This provider’s capabilities are referenced and dependency.
referenced
By using the referenced capability, the provider finds references in the source code.
when: go.referenced: "<regex_to_find_reference>"
when:
go.referenced: "<regex_to_find_reference>"
dependency
By using the dependency capability, the provider finds dependencies for a Go application.
when:
go.dependency:
name: "<dependency_name>"
upperbound: "<version_string>"
lowerbound: "<version_string>"
when:
go.dependency:
name: "<dependency_name>"
upperbound: "<version_string>"
lowerbound: "<version_string>"
where:
name- Name of the dependency to search for.
upperbound- Upper bound on the version of the dependency.
lowerbound- Lower bound on the version of the dependency.
3.5. Dotnet provider Copy linkLink copied to clipboard!
The dotnet provider is an external provider used to analyze .NET and C# source code. Currently, the provider supports the referenced capability.
referenced
By using the referenced capability, the provider finds references in the source code.
when:
dotnet.referenced:
pattern: "<pattern>"
namespace: "<namespace>"
when:
dotnet.referenced:
pattern: "<pattern>"
namespace: "<namespace>"
where:
pattern-
A regular expression pattern to match the desired reference. For example,
HttpNotFound. namespace-
Specifies the namespace to search within. For example,
System.Web.Mvc.