Skip to content

Commit

Permalink
Add support for Azure CDN endpoint URL (#280)
Browse files Browse the repository at this point in the history
Co-authored-by: Tim Jacomb <21194782+timja@users.noreply.github.com>
Co-authored-by: Tim Jacomb <timjacomb1@gmail.com>
  • Loading branch information
3 people authored Dec 13, 2023
1 parent e060643 commit 87922b9
Show file tree
Hide file tree
Showing 23 changed files with 260 additions and 76 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ index.html
*.dylib
.env
testshare*
.vscode/
32 changes: 14 additions & 18 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@
<version>${changelist}</version>
<packaging>hpi</packaging>
<name>Azure Storage plugin</name>
<description>Uploads build artifacts or downloads build dependencies using Azure storage</description>
<url>https://github.com/jenkinsci/azure-storage-plugin</url>

<properties>
<changelist>9999-SNAPSHOT</changelist>
<gitHubRepo>jenkinsci/azure-storage-plugin</gitHubRepo>
<jenkins.version>2.361.4</jenkins.version>
<jenkins.version>2.387.3</jenkins.version>
</properties>

<licenses>
Expand All @@ -26,6 +25,18 @@
</license>
</licenses>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.jenkins.tools.bom</groupId>
<artifactId>bom-2.387.x</artifactId>
<version>2543.vfb_1a_5fb_9496d</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>io.jenkins.plugins</groupId>
Expand All @@ -35,7 +46,6 @@
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>copyartifact</artifactId>
<version>1.46</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
Expand Down Expand Up @@ -82,7 +92,6 @@
<dependency>
<groupId>io.jenkins.blueocean</groupId>
<artifactId>blueocean-rest</artifactId>
<version>1.24.6</version>
</dependency>

<dependency>
Expand All @@ -97,21 +106,9 @@
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.jenkins.tools.bom</groupId>
<artifactId>bom-2.277.x</artifactId>
<version>984.vb5eaac999a7e</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>

<scm>
<connection>scm:git:ssh://github.com/${gitHubRepo}.git</connection>
<developerConnection>scm:git:ssh://git@github.com/${gitHubRepo}.git</developerConnection>
<developerConnection>scm:git:git@github.com:${gitHubRepo}.git</developerConnection>
<url>https://github.com/${gitHubRepo}</url>
<tag>${scmTag}</tag>
</scm>
Expand Down Expand Up @@ -164,7 +161,6 @@
</executions>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<!--
Exclude the generated sources.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ private void validateData(Run<?, ?> run,
listener.getLogger().println(Messages.Client_SA_val_fail());
listener.getLogger().println(storageAccountInfo.getStorageAccName());
listener.getLogger().println(storageAccountInfo.getBlobEndPointURL());
listener.getLogger().println(storageAccountInfo.getCdnEndPointURL());

Check warning on line 357 in src/main/java/com/microsoftopentechnologies/windowsazurestorage/AzureStorageBuilder.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 357 is not covered by tests
run.setResult(Result.UNSTABLE);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,7 @@ public boolean configure(StaplerRequest req, JSONObject formData)
* @param was_storageAccName
* @param was_storageAccountKey
* @param was_blobEndPointURL
* @param was_cdnEndPointURL

Check warning on line 638 in src/main/java/com/microsoftopentechnologies/windowsazurestorage/WAStoragePublisher.java

View check run for this annotation

ci.jenkins.io / JavaDoc

JavaDoc @param

NORMAL: no description for @param
* @return

Check warning on line 639 in src/main/java/com/microsoftopentechnologies/windowsazurestorage/WAStoragePublisher.java

View check run for this annotation

ci.jenkins.io / JavaDoc

JavaDoc @return

NORMAL: no description for @return
* @throws IOException
* @throws ServletException

Check warning on line 641 in src/main/java/com/microsoftopentechnologies/windowsazurestorage/WAStoragePublisher.java

View check run for this annotation

ci.jenkins.io / JavaDoc

JavaDoc @throws

NORMAL: no description for @throws
Expand All @@ -643,7 +644,8 @@ public FormValidation doCheckAccount(
//CHECKSTYLE:OFF
@QueryParameter String was_storageAccName,
@QueryParameter String was_storageAccountKey,
@QueryParameter String was_blobEndPointURL) throws IOException, ServletException {
@QueryParameter String was_blobEndPointURL,
@QueryParameter String was_cdnEndPointURL) throws IOException, ServletException {
//CHECKSTYLE:ON

if (StringUtils.isBlank(was_storageAccName)) {
Expand All @@ -657,11 +659,12 @@ public FormValidation doCheckAccount(
}

String blobEndPointURL = was_blobEndPointURL;
String cdnEndPointURL = was_cdnEndPointURL;

Check warning on line 662 in src/main/java/com/microsoftopentechnologies/windowsazurestorage/WAStoragePublisher.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 662 is not covered by tests
try {
// Get formatted blob end point URL.
// Get formatted blob endpoint URL.
blobEndPointURL = Utils.getBlobEP(blobEndPointURL);
StorageAccountInfo storageAccount = new StorageAccountInfo(
was_storageAccName, was_storageAccountKey, blobEndPointURL);
was_storageAccName, was_storageAccountKey, blobEndPointURL, cdnEndPointURL);
AzureUtils.validateStorageAccount(storageAccount, false);
} catch (Exception e) {
return FormValidation.error(e, "Error : " + e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,22 @@ public class StorageAccountInfo {
private String storageAccountKey;

/**
* Azure stoarge blob end point url.
* Azure storage blob endpoint URL.
*/
private String blobEndPointURL;

/**
* Azure storage CDN endpoint URL.
*/
private String cdnEndPointURL;

@DataBoundConstructor
public StorageAccountInfo(String storageAccName, String storageAccountKey,
String blobEndPointURL) {
String blobEndPointURL, String cdnEndPointURL) {
this.storageAccName = storageAccName;
this.blobEndPointURL = blobEndPointURL;
this.storageAccountKey = storageAccountKey;
this.cdnEndPointURL = cdnEndPointURL;
}

public String getStorageAccName() {
Expand All @@ -65,4 +71,12 @@ public String getBlobEndPointURL() {
public void setBlobEndPointURL(String blobEndPointURL) {
this.blobEndPointURL = blobEndPointURL;
}

public String getCdnEndPointURL() {
return cdnEndPointURL;
}

public void setCdnEndPointURL(String cdnEndPointURL) {
this.cdnEndPointURL = cdnEndPointURL;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ public class AzureCredentialsBinding extends MultiBinding<AzureStorageAccount> {
public static final String DEFAULT_STORAGE_ACCOUNT_NAME = "AZURE_STORAGE_ACCOUNT_NAME";
public static final String DEFAULT_STORAGE_ACCOUNT_KEY = "AZURE_STORAGE_ACCOUNT_KEY";
public static final String DEFAULT_BLOB_ENDPOINT_URL = "AZURE_BLOB_ENDPOINT_URL";
public static final String DEFAULT_CDN_ENDPOINT_URL = "AZURE_CDN_ENDPOINT_URL";

private String storageAccountNameVariable;
private String storageAccountKeyVariable;
private String blobEndpointUrlVariable;
private String cdnEndpointUrlVariable;

@DataBoundConstructor
public AzureCredentialsBinding(String credentialsId) {
Expand All @@ -51,6 +53,11 @@ public void setBlobEndpointUrlVariable(String blobEndpointUrlVariable) {
this.blobEndpointUrlVariable = blobEndpointUrlVariable;
}

@DataBoundSetter
public void setCdnEndpointUrlVariable(String cdnEndpointUrlVariable) {
this.cdnEndpointUrlVariable = cdnEndpointUrlVariable;
}

public String getStorageAccountNameVariable() {
if (!StringUtils.isBlank(storageAccountNameVariable)) {
return storageAccountNameVariable;
Expand All @@ -72,6 +79,13 @@ public String getBlobEndpointUrlVariable() {
return DEFAULT_BLOB_ENDPOINT_URL;
}

public String getCdnEndpointUrlVariable() {
if (!StringUtils.isBlank(cdnEndpointUrlVariable)) {
return cdnEndpointUrlVariable;
}
return DEFAULT_CDN_ENDPOINT_URL;
}

@Override
protected Class<AzureStorageAccount> type() {
return AzureStorageAccount.class;
Expand All @@ -88,6 +102,7 @@ public MultiEnvironment bind(@NonNull Run<?, ?> build,
variableMap.put(getStorageAccountNameVariable(), credentials.getStorageAccountName());
variableMap.put(getStorageAccountKeyVariable(), credentials.getPlainStorageKey());
variableMap.put(getBlobEndpointUrlVariable(), credentials.getBlobEndpointURL());
variableMap.put(getCdnEndpointUrlVariable(), credentials.getCdnEndpointURL());
return new MultiEnvironment(variableMap);
}

Expand Down Expand Up @@ -129,5 +144,9 @@ public static String getDefaultStorageAccountKeyVariable() {
public static String getDefaultBlobEndpointUrlVariable() {
return DEFAULT_BLOB_ENDPOINT_URL;
}

public static String getDefaultCdnEndpointUrlVariable() {
return DEFAULT_CDN_ENDPOINT_URL;

Check warning on line 149 in src/main/java/com/microsoftopentechnologies/windowsazurestorage/helper/AzureCredentialsBinding.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 58-149 are not covered by tests
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,25 @@ public static class StorageAccountCredential implements java.io.Serializable {
private final String storageAccountName;
private final Secret storageAccountKey;
private final String blobEndpointURL;
private final String cdnEndpointURL;

public StorageAccountCredential(
String storageAccountName,
String storageKey,
String endpointURL) {
String blobEndpointURL,
String cdnEndpointURL) {
this.storageAccountName = storageAccountName;
this.storageAccountKey = Secret.fromString(storageKey);
String url = endpointURL;
if (StringUtils.isBlank(endpointURL)) {
String url = blobEndpointURL;
if (StringUtils.isBlank(blobEndpointURL)) {

Check warning on line 63 in src/main/java/com/microsoftopentechnologies/windowsazurestorage/helper/AzureStorageAccount.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 63 is only partially covered, one branch is missing
url = Constants.DEF_BLOB_URL;
}
this.blobEndpointURL = joinAccountNameAndEndpoint(storageAccountName, url);
if (StringUtils.isBlank(cdnEndpointURL)) {
this.cdnEndpointURL = "";
} else {
this.cdnEndpointURL = cdnEndpointURL;
}
}

/**
Expand All @@ -85,6 +92,7 @@ public StorageAccountCredential() {
this.storageAccountName = "";
this.storageAccountKey = Secret.fromString("");
this.blobEndpointURL = Constants.DEF_BLOB_URL;
this.cdnEndpointURL = "";

Check warning on line 95 in src/main/java/com/microsoftopentechnologies/windowsazurestorage/helper/AzureStorageAccount.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 95 is not covered by tests
}

public boolean isValidStorageCredential() throws WAStorageException {
Expand Down Expand Up @@ -115,11 +123,15 @@ protected Secret getSecureKey() {
return storageAccountKey;
}

public String getEndpointURL() {
public String getBlobEndpointURL() {
// joined in getter as constructor isn't called when reading saved configuration
return joinAccountNameAndEndpoint(storageAccountName, blobEndpointURL);
}

public String getCdnEndpointURL() {
return cdnEndpointURL;
}

public String getId() {
String storageId = this.getStorageAccountName().concat(this.getStorageAccountKey());
return Utils.getMD5(storageId);
Expand All @@ -136,10 +148,11 @@ public AzureStorageAccount(
String description,
String storageAccountName,
String storageKey,
String blobEndpointURL
String blobEndpointURL,
String cdnEndpointURL
) {
super(scope, id, description);
storageData = new StorageAccountCredential(storageAccountName, storageKey, blobEndpointURL);
storageData = new StorageAccountCredential(storageAccountName, storageKey, blobEndpointURL, cdnEndpointURL);
}

public static AzureStorageAccount.StorageAccountCredential getStorageAccountCredential(Item owner,
Expand Down Expand Up @@ -213,7 +226,11 @@ public String getStorageKey() {
}

public String getBlobEndpointURL() {
return storageData.getEndpointURL();
return storageData.getBlobEndpointURL();
}

public String getCdnEndpointURL() {
return storageData.getCdnEndpointURL();
}

public StorageAccountCredential getStorageCred() {
Expand All @@ -235,11 +252,12 @@ public String getDefaultBlobURL() {
public FormValidation doVerifyConfiguration(
@QueryParameter String storageAccountName,
@QueryParameter Secret storageKey,
@QueryParameter String blobEndpointURL) {
@QueryParameter String blobEndpointURL,
@QueryParameter String cdnEndpointURL) {

try {
StorageAccountInfo storageAccount = new StorageAccountInfo(
storageAccountName, storageKey.getPlainText(), blobEndpointURL);
storageAccountName, storageKey.getPlainText(), blobEndpointURL, cdnEndpointURL);

Check warning on line 260 in src/main/java/com/microsoftopentechnologies/windowsazurestorage/helper/AzureStorageAccount.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 260 is not covered by tests
AzureUtils.validateStorageAccount(storageAccount, false);
} catch (Exception e) {
return FormValidation.error(e, e.getMessage());
Expand All @@ -252,7 +270,7 @@ public FormValidation doVerifyConfiguration(

public static StorageAccountInfo convertToStorageAccountInfo(StorageAccountCredential storageCreds) {
return new StorageAccountInfo(storageCreds.getStorageAccountName(), storageCreds.getStorageAccountKey(),
storageCreds.getEndpointURL());
storageCreds.getBlobEndpointURL(), storageCreds.getCdnEndpointURL());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,16 @@
import io.jenkins.plugins.azuresdk.HttpClientRetriever;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.time.Duration;
import java.time.OffsetDateTime;
import java.util.Collections;

import org.apache.commons.lang.StringUtils;

public final class AzureUtils {
private static final String TEST_CNT_NAME = "testcheckfromjenkins";
private static final String BLOB = "blob";
Expand All @@ -70,9 +74,18 @@ public static boolean validateStorageAccount(
storageAccount, TEST_CNT_NAME, false, allowRetry, null);
container.exists();

// Check if the CDN endpoint exists
if (!StringUtils.isBlank(storageAccount.getCdnEndPointURL())) {
URL cdnEndpointURL = new URL(storageAccount.getCdnEndPointURL());
HttpURLConnection huc = (HttpURLConnection) cdnEndpointURL.openConnection();
huc.setRequestMethod("HEAD");

huc.getResponseCode(); // Throws exception if no response received

Check warning on line 83 in src/main/java/com/microsoftopentechnologies/windowsazurestorage/helper/AzureUtils.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 78-83 are not covered by tests
}
} catch (Exception e) {
throw new WAStorageException(Messages.Client_SA_val_fail(), e);
}

return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ protected static List<StorageAccountInfo> getOldStorageConfig(
String blobURL = elem.getElementsByTagName("blobEndPointURL").item(0)
.getChildNodes().item(0).getNodeValue();

storages.add(new StorageAccountInfo(accName, accKey, blobURL));
storages.add(new StorageAccountInfo(accName, accKey, blobURL, ""));
}
}

Expand Down Expand Up @@ -119,7 +119,7 @@ public static void upgradeStorageConfig() throws Exception {

AzureStorageAccount.StorageAccountCredential u =
new AzureStorageAccount.StorageAccountCredential(
storageAccount, storageAccountKey, storageBlobURL);
storageAccount, storageAccountKey, storageBlobURL, "");
AzureStorageAccount cred = CredentialsMatchers.firstOrNull(
CredentialsProvider.lookupCredentials(
AzureStorageAccount.class,
Expand All @@ -142,7 +142,7 @@ public static void upgradeStorageConfig() throws Exception {
"credential for " + storageAccount,
storageAccount,
storageAccountKey,
storageBlobURL);
storageBlobURL, "");
final SecurityContext securityContext = ACL.impersonate(ACL.SYSTEM);

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@
<f:entry title="${%BlobEndpointUrlVariable}" field="blobEndpointUrlVariable" help="/plugin/windows-azure-storage/help-blobEndPointURL.html">
<f:textbox default="${descriptor.getDefaultBlobEndpointUrlVariable()}"/>
</f:entry>
<f:entry title="${%CdnEndpointUrlVariable}" field="cdnEndpointUrlVariable" help="/plugin/windows-azure-storage/help-cdnEndPointURL.html">
<f:textbox default="${descriptor.getDefaultBlobEndpointUrlVariable()}"/>
</f:entry>
</j:jelly>
Loading

0 comments on commit 87922b9

Please sign in to comment.