Verify Artifactory authentication before release build.
We now explicitly access an Artifactory resource to verify authentication so that it's less likely the deployment and promotion will fail later on. Added "artifactory verify" as command to be executed from the shell.
This commit is contained in:
@@ -102,6 +102,8 @@ public class ReleaseCommands implements CommandMarker {
|
||||
|
||||
} else {
|
||||
|
||||
deployment.verifyAuthentication();
|
||||
|
||||
List<DeploymentInformation> deploymentInformation = build.performRelease(iteration);
|
||||
git.commit(iteration, "Release version %s.");
|
||||
deploymentInformation.forEach(deployment::promote);
|
||||
|
||||
@@ -59,15 +59,32 @@ class ArtifactoryClient {
|
||||
try {
|
||||
template.postForEntity(uri, new PromotionRequest(information.getTargetRepository()), String.class);
|
||||
} catch (HttpClientErrorException o_O) {
|
||||
handle(o_O, module);
|
||||
handle("Promotion failed!", o_O, module);
|
||||
}
|
||||
}
|
||||
|
||||
private void handle(HttpClientErrorException o_O, ModuleIteration module) {
|
||||
public void verify() {
|
||||
|
||||
URI verificationResource = properties.getServer().getVerificationResource();
|
||||
|
||||
try {
|
||||
|
||||
logger.log(module, "Promotion failed!");
|
||||
logger.log("Artifactory", "Verifying authentication using a GET call to %s.", verificationResource);
|
||||
|
||||
template.getForEntity(verificationResource, String.class);
|
||||
|
||||
logger.log("Artifactory", "Authentication verified!");
|
||||
|
||||
} catch (HttpClientErrorException o_O) {
|
||||
handle("Authentication verification failed!", o_O);
|
||||
}
|
||||
}
|
||||
|
||||
private void handle(String log, HttpClientErrorException o_O, ModuleIteration module) {
|
||||
|
||||
try {
|
||||
|
||||
logger.log(module, log);
|
||||
|
||||
Errors errors = new ObjectMapper().readValue(o_O.getResponseBodyAsByteArray(), Errors.class);
|
||||
errors.getErrors().forEach(error -> logger.log(module, error));
|
||||
@@ -78,6 +95,21 @@ class ArtifactoryClient {
|
||||
}
|
||||
}
|
||||
|
||||
private void handle(String log, HttpClientErrorException o_O) {
|
||||
|
||||
try {
|
||||
|
||||
logger.log("Artifactory Client", log);
|
||||
|
||||
Errors errors = new ObjectMapper().readValue(o_O.getResponseBodyAsByteArray(), Errors.class);
|
||||
errors.getErrors().forEach(error -> logger.log("Artifactory Client", error));
|
||||
errors.getMessages().forEach(message -> logger.log("Artifactory Client", message));
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteArtifacts(DeploymentInformation information) {
|
||||
template.delete(properties.getServer().getDeleteBuildResource(information));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.release.deployment;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.release.CliComponent;
|
||||
import org.springframework.shell.core.CommandMarker;
|
||||
import org.springframework.shell.core.annotation.CliCommand;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@CliComponent
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired) )
|
||||
public class ArtifactoryCommands implements CommandMarker {
|
||||
|
||||
private final DeploymentOperations deployment;
|
||||
|
||||
@CliCommand(value = "artifactory verify", help = "Verifies authentication at Artifactory.")
|
||||
public void verify() {
|
||||
deployment.verifyAuthentication();
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ class DeploymentConfiguration {
|
||||
public RestTemplate artifactoryRestTemplate() {
|
||||
|
||||
RestTemplate template = new RestTemplate();
|
||||
template.setInterceptors(Arrays.asList(new AuthenticatingClientHttpRequestInterceptor(properties.getApiKey())));
|
||||
template.setInterceptors(Arrays.asList(new AuthenticatingClientHttpRequestInterceptor(properties)));
|
||||
|
||||
return template;
|
||||
}
|
||||
@@ -58,7 +58,7 @@ class DeploymentConfiguration {
|
||||
@RequiredArgsConstructor
|
||||
private static class AuthenticatingClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
|
||||
|
||||
private final @NonNull String apiKey;
|
||||
private final @NonNull DeploymentProperties properties;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -68,7 +68,8 @@ class DeploymentConfiguration {
|
||||
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
|
||||
throws IOException {
|
||||
|
||||
request.getHeaders().add("X-Api-Key", apiKey);
|
||||
request.getHeaders().add("X-Api-Key", properties.getApiKey());
|
||||
request.getHeaders().add("Authentication", properties.getCredentials().toString());
|
||||
|
||||
return execution.execute(request, body);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,10 @@ public class DeploymentOperations {
|
||||
|
||||
private final ArtifactoryClient client;
|
||||
|
||||
public void verifyAuthentication() {
|
||||
client.verify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Promotes the artifacts identified by the given {@link DeploymentInformation}.
|
||||
*
|
||||
|
||||
@@ -20,6 +20,7 @@ import lombok.Data;
|
||||
import java.net.URI;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.data.release.utils.HttpBasicCredentials;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.util.UriTemplate;
|
||||
@@ -69,11 +70,16 @@ public class DeploymentProperties {
|
||||
return server.getUri().toString().concat("/").concat(stagingRepository);
|
||||
}
|
||||
|
||||
public HttpBasicCredentials getCredentials() {
|
||||
return new HttpBasicCredentials(username, password);
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class Server {
|
||||
|
||||
private static final String PROMOTION_RESOURCE = "/api/build/promote/{buildName}/{buildNumber}";
|
||||
private static final String DELETE_BUILD_RESOURCE = "/api/build/{buildName}?buildNumbers={buildNumber}&artifacts=1";
|
||||
private static final String VERIFICATION_RESOURCE = "/api/storage/test-libs-staging-local";
|
||||
|
||||
private String uri;
|
||||
|
||||
@@ -94,5 +100,9 @@ public class DeploymentProperties {
|
||||
|
||||
return new UriTemplate(uri.concat(DELETE_BUILD_RESOURCE)).expand(information.getBuildInfoParameters());
|
||||
}
|
||||
|
||||
public URI getVerificationResource() {
|
||||
return URI.create(uri.concat(VERIFICATION_RESOURCE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import javax.annotation.PostConstruct;
|
||||
import org.eclipse.jgit.transport.CredentialsProvider;
|
||||
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.data.release.utils.HttpBasicCredentials;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -58,7 +59,7 @@ public class GitProperties {
|
||||
return new UsernamePasswordCredentialsProvider(username, password);
|
||||
}
|
||||
|
||||
public String getAuthenticationHeader() {
|
||||
return username.concat(":").concat(password);
|
||||
public HttpBasicCredentials getHttpCredentials() {
|
||||
return new HttpBasicCredentials(username, password);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,7 @@ package org.springframework.data.release.jira;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -154,12 +152,8 @@ class GitHubIssueTracker implements IssueTracker {
|
||||
|
||||
private HttpHeaders getAuthenticationHeaders() {
|
||||
|
||||
byte[] encodedAuth = Base64.getEncoder()
|
||||
.encode(properties.getAuthenticationHeader().getBytes(Charset.forName("US-ASCII")));
|
||||
String authHeader = "Basic " + new String(encodedAuth);
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("Authorization", authHeader);
|
||||
headers.set("Authorization", properties.getHttpCredentials().toString());
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,6 @@ public class ExecutionUtils {
|
||||
throw new RuntimeException(o_O);
|
||||
}
|
||||
})).collect(Collectors.toList()).forEach(future -> future.join());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.release.utils;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Value
|
||||
public class HttpBasicCredentials {
|
||||
|
||||
private final String username, password;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
|
||||
String header = username.concat(":").concat(password);
|
||||
byte[] encodedAuth = Base64.getEncoder().encode(header.getBytes(Charset.forName("US-ASCII")));
|
||||
|
||||
return "Basic ".concat(new String(encodedAuth));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user