diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionListCommand.java index df37832cfd..0e96733272 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionListCommand.java @@ -22,6 +22,8 @@ import com.fortify.cli.ssc._common.rest.query.SSCQParamValueGenerators; import com.fortify.cli.ssc._common.rest.query.cli.mixin.SSCQParamMixin; import com.fortify.cli.ssc.appversion.cli.mixin.SSCAppVersionBulkEmbedMixin; +import com.fortify.cli.ssc.appversion.cli.mixin.SSCAppVersionExcludeMixin; +import com.fortify.cli.ssc.appversion.cli.mixin.SSCAppVersionIncludeMixin; import com.fortify.cli.ssc.appversion.helper.SSCAppVersionHelper; import kong.unirest.HttpRequest; @@ -40,6 +42,8 @@ public class SSCAppVersionListCommand extends AbstractSSCBaseRequestOutputComman .add("application.id", "project.id", SSCQParamValueGenerators::plain) .add("name", SSCQParamValueGenerators::wrapInQuotes); @Mixin private SSCAppVersionBulkEmbedMixin bulkEmbedMixin; + @Mixin private SSCAppVersionIncludeMixin includeMixin; + @Mixin private SSCAppVersionExcludeMixin excludeMixin; @Override public HttpRequest getBaseRequest(UnirestInstance unirest) { diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/mixin/SSCAppVersionExcludeMixin.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/mixin/SSCAppVersionExcludeMixin.java new file mode 100644 index 0000000000..808b042cf9 --- /dev/null +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/mixin/SSCAppVersionExcludeMixin.java @@ -0,0 +1,43 @@ +package com.fortify.cli.ssc.appversion.cli.mixin; + +import java.util.Set; + +import com.fortify.cli.common.rest.unirest.IHttpRequestUpdater; +import com.fortify.cli.common.util.DisableTest; +import com.fortify.cli.common.util.DisableTest.TestType; + +import kong.unirest.HttpRequest; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import picocli.CommandLine.Option; + +public class SSCAppVersionExcludeMixin implements IHttpRequestUpdater { + @DisableTest(TestType.MULTI_OPT_PLURAL_NAME) + @Option(names = {"--exclude", "-e"}, split = ",", descriptionKey = "fcli.ssc.appversion.list.exclude", paramLabel="") + private Set excludes; + + public HttpRequest updateRequest(HttpRequest request) { + if ( excludes!=null ) { + for ( var exclude : excludes) { + var queryParameterName = exclude.getRequestParameterName(); + if ( queryParameterName!=null ) { + request = request.queryString(queryParameterName, "true"); + } + } + } + return request; + } + + @RequiredArgsConstructor + public static enum SSCAppVersionExclude { + empty("onlyIfHasIssues"), no_assigned_issues("myAssignedIssues"); + + @Getter + private final String requestParameterName; + + @Override + public String toString() { + return super.toString().replace('_', '-'); + } + } +} diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/mixin/SSCAppVersionIncludeMixin.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/mixin/SSCAppVersionIncludeMixin.java new file mode 100644 index 0000000000..1b86a7a3a0 --- /dev/null +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/mixin/SSCAppVersionIncludeMixin.java @@ -0,0 +1,54 @@ +package com.fortify.cli.ssc.appversion.cli.mixin; + +import java.util.Set; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fortify.cli.common.json.JsonHelper; +import com.fortify.cli.common.output.transform.IRecordTransformer; +import com.fortify.cli.common.rest.unirest.IHttpRequestUpdater; +import com.fortify.cli.common.util.DisableTest; +import com.fortify.cli.common.util.DisableTest.TestType; + +import kong.unirest.HttpRequest; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import picocli.CommandLine.Option; + +public class SSCAppVersionIncludeMixin implements IHttpRequestUpdater, IRecordTransformer { + @DisableTest(TestType.MULTI_OPT_PLURAL_NAME) + @Option(names = {"--include", "-i"}, split = ",", defaultValue = "active", descriptionKey = "fcli.ssc.appversion.list.include", paramLabel="") + private Set includes; + + public HttpRequest updateRequest(HttpRequest request) { + if ( includes!=null ) { + for ( var include : includes) { + var queryParameterName = include.getRequestParameterName(); + if ( queryParameterName!=null ) { + request = request.queryString(queryParameterName, "true"); + } + } + } + return request; + } + + @Override + public JsonNode transformRecord(JsonNode record) { + // If includes doesn't include 'active', we return null for any active application versions + // to remove those from the results. It would be more performant to add q=active:false request + // parameter instead to have SSC filter out active versions, but we need to figure out how + // to properly combine this with 'q'-parameters generated through SSCQParamGenerator as used + // in the 'fcli ssc av ls' command. + return !includes.contains(SSCAppVersionInclude.active) + && JsonHelper.evaluateSpelExpression(record, "active", Boolean.class) + ? null + : record; + } + + @RequiredArgsConstructor + public static enum SSCAppVersionInclude { + active(null), inactive("includeInactive"); + + @Getter + private final String requestParameterName; + } +} diff --git a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/i18n/SSCMessages.properties b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/i18n/SSCMessages.properties index 01fbf07a2d..60e2fd1684 100644 --- a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/i18n/SSCMessages.properties +++ b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/i18n/SSCMessages.properties @@ -353,6 +353,10 @@ fcli.ssc.appversion.list.embed = Embed extra application version data. Allowed v Using the --output option, this extra data can be included in the output. Using the --query option, \ this extra data can be queried upon. To get an understanding of the structure and contents of the \ embedded data, use the --output json or --output yaml options. +fcli.ssc.appversion.list.include = List either active (default), inactive, or both active and inactive versions. \ + Allowed values: ${COMPLETION-CANDIDATES}. +fcli.ssc.appversion.list.exclude = Exclude versions that either have no results, or no issues assigned to the current \ + user. Allowed values: ${COMPLETION-CANDIDATES}. fcli.ssc.appversion.purge-artifacts.usage.header = Purge application version artifacts. fcli.ssc.appversion.purge-artifacts.usage.description = Purge all application version artifacts older than the specified date. See 'fcli ssc artifact purge' for purging individual artifacts. fcli.ssc.appversion.purge-artifacts.older-than = Purge artifacts older than the specified value, \ @@ -609,7 +613,7 @@ fcli.ssc.alert.output.table.options = id,triggeredDate,alertDefinitionName,userN fcli.ssc.alert.definition.output.table.options = id,name,createdBy,recipientType,monitoredEntityType,triggerDescriptionName fcli.ssc.app.output.table.options = id,name fcli.ssc.app.delete.output.table.options = id,application.name,name,createdBy,action -fcli.ssc.appversion.output.table.options = id,application.name,name,issueTemplateName,createdBy +fcli.ssc.appversion.output.table.options = id,application.name,name,active,issueTemplateName,createdBy fcli.ssc.appversion.copy-state.output.table.options = previousProjectVersionId,projectVersionId # TODO Add scanTypes property using recordTransformer in command implementation fcli.ssc.artifact.output.table.options = id,scanTypes,lastScanDate,uploadDate,status