Skip to content

Commit

Permalink
feat: Add fcli fod report commands for creating and downloading FoD…
Browse files Browse the repository at this point in the history
… reports (resolves #263)
  • Loading branch information
kadraman authored Jan 29, 2024
1 parent ad56b85 commit c5dd780
Show file tree
Hide file tree
Showing 22 changed files with 969 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,6 @@ public class FoDUrls {
public static final String ENTITLEMENTS = ApiBase + "/tenant-entitlements";
public static final String OSS_SCANS = ApiBase + "/releases/{relId}/open-source-scans";
public static final String OSS_SCANS_START = OSS_SCANS + "/start-scan";

public static final String REPORTS = ApiBase + "/reports";
public static final String REPORT = ApiBase + "/reports/{reportId}";
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,51 @@
/*******************************************************************************
* Copyright 2021, 2023 Open Text.
*
* The only warranties for products and services of Open Text
* and its affiliates and licensors ("Open Text") are as may
* be set forth in the express warranty statements accompanying
* such products and services. Nothing herein should be construed
* as constituting an additional warranty. Open Text shall not be
* liable for technical or editorial errors or omissions contained
* herein. The information contained herein is subject to change
* The only warranties for products and services of Open Text
* and its affiliates and licensors ("Open Text") are as may
* be set forth in the express warranty statements accompanying
* such products and services. Nothing herein should be construed
* as constituting an additional warranty. Open Text shall not be
* liable for technical or editorial errors or omissions contained
* herein. The information contained herein is subject to change
* without notice.
*******************************************************************************/

package com.fortify.cli.fod._common.scan.helper;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.util.ArrayList;
import java.util.stream.Stream;

public enum FoDScanStatus {
Not_Started, In_Progress, Completed, Canceled, Waiting, Scheduled, Queued;
Not_Started(1), In_Progress(2), Completed(3), Canceled(4), Waiting(5), Scheduled(6), Queued(7);

private int statusValue;

FoDScanStatus(int i) {
this.statusValue = i;
}

public int getValue() {
return statusValue;
}

public static FoDScanStatus valueOf(Integer index){
return FoDScanStatus.values()[index-1];
}

public static JsonNode addScanStatus(JsonNode scanRecord) {
ObjectNode record = scanRecord==null || !(scanRecord instanceof ObjectNode)
? null
: (ObjectNode)scanRecord;
if ( record != null ) {
int scanStatusType = record.get("scanStatusType").asInt();
return record.put("scanStatus", FoDScanStatus.valueOf(scanStatusType).toString());
}
return scanRecord;
}

public static final FoDScanStatus[] getFailureStates() {
return new FoDScanStatus[]{ Canceled };
Expand All @@ -34,19 +62,19 @@ public static final FoDScanStatus[] getDefaultCompleteStates() {
public static final String[] getFailureStateNames() {
return Stream.of(getFailureStates()).map(FoDScanStatus::name).toArray(String[]::new);
}

public static final String[] getKnownStateNames() {
return Stream.of(getKnownStates()).map(FoDScanStatus::name).toArray(String[]::new);
}

public static final String[] getDefaultCompleteStateNames() {
return Stream.of(getDefaultCompleteStates()).map(FoDScanStatus::name).toArray(String[]::new);
}

public static final class FoDScanStatusIterable extends ArrayList<String> {
private static final long serialVersionUID = 1L;
public FoDScanStatusIterable() {
super(Stream.of(FoDScanStatus.values()).map(Enum::name).toList());
public FoDScanStatusIterable() {
super(Stream.of(FoDScanStatus.values()).map(Enum::name).toList());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.fortify.cli.fod.microservice.cli.cmd.FoDMicroserviceCommands;
import com.fortify.cli.fod.oss_scan.cli.cmd.FoDOssScanCommands;
import com.fortify.cli.fod.release.cli.cmd.FoDReleaseCommands;
import com.fortify.cli.fod.report.cli.cmd.FoDReportCommands;
import com.fortify.cli.fod.rest.cli.cmd.FoDRestCommands;
import com.fortify.cli.fod.sast_scan.cli.cmd.FoDSastScanCommands;

Expand Down Expand Up @@ -49,6 +50,7 @@
FoDDastScanCommands.class,
FoDMastScanCommands.class,
FoDOssScanCommands.class,
FoDReportCommands.class,
FoDRestCommands.class,

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*******************************************************************************
* Copyright 2021, 2023 Open Text.
*
* The only warranties for products and services of Open Text
* and its affiliates and licensors ("Open Text") are as may
* be set forth in the express warranty statements accompanying
* such products and services. Nothing herein should be construed
* as constituting an additional warranty. Open Text shall not be
* liable for technical or editorial errors or omissions contained
* herein. The information contained herein is subject to change
* without notice.
*******************************************************************************/
package com.fortify.cli.fod.report.cli.cmd;

import com.fortify.cli.common.cli.cmd.AbstractContainerCommand;
import com.fortify.cli.common.variable.DefaultVariablePropertyName;
import picocli.CommandLine;

@CommandLine.Command(name = "report",
subcommands = {
FoDReportListCommand.class,
FoDReportGetCommand.class,
FoDReportCreateCommand.class,
FoDReportDeleteCommand.class,
FoDReportWaitForCommand.class,
FoDReportDownloadCommand.class,
FoDReportTemplateListCommand.class
}
)
@DefaultVariablePropertyName("reportId")
public class FoDReportCommands extends AbstractContainerCommand {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*******************************************************************************
* Copyright 2021, 2023 Open Text.
*
* The only warranties for products and services of Open Text
* and its affiliates and licensors ("Open Text") are as may
* be set forth in the express warranty statements accompanying
* such products and services. Nothing herein should be construed
* as constituting an additional warranty. Open Text shall not be
* liable for technical or editorial errors or omissions contained
* herein. The information contained herein is subject to change
* without notice.
*******************************************************************************/
package com.fortify.cli.fod.report.cli.cmd;

import com.fasterxml.jackson.databind.JsonNode;
import com.fortify.cli.common.cli.util.EnvSuffix;
import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins;
import com.fortify.cli.common.output.transform.IActionCommandResultSupplier;
import com.fortify.cli.common.output.transform.IRecordTransformer;
import com.fortify.cli.common.util.StringUtils;
import com.fortify.cli.fod._common.cli.mixin.FoDDelimiterMixin;
import com.fortify.cli.fod._common.output.cli.AbstractFoDJsonNodeOutputCommand;
import com.fortify.cli.fod.release.cli.mixin.FoDReleaseByQualifiedNameOrIdResolverMixin;
import com.fortify.cli.fod.release.helper.FoDReleaseDescriptor;
import com.fortify.cli.fod.report.cli.mixin.FoDReportTemplateByNameOrIdResolverMixin;
import com.fortify.cli.fod.report.helper.FoDReportCreateRequest;
import com.fortify.cli.fod.report.helper.FoDReportFormatType;
import com.fortify.cli.fod.report.helper.FoDReportHelper;
import kong.unirest.UnirestInstance;
import lombok.Getter;
import picocli.CommandLine.Command;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;

@Command(name = OutputHelperMixins.Create.CMD_NAME)
public class FoDReportCreateCommand extends AbstractFoDJsonNodeOutputCommand implements IActionCommandResultSupplier {
@Getter @Mixin private OutputHelperMixins.Create outputHelper;

@Mixin private FoDDelimiterMixin delimiterMixin; // Is automatically injected in resolver mixins
@Mixin private FoDReleaseByQualifiedNameOrIdResolverMixin.RequiredOption releaseResolver;

@Mixin private FoDReportTemplateByNameOrIdResolverMixin.RequiredOption reportTemplateResolver;

@EnvSuffix("NAME") @Parameters(index = "0", arity = "1", descriptionKey = "fcli.fod.report.create.name")
protected String reportName;

@Option(names = {"--format"}, required = true)
protected FoDReportFormatType format;

@Option(names = {"--notes"})
protected String notes;

@Override
public JsonNode getJsonNode(UnirestInstance unirest) {
FoDReleaseDescriptor releaseDescriptor = releaseResolver.getReleaseDescriptor(unirest);
int reportTemplateId = Integer.parseInt(reportTemplateResolver.getReportTemplateId(unirest));

FoDReportCreateRequest reportCreateRequest = FoDReportCreateRequest.builder()
.applicationId(Integer.valueOf(releaseDescriptor.getApplicationId()))
.releaseId(Integer.valueOf(releaseDescriptor.getReleaseId()))
.reportTemplateTypeId(reportTemplateId)
.reportName(reportName)
.reportFormat(StringUtils.capitalize(format.name().toLowerCase()))
.notes((notes == null || notes.isEmpty() ? "Generated by fcli" : notes))
.build();

return FoDReportHelper.createReport(unirest, reportCreateRequest).asJsonNode();
}

@Override
public String getActionCommandResult() {
return "CREATED";
}

@Override
public boolean isSingular() {
return true;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright 2021, 2023 Open Text.
*
* The only warranties for products and services of Open Text
* and its affiliates and licensors ("Open Text") are as may
* be set forth in the express warranty statements accompanying
* such products and services. Nothing herein should be construed
* as constituting an additional warranty. Open Text shall not be
* liable for technical or editorial errors or omissions contained
* herein. The information contained herein is subject to change
* without notice.
*******************************************************************************/
package com.fortify.cli.fod.report.cli.cmd;

import com.fasterxml.jackson.databind.JsonNode;
import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins;
import com.fortify.cli.common.output.transform.IActionCommandResultSupplier;
import com.fortify.cli.common.output.transform.IRecordTransformer;
import com.fortify.cli.fod._common.output.cli.AbstractFoDJsonNodeOutputCommand;
import com.fortify.cli.fod._common.rest.FoDUrls;
import com.fortify.cli.fod.report.cli.mixin.FoDReportResolverMixin;
import com.fortify.cli.fod.report.helper.FoDReportDescriptor;
import com.fortify.cli.fod.report.helper.FoDReportHelper;
import kong.unirest.UnirestInstance;
import lombok.Getter;
import picocli.CommandLine.Command;
import picocli.CommandLine.Mixin;

@Command(name = OutputHelperMixins.Delete.CMD_NAME)
public class FoDReportDeleteCommand extends AbstractFoDJsonNodeOutputCommand implements IActionCommandResultSupplier {
@Getter @Mixin private OutputHelperMixins.Delete outputHelper;
@Mixin private FoDReportResolverMixin.PositionalParameter reportResolver;

@Override
public JsonNode getJsonNode(UnirestInstance unirest) {
FoDReportDescriptor reportDescriptor = FoDReportHelper.getReportDescriptor(unirest, reportResolver.getReportId());
unirest.delete(FoDUrls.REPORT)
.routeParam("reportId", reportResolver.getReportId())
.asObject(JsonNode.class).getBody();
return reportDescriptor.asObjectNode();
}

@Override
public String getActionCommandResult() {
return "DELETED";
}

@Override
public boolean isSingular() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*******************************************************************************
* Copyright 2021, 2023 Open Text.
*
* The only warranties for products and services of Open Text
* and its affiliates and licensors ("Open Text") are as may
* be set forth in the express warranty statements accompanying
* such products and services. Nothing herein should be construed
* as constituting an additional warranty. Open Text shall not be
* liable for technical or editorial errors or omissions contained
* herein. The information contained herein is subject to change
* without notice.
*******************************************************************************/
package com.fortify.cli.fod.report.cli.cmd;

import com.fasterxml.jackson.databind.JsonNode;
import com.fortify.cli.common.cli.mixin.CommonOptionMixins;
import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins;
import com.fortify.cli.common.output.transform.IActionCommandResultSupplier;
import com.fortify.cli.common.output.transform.IRecordTransformer;
import com.fortify.cli.fod._common.output.cli.AbstractFoDJsonNodeOutputCommand;
import com.fortify.cli.fod._common.rest.FoDUrls;
import com.fortify.cli.fod.report.cli.mixin.FoDReportResolverMixin;
import com.fortify.cli.fod.report.helper.FoDReportDescriptor;
import com.fortify.cli.fod.report.helper.FoDReportHelper;
import kong.unirest.GetRequest;
import kong.unirest.UnirestInstance;
import lombok.Getter;
import lombok.SneakyThrows;
import picocli.CommandLine.Command;
import picocli.CommandLine.Mixin;

import java.nio.file.StandardCopyOption;

@Command(name = OutputHelperMixins.Download.CMD_NAME)
public class FoDReportDownloadCommand extends AbstractFoDJsonNodeOutputCommand implements IActionCommandResultSupplier {
@Getter @Mixin private OutputHelperMixins.Download outputHelper;
@Mixin private FoDReportResolverMixin.PositionalParameter reportResolver;

@Mixin private CommonOptionMixins.RequiredFile outputFileMixin;

@Override @SneakyThrows
public JsonNode getJsonNode(UnirestInstance unirest) {
FoDReportDescriptor reportDescriptor = FoDReportHelper.getReportDescriptor(unirest, reportResolver.getReportId());
var file = outputFileMixin.getFile().getAbsolutePath();
GetRequest request = unirest.get(FoDUrls.REPORT + "/download")
.routeParam("reportId", reportResolver.getReportId())
.accept("application/octet-stream");
int status = 202;
while ( status==202 ) {
status = request
.asFile(file, StandardCopyOption.REPLACE_EXISTING)
.getStatus();
if ( status==202 ) { Thread.sleep(30000L); }
}
return reportDescriptor.asObjectNode().put("file", file);
}

@Override
public String getActionCommandResult() {
return "REPORT_DOWNLOADED";
}

@Override
public boolean isSingular() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright 2021, 2023 Open Text.
*
* The only warranties for products and services of Open Text
* and its affiliates and licensors ("Open Text") are as may
* be set forth in the express warranty statements accompanying
* such products and services. Nothing herein should be construed
* as constituting an additional warranty. Open Text shall not be
* liable for technical or editorial errors or omissions contained
* herein. The information contained herein is subject to change
* without notice.
*******************************************************************************/
package com.fortify.cli.fod.report.cli.cmd;

import com.fasterxml.jackson.databind.JsonNode;
import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins;
import com.fortify.cli.common.output.transform.IRecordTransformer;
import com.fortify.cli.fod._common.output.cli.AbstractFoDJsonNodeOutputCommand;
import com.fortify.cli.fod.report.cli.mixin.FoDReportResolverMixin;
import com.fortify.cli.fod.report.helper.FoDReportHelper;
import kong.unirest.UnirestInstance;
import lombok.Getter;
import picocli.CommandLine.Command;
import picocli.CommandLine.Mixin;

@Command(name = OutputHelperMixins.Get.CMD_NAME)
public class FoDReportGetCommand extends AbstractFoDJsonNodeOutputCommand {
@Getter @Mixin private OutputHelperMixins.Get outputHelper;
@Mixin private FoDReportResolverMixin.PositionalParameter reportResolver;

@Override
public JsonNode getJsonNode(UnirestInstance unirest) {
return reportResolver.getReportDescriptor(unirest).asJsonNode();
}

@Override
public boolean isSingular() {
return true;
}

}
Loading

0 comments on commit c5dd780

Please sign in to comment.