Polish "Support authentication to private Docker registry"

See gh-22972
This commit is contained in:
Scott Frederick
2020-08-24 14:10:01 -05:00
parent e8f555e13d
commit 86fa8144f5
40 changed files with 1193 additions and 747 deletions

View File

@@ -20,6 +20,8 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import groovy.lang.Closure;
import org.gradle.api.Action;
import org.gradle.api.DefaultTask;
import org.gradle.api.JavaVersion;
import org.gradle.api.Project;
@@ -27,15 +29,16 @@ import org.gradle.api.Task;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Nested;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.options.Option;
import org.gradle.util.ConfigureUtil;
import org.springframework.boot.buildpack.platform.build.BuildRequest;
import org.springframework.boot.buildpack.platform.build.Builder;
import org.springframework.boot.buildpack.platform.build.Creator;
import org.springframework.boot.buildpack.platform.build.PullPolicy;
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration;
import org.springframework.boot.buildpack.platform.docker.transport.DockerEngineException;
import org.springframework.boot.buildpack.platform.docker.type.ImageName;
import org.springframework.boot.buildpack.platform.docker.type.ImageReference;
@@ -73,7 +76,7 @@ public class BootBuildImage extends DefaultTask {
private PullPolicy pullPolicy;
private Docker docker;
private DockerSpec docker = new DockerSpec();
public BootBuildImage() {
this.jar = getProject().getObjects().fileProperty();
@@ -250,30 +253,36 @@ public class BootBuildImage extends DefaultTask {
}
/**
* Returns the Docker configuration with the builder will be used.
* Returns the Docker configuration the builder will use.
* @return docker configuration.
* @since 2.4.0
*/
@Input
@Optional
public Docker getDocker() {
@Nested
public DockerSpec getDocker() {
return this.docker;
}
/**
* Sets the Docker configuration with the builder will be used.
* @param docker docker configuration.
* Configures the Docker connection using the given {@code action}.
* @param action the action to apply
* @since 2.4.0
*/
@Option(option = "docker", description = "The Docker configuration to use")
public void setDocker(Docker docker) {
this.docker = docker;
public void docker(Action<DockerSpec> action) {
action.execute(this.docker);
}
/**
* Configures the Docker connection using the given {@code closure}.
* @param closure the closure to apply
* @since 2.4.0
*/
public void docker(Closure<?> closure) {
docker(ConfigureUtil.configureUsing(closure));
}
@TaskAction
void buildImage() throws DockerEngineException, IOException {
DockerConfiguration dockerConfiguration = (this.docker != null) ? this.docker.getDockerConfiguration()
: new DockerConfiguration();
Builder builder = new Builder(dockerConfiguration);
Builder builder = new Builder(this.docker.asDockerConfiguration());
BuildRequest request = createRequest();
builder.build(request);
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright 2012-2020 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
*
* https://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.boot.gradle.tasks.bundling;
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration;
import org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryConfiguration;
/**
* Docker configuration options.
*
* @author Wei Jiang
* @since 2.4.0
*/
public class Docker {
/**
* The docker registry configuration.
*/
private DockerRegistry registry;
public DockerRegistry getRegistry() {
return this.registry;
}
public void setRegistry(DockerRegistry registry) {
this.registry = registry;
}
public DockerConfiguration getDockerConfiguration() {
DockerRegistryConfiguration dockerRegistryConfiguration = null;
if (this.registry != null) {
dockerRegistryConfiguration = this.registry.getDockerRegistryConfiguration();
}
return new DockerConfiguration(dockerRegistryConfiguration);
}
}

View File

@@ -1,98 +0,0 @@
/*
* Copyright 2012-2020 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
*
* https://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.boot.gradle.tasks.bundling;
import org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryConfiguration;
/**
* Docker registry configuration options.
*
* @author Wei Jiang
* @since 2.4.0
*/
public class DockerRegistry {
/**
* Docker registry server address.
*/
private String url;
/**
* Docker registry authentication username.
*/
private String username;
/**
* Docker registry authentication password.
*/
private String password;
/**
* Docker registry authentication email.
*/
private String email;
/**
* Docker registry authentication identity token.
*/
private String token;
public String getUrl() {
return this.url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getToken() {
return this.token;
}
public void setToken(String token) {
this.token = token;
}
public DockerRegistryConfiguration getDockerRegistryConfiguration() {
return new DockerRegistryConfiguration(this.url, this.username, this.password, this.email, this.token);
}
}

View File

@@ -0,0 +1,214 @@
/*
* Copyright 2012-2020 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
*
* https://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.boot.gradle.tasks.bundling;
import groovy.lang.Closure;
import org.gradle.api.Action;
import org.gradle.api.GradleException;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Nested;
import org.gradle.api.tasks.Optional;
import org.gradle.util.ConfigureUtil;
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration;
/**
* Encapsulates Docker configuration options.
*
* @author Wei Jiang
* @author Scott Frederick
* @since 2.4.0
*/
public class DockerSpec {
private final DockerRegistrySpec registry;
public DockerSpec() {
this.registry = new DockerRegistrySpec();
}
DockerSpec(DockerRegistrySpec registry) {
this.registry = registry;
}
/**
* Returns the {@link DockerRegistrySpec} that configures registry authentication.
* @return the registry spec
*/
@Nested
public DockerRegistrySpec getRegistry() {
return this.registry;
}
/**
* Customizes the {@link DockerRegistrySpec} that configures registry authentication.
* @param action the action to apply
*/
public void registry(Action<DockerRegistrySpec> action) {
action.execute(this.registry);
}
/**
* Customizes the {@link DockerRegistrySpec} that configures registry authentication.
* @param closure the closure to apply
*/
public void registry(Closure<?> closure) {
registry(ConfigureUtil.configureUsing(closure));
}
/**
* Returns this configuration as a {@link DockerConfiguration} instance. This method
* should only be called when the configuration is complete and will no longer be
* changed.
* @return the Docker configuration
*/
DockerConfiguration asDockerConfiguration() {
if (this.registry == null || this.registry.hasEmptyAuth()) {
return null;
}
if (this.registry.hasTokenAuth() && !this.registry.hasUserAuth()) {
return DockerConfiguration.withRegistryTokenAuthentication(this.registry.getToken());
}
if (this.registry.hasUserAuth() && !this.registry.hasTokenAuth()) {
return DockerConfiguration.withRegistryUserAuthentication(this.registry.getUsername(),
this.registry.getPassword(), this.registry.getUrl(), this.registry.getEmail());
}
throw new GradleException(
"Invalid Docker registry configuration, either token or username/password must be provided");
}
/**
* Encapsulates Docker registry authentication configuration options.
*/
public static class DockerRegistrySpec {
private String username;
private String password;
private String url;
private String email;
private String token;
/**
* Returns the username to use when authenticating to the Docker registry.
* @return the registry username
*/
@Input
@Optional
public String getUsername() {
return this.username;
}
/**
* Sets the username to use when authenticating to the Docker registry.
* @param username the registry username
*/
public void setUsername(String username) {
this.username = username;
}
/**
* Returns the password to use when authenticating to the Docker registry.
* @return the registry password
*/
@Input
@Optional
public String getPassword() {
return this.password;
}
/**
* Sets the password to use when authenticating to the Docker registry.
* @param password the registry username
*/
public void setPassword(String password) {
this.password = password;
}
/**
* Returns the Docker registry URL.
* @return the registry URL
*/
@Input
@Optional
public String getUrl() {
return this.url;
}
/**
* Sets the Docker registry URL.
* @param url the registry URL
*/
public void setUrl(String url) {
this.url = url;
}
/**
* Returns the email address associated with the Docker registry username.
* @return the registry email address
*/
@Input
@Optional
public String getEmail() {
return this.email;
}
/**
* Sets the email address associated with the Docker registry username.
* @param email the registry email address
*/
public void setEmail(String email) {
this.email = email;
}
/**
* Returns the identity token to use when authenticating to the Docker registry.
* @return the registry identity token
*/
@Input
@Optional
public String getToken() {
return this.token;
}
/**
* Sets the identity token to use when authenticating to the Docker registry.
* @param token the registry identity token
*/
public void setToken(String token) {
this.token = token;
}
boolean hasEmptyAuth() {
return this.username == null && this.password == null && this.url == null && this.email == null
&& this.token == null;
}
boolean hasUserAuth() {
return this.getUsername() != null && this.getPassword() != null;
}
boolean hasTokenAuth() {
return this.getToken() != null;
}
}
}