Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: use new download url for snyk downloads #150

Merged
merged 4 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ To see more information on your steps, you can increase logging and re-run your

### Failed Installations

By default, Snyk Installations will download Snyk's binaries over the network from `static.snyk.io`. If this fails there
By default, Snyk Installations will download Snyk's binaries over the network from `downloads.snyk.io` and use `static.snyk.io` as a fallback. If this fails there
may be a network or proxy issue. If you cannot fix the issue, you can use a [Manual Installation](#2-configure-a-snyk-installation) instead.

---
Expand Down
50 changes: 28 additions & 22 deletions src/main/java/io/snyk/jenkins/tools/SnykInstaller.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,34 +88,40 @@
}

private FilePath downloadSnykBinaries(FilePath expected, Node node) {
try {
LOG.info("Installing Snyk '{}' on Build Node '{}'", version, node.getDisplayName());
for (String snykUrlTemplate : DownloadService.SNYK_CLI_DOWNLOAD_URLS) {
try {
LOG.info("Installing Snyk '{}' on Build Node '{}'", version, node.getDisplayName());

final VirtualChannel nodeChannel = node.getChannel();
if (nodeChannel == null) {
throw new IOException(format("Build Node '%s' is offline.", node.getDisplayName()));
}
final VirtualChannel nodeChannel = node.getChannel();
if (nodeChannel == null) {
throw new IOException(format("Build Node '%s' is offline.", node.getDisplayName()));
}

Platform platform = PlatformItem.convert(this.platform);
if (platform == null) {
LOG.info("Installer architecture is not configured or use AUTO mode");
platform = nodeChannel.call(new GetPlatform());
}
LOG.info("Configured installer architecture is {}", platform);
Platform platform = PlatformItem.convert(this.platform);
if (platform == null) {
LOG.info("Installer architecture is not configured or use AUTO mode");
platform = nodeChannel.call(new GetPlatform());
}
LOG.info("Configured installer architecture is {}", platform);

URL snykDownloadUrl = DownloadService.getDownloadUrlForSnyk(version, platform);
URL snykToHtmlDownloadUrl = DownloadService.getDownloadUrlForSnykToHtml("latest", platform);
URL snykDownloadUrl = DownloadService.constructDownloadUrlForSnyk(snykUrlTemplate, "cli", version, platform);
URL snykToHtmlDownloadUrl = DownloadService.constructDownloadUrlForSnyk(snykUrlTemplate, "snyk-to-html", "latest", platform);

expected.mkdirs();
nodeChannel.call(new Downloader(snykDownloadUrl, expected.child(platform.snykWrapperFileName)));
nodeChannel.call(new Downloader(snykToHtmlDownloadUrl, expected.child(platform.snykToHtmlWrapperFileName)));
expected.child(INSTALLED_FROM).write(snykDownloadUrl.toString(), UTF_8.name());
expected.child(TIMESTAMP_FILE).write(valueOf(Instant.now().toEpochMilli()), UTF_8.name());
LOG.info("Downloading CLI from {}", snykDownloadUrl);
LOG.info("Downloading snyk-to-html from {}", snykToHtmlDownloadUrl);

return expected;
} catch (RuntimeException | IOException | InterruptedException ex) {
throw new RuntimeException("Failed to install Snyk.", ex);
expected.mkdirs();
nodeChannel.call(new Downloader(snykDownloadUrl, expected.child(platform.snykWrapperFileName)));
nodeChannel.call(new Downloader(snykToHtmlDownloadUrl, expected.child(platform.snykToHtmlWrapperFileName)));
expected.child(INSTALLED_FROM).write(snykDownloadUrl.toString(), UTF_8.name());
expected.child(TIMESTAMP_FILE).write(valueOf(Instant.now().toEpochMilli()), UTF_8.name());

return expected;
} catch (RuntimeException | IOException | InterruptedException ex) {
LOG.error("Failed to install Snyk.", ex);
}
}
throw new RuntimeException("Failed to install Snyk.");

Check warning on line 124 in src/main/java/io/snyk/jenkins/tools/SnykInstaller.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 91-124 are not covered by tests
}

@SuppressWarnings("unused")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
package io.snyk.jenkins.tools.internal;

import io.snyk.jenkins.PluginMetadata;
import io.snyk.jenkins.tools.Platform;

import javax.annotation.Nonnull;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static java.lang.String.format;

public class DownloadService {
private static final String SNYK_DOWNLOAD_PRIMARY = "https://downloads.snyk.io/%s/%s/%s";
private static final String SNYK_DOWNLOAD_SECONDARY = "https://static.snyk.io/%s/%s/%s";
public static final List<String> SNYK_CLI_DOWNLOAD_URLS = Collections.unmodifiableList(Arrays.asList(SNYK_DOWNLOAD_PRIMARY, SNYK_DOWNLOAD_SECONDARY));

private DownloadService() {
// squid:S1118
}

public static URL getDownloadUrlForSnyk(@Nonnull String version, @Nonnull Platform platform) throws IOException {
return new URL(format("https://static.snyk.io/cli/%s/%s", version, platform.snykWrapperFileName));
}
public static URL constructDownloadUrlForSnyk(@Nonnull String urlTemplate, @Nonnull String product, @Nonnull String version, @Nonnull Platform platform) throws IOException {
URL urlNoUtm;

public static URL getDownloadUrlForSnykToHtml(@Nonnull String version, @Nonnull Platform platform) throws IOException {
return new URL(format("https://static.snyk.io/snyk-to-html/%s/%s", version, platform.snykToHtmlWrapperFileName));
if (product.equals("cli")) {
urlNoUtm = new URL(format(urlTemplate, product, version, platform.snykWrapperFileName));
} else { // snyk-to-html
urlNoUtm = new URL(format(urlTemplate, product, version, platform.snykToHtmlWrapperFileName));
}
return new URL(urlNoUtm.toString() + "?utm_source=" + PluginMetadata.getIntegrationName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package io.snyk.jenkins.tools.internal;

import io.snyk.jenkins.PluginMetadata;
import org.junit.Test;

import io.snyk.jenkins.tools.Platform;

import java.io.IOException;
import java.net.URL;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.hamcrest.core.IsNull.notNullValue;


public class DownloadServiceTest {

@Test
public void constructDownloadUrlForSnyk_shouldReturnExpectedUrlForCli() throws IOException {
String urlTemplate = "https://downloads.snyk.io/%s/%s/%s";
String product = "cli";
String version = "stable";
String queryParam = "?utm_source=" + PluginMetadata.getIntegrationName();
Platform platform = Platform.MAC_OS;

URL expectedUrl = new URL("https://downloads.snyk.io/" + product + "/" + version + "/" + "snyk-macos" + queryParam);
URL actualUrl = DownloadService.constructDownloadUrlForSnyk(urlTemplate, product, version, platform);

assertThat(actualUrl, notNullValue());
assertThat(actualUrl, equalTo(expectedUrl));
}

@Test
public void constructDownloadUrlForSnyk_shouldReturnExpectedUrlForSnykToHtml() throws IOException {
String urlTemplate = "https://downloads.snyk.io/%s/%s/%s";
String product = "snyk-to-html";
String version = "stable";
String queryParam = "?utm_source=" + PluginMetadata.getIntegrationName();
Platform platform = Platform.MAC_OS;

URL expectedUrl = new URL("https://downloads.snyk.io/" + product + "/" + version + "/" + "snyk-to-html-macos" + queryParam);
URL actualUrl = DownloadService.constructDownloadUrlForSnyk(urlTemplate, product, version, platform);

assertThat(actualUrl, notNullValue());
assertThat(actualUrl, equalTo(expectedUrl));
}
}
Loading