Skip to content

Commit

Permalink
Merge pull request #571 from fortify/develop
Browse files Browse the repository at this point in the history
Prepare for new 2.x release
  • Loading branch information
rsenden authored Aug 13, 2024
2 parents 7857239 + a454968 commit 3cb2141
Show file tree
Hide file tree
Showing 59 changed files with 1,178 additions and 535 deletions.
8 changes: 3 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,11 @@ jobs:
- name: PROD - Prepare GitHub release
id: create_prod_release
uses: GoogleCloudPlatform/release-please-action@v3
if: github.ref == 'refs/heads/main'
if: github.ref == 'refs/heads/v2.x'
with:
command: github-release
release-type: simple
package-name: ${{ github.event.repository.name }}
default-branch: main

- name: PROD - Define release info
if: steps.create_prod_release.outputs.release_created
Expand Down Expand Up @@ -266,13 +265,12 @@ jobs:
name: combined-artifacts

- name: PROD - Prepare release PR
if: github.ref == 'refs/heads/main'
if: github.ref == 'refs/heads/v2.x'
uses: GoogleCloudPlatform/release-please-action@v3
with:
command: release-pr
release-type: simple
package-name: ${{ github.event.repository.name }}
default-branch: main

- name: DEV - Prepare GitHub release
if: needs.build.outputs.do_dev_release
Expand Down Expand Up @@ -322,7 +320,7 @@ jobs:
rm -rf docs/.git*
# Extract top-level documentation resources
# TODO Should we do this only when building a release, or also for dev_main,
# TODO Should we do this only when building a release, or also for dev_v2.x,
# or for all (dev & release) versions like we do now?
unzip -o artifacts/docs-gh-pages.zip -d "docs"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.fortify.cli.common.progress.helper.ProgressWriterType;
import com.fortify.cli.common.util.DisableTest;
import com.fortify.cli.common.util.DisableTest.TestType;
import com.fortify.cli.common.util.EnvHelper;

