diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Builder.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Builder.java index de06b365239a..0f3b69bb8d82 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Builder.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Builder.java @@ -24,6 +24,7 @@ import org.springframework.boot.buildpack.platform.docker.TotalProgressEvent; import org.springframework.boot.buildpack.platform.docker.TotalProgressPullListener; import org.springframework.boot.buildpack.platform.docker.UpdateListener; +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.Image; import org.springframework.boot.buildpack.platform.docker.type.ImageReference; @@ -48,8 +49,16 @@ public Builder() { this(BuildLog.toSystemOut()); } + public Builder(DockerConfiguration dockerConfiguration) { + this(BuildLog.toSystemOut(), dockerConfiguration); + } + public Builder(BuildLog log) { - this(log, new DockerApi()); + this(log, new DockerApi(new DockerConfiguration())); + } + + public Builder(BuildLog log, DockerConfiguration dockerConfiguration) { + this(log, new DockerApi(dockerConfiguration)); } Builder(BuildLog log, DockerApi docker) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java index 053aeeb6e8d7..17daf6f45b58 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java @@ -24,8 +24,12 @@ import java.util.Collections; import java.util.List; +import org.apache.http.Header; import org.apache.http.client.utils.URIBuilder; +import org.apache.http.message.BasicHeader; +import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration; +import org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryConfiguration; import org.springframework.boot.buildpack.platform.docker.transport.HttpTransport; import org.springframework.boot.buildpack.platform.docker.transport.HttpTransport.Response; import org.springframework.boot.buildpack.platform.docker.type.ContainerConfig; @@ -68,7 +72,15 @@ public class DockerApi { * Create a new {@link DockerApi} instance. */ public DockerApi() { - this(HttpTransport.create()); + this(new DockerConfiguration()); + } + + /** + * Create a new {@link DockerApi} instance. + * @param dockerConfiguration the Docker configuration options. + */ + public DockerApi(DockerConfiguration dockerConfiguration) { + this(HttpTransport.create(createDockerEngineAuthenticationHeaders(dockerConfiguration))); } /** @@ -84,6 +96,22 @@ public DockerApi() { this.volume = new VolumeApi(); } + static Collection
createDockerEngineAuthenticationHeaders(DockerConfiguration dockerConfiguration) { + Assert.notNull(dockerConfiguration, "Docker configuration must not be null"); + + DockerRegistryConfiguration dockerRegistryConfiguration = dockerConfiguration.getDockerRegistryConfiguration(); + if (dockerRegistryConfiguration == null) { + return Collections.emptyList(); + } + + String dockerRegistryAuthToken = dockerRegistryConfiguration.createDockerRegistryAuthToken(); + if (StringUtils.isEmpty(dockerRegistryAuthToken)) { + return Collections.emptyList(); + } + + return Arrays.asList(new BasicHeader("X-Registry-Auth", dockerRegistryAuthToken)); + } + private HttpTransport http() { return this.http; } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerConfiguration.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerConfiguration.java new file mode 100644 index 000000000000..fbffe6cb83f0 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerConfiguration.java @@ -0,0 +1,49 @@ +/* + * 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.buildpack.platform.docker.configuration; + +/** + * Docker configuration options. + * + * @author Wei Jiang + * @since 2.4.0 + */ +public class DockerConfiguration { + + /** + * The docker registry configuration. + */ + private DockerRegistryConfiguration dockerRegistryConfiguration; + + public DockerConfiguration() { + super(); + } + + public DockerConfiguration(DockerRegistryConfiguration dockerRegistryConfiguration) { + super(); + this.dockerRegistryConfiguration = dockerRegistryConfiguration; + } + + public DockerRegistryConfiguration getDockerRegistryConfiguration() { + return this.dockerRegistryConfiguration; + } + + public void setDockerRegistryConfiguration(DockerRegistryConfiguration dockerRegistryConfiguration) { + this.dockerRegistryConfiguration = dockerRegistryConfiguration; + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerRegistryConfiguration.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerRegistryConfiguration.java new file mode 100644 index 000000000000..5699f2b2e629 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerRegistryConfiguration.java @@ -0,0 +1,129 @@ +/* + * 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.buildpack.platform.docker.configuration; + +import java.io.IOException; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; + +import org.springframework.boot.buildpack.platform.json.SharedObjectMapper; +import org.springframework.util.Base64Utils; +import org.springframework.util.StringUtils; + +/** + * Docker registry configuration options. + * + * @author Wei Jiang + * @since 2.4.0 + */ +public class DockerRegistryConfiguration { + + /** + * Docker registry server address. + */ + @JsonProperty("serveraddress") + 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. + */ + @JsonIgnore + private String token; + + public DockerRegistryConfiguration() { + super(); + } + + public DockerRegistryConfiguration(String url, String username, String password, String email, String token) { + super(); + this.url = url; + this.username = username; + this.password = password; + this.email = email; + this.token = token; + } + + public String createDockerRegistryAuthToken() { + if (!StringUtils.isEmpty(this.getToken())) { + return this.getToken(); + } + + try { + return Base64Utils.encodeToString(SharedObjectMapper.get().writeValueAsBytes(this)); + } + catch (IOException ex) { + throw new IllegalStateException("create docker registry authentication token failed.", ex); + } + } + + 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; + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/configuration/package-info.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/configuration/package-info.java new file mode 100644 index 000000000000..d5c3fe8a3c62 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/configuration/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Docker configuration options. + */ +package org.springframework.boot.buildpack.platform.docker.configuration; diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/HttpTransport.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/HttpTransport.java index 07b581e426a9..f374a23b9671 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/HttpTransport.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/HttpTransport.java @@ -21,6 +21,10 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.URI; +import java.util.Collection; +import java.util.Collections; + +import org.apache.http.Header; import org.springframework.boot.buildpack.platform.io.IOConsumer; import org.springframework.boot.buildpack.platform.system.Environment; @@ -84,7 +88,17 @@ public interface HttpTransport { * @return a {@link HttpTransport} instance */ static HttpTransport create() { - return create(Environment.SYSTEM); + return create(Collections.emptyList()); + } + + /** + * Create the most suitable {@link HttpTransport} based on the + * {@link Environment#SYSTEM system environment}. + * @param dockerEngineAuthenticationHeaders authentication headerS for Docker engine. + * @return a {@link HttpTransport} instance + */ + static HttpTransport create(Collection
dockerEngineAuthenticationHeaders) { + return create(Environment.SYSTEM, dockerEngineAuthenticationHeaders); } /** @@ -94,8 +108,21 @@ static HttpTransport create() { * @return a {@link HttpTransport} instance */ static HttpTransport create(Environment environment) { - HttpTransport remote = RemoteHttpClientTransport.createIfPossible(environment); - return (remote != null) ? remote : LocalHttpClientTransport.create(environment); + return create(environment, Collections.emptyList()); + } + + /** + * Create the most suitable {@link HttpTransport} based on the given + * {@link Environment}. + * @param environment the source environment + * @param dockerEngineAuthenticationHeaders authentication headerS for Docker engine. + * @return a {@link HttpTransport} instance + */ + static HttpTransport create(Environment environment, Collection
dockerEngineAuthenticationHeaders) { + HttpTransport remote = RemoteHttpClientTransport.createIfPossible(environment, + dockerEngineAuthenticationHeaders); + return (remote != null) ? remote + : LocalHttpClientTransport.create(environment, dockerEngineAuthenticationHeaders); } /** diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/LocalHttpClientTransport.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/LocalHttpClientTransport.java index 9861f4d45a6c..6c4b2a99a9af 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/LocalHttpClientTransport.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/LocalHttpClientTransport.java @@ -21,8 +21,10 @@ import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; +import java.util.Collection; import com.sun.jna.Platform; +import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; @@ -41,6 +43,7 @@ import org.springframework.boot.buildpack.platform.socket.DomainSocket; import org.springframework.boot.buildpack.platform.socket.NamedPipeSocket; import org.springframework.boot.buildpack.platform.system.Environment; +import org.springframework.util.CollectionUtils; /** * {@link HttpClientTransport} that talks to local Docker. @@ -60,10 +63,14 @@ private LocalHttpClientTransport(CloseableHttpClient client) { super(client, LOCAL_DOCKER_HOST); } - static LocalHttpClientTransport create(Environment environment) { + static LocalHttpClientTransport create(Environment environment, + Collection
dockerEngineAuthenticationHeaders) { HttpClientBuilder builder = HttpClients.custom(); builder.setConnectionManager(new LocalConnectionManager(socketFilePath(environment))); builder.setSchemePortResolver(new LocalSchemePortResolver()); + if (!CollectionUtils.isEmpty(dockerEngineAuthenticationHeaders)) { + builder.setDefaultHeaders(dockerEngineAuthenticationHeaders); + } return new LocalHttpClientTransport(builder.build()); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/RemoteHttpClientTransport.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/RemoteHttpClientTransport.java index 1b4df90b38ec..8ccc7fcc85e7 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/RemoteHttpClientTransport.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/transport/RemoteHttpClientTransport.java @@ -18,9 +18,12 @@ import java.nio.file.Files; import java.nio.file.Paths; +import java.util.Collection; +import java.util.Collections; import javax.net.ssl.SSLContext; +import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.conn.socket.LayeredConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; @@ -31,6 +34,7 @@ import org.springframework.boot.buildpack.platform.docker.ssl.SslContextFactory; import org.springframework.boot.buildpack.platform.system.Environment; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; /** * {@link HttpClientTransport} that talks to a remote Docker. @@ -53,15 +57,25 @@ private RemoteHttpClientTransport(CloseableHttpClient client, HttpHost host) { } static RemoteHttpClientTransport createIfPossible(Environment environment) { - return createIfPossible(environment, new SslContextFactory()); + return createIfPossible(environment, Collections.emptyList()); + } + + static RemoteHttpClientTransport createIfPossible(Environment environment, + Collection
dockerEngineAuthenticationHeaders) { + return createIfPossible(environment, new SslContextFactory(), dockerEngineAuthenticationHeaders); } static RemoteHttpClientTransport createIfPossible(Environment environment, SslContextFactory sslContextFactory) { + return createIfPossible(environment, sslContextFactory, Collections.emptyList()); + } + + static RemoteHttpClientTransport createIfPossible(Environment environment, SslContextFactory sslContextFactory, + Collection
dockerEngineAuthenticationHeaders) { String host = environment.get(DOCKER_HOST); if (host == null || isLocalFileReference(host)) { return null; } - return create(environment, sslContextFactory, HttpHost.create(host)); + return create(environment, sslContextFactory, HttpHost.create(host), dockerEngineAuthenticationHeaders); } private static boolean isLocalFileReference(String host) { @@ -75,12 +89,15 @@ private static boolean isLocalFileReference(String host) { } private static RemoteHttpClientTransport create(Environment environment, SslContextFactory sslContextFactory, - HttpHost tcpHost) { + HttpHost tcpHost, Collection
dockerEngineAuthenticationHeaders) { HttpClientBuilder builder = HttpClients.custom(); boolean secure = isSecure(environment); if (secure) { builder.setSSLSocketFactory(getSecureConnectionSocketFactory(environment, sslContextFactory)); } + if (!CollectionUtils.isEmpty(dockerEngineAuthenticationHeaders)) { + builder.setDefaultHeaders(dockerEngineAuthenticationHeaders); + } String scheme = secure ? "https" : "http"; HttpHost httpHost = new HttpHost(tcpHost.getHostName(), tcpHost.getPort(), scheme); return new RemoteHttpClientTransport(builder.build(), httpHost); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/BuilderTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/BuilderTests.java index dd9669f0ee3b..740cf75b4132 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/BuilderTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/BuilderTests.java @@ -30,6 +30,7 @@ import org.springframework.boot.buildpack.platform.docker.DockerApi.ImageApi; import org.springframework.boot.buildpack.platform.docker.DockerApi.VolumeApi; import org.springframework.boot.buildpack.platform.docker.TotalProgressPullListener; +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.ContainerReference; import org.springframework.boot.buildpack.platform.docker.type.ContainerStatus; @@ -60,7 +61,14 @@ class BuilderTests { @Test void createWhenLogIsNullThrowsException() { - assertThatIllegalArgumentException().isThrownBy(() -> new Builder(null)).withMessage("Log must not be null"); + assertThatIllegalArgumentException().isThrownBy(() -> new Builder((BuildLog) null)) + .withMessage("Log must not be null"); + } + + @Test + void createWithDockerConfiguration() { + Builder builder = new Builder(BuildLog.toSystemOut(), new DockerConfiguration()); + assertThat(builder).isNotNull(); } @Test diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/DockerApiTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/DockerApiTests.java index dc72c38622d7..e4fa8d66ef15 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/DockerApiTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/DockerApiTests.java @@ -20,7 +20,9 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.URI; +import java.util.Collection; +import org.apache.http.Header; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -34,6 +36,8 @@ import org.springframework.boot.buildpack.platform.docker.DockerApi.ContainerApi; import org.springframework.boot.buildpack.platform.docker.DockerApi.ImageApi; import org.springframework.boot.buildpack.platform.docker.DockerApi.VolumeApi; +import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration; +import org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryConfiguration; import org.springframework.boot.buildpack.platform.docker.transport.HttpTransport; import org.springframework.boot.buildpack.platform.docker.transport.HttpTransport.Response; import org.springframework.boot.buildpack.platform.docker.type.ContainerConfig; @@ -48,6 +52,7 @@ import org.springframework.boot.buildpack.platform.io.IOConsumer; import org.springframework.boot.buildpack.platform.io.Owner; import org.springframework.boot.buildpack.platform.io.TarArchive; +import org.springframework.util.Base64Utils; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -112,6 +117,46 @@ public InputStream getContent() { }; } + @Test + void createDockerApi() { + DockerApi api = new DockerApi(); + assertThat(api).isNotNull(); + } + + @Test + void createDockerApiWithDockerConfiguration() { + DockerApi api = new DockerApi(new DockerConfiguration()); + assertThat(api).isNotNull(); + } + + @Test + void createWhenDockerConfigurationIsNullThrowsException() { + assertThatIllegalArgumentException().isThrownBy(() -> new DockerApi((DockerConfiguration) null)) + .withMessage("Docker configuration must not be null"); + } + + @Test + void createDockerEngineAuthenticationHeaders() { + DockerRegistryConfiguration dockerRegistryConfiguration = new DockerRegistryConfiguration(); + dockerRegistryConfiguration.setUsername("username"); + dockerRegistryConfiguration.setPassword("password"); + dockerRegistryConfiguration.setEmail("mock@spring.com"); + dockerRegistryConfiguration.setUrl("http://mock.docker.registry"); + DockerConfiguration dockerConfiguration = new DockerConfiguration(); + dockerConfiguration.setDockerRegistryConfiguration(dockerRegistryConfiguration); + Collection
dockerEngineAuthenticationHeaders = DockerApi + .createDockerEngineAuthenticationHeaders(dockerConfiguration); + assertThat(dockerEngineAuthenticationHeaders.size() == 1).isTrue(); + Header header = dockerEngineAuthenticationHeaders.iterator().next(); + assertThat(header.getName()).isEqualTo("X-Registry-Auth"); + assertThat(header.getValue()).isEqualTo( + "ewogICJ1c2VybmFtZSIgOiAidXNlcm5hbWUiLAogICJwYXNzd29yZCIgOiAicGFzc3dvcmQiLAogICJlbWFpbCIgOiAibW9ja0BzcHJpbmcuY29tIiwKICAic2VydmVyYWRkcmVzcyIgOiAiaHR0cDovL21vY2suZG9ja2VyLnJlZ2lzdHJ5Igp9"); + assertThat(new String(Base64Utils.decodeFromString(header.getValue()))) + .isEqualTo("{\n" + " \"username\" : \"username\",\n" + " \"password\" : \"password\",\n" + + " \"email\" : \"mock@spring.com\",\n" + + " \"serveraddress\" : \"http://mock.docker.registry\"\n" + "}"); + } + @Nested class ImageDockerApiTests { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerConfigurationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerConfigurationTests.java new file mode 100644 index 000000000000..592a7f4af9f7 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerConfigurationTests.java @@ -0,0 +1,35 @@ +/* + * 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.buildpack.platform.docker.configuration; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link DockerConfiguration}. + * + * @author Wei Jiang + */ +public class DockerConfigurationTests { + + @Test + void createDockerConfiguration() { + assertThat(new DockerConfiguration()).isNotNull(); + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerRegistryConfigurationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerRegistryConfigurationTests.java new file mode 100644 index 000000000000..0d1aa79b2813 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerRegistryConfigurationTests.java @@ -0,0 +1,79 @@ +/* + * 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.buildpack.platform.docker.configuration; + +import org.junit.jupiter.api.Test; + +import org.springframework.util.Base64Utils; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link DockerRegistryConfiguration}. + * + * @author Wei Jiang + */ +public class DockerRegistryConfigurationTests { + + @Test + void createDockerRegistryAuthTokenWithToken() { + DockerRegistryConfiguration dockerRegistryConfiguration = new DockerRegistryConfiguration(); + dockerRegistryConfiguration.setToken("mockToken"); + assertThat(dockerRegistryConfiguration.createDockerRegistryAuthToken()).isEqualTo("mockToken"); + } + + @Test + void createDockerRegistryAuthTokenWithoutToken() { + DockerRegistryConfiguration dockerRegistryConfiguration = new DockerRegistryConfiguration(); + dockerRegistryConfiguration.setUsername("username"); + dockerRegistryConfiguration.setPassword("password"); + dockerRegistryConfiguration.setEmail("mock@spring.com"); + dockerRegistryConfiguration.setUrl("http://mock.docker.registry"); + String token = dockerRegistryConfiguration.createDockerRegistryAuthToken(); + assertThat(token).isEqualTo( + "ewogICJ1c2VybmFtZSIgOiAidXNlcm5hbWUiLAogICJwYXNzd29yZCIgOiAicGFzc3dvcmQiLAogICJlbWFpbCIgOiAibW9ja0BzcHJpbmcuY29tIiwKICAic2VydmVyYWRkcmVzcyIgOiAiaHR0cDovL21vY2suZG9ja2VyLnJlZ2lzdHJ5Igp9"); + assertThat(new String(Base64Utils.decodeFromString(token))).isEqualTo("{\n" + " \"username\" : \"username\",\n" + + " \"password\" : \"password\",\n" + " \"email\" : \"mock@spring.com\",\n" + + " \"serveraddress\" : \"http://mock.docker.registry\"\n" + "}"); + } + + @Test + void createDockerRegistryAuthTokenWithUsernameAndPassword() { + DockerRegistryConfiguration dockerRegistryConfiguration = new DockerRegistryConfiguration(); + dockerRegistryConfiguration.setUsername("username"); + dockerRegistryConfiguration.setPassword("password"); + String token = dockerRegistryConfiguration.createDockerRegistryAuthToken(); + assertThat(dockerRegistryConfiguration.getEmail()).isNull(); + assertThat(dockerRegistryConfiguration.getUrl()).isNull(); + assertThat(token).isEqualTo( + "ewogICJ1c2VybmFtZSIgOiAidXNlcm5hbWUiLAogICJwYXNzd29yZCIgOiAicGFzc3dvcmQiLAogICJlbWFpbCIgOiBudWxsLAogICJzZXJ2ZXJhZGRyZXNzIiA6IG51bGwKfQ=="); + assertThat(new String(Base64Utils.decodeFromString(token))).isEqualTo("{\n" + " \"username\" : \"username\",\n" + + " \"password\" : \"password\",\n" + " \"email\" : null,\n" + " \"serveraddress\" : null\n" + "}"); + } + + @Test + void createDockerRegistryAuthTokenWithTokenAndUsername() { + DockerRegistryConfiguration dockerRegistryConfiguration = new DockerRegistryConfiguration(); + dockerRegistryConfiguration.setToken("mockToken"); + dockerRegistryConfiguration.setUsername("username"); + dockerRegistryConfiguration.setPassword("password"); + dockerRegistryConfiguration.setEmail("mock@spring.com"); + dockerRegistryConfiguration.setUrl("http://mock.docker.registry"); + assertThat(dockerRegistryConfiguration.createDockerRegistryAuthToken()).isEqualTo("mockToken"); + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/transport/HttpTransportTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/transport/HttpTransportTests.java index 38a65a819c91..3c4a8bbcc2b9 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/transport/HttpTransportTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/transport/HttpTransportTests.java @@ -19,9 +19,13 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Map; +import org.apache.http.Header; +import org.apache.http.message.BasicHeader; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -65,4 +69,12 @@ void createWhenDoesNotHaveDockerHostVariableReturnsLocal() { assertThat(transport).isInstanceOf(LocalHttpClientTransport.class); } + @Test + void createWithDockerEngineAuthenticationHeaders() { + Collection
dockerEngineAuthenticationHeaders = Arrays.asList(new BasicHeader("X-Registry-Auth", + "eyJ1c2VybmFtZSI6ICJ1c2VybmFtZSIsInBhc3N3b3JkIjogInBhc3N3b3JkIiwiZW1haWwiOiAibW9ja0BzcHJpbmcuY29tIiwic2VydmVyYWRkcmVzcyI6ICJodHRwOi8vbW9jay5kb2NrZXIucmVnaXN0cnkifQ==")); + HttpTransport transport = HttpTransport.create((name) -> null, dockerEngineAuthenticationHeaders); + assertThat(transport).isInstanceOf(LocalHttpClientTransport.class); + } + } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/transport/RemoteHttpClientTransportTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/transport/RemoteHttpClientTransportTests.java index 784fa717c3dc..86c636bfec5c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/transport/RemoteHttpClientTransportTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/transport/RemoteHttpClientTransportTests.java @@ -19,13 +19,17 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Arrays; +import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; import java.util.function.Consumer; import javax.net.ssl.SSLContext; +import org.apache.http.Header; import org.apache.http.HttpHost; +import org.apache.http.message.BasicHeader; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -68,6 +72,16 @@ void createIfPossibleWhenDockerHostIsAddressReturnsTransport() { assertThat(transport).isNotNull(); } + @Test + void createWithDockerEngineAuthenticationHeaders() { + Collection
dockerEngineAuthenticationHeaders = Arrays.asList(new BasicHeader("X-Registry-Auth", + "eyJ1c2VybmFtZSI6ICJ1c2VybmFtZSIsInBhc3N3b3JkIjogInBhc3N3b3JkIiwiZW1haWwiOiAibW9ja0BzcHJpbmcuY29tIiwic2VydmVyYWRkcmVzcyI6ICJodHRwOi8vbW9jay5kb2NrZXIucmVnaXN0cnkifQ==")); + this.environment.put("DOCKER_HOST", "tcp://192.168.1.2:2376"); + RemoteHttpClientTransport transport = RemoteHttpClientTransport.createIfPossible(this.environment::get, + dockerEngineAuthenticationHeaders); + assertThat(transport).isNotNull(); + } + @Test void createIfPossibleWhenTlsVerifyWithMissingCertPathThrowsException() { this.environment.put("DOCKER_HOST", "tcp://192.168.1.2:2376"); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImage.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImage.java index dfdc211f2d73..a1aa9aa10897 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImage.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImage.java @@ -35,6 +35,7 @@ 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; @@ -72,6 +73,8 @@ public class BootBuildImage extends DefaultTask { private PullPolicy pullPolicy; + private Docker docker; + public BootBuildImage() { this.jar = getProject().getObjects().fileProperty(); this.targetJavaVersion = getProject().getObjects().property(JavaVersion.class); @@ -246,9 +249,31 @@ public void setPullPolicy(PullPolicy pullPolicy) { this.pullPolicy = pullPolicy; } + /** + * Returns the Docker configuration with the builder will be used. + * @return docker configuration. + */ + @Input + @Optional + public Docker getDocker() { + return this.docker; + } + + /** + * Sets the Docker configuration with the builder will be used. + * @param docker docker configuration. + */ + @Option(option = "docker", description = "The Docker configuration to use") + public void setDocker(Docker docker) { + this.docker = docker; + } + @TaskAction void buildImage() throws DockerEngineException, IOException { - Builder builder = new Builder(); + DockerConfiguration dockerConfiguration = (this.docker != null) ? this.docker.getDockerConfiguration() + : new DockerConfiguration(); + + Builder builder = new Builder(dockerConfiguration); BuildRequest request = createRequest(); builder.build(request); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/Docker.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/Docker.java new file mode 100644 index 000000000000..188775c9eb29 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/Docker.java @@ -0,0 +1,53 @@ +/* + * 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); + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/DockerRegistry.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/DockerRegistry.java new file mode 100644 index 000000000000..0a320ec7bd49 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/DockerRegistry.java @@ -0,0 +1,98 @@ +/* + * 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); + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/DockerRegistryTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/DockerRegistryTests.java new file mode 100644 index 000000000000..bc86e24cba38 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/DockerRegistryTests.java @@ -0,0 +1,47 @@ +/* + * 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.junit.jupiter.api.Test; + +import org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryConfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link DockerRegistry}. + * + * @author Wei Jiang + */ +public class DockerRegistryTests { + + @Test + void getDockerRegistryConfiguration() { + DockerRegistry dockerRegistry = new DockerRegistry(); + dockerRegistry.setUsername("username"); + dockerRegistry.setPassword("password"); + dockerRegistry.setEmail("mock@spring.com"); + dockerRegistry.setUrl("http://mock.docker.registry"); + DockerRegistryConfiguration dockerRegistryConfiguration = dockerRegistry.getDockerRegistryConfiguration(); + assertThat(dockerRegistryConfiguration).isNotNull(); + assertThat(dockerRegistryConfiguration.getUsername()).isEqualTo(dockerRegistry.getUsername()); + assertThat(dockerRegistryConfiguration.getPassword()).isEqualTo(dockerRegistry.getPassword()); + assertThat(dockerRegistryConfiguration.getEmail()).isEqualTo(dockerRegistry.getEmail()); + assertThat(dockerRegistryConfiguration.getUrl()).isEqualTo(dockerRegistry.getUrl()); + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildImageMojo.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildImageMojo.java index d63397931825..96b0eb6fcaaf 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildImageMojo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildImageMojo.java @@ -44,6 +44,7 @@ import org.springframework.boot.buildpack.platform.build.Creator; import org.springframework.boot.buildpack.platform.build.PullPolicy; import org.springframework.boot.buildpack.platform.docker.TotalProgressEvent; +import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration; import org.springframework.boot.buildpack.platform.io.Owner; import org.springframework.boot.buildpack.platform.io.TarArchive; import org.springframework.boot.loader.tools.EntryWriter; @@ -131,6 +132,13 @@ public class BuildImageMojo extends AbstractPackagerMojo { @Parameter(property = "spring-boot.build-image.pullPolicy", readonly = true) PullPolicy pullPolicy; + /** + * Docker configuration options. + * @since 2.4.0 + */ + @Parameter + private Docker docker; + @Override public void execute() throws MojoExecutionException { if (this.project.getPackaging().equals("pom")) { @@ -147,7 +155,9 @@ public void execute() throws MojoExecutionException { private void buildImage() throws MojoExecutionException { Libraries libraries = getLibraries(Collections.emptySet()); try { - Builder builder = new Builder(new MojoBuildLog(this::getLog)); + DockerConfiguration dockerConfiguration = (this.docker != null) ? this.docker.getDockerConfiguration() + : new DockerConfiguration(); + Builder builder = new Builder(new MojoBuildLog(this::getLog), dockerConfiguration); BuildRequest request = getBuildRequest(libraries); builder.build(request); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Docker.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Docker.java new file mode 100644 index 000000000000..14e43af95ac5 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Docker.java @@ -0,0 +1,53 @@ +/* + * 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.maven; + +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); + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/DockerRegistry.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/DockerRegistry.java new file mode 100644 index 000000000000..8020eb261ecf --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/DockerRegistry.java @@ -0,0 +1,98 @@ +/* + * 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.maven; + +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); + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/DockerRegistryTests.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/DockerRegistryTests.java new file mode 100644 index 000000000000..2fcba6fbd9bf --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/DockerRegistryTests.java @@ -0,0 +1,47 @@ +/* + * 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.maven; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryConfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link DockerRegistry}. + * + * @author Wei Jiang + */ +public class DockerRegistryTests { + + @Test + void getDockerRegistryConfiguration() { + DockerRegistry dockerRegistry = new DockerRegistry(); + dockerRegistry.setUsername("username"); + dockerRegistry.setPassword("password"); + dockerRegistry.setEmail("mock@spring.com"); + dockerRegistry.setUrl("http://mock.docker.registry"); + DockerRegistryConfiguration dockerRegistryConfiguration = dockerRegistry.getDockerRegistryConfiguration(); + assertThat(dockerRegistryConfiguration).isNotNull(); + assertThat(dockerRegistryConfiguration.getUsername()).isEqualTo(dockerRegistry.getUsername()); + assertThat(dockerRegistryConfiguration.getPassword()).isEqualTo(dockerRegistry.getPassword()); + assertThat(dockerRegistryConfiguration.getEmail()).isEqualTo(dockerRegistry.getEmail()); + assertThat(dockerRegistryConfiguration.getUrl()).isEqualTo(dockerRegistry.getUrl()); + } + +}