Skip to content

Commit

Permalink
Consolidate upload (#432) (#433)
Browse files Browse the repository at this point in the history
* Consolidate upload (#432)

* feat: merge uploadConfig into CommonConfig

* chore: tests successful changes compiled

* feat: respect parentProject in upload request

When the upload request contains correct parent project information separate requests

  1. to check if the parent exists
  2. to move the uploaded project in the tree

could be skipped.
The big advantage is, that admin could separate permissions of teams using the new feature "Portfolio Access Control".

Additionally if the uploaded project already exists in any other version the user account does not need the permission PORTFOLIO_MANAGEMENT.

* chore: housekeeping

* chore: fixed README.md

* chore: fixed SonarQube findings

* chore: fixed SonarQube findings

* fix: added parentUuid to put request

* fix: updated README.md

* fix: replaced UUID type with String

* fix: README.md

* chore: Removed unused import 'java.util.UUID'.

* Update src/main/java/io/github/pmckeown/dependencytrack/CommonConfig.java

Co-authored-by: Paul McKeown <[email protected]>

* chore: implemented review comments

---------

Co-authored-by: Thomas Hucke <[email protected]>
Co-authored-by: Paul McKeown <[email protected]>

* fix: prioritized handling of parentUuid
chore: updated maven dependencies

* fix: Codacity findings

---------

Co-authored-by: thomashucke <[email protected]>
Co-authored-by: Thomas Hucke <[email protected]>
  • Loading branch information
3 people authored Dec 14, 2024
1 parent 398bded commit 202325a
Show file tree
Hide file tree
Showing 25 changed files with 468 additions and 210 deletions.
54 changes: 42 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,32 @@ in the `pluginManagement` section of your POM to avoid repetition.
</plugins>
</pluginManagement>
```
Especially if you're in a multi-module configuration you should additionally include the plugin
in the regular build plugin section that contains `<inherited>false</inherited>`.
This assures that your submodules reflect the parent/child hierarchy of your pom.

```xml
<plugins>
<!-- Generate SBOM file -->
<plugin>
<groupId>org.cyclonedx</groupId>
<artifactId>cyclonedx-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.github.pmckeown</groupId>
<artifactId>dependency-track-maven-plugin</artifactId>
<inherited>false</inherited>
<configuration>
<!-- set either -->
<parentUuid>UUID_OF_PARENT_PROJECT_IN_DTRACK</parentUuid>
<!-- or -->
<parentName>NAME_OF_PARENT_PROJECT_IN_DTRACK</parentName>
<parentVersion>VERSION_OF_PARENT_PROJECT_IN_DTRACK</parentVersion>
</configuration>
</plugin>
</plugins>
```

**IMPORTANT** Dependency Track includes a front-end and an api-server component on different ports (defaulting to
8080 and 8081 respectively). You must ensure that you target the api server component (8081) and not the front-end
component URL in the `dependencyTrackBaseUrl` property.
Expand Down Expand Up @@ -117,6 +142,8 @@ The Automation team needs the following permissions:
* In Dependency Track v4.4.x and later:
* BOM_UPLOAD
* PORTFOLIO_MANAGEMENT

Only when project should be automatically created. If a project exists in any version, this permission is not needed.
* PROJECT_CREATION_UPLOAD
* VIEW_PORTFOLIO
* VIEW_VULNERABILITY
Expand Down Expand Up @@ -206,25 +233,28 @@ Dependency-Track based on the metadata present in the BOM:

**Notes:**
* This requires a CycloneDX BOM using Schema 1.2 or later.
* required permission `PORTFOLIO_MANAGEMENT` if `updateProjectInfo` or `updateParent` is `true`
* Not all information is visible in the Dependency-Track server UI.

From Dependency-Track server 4.8.0 onwards, you can set the project parent by setting `updateParent` to `true`. The
parent name will be defaulted to that POM's project parent name. If you wish to override that value, or there is
no parent set within the `pom.xml`, then explicitly set `parentName` and `parentVersion`. `projectVersion` is optional
Dependency-Track, so this has no default to allow for blank values.

**Note:** If the parent cannot be found on the Dependency-Track server, the BOM upload will not be attempted in order to
prevent a project being incorrectly created or updated the server.

| Property | Required | Default Value | Example Values |
|----------------------|----------|------------------------|---------------------------|
| bomLocation | false | target/bom.xml | target/custom-bom.xml |
| updateProjectInfo | false | false | false |
| updateParent | false | false | true |
| parentName | false | ${project.parent.name} | my-name-override |
| parentVersion | false | | ${project.parent.version} |
| isLatest | false | false | true |
| projectTags[].name | false | false | <name>tag1</name> |
**Note 1:** If both `parentUuid` and `parentName` / `parentVersion` are provided in configuration `parentUuid` will take precedence.

**Note 2:** If a non-existing parent information is provided, the plugin will fail with `404 Not found`.

| Property | Required | Default Value | Example Values |
|--------------------|----------|------------------------|---------------------------------------|
| bomLocation | false | target/bom.xml | target/custom-bom.xml |
| updateProjectInfo | false | false | false |
| updateParent | false | false | true |
| parentUuid | false | | 628df5eb-a7fe-4c3f-831c-4536839a05ed |
| parentName | false | ${project.parent.name} | my-name-override |
| parentVersion | false | | ${project.parent.version} |
| isLatest | false | false | true |
| projectTags[].name | false | false | <name>tag1</name> |

The `isLatest` option sets the flag on the project to indicate that it is the latest version.

Expand Down
28 changes: 14 additions & 14 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.8.1</version>
<version>3.15.1</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand All @@ -192,13 +192,13 @@
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId>
<version>2.27.2</version>
<version>3.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.9.0</version>
<version>5.14.2</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand All @@ -208,7 +208,7 @@
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.3.1</version>
<version>3.4.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_maven-plugin_packaging -->
<plugin>
Expand All @@ -227,48 +227,48 @@
</plugin>
<plugin>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.9.0</version>
<version>3.15.1</version>
<configuration>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.1</version>
<version>3.5.2</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<version>3.4.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>3.1.1</version>
<version>3.1.3</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.1.1</version>
<version>3.1.3</version>
</plugin>
<plugin>
<artifactId>maven-invoker-plugin</artifactId>
<version>3.6.0</version>
<version>3.8.1</version>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<version>3.3.1</version>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.4.1</version>
<version>3.11.2</version>
</plugin>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.9.1.2184</version>
<version>5.0.0.4389</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.10</version>
<version>0.8.12</version>
<configuration>
<append>true</append>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import static io.github.pmckeown.dependencytrack.ObjectMapperFactory.relaxedObjectMapper;
import static kong.unirest.HeaderNames.ACCEPT;
import static kong.unirest.HeaderNames.ACCEPT_ENCODING;

/**
* Base class for Mojos in this project.
*
Expand Down Expand Up @@ -138,8 +137,8 @@ public void setSkip(String skip) {
this.skip = skip;
}

public void setPollingConfig(PollingConfig commonConfig) {
this.pollingConfig = commonConfig;
public void setPollingConfig(PollingConfig pollingConfig) {
this.pollingConfig = pollingConfig;
}

protected void handleFailure(String message) throws MojoFailureException {
Expand Down
110 changes: 105 additions & 5 deletions src/main/java/io/github/pmckeown/dependencytrack/CommonConfig.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package io.github.pmckeown.dependencytrack;

import io.github.pmckeown.util.Logger;
import java.util.Collections;
import java.util.Set;
import javax.inject.Singleton;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugin.logging.SystemStreamLog;
import org.apache.maven.project.MavenProject;

/**
* Holder for common configuration supplied on Mojo execution
Expand All @@ -10,15 +16,28 @@
@Singleton
public class CommonConfig {

private String projectName;
private String projectVersion;
private String projectUuid="";
private String projectName="";
private String projectVersion="";
private String dependencyTrackBaseUrl;
private String apiKey;
private PollingConfig pollingConfig;
private String bomLocation;
private MavenProject mavenProject;
private boolean updateProjectInfo;
private boolean updateParent;
private String parentUuid;
private String parentName;
private String parentVersion;
private boolean isLatest;
private boolean autoCreate = true;
private Set<String> projectTags = Collections.emptySet();

public CommonConfig() {
// For dependency injection
}
protected Logger logger = new Logger(new SystemStreamLog());

public String getProjectUuid() { return projectUuid; }

public void setProjectUuid(String projectUuid) { this.projectUuid = projectUuid; }

public String getProjectName() {
return projectName;
Expand Down Expand Up @@ -59,5 +78,86 @@ public void setApiKey(String apiKey) {
public void setPollingConfig(PollingConfig pollingConfig) {
this.pollingConfig = pollingConfig;
}
public Set<String> getProjectTags() {
return projectTags;
}

public void setProjectTags(Set<String> projectTags) {
this.projectTags = projectTags;
}

public boolean isLatest() {
return isLatest;
}

public void setLatest(boolean latest) {
isLatest = latest;
}

public String getParentVersion() {
return parentVersion;
}

public void setParentVersion(String parentVersion) {
if (StringUtils.isBlank(parentUuid)) {
this.parentVersion = parentVersion;
} else if (StringUtils.isNotBlank(parentUuid))
logger.info("parentUuid set so ignoring parentVersion: %s", parentVersion);
}

public String getParentUuid() { return parentUuid; }

public void setParentUuid(String parentUuid) {
this.parentUuid = parentUuid;
if (StringUtils.isNotBlank(parentUuid)) {
logger.info("parentUuid set to: %s", parentUuid);
logger.info("clearing parentName and parentVersion");
this.setParentName(null);
this.setParentVersion(null);
}
}

public String getParentName() {
return parentName;
}

public void setParentName(String parentName) {
if (StringUtils.isBlank(parentUuid)) {
this.parentName = parentName;
} else if (StringUtils.isNotBlank(parentUuid))
logger.info("parentUuid set so ignoring parentName: %s", parentName);
}

public boolean getUpdateParent() { return updateParent; }

public void setUpdateParent(boolean updateParent) {
this.updateParent = updateParent;
}

public boolean getUpdateProjectInfo() { return updateProjectInfo; }

public void setUpdateProjectInfo(boolean updateProjectInfo) { this.updateProjectInfo = updateProjectInfo; }

public MavenProject getMavenProject() { return mavenProject; }

public void setMavenProject(MavenProject mavenProject) {
this.mavenProject = mavenProject;
}

public void setBomLocation(String bomLocation) {
this.bomLocation = bomLocation;
}
public String getBomLocation() {
if (StringUtils.isNotBlank(bomLocation)) {
return bomLocation;
} else {
String defaultLocation = getMavenProject().getBasedir() + "/target/bom.xml";
this.logger.debug("bomLocation not supplied so using: %s", defaultLocation);
return defaultLocation;
}
}

public boolean isAutoCreate() {
return autoCreate;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public FindingsMojo(ProjectAction projectAction, FindingsAction findingsAction,
protected void performAction() throws MojoExecutionException, MojoFailureException {
List<Finding> findings;
try {
Project project = projectAction.getProject(commonConfig.getProjectName(), commonConfig.getProjectVersion());
Project project = projectAction.getProject(commonConfig);
findings = findingsAction.getFindings(project);
findingsPrinter.printFindings(project, findings);
populateThresholdFromCliOptions();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public MetricsMojo(MetricsAction metricsAction, ProjectAction getProjectAction,
@Override
public void performAction() throws MojoExecutionException, MojoFailureException {
try {
Project project = getProjectAction.getProject(projectName, projectVersion);
Project project = getProjectAction.getProject(commonConfig);
logger.debug("Project Details: %s", project.toString());

Metrics metrics = getMetrics(project);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public PolicyViolationsMojo(ProjectAction projectAction, PolicyViolationsReportG
protected void performAction() throws MojoExecutionException, MojoFailureException {
List<PolicyViolation> policyViolations;
try {
Project project = projectAction.getProject(commonConfig.getProjectName(), commonConfig.getProjectVersion());
Project project = projectAction.getProject(commonConfig);
policyViolations = policyAction.getPolicyViolations(project);
policyViolationsPrinter.printPolicyViolations(project, policyViolations);
boolean policyViolationsBreached = policyAnalyser.isAnyPolicyViolationBreached(policyViolations,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public DeleteProjectMojo(ProjectAction projectAction, CommonConfig commonConfig,
@Override
protected void performAction() throws MojoExecutionException, MojoFailureException {
try {
Project project = projectAction.getProject(projectName, projectVersion);
Project project = projectAction.getProject(commonConfig);

boolean success = projectAction.deleteProject(project);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,4 @@ public boolean isLatest() {
public List<ProjectTag> getTags() {
return tags;
}

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
}
}
Loading

0 comments on commit 202325a

Please sign in to comment.