Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions CONVENTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ src/main/java/io/github/guacsec/trustifyda/
│ ├── lock/ # Distributed locking (LockService)
│ ├── providers/ # Vulnerability providers
│ │ └── trustify/
│ │ ├── hardened/ # Hardened image recommendation provider
│ │ └── ubi/ # UBI image recommendation (config-based)
│ │ └── hardened/ # Hardened image recommendation provider
│ ├── report/ # Report generation
│ ├── registry/ # Ecosystem registry integrations (PEP 691, etc.)
│ ├── sbom/ # SBOM parsing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ private Map<PackageRef, List<IndexedRecommendation>> getRecommendations(

/**
* Normalizes recommendation maps to a consistent List-valued format. Handles both the legacy
* single-value format (Map&lt;PackageRef, IndexedRecommendation&gt;) from trusted-content/UBI
* providers and the new list format (Map&lt;PackageRef, List&lt;IndexedRecommendation&gt;&gt;)
* from the hardened image provider.
* single-value format (Map&lt;PackageRef, IndexedRecommendation&gt;) from the trusted-content
* provider and the list format (Map&lt;PackageRef, List&lt;IndexedRecommendation&gt;&gt;) from
* the hardened image provider.
*/
@SuppressWarnings("unchecked")
private Map<PackageRef, List<IndexedRecommendation>> normalizeRecommendations(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
import io.github.guacsec.trustifyda.integration.cache.CacheService;
import io.github.guacsec.trustifyda.integration.providers.VulnerabilityProvider;
import io.github.guacsec.trustifyda.integration.providers.trustify.hardened.HardenedImageProvider;
import io.github.guacsec.trustifyda.integration.providers.trustify.ubi.UBIRecommendation;
import io.github.guacsec.trustifyda.model.DependencyTree;
import io.github.guacsec.trustifyda.model.PackageItem;
import io.github.guacsec.trustifyda.model.ProviderHealthCheckResult;
Expand Down Expand Up @@ -84,7 +83,6 @@ public class TrustifyIntegration extends EndpointRouteBuilder {
@Inject TrustifyResponseHandler responseHandler;
@Inject TrustifyRequestBuilder requestBuilder;
@Inject ObjectMapper mapper;
@Inject UBIRecommendation ubiRecommendation;
@Inject HardenedImageProvider hardenedImageProvider;
@Inject MeterRegistry registry;
@Inject CacheService cacheService;
Expand All @@ -94,7 +92,6 @@ public class TrustifyIntegration extends EndpointRouteBuilder {
private static final List<String> FIXED_STATUSES = List.of("NotAffected", "Fixed");
private static final String OCI_PURL_TYPE = "oci";
private static final String TRUSTED_CONTENT_SOURCE = "trusted-content";
private static final String HARDENED_IMAGES_SOURCE = "hardened-images";

@Override
public void configure() throws Exception {
Expand Down Expand Up @@ -372,11 +369,9 @@ private String getTokenHeader(Exchange exchange) {
*/
public void processRecommendations(Exchange exchange) throws IOException {
byte[] tcResponse = exchange.getIn().getBody(byte[].class);
String sbomId = exchange.getProperty(Constants.SBOM_ID_PROPERTY, String.class);

var response = mapper.readValue(tcResponse, RecommendationsResponse.class);
var mergedRecommendations = indexRecommendations(response);
mergedRecommendations.putAll(getUBIRecommendation(sbomId));

exchange.getMessage().setBody(mergedRecommendations);
}
Expand Down Expand Up @@ -411,26 +406,6 @@ private Map<PackageRef, IndexedRecommendation> indexRecommendations(
return result;
}

private Map<PackageRef, IndexedRecommendation> getUBIRecommendation(String sbomId) {
if (sbomId == null) {
return Collections.emptyMap();
}

var pkgRef = new PackageRef(sbomId);
if (!OCI_PURL_TYPE.equals(pkgRef.purl().getType())) {
return Collections.emptyMap();
}

var recommendedUBIPurl = ubiRecommendation.mapping().get(pkgRef.name());
if (recommendedUBIPurl != null) {
var recommendation =
new IndexedRecommendation(
new PackageRef(recommendedUBIPurl), null, HARDENED_IMAGES_SOURCE);
return Collections.singletonMap(pkgRef, recommendation);
}
return Collections.emptyMap();
}

private void processHardenedRecommendations(Exchange exchange) {
String sbomId = exchange.getProperty(Constants.SBOM_ID_PROPERTY, String.class);
exchange.getMessage().setBody(hardenedImageProvider.lookupBySbomId(sbomId));
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

Expand All @@ -33,10 +32,8 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;

import io.github.guacsec.trustifyda.integration.Constants;
import io.github.guacsec.trustifyda.integration.providers.trustify.ubi.UBIRecommendation;
import io.quarkus.runtime.annotations.RegisterForReflection;

import jakarta.enterprise.context.ApplicationScoped;
Expand All @@ -52,8 +49,6 @@ public class ReportTemplate {
@ConfigProperty(name = "report.remediation.template")
String remediationTemplate;

@Inject UBIRecommendation ubiRecommendation;

@ConfigProperty(name = Constants.TELEMETRY_WRITE_KEY)
Optional<String> writeKey;

Expand All @@ -74,7 +69,7 @@ public Map<String, Object> setVariables(
params.put("report", report);
params.put("cveIssueTemplate", cveIssuePathRegex);
params.put("remediationTemplate", remediationTemplate);
params.put("imageMapping", getImageMapping());
params.put("imageMapping", "[]");
params.put("rhdaSource", rhdaSource);
getBrandingConfig()
.ifPresent(config -> params.put("brandingConfig", getBrandingConfigMap(config)));
Expand All @@ -96,22 +91,6 @@ private String sanitize(String report) {
return sanitizedReport;
}

private String getImageMapping() throws JsonProcessingException {
List<Map<String, String>> urlMapping =
ubiRecommendation.purl().keySet().stream()
.map(
ubi -> {
Map<String, String> urls = new HashMap<>(2);
urls.put("purl", ubiRecommendation.purl().get(ubi));
urls.put("catalogUrl", ubiRecommendation.catalogurl().get(ubi));
return urls;
})
.toList();

ObjectWriter objectWriter = new ObjectMapper().writer();
return objectWriter.writeValueAsString(urlMapping);
}

private Optional<BrandingConfig> getBrandingConfig() {
try {
Config config = ConfigProvider.getConfig();
Expand Down
11 changes: 0 additions & 11 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,6 @@ quarkus.management.enabled=true
quarkus.micrometer.binder.http-server.enabled=false
quarkus.http.limits.max-body-size=4G

trustedcontent.recommendation.ubi.purl.ubi9=pkg:oci/ubi@sha256:f5983f7c7878cc9b26a3962be7756e3c810e9831b0b9f9613e6f6b445f884e74?repository_url=registry.access.redhat.com/ubi9/ubi&tag=9.3-1552&arch=amd64
trustedcontent.recommendation.ubi.catalogurl.ubi9=https://catalog.redhat.com/software/containers/ubi9/ubi/615bcf606feffc5384e8452e?architecture=amd64&image=65a82982a10f3e68777870b5f
trustedcontent.recommendation.ubi.purl.ubi9-minimal=pkg:oci/ubi-minimal@sha256:06d06f15f7b641a78f2512c8817cbecaa1bf549488e273f5ac27ff1654ed33f0?repository_url=registry.access.redhat.com/ubi9/ubi-minimal&tag=9.3-1552&arch=amd64
trustedcontent.recommendation.ubi.catalogurl.ubi9-minimal=https://catalog.redhat.com/software/containers/ubi9/ubi-minimal/615bd9b4075b022acc111bf5?architecture=amd64&image=65a828e3cda4984705d45d26
trustedcontent.recommendation.ubi.mapping.alpine=${trustedcontent.recommendation.ubi.purl.ubi9-minimal}
trustedcontent.recommendation.ubi.mapping.ubuntu=${trustedcontent.recommendation.ubi.purl.ubi9}
trustedcontent.recommendation.ubi.mapping.centos=${trustedcontent.recommendation.ubi.purl.ubi9}
trustedcontent.recommendation.ubi.mapping.debian=${trustedcontent.recommendation.ubi.purl.ubi9}
trustedcontent.recommendation.ubi.mapping.fedora=${trustedcontent.recommendation.ubi.purl.ubi9}
trustedcontent.recommendation.ubi.mapping.amazonlinux=${trustedcontent.recommendation.ubi.purl.ubi9}

# Hardened image recommendation provider (Hummingbird)
trustedcontent.recommendation.hardened.url=${HUMMINGBIRD_URL:}
trustedcontent.recommendation.hardened.refresh-interval=${HUMMINGBIRD_REFRESH_INTERVAL:1h}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
import io.github.guacsec.trustifyda.api.v5.RemediationInfo;
import io.github.guacsec.trustifyda.api.v5.Severity;
import io.github.guacsec.trustifyda.integration.Constants;
import io.github.guacsec.trustifyda.integration.providers.trustify.ubi.UBIRecommendation;
import io.github.guacsec.trustifyda.model.DependencyTree;
import io.github.guacsec.trustifyda.model.DirectDependency;
import io.github.guacsec.trustifyda.model.PackageItem;
Expand All @@ -66,7 +65,6 @@ public class TrustifyResponseHandlerTest {
private DependencyTree dependencyTree;

private TrustifyIntegration trustifyIntegration;
private UBIRecommendation ubiRecommendation;

private static final PackageRef rootPackageRef = new PackageRef("pkg:maven/org.acme/app@1.0");

Expand All @@ -89,15 +87,6 @@ void setUp() {
// Setup for TrustifyIntegration.processRecommendations() tests
trustifyIntegration = new TrustifyIntegration();
trustifyIntegration.mapper = new ObjectMapper();

// Create a mock UBIRecommendation
ubiRecommendation = mock(UBIRecommendation.class);
Map<String, String> mapping = new HashMap<>();
mapping.put("alpine", "pkg:oci/ubi@0.0.2");
when(ubiRecommendation.mapping()).thenReturn(mapping);
when(ubiRecommendation.purl()).thenReturn(Collections.emptyMap());
when(ubiRecommendation.catalogurl()).thenReturn(Collections.emptyMap());
trustifyIntegration.ubiRecommendation = ubiRecommendation;
}

private static Stream<String> testResponseToIssuesWithValidData() {
Expand Down Expand Up @@ -989,40 +978,6 @@ void testProcessRecommendationsEmpty() throws IOException {
assertTrue(recommendations.isEmpty());
}

@Test
void testProcessRecommendationsWithSbomId() throws IOException {
String sbomId = "pkg:oci/alpine@0.0.1";
Exchange exchange = mock(Exchange.class);
Message inMessage = mock(Message.class);
Message outMessage = mock(Message.class);

when(exchange.getIn()).thenReturn(inMessage);
when(exchange.getMessage()).thenReturn(outMessage);
when(exchange.getProperty(Constants.SBOM_ID_PROPERTY, String.class)).thenReturn(sbomId);

byte[] responseBytes =
getClass()
.getClassLoader()
.getResourceAsStream("__files/trustedcontent/empty_report.json")
.readAllBytes();
when(inMessage.getBody(byte[].class)).thenReturn(responseBytes);

trustifyIntegration.processRecommendations(exchange);

@SuppressWarnings("rawtypes")
ArgumentCaptor<Map> bodyCaptor = forClass(Map.class);
verify(outMessage).setBody(bodyCaptor.capture());
@SuppressWarnings("unchecked")
Map<PackageRef, IndexedRecommendation> recommendations = bodyCaptor.getValue();
assertNotNull(recommendations);

PackageRef sbomRef = new PackageRef(sbomId);
IndexedRecommendation recommendation =
new IndexedRecommendation(new PackageRef("pkg:oci/ubi@0.0.2"), null, "hardened-images");
assertEquals(1, recommendations.size());
assertEquals(recommendation, recommendations.get(sbomRef));
}

@Test
void testResponseToIssuesWithUnscannedRefs() throws IOException {
String jsonResponse =
Expand Down
14 changes: 1 addition & 13 deletions src/test/resources/__files/reports/batch_report.json
Original file line number Diff line number Diff line change
Expand Up @@ -1124,19 +1124,7 @@
"warnings": {}
},
"sources": {},
"recommendations": {
"hardened-images": {
"summary": {
"total": 1
},
"dependencies": [
{
"ref": "pkg:oci/debian@sha256%3A7c288032ecf3319045d9fa538c3b0cc868a320d01d03bce15b99c2c336319994?tag=0.0.1",
"recommendation": "pkg:oci/ubi@sha256%3Af5983f7c7878cc9b26a3962be7756e3c810e9831b0b9f9613e6f6b445f884e74?arch=amd64&repository_url=registry.access.redhat.com%2Fubi9%2Fubi&tag=9.3-1552"
}
]
}
}
"recommendations": {}
}
},
"licenses": [
Expand Down
Loading