Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Container scan eligibility and config validations #957

Merged
merged 2 commits into from
Oct 2, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,12 @@ private BlackDuckRunData getBlackDuckRunData(
blackDuckDecision.scanMode(),
blackDuckServicesFactory,
phoneHomeManager,
blackDuckConnectivityResult.getBlackDuckServerConfig(),
blackDuckConnectivityResult,
waitAtScanLevel
);
} else {
logger.debug("Skipping phone home due to Black Duck global settings.");
bdRunData = BlackDuckRunData.onlineNoPhoneHome(blackDuckDecision.scanMode(), blackDuckServicesFactory, blackDuckConnectivityResult.getBlackDuckServerConfig(), waitAtScanLevel);
bdRunData = BlackDuckRunData.onlineNoPhoneHome(blackDuckDecision.scanMode(), blackDuckServicesFactory, blackDuckConnectivityResult, waitAtScanLevel);
}
return bdRunData;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@

import com.synopsys.integration.blackduck.configuration.BlackDuckServerConfig;
import com.synopsys.integration.blackduck.service.BlackDuckServicesFactory;
import com.synopsys.integration.blackduck.version.BlackDuckVersion;
import com.synopsys.integration.detect.configuration.enumeration.BlackduckScanMode;
import com.synopsys.integration.detect.lifecycle.boot.product.BlackDuckConnectivityResult;
import com.synopsys.integration.detect.lifecycle.boot.product.version.BlackDuckVersionParser;
import com.synopsys.integration.detect.workflow.phonehome.PhoneHomeManager;

