use of com.epam.pipeline.entity.pipeline.Tool in project cloud-pipeline by epam.
the class AggregatingToolScanManager method fetchLayers.
private List<String> fetchLayers(Tool tool, String tag, DockerRegistry registry) throws ToolScanExternalServiceException {
DockerClient dockerClient = getDockerClient(tool.getImage(), registry);
ManifestV2 manifest = dockerClient.getManifest(registry, tool.getImage(), tag).orElseThrow(() -> new ToolScanExternalServiceException(tool, messageHelper.getMessage(MessageConstants.ERROR_REGISTRY_COULD_NOT_GET_MANIFEST, tool.getImage())));
return manifest.getLayers().stream().map(c -> c.getDigest()).collect(Collectors.toList());
}
use of com.epam.pipeline.entity.pipeline.Tool in project cloud-pipeline by epam.
the class AggregatingToolScanManager method convertResults.
private ToolVersionScanResult convertResults(ClairScanResult clairScanResult, DockerComponentScanResult compScanResult, Tool tool, String tag, String digest) {
List<Vulnerability> vulnerabilities = Optional.ofNullable(clairScanResult).map(result -> ListUtils.emptyIfNull(result.getFeatures()).stream()).orElse(Stream.empty()).flatMap(f -> f.getVulnerabilities() != null ? f.getVulnerabilities().stream().map(v -> {
Vulnerability vulnerability = new Vulnerability();
vulnerability.setName(v.getName());
vulnerability.setDescription(v.getDescription());
vulnerability.setFixedBy(v.getFixedBy());
vulnerability.setLink(v.getLink());
vulnerability.setSeverity(v.getSeverity());
vulnerability.setFeature(f.getName());
vulnerability.setFeatureVersion(f.getVersion());
return vulnerability;
}) : Stream.empty()).collect(Collectors.toList());
LOGGER.debug("Found: " + vulnerabilities.size() + " vulnerabilities for " + tool.getImage() + ":" + tag);
// Concat dependencies from Clair and DockerCompScan
List<ToolDependency> dependencies = Stream.concat(Optional.ofNullable(compScanResult).map(result -> ListUtils.emptyIfNull(result.getLayers()).stream()).orElse(Stream.empty()).flatMap(l -> l.getDependencies().stream().peek(dependency -> {
dependency.setToolVersion(tag);
dependency.setToolId(tool.getId());
})), Optional.ofNullable(clairScanResult).map(result -> ListUtils.emptyIfNull(result.getFeatures()).stream()).orElse(Stream.empty()).map(f -> new ToolDependency(tool.getId(), tag, f.getName(), f.getVersion(), ToolDependency.Ecosystem.SYSTEM, null))).collect(Collectors.toList());
LOGGER.debug("Found: " + dependencies.size() + " dependencies for " + tool.getImage() + ":" + tag);
return new ToolVersionScanResult(tag, vulnerabilities, dependencies, ToolScanStatus.COMPLETED, clairScanResult.getName(), digest);
}
use of com.epam.pipeline.entity.pipeline.Tool in project cloud-pipeline by epam.
the class ToolScanScheduler method scheduledToolScan.
/**
* A scheduled scan, that runs for all the registries, all tools and all tool versions, sends them to Tool Scanning
* System and stores scanning results to the database.
*/
public void scheduledToolScan() {
if (!preferenceManager.getPreference(SystemPreferences.DOCKER_SECURITY_TOOL_SCAN_ENABLED)) {
LOGGER.info(messageHelper.getMessage(MessageConstants.ERROR_TOOL_SCAN_DISABLED));
return;
} else {
LOGGER.info(messageHelper.getMessage(MessageConstants.INFO_TOOL_SCAN_SCHEDULED_STARTED));
}
boolean scanAllRegistries = preferenceManager.getPreference(SystemPreferences.DOCKER_SECURITY_TOOL_SCAN_ALL_REGISTRIES);
List<DockerRegistry> registries = scanAllRegistries ? dockerRegistryDao.loadAllDockerRegistry() : dockerRegistryDao.loadDockerRegistriesWithSecurityScanEnabled();
for (DockerRegistry registry : registries) {
LOGGER.info(messageHelper.getMessage(MessageConstants.INFO_TOOL_SCAN_REGISTRY_STARTED, registry.getPath()));
for (Tool tool : registry.getTools()) {
DockerClient dockerClient = getDockerClient(registry, tool);
try {
List<String> versions = toolManager.loadTags(tool.getId());
for (String version : versions) {
try {
ToolVersionScanResult result = toolScanManager.scanTool(tool, version, false);
toolManager.updateToolVulnerabilities(result.getVulnerabilities(), tool.getId(), version);
toolManager.updateToolDependencies(result.getDependencies(), tool.getId(), version);
toolManager.updateToolVersionScanStatus(tool.getId(), ToolScanStatus.COMPLETED, new Date(), version, result.getLastLayerRef(), result.getDigest());
updateToolVersion(tool, version, registry, dockerClient);
} catch (ToolScanExternalServiceException e) {
LOGGER.error(messageHelper.getMessage(MessageConstants.ERROR_TOOL_SCAN_FAILED, tool.getImage(), version), e);
toolManager.updateToolVersionScanStatus(tool.getId(), ToolScanStatus.FAILED, new Date(), version, null, null);
}
}
} catch (Exception e) {
LOGGER.error(messageHelper.getMessage(MessageConstants.ERROR_TOOL_SCAN_FAILED, tool.getImage()), e);
toolManager.updateToolVersionScanStatus(tool.getId(), ToolScanStatus.FAILED, new Date(), "latest", null, null);
}
}
}
LOGGER.info(messageHelper.getMessage(MessageConstants.INFO_TOOL_SCAN_SCHEDULED_DONE));
}
use of com.epam.pipeline.entity.pipeline.Tool in project cloud-pipeline by epam.
the class ToolScanScheduler method forceScheduleScanTool.
/**
* Schedule a Tool for security scan. Since a Tool's scan is a time costly operation, there's a queue for that.
* A tool is added to that queue and will be processed in order. Once the tool is added to a queue, it's scanStatus
* field is being set to {@link ToolScanStatus}.PENDING
* @param registry a registry path, where tool is located
* @param id Tool's id or image
* @param version Tool's version (Docker tag)
* @param rescan
*/
public Future<ToolVersionScanResult> forceScheduleScanTool(final String registry, final String id, final String version, final Boolean rescan) {
if (!preferenceManager.getPreference(SystemPreferences.DOCKER_SECURITY_TOOL_SCAN_ENABLED)) {
throw new IllegalArgumentException(messageHelper.getMessage(MessageConstants.ERROR_TOOL_SCAN_DISABLED));
}
Tool tool = toolManager.loadTool(registry, id);
Optional<ToolVersionScanResult> toolVersionScanResult = toolManager.loadToolVersionScan(tool.getId(), version);
ToolScanStatus curentStatus = toolVersionScanResult.map(ToolVersionScanResult::getStatus).orElse(ToolScanStatus.NOT_SCANNED);
// The tool is already in the queue
if (curentStatus != ToolScanStatus.PENDING) {
String layerRef = toolVersionScanResult.map(ToolVersionScanResult::getLastLayerRef).orElse(null);
String digest = toolVersionScanResult.map(ToolVersionScanResult::getDigest).orElse(null);
toolManager.updateToolVersionScanStatus(tool.getId(), ToolScanStatus.PENDING, null, version, layerRef, digest);
return forceScanExecutor.submit(new DelegatingSecurityContextCallable<>(() -> {
LOGGER.info(messageHelper.getMessage(MessageConstants.INFO_TOOL_FORCE_SCAN_STARTED, tool.getImage()));
try {
ToolVersionScanResult scanResult = toolScanManager.scanTool(tool, version, rescan);
toolManager.updateToolVulnerabilities(scanResult.getVulnerabilities(), tool.getId(), version);
toolManager.updateToolDependencies(scanResult.getDependencies(), tool.getId(), version);
toolManager.updateToolVersionScanStatus(tool.getId(), ToolScanStatus.COMPLETED, scanResult.getScanDate(), version, scanResult.getLastLayerRef(), scanResult.getDigest());
return scanResult;
} catch (Exception e) {
toolManager.updateToolVersionScanStatus(tool.getId(), ToolScanStatus.FAILED, new Date(), version, null, null);
LOGGER.error(messageHelper.getMessage(MessageConstants.ERROR_TOOL_SCAN_FAILED, tool.getImage()), e);
throw new PipelineException(e);
}
}, SecurityContextHolder.getContext()));
}
return CompletableFuture.completedFuture(new ToolVersionScanResult(ToolScanStatus.PENDING, null, Collections.emptyList(), Collections.emptyList()));
}
use of com.epam.pipeline.entity.pipeline.Tool in project cloud-pipeline by epam.
the class DockerRegistryManager method parseAndValidateScope.
// expected format: repository:group/image:push
private List<DockerRegistryClaim> parseAndValidateScope(String userName, DockerRegistry registry, String scope) {
if (StringUtils.isBlank(scope)) {
// read permission for at least one child in the registry is required
if (!permissionManager.isActionAllowedForUser(registry, userName, AclPermission.READ)) {
DockerRegistry fullTree = getDockerRegistryTree(registry.getId());
permissionManager.filterTree(userName, fullTree, AclPermission.READ);
if (CollectionUtils.isEmpty(fullTree.getChildren())) {
throw new DockerAuthorizationException(registry.getPath(), messageHelper.getMessage(MessageConstants.ERROR_REGISTRY_IS_NOT_ALLOWED, userName, registry.getPath()));
}
}
return Collections.emptyList();
}
List<DockerRegistryClaim> claims = DockerRegistryClaim.parseClaims(scope);
claims.forEach(claim -> {
AbstractSecuredEntity entity = registry;
List<Permission> permissions = claim.getRequestedPermissions();
boolean toolRequired = !permissions.contains(AclPermission.WRITE);
try {
ToolGroup toolGroup = toolGroupManager.loadToolGroupByImage(registry.getPath(), claim.getImageName());
entity = toolGroup;
Optional<Tool> tool = toolManager.loadToolInGroup(claim.getImageName(), toolGroup.getId());
entity = tool.orElseThrow(() -> new IllegalArgumentException(messageHelper.getMessage(MessageConstants.ERROR_TOOL_IMAGE_UNAVAILABLE, claim.getImageName())));
} catch (IllegalArgumentException e) {
LOGGER.trace(e.getMessage(), e);
if (toolRequired) {
throw new IllegalArgumentException(messageHelper.getMessage(MessageConstants.ERROR_TOOL_IMAGE_UNAVAILABLE, claim.getImageName()));
}
}
if (!permissionManager.isActionAllowedForUser(entity, userName, permissions)) {
throw new DockerAuthorizationException(registry.getPath(), messageHelper.getMessage(MessageConstants.ERROR_REGISTRY_ACTION_IS_NOT_ALLOWED, scope, userName, registry.getPath()));
}
});
return claims;
}
Aggregations