import lombok.SneakyThrows;
import picocli.CommandLine.Mixin;
Expand Down Expand Up @@ -68,7 +69,26 @@ public final Integer call() {
private Callable<Integer> run(ActionRunner actionRunner, IProgressWriterI18n progressWriter) {
actionRunner.getSpelEvaluator().configure(context->configure(actionRunner, context));
progressWriter.writeProgress("Executing action %s", actionRunner.getAction().getMetadata().getName());
return actionRunner.run(actionArgs);
// We need to set the FCLI_DEFAULT_<module>_SESSION environment variable to allow fcli: statements to
// pick up the current session name, and (although probably not needed currently), reset the default
// session name to the previous value once the action completes.
var sessionEnvName = String.format("%s_%s_SESSION", System.getProperty("fcli.env.default.prefix", "FCLI_DEFAULT"), getType().toUpperCase());
var sessionPropertyName = EnvHelper.envSystemPropertyName(sessionEnvName);
var sessionEnvOrgValue = EnvHelper.env(sessionEnvName);
try {
setOrClearSystemProperty(sessionPropertyName, getSessionName());
return actionRunner.run(actionArgs);
} finally {
setOrClearSystemProperty(sessionPropertyName, sessionEnvOrgValue);
}
}

private void setOrClearSystemProperty(String name, String value) {
if ( value==null ) {
System.clearProperty(name);
} else {
System.setProperty(name, value);
}
}

private ParameterException onValidationErrors(OptionsParseResult optionsParseResult) {
Expand All @@ -79,5 +99,6 @@ private ParameterException onValidationErrors(OptionsParseResult optionsParseRes
}

protected abstract String getType();
protected abstract String getSessionName();
protected abstract void configure(ActionRunner actionRunner, SimpleEvaluationContext context);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* herein. The information contained herein is subject to change
* without notice.
*******************************************************************************/
package com.fortify.cli.ssc.artifact.cli.cmd.import_debricked;
package com.fortify.cli.common.cli.cmd.import_debricked;

import java.io.File;
import java.nio.file.StandardCopyOption;
Expand All @@ -24,85 +24,35 @@
import com.fasterxml.jackson.databind.util.RawValue;
import com.fortify.cli.common.http.proxy.helper.ProxyHelper;
import com.fortify.cli.common.json.JsonHelper;
import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins;
import com.fortify.cli.common.progress.helper.IProgressWriterI18n;
import com.fortify.cli.common.rest.unirest.GenericUnirestFactory;
import com.fortify.cli.common.rest.unirest.config.UnirestJsonHeaderConfigurer;
import com.fortify.cli.common.rest.unirest.config.UnirestUnexpectedHttpResponseConfigurer;
import com.fortify.cli.common.rest.unirest.config.UnirestUrlConfigConfigurer;
import com.fortify.cli.common.util.StringUtils;
import com.fortify.cli.ssc.artifact.cli.cmd.AbstractSSCArtifactUploadCommand;
import com.fortify.cli.ssc.artifact.cli.cmd.import_debricked.DebrickedLoginOptions.DebrickedAccessTokenCredentialOptions;
import com.fortify.cli.ssc.artifact.cli.cmd.import_debricked.DebrickedLoginOptions.DebrickedAuthOptions;
import com.fortify.cli.ssc.artifact.cli.cmd.import_debricked.DebrickedLoginOptions.DebrickedUserCredentialOptions;
import com.fortify.cli.common.cli.cmd.import_debricked.DebrickedLoginOptions.DebrickedAccessTokenCredentialOptions;
import com.fortify.cli.common.cli.cmd.import_debricked.DebrickedLoginOptions.DebrickedAuthOptions;
import com.fortify.cli.common.cli.cmd.import_debricked.DebrickedLoginOptions.DebrickedUserCredentialOptions;

import kong.unirest.UnirestInstance;
import lombok.Getter;
import lombok.SneakyThrows;
import picocli.CommandLine.Command;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Option;

@Command(name = "import-debricked")
public class SSCArtifactImportDebrickedCommand extends AbstractSSCArtifactUploadCommand {
@Mixin @Getter private OutputHelperMixins.TableNoQuery outputHelper;
@Mixin private DebrickedLoginOptions debrickedLoginOptions;

@Option(names = {"-e", "--engine-type"}, required = true, defaultValue = "DEBRICKED")
@Getter private String engineType;

@Option(names = {"-f", "--save-sbom-as"}, required = false)
private String fileName;

@Option(names = {"-r", "--repository"}, required = true)
private String repository;

@Option(names = {"-b", "--branch"}, required = true)
private String branch;

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

@Override @SneakyThrows
protected File getFile() {
File sbomFile = null;
if ( StringUtils.isNotBlank(fileName) ) {
sbomFile = new File(fileName);
} else {
sbomFile = File.createTempFile("debricked", ".json");
sbomFile.deleteOnExit();
}
return sbomFile;
}

@Override
protected void preUpload(UnirestInstance unirest, IProgressWriterI18n progressWriter, File file) {
progressWriter.writeProgress("Status: Generating & downloading SBOM");
try ( var debrickedUnirest = GenericUnirestFactory.createUnirestInstance() ) {
downloadSbom(debrickedUnirest, file);
}
progressWriter.writeProgress("Status: Uploading SBOM to SSC");
}

@Override
protected void postUpload(UnirestInstance unirest, IProgressWriterI18n progressWriter, File file) {
if ( StringUtils.isBlank(fileName) ) {
file.delete();
}
progressWriter.writeProgress("Status: SBOM uploaded to SSC");
progressWriter.clearProgress();
}
public final class DebrickedHelper {

private Void downloadSbom(UnirestInstance debrickedUnirest, File file) {
private DebrickedLoginOptions debrickedLoginOptions;
private String repository;
private String branch;

public DebrickedHelper(DebrickedLoginOptions debrickedLoginOptions, String repository, String branch) {
this.debrickedLoginOptions = debrickedLoginOptions;
this.repository = repository;
this.branch = branch;
}

public final void downloadSbom(UnirestInstance debrickedUnirest, File file) {
configureDebrickedUnirest(debrickedUnirest);
String reportUuid = startSbomGeneration(debrickedUnirest);
waitSbomGeneration(debrickedUnirest, reportUuid, file);
return null;
}

private void configureDebrickedUnirest(UnirestInstance debrickedUnirest) {
public final void configureDebrickedUnirest(UnirestInstance debrickedUnirest) {
UnirestUnexpectedHttpResponseConfigurer.configure(debrickedUnirest);
DebrickedUrlConfigOptions debrickedUrlConfig = debrickedLoginOptions.getUrlConfigOptions();
UnirestUrlConfigConfigurer.configure(debrickedUnirest, debrickedUrlConfig);
Expand All @@ -113,7 +63,7 @@ private void configureDebrickedUnirest(UnirestInstance debrickedUnirest) {
debrickedUnirest.config().setDefaultHeader("Authorization", authHeader);
}

private String getDebrickedJwtToken(UnirestInstance debrickedUnirest) {
public final String getDebrickedJwtToken(UnirestInstance debrickedUnirest) {
DebrickedAuthOptions authOptions = debrickedLoginOptions.getAuthOptions();
DebrickedUserCredentialOptions userCredentialsOptions = authOptions.getUserCredentialsOptions();
DebrickedAccessTokenCredentialOptions tokenOptions = authOptions.getTokenOptions();
Expand All @@ -126,7 +76,7 @@ private String getDebrickedJwtToken(UnirestInstance debrickedUnirest) {
}
}

private String getDebrickedJwtToken(UnirestInstance debrickedUnirest, DebrickedAccessTokenCredentialOptions tokenOptions) {
public final String getDebrickedJwtToken(UnirestInstance debrickedUnirest, DebrickedAccessTokenCredentialOptions tokenOptions) {
return debrickedUnirest.post("/api/login_refresh")
.header("Content-Type", "application/x-www-form-urlencoded")
.field("refresh_token", new String(tokenOptions.getAccessToken()))
Expand All @@ -136,7 +86,7 @@ private String getDebrickedJwtToken(UnirestInstance debrickedUnirest, DebrickedA
.asText();
}

private String getDebrickedJwtToken(UnirestInstance debrickedUnirest, DebrickedUserCredentialOptions userCredentialsOptions) {
public final String getDebrickedJwtToken(UnirestInstance debrickedUnirest, DebrickedUserCredentialOptions userCredentialsOptions) {
return debrickedUnirest.post("/api/login_check")
.header("Content-Type", "application/x-www-form-urlencoded")
.field("_username", userCredentialsOptions.getUser())
Expand All @@ -147,7 +97,7 @@ private String getDebrickedJwtToken(UnirestInstance debrickedUnirest, DebrickedU
.asText();
}

private String getRepositoryId(UnirestInstance debrickedUnirest) {
public final String getRepositoryId(UnirestInstance debrickedUnirest) {
try {
Integer.parseInt(repository);
return repository;
Expand All @@ -166,7 +116,7 @@ private String getRepositoryId(UnirestInstance debrickedUnirest) {
}
}

private String startSbomGeneration(UnirestInstance debrickedUnirest) {
public final String startSbomGeneration(UnirestInstance debrickedUnirest) {
ObjectNode body = new ObjectMapper().createObjectNode()
// TODO generate a proper ArrayNode
.putRawValue("repositoryIds", new RawValue("["+getRepositoryId(debrickedUnirest)+"]"))
Expand All @@ -184,7 +134,7 @@ private String startSbomGeneration(UnirestInstance debrickedUnirest) {
}

@SneakyThrows
private void waitSbomGeneration(UnirestInstance debrickedUnirest, String reportUuid, File outputFile) {
public final void waitSbomGeneration(UnirestInstance debrickedUnirest, String reportUuid, File outputFile) {
int status = 202;
while ( status==202 ) {
Thread.sleep(5000L);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* herein. The information contained herein is subject to change
* without notice.
*******************************************************************************/
package com.fortify.cli.ssc.artifact.cli.cmd.import_debricked;
package com.fortify.cli.common.cli.cmd.import_debricked;

import com.fortify.cli.common.rest.unirest.config.IUserCredentialsConfig;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* herein. The information contained herein is subject to change
* without notice.
*******************************************************************************/
package com.fortify.cli.ssc.artifact.cli.cmd.import_debricked;
package com.fortify.cli.common.cli.cmd.import_debricked;

import com.fortify.cli.common.rest.cli.mixin.ConnectionConfigOptions;
import com.fortify.cli.common.rest.unirest.config.IUrlConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public JSONDateTimeConverter(DateTimeFormatter fmtDateTime, ZoneId defaultZoneId
}

public static final DateTimeFormatter createDefaultDateTimeFormatter() {
return DateTimeFormatter.ofPattern("yyyy-MM-dd[['T'][' ']HH:mm:ss[.SSS][.SS]][ZZZZ][Z][XXX][XX][X]");
return DateTimeFormatter.ofPattern("yyyy-MM-dd[['T'][' ']HH:mm:ss[.SSS][.SS][.S]][ZZZZ][Z][XXX][XX][X]");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
package com.fortify.cli.common.progress.cli.mixin;

import com.fortify.cli.common.cli.mixin.CommandHelperMixin;
import com.fortify.cli.common.progress.cli.mixin.ProgressWriterTypeConverter.ProgressWriterTypeIterable;
import com.fortify.cli.common.progress.helper.IProgressWriterI18n;
import com.fortify.cli.common.progress.helper.ProgressWriterI18n;
import com.fortify.cli.common.progress.helper.ProgressWriterType;
Expand All @@ -24,7 +23,7 @@

public class ProgressWriterFactoryMixin {
@Mixin private CommandHelperMixin commandHelper;
@Getter @Option(names="--progress", defaultValue = "auto", completionCandidates = ProgressWriterTypeIterable.class, converter = ProgressWriterTypeConverter.class )
@Getter @Option(names="--progress", defaultValue = "auto")
private ProgressWriterType type;

public final IProgressWriterI18n create() {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ public enum ProgressWriterType {
single_line(SingleLineProgressWriter::new),
ansi(AnsiProgressWriter::new);

@Override
public String toString() {
// Show and accept dashes instead of underscores when this
// enum is used in picocli options.
return name().replace('_', '-');
}

private final Supplier<IProgressWriter> factory;

public IProgressWriter create() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.fortify.cli.common.output.transform.IActionCommandResultSupplier;
import com.fortify.cli.common.session.cli.mixin.SessionNameMixin;
import com.fortify.cli.common.session.helper.ISessionDescriptor;
import com.fortify.cli.common.session.helper.SessionLogoutException;

import lombok.Getter;
import picocli.CommandLine.Mixin;
Expand All @@ -36,11 +37,15 @@ public JsonNode getJsonNode() {
result = sessionHelper.sessionSummaryAsObjectNode(sessionName);
try {
logout(sessionName, sessionHelper.get(sessionName, false));
} catch (Exception e){
LOG.warn("Logout failed");
LOG.debug("Exception details:", e);
} finally {
getSessionHelper().destroy(sessionName);
} catch (Exception e) {
if ( e instanceof SessionLogoutException && !((SessionLogoutException)e).isDestroySession() ) {
throw e;
} else {
LOG.warn("Logout failed");
LOG.debug("Exception details:", e);
getSessionHelper().destroy(sessionName);
}
}
}
return result;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.fortify.cli.common.session.helper;

import lombok.Getter;

public class SessionLogoutException extends RuntimeException {
private static final long serialVersionUID = 1L;
@Getter private boolean destroySession;
public SessionLogoutException(String message, boolean destroySession) {
this(message, null, destroySession);
}

public SessionLogoutException(Throwable cause, boolean destroySession) {
this(null, cause, destroySession);
}

public SessionLogoutException(String message, Throwable cause, boolean destroySession) {
super(message, cause);
this.destroySession = destroySession;
}
}
Loading

0 comments on commit 3cb2141

Please sign in to comment.