feat: Aviator apply-remediations issue-id filtering for SSC/FoD#1050
feat: Aviator apply-remediations issue-id filtering for SSC/FoD#1050kireetivar wants to merge 16 commits into
Conversation
There was a problem hiding this comment.
I've done a partial review and added some individual code comments, which mostly originate from current (command) design. Can we improve the design, thereby automatically resolving most of these comments?
I think the key issue is that these commands operate on individual FPR files, thus requiring separate --file/--dir output options depending on how many FPRs are being downloaded, and deviating from fcli arity conventions to pass these FPRs through wildcards to apply-remediations commands. Also, when depending on user-specified dirs/wildcards, there's a risk that incorrect FPR files get picked up, for example from a previous run, possibly even from a different app version/release.
Three alternative approaches come to mind (but maybe you can think of other approaches):
- Get rid of
download-remediations-fprcommands, and instead add caching options onapply-remediationscommands, for example a--[no-]use-cacheoption that checks fcli state directory whether cached FPR files for current set of args (--av/--rel& artifact selection criteria) is available, downloading these to the cache on the fly if not yet available or outdated. Main complexity is cache management, for example requiring extra commands/options for updating or clearing cache, detecting outdated cache, ... - Have
download-remediations-fpr(possibly renamed to something likeprepare-remediations-cacheoutput a single 'remediations cache' zip file; depending on FPR selection criteria, this zip-file can contain either single or multiple FPR files, which users can then pass toapply-remediationscmd using--from-cache=<zip-file> - Combination of the above; have
apply-remediations --use-cache=<zip-file>; if given zip-file exists, it's used as is, otherwise it's created by downloading FPR files based on current FPR selection criteria. Possibly, the zip-file could contain metadata like app version/release and FPR selection criteria; if there's a mismatch with current selection criteria on theapply-remediationscommand, an error would be thrown.
|
|
||
| @Override | ||
| public boolean isSingular() { | ||
| return true; |
There was a problem hiding this comment.
What's the rationale for having singular output with artifact id's embedded in that single output record, rather than outputting separate records for every individual artifact? Unless there are good reasons against the latter, that's the more common fcli convention.
| result.putArray("artifactIds").add(artifact.getId()); | ||
| result.putArray("files").add(destination.toString()); | ||
| result.put("file", destination.toString()); | ||
| result.put(IActionCommandResultSupplier.actionFieldName, getActionCommandResult()); |
There was a problem hiding this comment.
fcli output framework automatically sets the 'action' column based on getActionCommandResult; explicitly setting this field is only necessary if you want to display dynamic action values, i.e., if that value depends on execution flow/result.
| files.add(destination.toString()); | ||
| artifactIds.add(artifact.getId()); | ||
| } | ||
| result.put(IActionCommandResultSupplier.actionFieldName, getActionCommandResult()); |
There was a problem hiding this comment.
fcli output framework automatically sets the 'action' column based on getActionCommandResult; explicitly setting this field is only necessary if you want to display dynamic action values, i.e., if that value depends on execution flow/result.
| throw new FcliSimpleException("--dir must be specified when using --all"); | ||
| } | ||
| } else if (outputDir != null) { | ||
| throw new FcliSimpleException("--dir can only be used with --all; use -f/--file for a single FPR download"); |
There was a problem hiding this comment.
Why is --dir not supported for single-file downloads, using the default FPR file name as defined in getSingleDestination.
| private boolean latest; | ||
|
|
||
| @Option(names = {"--all"}, required = true, descriptionKey = "fcli.aviator.ssc.download-remediations-fpr.all") | ||
| private boolean allOpenIssues; |
There was a problem hiding this comment.
Weird field name for 'all FPRs'
|
|
||
| @Option(names = {"--fpr"}, required = true, arity = "1..*", paramLabel = "<file>", | ||
| descriptionKey = "fcli.aviator.ssc.apply-remediations.fpr") | ||
| @DisableTest({TestType.MULTI_OPT_SPLIT, TestType.MULTI_OPT_PLURAL_NAME, TestType.OPT_ARITY_VARIABLE}) |
There was a problem hiding this comment.
I guess the rationale for non-standard arity and the disabled tests is to allow this to work with wildcard patterns, i.e., --fpr /path/to/downloads/*.fpr? Although picocli does its best to handle multi-arity options, we encountered issues with this in the past, hence we usually disallow this.
| return outputFile == null ? Path.of(String.format("remediations_artifact_%s.fpr", artifact.getId())) : outputFile.toPath(); | ||
| } | ||
|
|
||
| private void validateDestinationOptions() { |
There was a problem hiding this comment.
In general, I don't like exclusive sets of options as it affects user experience (difficult to figure out which sets of options can be combined), nor manual validation instead of picocli handling option exclusivity (also to properly display this in command syntax). Any way around this, by reorganizing ArgGroups?
|
Thanks for the review comments. I’m planning to revise the PR away from the current raw-FPR workflow. Proposed solution:
Example {
"schemaVersion": 1,
"kind": "aviator-remediations-cache",
"product": "ssc",
"createdAt": "2026-07-16T12:00:00Z",
"selection": {
"mode": "all",
"appVersionId": "10001",
"since": "2026-07-01T00:00:00Z"
},
"entries": [
{
"order": 1,
"artifactId": "12345",
"uploadDate": "2026-07-10T08:00:00Z",
"path": "fprs/001_artifact_12345.fpr",
"sha256": "8f14e45fceea167a5a36dedd4bea2543"
},
{
"order": 2,
"artifactId": "67890",
"uploadDate": "2026-07-11T09:30:00Z",
"path": "fprs/002_artifact_67890.fpr",
"sha256": "45c48cce2e2d7fbdea1afc51c7c6ad26"
}
]
}
If you are ok with this proposal, I have a few questions I’d like your input on:
|
|
I don't have a strong preference for either option 2 or 3:
For option 2, I think it's better to have For option 3, we would need to verify options against cache, but then need to decide what to do if there's a mismatch; throw an error, replace the cache based on current selection options, ...
Yes, if we go for option 2
I think requiring
Use
Not sure; probably should have same behavior as current non-cache based |
…equired option mixin
| try { | ||
| // ZipFS on sibling work file; existing destination is left intact until publish. | ||
| fs = ZipHelper.createZipFileSystem(workPath); | ||
| Files.createDirectories(fs.getPath(RemediationsCacheConstants.FPRS_DIR)); |
There was a problem hiding this comment.
I think state management in this class can be significantly simplified if directory creation is moved outside of the constructor:
- Constructor just performs prerequisite ops/checks and then
this.zipFs = ZipHelper.createZipFileSystem(workPath) - Any exceptions in constructor can be immediately thrown; no need to store error and check/handle elsewhere
- No need to keep
closedstatus, asclose()would only need to be called by try-with-resources
| public static RemediationsCacheWriter create(Path destination, String product, Map<String, String> selection) { | ||
| FcliSimpleException.throwIf(destination == null, | ||
| "-f/--file must specify a remediations cache zip path"); | ||
| RemediationsCacheWriter writer = new RemediationsCacheWriter(destination, product, selection); |
There was a problem hiding this comment.
As an example of the simplification mentioned above, this code could be reduced to just a simple return new RemediationsCacheWriter(...);
| RemediationsCacheWriter writer = new RemediationsCacheWriter(destination, product, selection); | ||
| if (writer.initError != null) { | ||
| Exception cause = writer.initError; | ||
| writer.close(); |
There was a problem hiding this comment.
With the mechanism described above, there's no need to explicitly call close(); either zipFs was successfully initialized (in which case it will be automatically closed by outer try-with-resources), or zipFs` initialization failed (in which case there's nothing to close)
| * successful {@link #close()}. | ||
| * Returns the completed manifest. | ||
| */ | ||
| public RemediationsCacheManifest finish() { |
There was a problem hiding this comment.
Why have this as a separate public method that needs to be explicitly called? Why not just have the close() method automatically perform all finalization operations (but through separate private helper methods, to keep close() method fairly short)
| } | ||
| } | ||
|
|
||
| private void requireWritable() { |
There was a problem hiding this comment.
Based on comments above, I think there's little use for this method
| } | ||
| } | ||
|
|
||
| public record FprSource(Path path, String artifactId, String releaseId, String uploadDate) { |
There was a problem hiding this comment.
Having a single record that may represent two types of entities (SSC artifact id vs FoD release id) looks like a code smell; any way to improve?
| * Source selection for apply-remediations: either online SSC selection or a local remediations cache zip. | ||
| */ | ||
| @Getter | ||
| public class AviatorSSCApplyRemediationsSourceMixin { |
There was a problem hiding this comment.
There seems to be quite some code duplication (like getter methods) between this class, AviatorSSCRemediationsCacheDownloadSelectorMixin, and possibly AviatorSSCRemediationsSelectorArgGroups ; any way to improve? Given that these classes are now by themselves responsible for resolving artifact descriptors, do we still need these accessors? If so, can we use @Getter (where appropriate) instead?
| * Factory for writers (not Jackson). Avoids multi-arg same-type call sites on the wire model. | ||
| * Do not add {@code @Builder} on this {@code @Reflectable} class. | ||
| */ | ||
| public static RemediationsCacheEntry of( |
There was a problem hiding this comment.
Although it's an improvement to move this responsibility to the appropriate class:
- Given the number of arguments, most with the same type, there's still the risk that arguments are passed in the wrong order
- I don't like individual SSC and FoD properties being mixed in a single class; this makes it difficult to understand which properties are always required, and which properties are only applicable to either FoD or SSC
Before reading the below, please check the later comment about refactoring validation, as this is closely related and referenced in the proposals below.
A potentially better approach would be to have:
- Separate
RemediationsCacheFoDEntryandRemediationsCacheSSCEntryclasses (please check correct case forFoDandSSCin these class names to be consistent with other fcli classes), each containing only the relevant properties for either FoD or SSC - Have both classes implement interface/abstract class that defines the shared properties like
order,path, andsha256 - If SSC/FoD-specific properties may not be null, add a
validatemethod to each entry class - In
RemediationsCacheManifest, declare two separate entry lists, i.e.,fodEntriesandsscEntries, or maybe keep singleList<? extends ...> entries, deriving actual type from theproductproperty
Alternatively, potentially easier from a caller perspective:
- Keep a single
RemediationsCacheEntryclass, but introduce two (inner) model classes that represent FoD/SSC-specific properties - Introduce corresponding properties and accessors in this class, for example
sscDataandfodData(any better property names?) - Validation would require exactly one of these properties to be set
- Validation of individual SSC/FoD-specific properties is done in the respective SSC/FoD-specific model classes
- Instead of the single
ofmethod, introduce separate factory methods for SSC/FoD, each taking the SSC/FoD-specific model class (not individual properties), just assigning the provided model object to thesscDataorfodDatafield - If useful, introduce factory methods on the SSC/FoD-specific model classes, like
of(artifactId, ...)on the SSC model class, andof(releaseId, ...)on the FoD model class
| } | ||
| } | ||
|
|
||
| private void validateManifest(RemediationsCacheManifest manifest) { |
There was a problem hiding this comment.
I think validation would be better moved to the model classes, i.e., this class would just check that manifest is not null, then call manifest.validate(cacheZip), which checks its own property values, then calls getEntries().forEach(e->e.validate(cacheZip)). This provides better encapsulation, reducing the risk of missing any validation checks, and based on the suggestion above about having different model classes for SSC/FoD, this would then also automatically allow SSC/FoD-specific properties to be validated.
| return descriptor.getVersionId(); | ||
| } | ||
|
|
||
| public String getSelectionMode() { |
There was a problem hiding this comment.
I haven't checked whether the values produced by this method are only used in fcli output (in which case current implementation may be fine), or referenced/compared in any other code (in which case it would be better to use a proper enum)
| .build()); | ||
| } | ||
|
|
||
| private static ObjectNode toOnlineJson(OnlineResultData data) { |
There was a problem hiding this comment.
Several observations/questions on this method and related methods/classes:
- In general, we should attempt to have each fcli command output a consistent (sub)set of properties regardless of options/operating mode, for example to allow for proper, useful table output (even if that's not the default output format). Ideally, to ensure consistent output and allow for better code re-use, code/class structure should represent which properties are always being written (independent of operating mode), and what properties are only applicable to a certain operating mode, for example by moving shared properties to a common superclass that's inherited by both
CacheResultDataandOnlineResultData. - Given that these
*ResultDataclasses are (primarily) meant to represent output properties, why are we manually constructing anObjectNodeinstead of using Jackson serialization? - If Jackson serialization isn't possible for any reason, rendering JSON output should be the responsibility of the data class, i.e., having
*ResultData::toJsonmethods, to provide better encapsulation and make it less likely (being closer to the actual property definitions) that any properties are missed.
There was a problem hiding this comment.
Pull request overview
This PR extends the Aviator remediation workflows to support generating a reusable “remediations cache” zip for both SSC and FoD, and adds cache-based apply flows that can optionally filter remediations by issue id(s). It also introduces shared cache-zip read/write/validation utilities and refactors the apply flows to use a common “iterate FPR sources + apply” loop for both online and offline sources.
Changes:
- Added
download-remediations-cachecommands for SSC and FoD, producing an ordered zip (manifest + FPR entries + checksums). - Extended SSC/FoD
apply-remediationsto support--from-cacheand optional--issue-idsfiltering for cache-based runs. - Introduced shared cache utilities (ZipFS helpers, cache reader/writer, checksum validation, common apply loop) and improved temp FPR handling.
Reviewed changes
Copilot reviewed 47 out of 47 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| fcli-core/fcli-ssc/src/test/java/com/fortify/cli/ssc/artifact/helper/SSCArtifactHelperTest.java | Adds unit tests for new Aviator artifact detection/validation logic. |
| fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/artifact/helper/SSCArtifactHelper.java | Adds isAviatorArtifact()/requireAviatorArtifact() helpers used by SSC selection flows. |
| fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/_common/rest/ssc/transfer/SSCFileTransferHelper.java | Adds Path-based download support for ZipFS destinations and safer write-on-ready behavior. |
| fcli-core/fcli-fod/src/test/java/com/fortify/cli/fod/aviator/FoDAviatorDownloadRemediationsCacheCommandTest.java | Adds CLI parse/required-arg tests for FoD cache download command. |
| fcli-core/fcli-fod/src/test/java/com/fortify/cli/fod/aviator/FoDAviatorApplyRemediationsCommandTest.java | Updates FoD apply-remediations tests for new source selection + issue-id rules. |
| fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/i18n/FoDMessages.properties | Documents new FoD cache and issue-id options and adds output table args for cache download. |
| fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/aviator/helper/FoDRemediationsFprDownloadHelper.java | Adds FoD download helper with 202 retry + “write body only when ready” semantics. |
| fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/aviator/helper/FodOnlineRemediationsFprSource.java | Implements online FoD FPR source that downloads to managed temp files per entry. |
| fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/aviator/helper/AviatorFoDApplyRemediationsHelper.java | Refactors FoD apply output JSON building for both online and cache flows. |
| fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/aviator/cmd/FoDAviatorDownloadRemediationsCacheCommand.java | Adds FoD download-remediations-cache command that writes a cache zip. |
| fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/aviator/cmd/FoDAviatorCommands.java | Registers FoD download-cache subcommand. |
| fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/aviator/cmd/FoDAviatorApplyRemediationsCommand.java | Adds FoD --from-cache and --issue-ids handling and splits online vs cache processing. |
| fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/aviator/cli/mixin/FoDAviatorApplyRemediationsSourceMixin.java | Adds FoD apply source selector ArgGroup (release vs cache). |
| fcli-core/fcli-common-core/src/main/java/com/fortify/cli/common/util/ZipHelper.java | Adds ZipFS open/create helpers used by cache reader/writer. |
| fcli-core/fcli-common-core/src/main/java/com/fortify/cli/common/exception/FcliSimpleException.java | Adds FcliSimpleException.throwIf(...) guard helper for compact validations. |
| fcli-core/fcli-aviator/src/test/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCDownloadRemediationsCacheCommandTest.java | Adds tests for SSC cache download CLI rules/validation behavior. |
| fcli-core/fcli-aviator/src/test/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCApplyRemediationsCommandTest.java | Adds tests for SSC apply-remediations cache selection and issue-id rule. |
| fcli-core/fcli-aviator/src/main/resources/com/fortify/cli/aviator/i18n/AviatorMessages.properties | Updates SSC help text and adds messages for cache download/apply and issue-id filtering. |
| fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/helper/SscOnlineRemediationsFprSource.java | Implements online SSC FPR source that downloads each artifact to a temp file. |
| fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/helper/AviatorSSCApplyRemediationsHelper.java | Refactors SSC apply output JSON building for online and cache flows. |
| fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/mixin/AviatorSSCRemediationsSelectorArgGroups.java | Adds shared SSC online selection ArgGroups for both apply and cache-download commands. |
| fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/mixin/AviatorSSCRemediationsCacheDownloadSelectorMixin.java | Wraps shared SSC online selection group for cache download command. |
| fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/mixin/AviatorSSCApplyRemediationsSourceMixin.java | Adds SSC apply source selector (online vs cache). |
| fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/mixin/AviatorSSCApplyRemediationsArtifactSelectorMixin.java | Removes old apply selector mixin (replaced by shared selector + source mixin). |
| fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCDownloadRemediationsCacheCommand.java | Adds SSC download-remediations-cache command that writes a cache zip from artifacts. |
| fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCCommands.java | Registers SSC download-cache subcommand. |
| fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCApplyRemediationsCommand.java | Adds SSC --from-cache + --issue-ids support and refactors apply loop into shared helper. |
| fcli-core/fcli-aviator-common/src/test/java/com/fortify/cli/aviator/fpr/processor/RemediationProcessorTest.java | Adds tests for issue-id filtering behavior and path traversal resilience. |
| fcli-core/fcli-aviator-common/src/test/java/com/fortify/cli/aviator/_common/util/AviatorRemediationMetricsHelperTest.java | Adds tests for aggregation semantics when issue-id filtering is enabled. |
| fcli-core/fcli-aviator-common/src/test/java/com/fortify/cli/aviator/_common/util/AviatorLocalFprHelperTest.java | Adds tests for local FPR validation helper. |
| fcli-core/fcli-aviator-common/src/test/java/com/fortify/cli/aviator/_common/util/AviatorIssueIdFilterUtilsTest.java | Adds tests for issue-id normalization + blank-value rejection. |
| fcli-core/fcli-aviator-common/src/test/java/com/fortify/cli/aviator/_common/remediations_cache/RemediationsCacheRoundTripTest.java | Adds end-to-end cache zip writer/reader tests (order, checksums, path safety). |
| fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/fpr/processor/RemediationProcessor.java | Refactors remediation application logic and adds optional issue-id filtering metric tracking. |
| fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/applyRemediation/ApplyAutoRemediationOnSource.java | Extends apply API to accept an optional issue-id filter set. |
| fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/util/AviatorTempFprFile.java | Adds managed temp-file utility for online-download FPR staging. |
| fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/util/AviatorRemediationMetricsHelper.java | Adds helper to aggregate metrics across entries and handle remaining issue-id logic. |
| fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/util/AviatorLocalFprHelper.java | Adds helper for validating local on-disk FPR files before processing. |
| fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/util/AviatorIssueIdFilterUtils.java | Adds normalization/deduplication and validation for issue-id filters. |
| fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/RemediationsCacheWriter.java | Adds cache zip writer (ZipFS-based, ordered entries, manifest writing, publish-on-close). |
| fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/RemediationsCacheSha256.java | Adds SHA-256 helpers for cache entry integrity checks. |
| fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/RemediationsCacheReader.java | Adds cache zip reader (manifest/schema validation, safe entry resolution, checksum validation). |
| fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/RemediationsCacheManifest.java | Adds manifest wire model for cache zip metadata. |
| fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/RemediationsCacheEntry.java | Adds manifest entry model + factory method for writer-side creation. |
| fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/RemediationsCacheConstants.java | Adds cache schema/product constants shared across modules. |
| fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/RemediationsApplyHelper.java | Adds shared apply loop that processes entries sequentially and soft-skips unsupported entries. |
| fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/IRemediationsFprSource.java | Adds common abstraction for “iterate FPR entries” (online or cache sources). |
| fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/CacheRemediationsFprSource.java | Adds cache-backed implementation of IRemediationsFprSource using the cache reader. |
Comments suppressed due to low confidence (1)
fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/_common/rest/ssc/transfer/SSCFileTransferHelper.java:63
- The
download(..., File downloadPath, ...)overload writes the response directly viaasFile()and doesn’t perform the status/202 check or incomplete-download cleanup that the newPath-based overload provides. If the server returns a non-2xx/202 response, this can leave a partially written or error-body file on disk.
| // Log requested issue IDs that were not found in any remediation entries | ||
| for (String notFoundIssueId : processingState.getRequestedButNotApplied()) { | ||
| logger.debug("Requested issue ID '{}' was not found in any remediation entries in remediations.xml", notFoundIssueId); | ||
| } |
This PR adds remediations cache download/apply workflows for SSC and FoD so teams can download remediations once into a cache zip and apply them locally, including optional issue-level filtering.
What changed
fcli aviator ssc download-remediations-cachefcli fod aviator download-remediations-cachefcli aviator ssc apply-remediationsfcli fod aviator apply-remediations--from-cachesupport to SSC and FoD apply-remediations.--issue-idssupport for cache-based apply-remediations.--artifact-id--latest--all--release/--relremediations.xml.Behavior
--from-cache:--issue-ids:instanceIdmatches requested ids are considered.--issue-idsis only supported together with--from-cache.--issue-ids:remediations.xml:SSC cache behavior
download-remediations-cache --allstores artifacts in chronological order.apply-remediations --from-cacheprocesses entries in the same stored order.FoD cache behavior
download-remediations-cachestores the selected release FPR in the cache zip.apply-remediations --from-cacheprocesses entries in cache order.apply-remediations command additions
fcli aviator ssc apply-remediations --from-cache <zip>fcli aviator ssc apply-remediations --from-cache <zip> --issue-ids <id1,id2,...>fcli fod aviator apply-remediations --from-cache <zip>fcli fod aviator apply-remediations --from-cache <zip> --issue-ids <id1,id2,...>