public class BlackDuckRunData {
Expand All @@ -13,19 +16,22 @@ public class BlackDuckRunData {
private final BlackDuckServicesFactory blackDuckServicesFactory;
private final BlackduckScanMode scanMode;
private final boolean waitAtScanLevel;
private Optional<BlackDuckVersion> blackDuckServerVersion;

protected BlackDuckRunData(
PhoneHomeManager phoneHomeManager,
BlackDuckServerConfig blackDuckServerConfig,
BlackDuckConnectivityResult blackDuckConnectivityResult,
BlackDuckServicesFactory blackDuckServicesFactory,
BlackduckScanMode scanMode,
boolean waitAtScanLevel
) {
this.phoneHomeManager = phoneHomeManager;
this.blackDuckServerConfig = blackDuckServerConfig;
this.blackDuckServerConfig = blackDuckConnectivityResult != null ? blackDuckConnectivityResult.getBlackDuckServerConfig() : null;
this.blackDuckServicesFactory = blackDuckServicesFactory;
this.scanMode = scanMode;
this.waitAtScanLevel = waitAtScanLevel;

determineBlackDuckServerVersion(blackDuckConnectivityResult);
}

public boolean isOnline() {
Expand All @@ -52,14 +58,14 @@ public static BlackDuckRunData online(
BlackduckScanMode scanMode,
BlackDuckServicesFactory blackDuckServicesFactory,
PhoneHomeManager phoneHomeManager,
BlackDuckServerConfig blackDuckServerConfig,
BlackDuckConnectivityResult blackDuckConnectivityResult,
boolean waitAtScanLevel
) {
return new BlackDuckRunData(phoneHomeManager, blackDuckServerConfig, blackDuckServicesFactory, scanMode, waitAtScanLevel);
return new BlackDuckRunData(phoneHomeManager, blackDuckConnectivityResult, blackDuckServicesFactory, scanMode, waitAtScanLevel);
}

public static BlackDuckRunData onlineNoPhoneHome(BlackduckScanMode scanMode, BlackDuckServicesFactory blackDuckServicesFactory, BlackDuckServerConfig blackDuckServerConfig, boolean waitAtScanLevel) {
return new BlackDuckRunData(null, blackDuckServerConfig, blackDuckServicesFactory, scanMode, waitAtScanLevel);
public static BlackDuckRunData onlineNoPhoneHome(BlackduckScanMode scanMode, BlackDuckServicesFactory blackDuckServicesFactory, BlackDuckConnectivityResult blackDuckConnectivityResult, boolean waitAtScanLevel) {
return new BlackDuckRunData(null, blackDuckConnectivityResult, blackDuckServicesFactory, scanMode, waitAtScanLevel);
}

public Boolean isNonPersistent() {
Expand All @@ -73,4 +79,17 @@ public BlackduckScanMode getScanMode() {
public boolean shouldWaitAtScanLevel() {
return waitAtScanLevel;
}

public Optional<BlackDuckVersion> getBlackDuckServerVersion() {
return blackDuckServerVersion;
}

private void determineBlackDuckServerVersion(BlackDuckConnectivityResult blackDuckConnectivityResult) {
if (blackDuckConnectivityResult == null || blackDuckConnectivityResult.getContactedServerVersion() == null) {
blackDuckServerVersion = null;
} else {
BlackDuckVersionParser parser = new BlackDuckVersionParser();
blackDuckServerVersion = parser.parse(blackDuckConnectivityResult.getContactedServerVersion());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,10 @@ public String getScanServicePostContentType() {
return DEVELOPER_SCAN_CONTENT_TYPE;
}

public Optional<String> getContainerScanFilePath() {
return detectConfigurationFactory.getContainerScanFilePath();
}

public File downloadContainerImage(Gson gson, File downloadDirectory, String containerImageUri) throws DetectUserFriendlyException, IntegrationException, IOException {
String targetPathName = downloadDirectory.toString().concat("/targetImage");
ConnectionFactory connectionFactory = new ConnectionFactory(detectConfigurationFactory.createConnectionDetails());
Expand All @@ -387,7 +391,7 @@ public File downloadContainerImage(Gson gson, File downloadDirectory, String con
}

public File getContainerScanImage(Gson gson, File downloadDirectory) throws IntegrationException, IOException, DetectUserFriendlyException {
Optional<String> containerImageFilePath = detectConfigurationFactory.getContainerScanFilePath();
Optional<String> containerImageFilePath = getContainerScanFilePath();
File containerImageFile = null;
if (containerImageFilePath.isPresent()) {
String containerImageUri = containerImageFilePath.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.synopsys.integration.blackduck.version.BlackDuckVersion;
import com.synopsys.integration.detect.configuration.DetectUserFriendlyException;
import com.synopsys.integration.detect.lifecycle.run.data.BlackDuckRunData;
import com.synopsys.integration.detect.lifecycle.run.operation.OperationRunner;
Expand All @@ -30,6 +31,7 @@ public class ContainerScanStepRunner {
private final BlackDuckRunData blackDuckRunData;
private final File binaryRunDirectory;
private final File containerImage;
private static final BlackDuckVersion MIN_BLACK_DUCK_VERSION = new BlackDuckVersion(2023, 10, 0);
private static final String STORAGE_CONTAINERS_ENDPOINT = "/api/storage/containers/";
private static final String STORAGE_IMAGE_CONTENT_TYPE = "application/vnd.blackducksoftware.container-scan-data-1+octet-stream";
private static final String STORAGE_IMAGE_METADATA_CONTENT_TYPE = "application/vnd.blackducksoftware.container-scan-message-1+json";
Expand All @@ -50,26 +52,47 @@ public ContainerScanStepRunner(OperationRunner operationRunner, NameVersion proj
public Optional<UUID> invokeContainerScanningWorkflow() {
try {
logger.debug("Determining if configuration is valid to run a container scan.");
if (shouldRunContainerScan()) {
initiateScan();
logger.info("Container scan initiated.");
uploadImageToStorageService();
uploadImageMetadataToStorageService();
operationRunner.publishContainerSuccess();
logger.info("Container scan image uploaded successfully.");
} else {
logger.info("Container image file not provided or could not be downloaded. Container scan will not run.");
if (!isContainerScanEligible()) {
logger.info("No container.scan.file.path property was provided. Skipping container scan.");
return Optional.ofNullable(scanId);
}
if (!isBlackDuckVersionValid()) {
String minBlackDuckVersion = String.join(".",
Integer.toString(MIN_BLACK_DUCK_VERSION.getMajor()),
Integer.toString(MIN_BLACK_DUCK_VERSION.getMinor()),
Integer.toString(MIN_BLACK_DUCK_VERSION.getPatch())
);
throw new IntegrationException("Container scan is only supported with BlackDuck version " + minBlackDuckVersion + " or greater. Container scan could not be run.");
}
if (!isContainerImageResolved()) {
throw new IOException("Container image file path not resolved or file could not be downloaded. Container scan could not be run.");
}

initiateScan();
logger.info("Container scan initiated.");
uploadImageToStorageService();
uploadImageMetadataToStorageService();
operationRunner.publishContainerSuccess();
logger.info("Container scan image uploaded successfully.");
} catch (IntegrationException | IOException e) {
operationRunner.publishContainerFailure(e);
}
return Optional.ofNullable(scanId);
}

private boolean shouldRunContainerScan() {
private boolean isContainerImageResolved() {
return containerImage != null && containerImage.exists();
}

private boolean isContainerScanEligible() {
return operationRunner.getContainerScanFilePath().isPresent();
}

private boolean isBlackDuckVersionValid() {
Optional<BlackDuckVersion> blackDuckVersion = blackDuckRunData.getBlackDuckServerVersion();
return blackDuckVersion.isPresent() && blackDuckVersion.get().isAtLeast(MIN_BLACK_DUCK_VERSION);
}

private String getContainerScanCodeLocationName() {
CodeLocationNameManager codeLocationNameManager = operationRunner.getCodeLocationNameManager();
return codeLocationNameManager.createContainerScanCodeLocationName(containerImage, projectNameVersion.getName(), projectNameVersion.getVersion());
Expand Down