Skip to content
This repository was archived by the owner on Jun 19, 2024. It is now read-only.

Commit b6a8f02

Browse files
author
Piyush Garg
authored
Merge pull request #1300 from yadavnikhil/pulSecret
Create pullSecret in buildConfig when pulling from private registry in Openshift.
2 parents 4da1b8b + 0139e85 commit b6a8f02

File tree

6 files changed

+319
-29
lines changed

6 files changed

+319
-29
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ We use semantic versioning in some slight variation until our feature set has st
99
* The `PATCH_LEVEL` is used for regular CD releases which add new features and bug fixes.
1010

1111
After this we will switch probably to real [Semantic Versioning 2.0.0](http://semver.org/)
12+
###3.5.40
13+
* Feature 1293: Added support to create pullSecret in buildConfig when pulling from private registry in Openshift.
1214

1315
###3.5.40
1416
* Feature 1264: Added `osio` profile, with enricher to apply OpenShift.io space labels to resources

core/src/main/java/io/fabric8/maven/core/service/BuildService.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ class BuildServiceConfig {
5858

5959
private String s2iBuildNameSuffix;
6060

61+
private String openshiftPullSecret;
62+
6163
private Task<KubernetesListBuilder> enricherTask;
6264

6365
private String buildDirectory;
@@ -89,6 +91,10 @@ public String getS2iBuildNameSuffix() {
8991
return s2iBuildNameSuffix;
9092
}
9193

94+
public String getOpenshiftPullSecret() {
95+
return openshiftPullSecret;
96+
}
97+
9298
public Task<KubernetesListBuilder> getEnricherTask() {
9399
return enricherTask;
94100
}
@@ -147,6 +153,11 @@ public Builder s2iBuildNameSuffix(String s2iBuildNameSuffix) {
147153
return this;
148154
}
149155

156+
public Builder openshiftPullSecret(String openshiftPullSecret) {
157+
config.openshiftPullSecret = openshiftPullSecret;
158+
return this;
159+
}
160+
150161
public Builder s2iImageStreamLookupPolicyLocal(boolean s2iImageStreamLookupPolicyLocal) {
151162
config.s2iImageStreamLookupPolicyLocal = s2iImageStreamLookupPolicyLocal;
152163
return this;

core/src/main/java/io/fabric8/maven/core/service/openshift/OpenshiftBuildService.java

Lines changed: 150 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@
1616

1717
package io.fabric8.maven.core.service.openshift;
1818

19-
import java.io.File;
20-
import java.io.FileWriter;
21-
import java.io.IOException;
22-
import java.io.PrintWriter;
19+
import java.io.*;
20+
import java.util.HashMap;
2321
import java.util.List;
2422
import java.util.Map;
2523
import java.util.Objects;
@@ -41,25 +39,24 @@
4139
import io.fabric8.maven.core.util.KubernetesClientUtil;
4240
import io.fabric8.maven.core.util.KubernetesResourceUtil;
4341
import io.fabric8.maven.core.util.ResourceFileType;
42+
import io.fabric8.maven.docker.access.AuthConfig;
4443
import io.fabric8.maven.docker.assembly.ArchiverCustomizer;
44+
import io.fabric8.maven.docker.assembly.DockerAssemblyManager;
45+
import io.fabric8.maven.docker.config.AssemblyConfiguration;
4546
import io.fabric8.maven.docker.config.BuildImageConfiguration;
4647
import io.fabric8.maven.docker.config.ImageConfiguration;
48+
import io.fabric8.maven.docker.service.RegistryService;
4749
import io.fabric8.maven.docker.service.ServiceHub;
48-
import io.fabric8.maven.docker.util.ImageName;
49-
import io.fabric8.maven.docker.util.Logger;
50-
import io.fabric8.openshift.api.model.Build;
51-
import io.fabric8.openshift.api.model.BuildConfig;
52-
import io.fabric8.openshift.api.model.BuildConfigSpec;
53-
import io.fabric8.openshift.api.model.BuildOutput;
54-
import io.fabric8.openshift.api.model.BuildOutputBuilder;
55-
import io.fabric8.openshift.api.model.BuildSource;
56-
import io.fabric8.openshift.api.model.BuildStrategy;
57-
import io.fabric8.openshift.api.model.BuildStrategyBuilder;
50+
import io.fabric8.maven.docker.util.*;
51+
import io.fabric8.openshift.api.model.*;
5852
import io.fabric8.openshift.client.OpenShiftClient;
5953

54+
import org.apache.commons.codec.binary.Base64;
6055
import org.apache.commons.lang3.StringUtils;
6156
import org.apache.maven.plugin.MojoExecutionException;
6257
import org.codehaus.plexus.archiver.tar.TarArchiver;
58+
import org.json.JSONArray;
59+
import org.json.JSONObject;
6360

6461
/**
6562
* @author nicola
@@ -71,6 +68,9 @@ public class OpenshiftBuildService implements BuildService {
7168
private final Logger log;
7269
private ServiceHub dockerServiceHub;
7370
private BuildServiceConfig config;
71+
private RegistryService.RegistryConfig registryConfig;
72+
private AuthConfigFactory authConfigFactory;
73+
7474

7575
public OpenshiftBuildService(OpenShiftClient client, Logger log, ServiceHub dockerServiceHub, BuildServiceConfig config) {
7676
Objects.requireNonNull(client, "client");
@@ -94,8 +94,15 @@ public void build(ImageConfiguration imageConfig) throws Fabric8ServiceException
9494

9595
KubernetesListBuilder builder = new KubernetesListBuilder();
9696

97-
// Check for buildconfig / imagestream and create them if necessary
98-
buildName = updateOrCreateBuildConfig(config, client, builder, imageConfig);
97+
// Check for buildconfig / imagestream / pullSecret and create them if necessary
98+
String openshiftPullSecret = config.getOpenshiftPullSecret();
99+
Boolean usePullSecret = checkOrCreatePullSecret(config, client, builder, openshiftPullSecret, imageConfig);
100+
if (usePullSecret) {
101+
buildName = updateOrCreateBuildConfig(config, client, builder, imageConfig, openshiftPullSecret);
102+
} else {
103+
buildName = updateOrCreateBuildConfig(config, client, builder, imageConfig, null);
104+
}
105+
99106
checkOrCreateImageStream(config, client, builder, getImageStreamName(imageName));
100107
applyResourceObjects(config, client, builder);
101108

@@ -174,13 +181,13 @@ public void postProcess(BuildServiceConfig config) {
174181
config.attachArtifact("is", getImageStreamFile(config));
175182
}
176183

177-
private String updateOrCreateBuildConfig(BuildServiceConfig config, OpenShiftClient client, KubernetesListBuilder builder, ImageConfiguration imageConfig) {
184+
private String updateOrCreateBuildConfig(BuildServiceConfig config, OpenShiftClient client, KubernetesListBuilder builder, ImageConfiguration imageConfig, String openshiftPullSecret) {
178185
ImageName imageName = new ImageName(imageConfig.getName());
179186
String buildName = getS2IBuildName(config, imageName);
180187
String imageStreamName = getImageStreamName(imageName);
181188
String outputImageStreamTag = imageStreamName + ":" + (imageName.getTag() != null ? imageName.getTag() : "latest");
182189

183-
BuildStrategy buildStrategyResource = createBuildStrategy(imageConfig, config.getOpenshiftBuildStrategy());
190+
BuildStrategy buildStrategyResource = createBuildStrategy(imageConfig, config.getOpenshiftBuildStrategy(), openshiftPullSecret);
184191
BuildOutput buildOutput = new BuildOutputBuilder().withNewTo()
185192
.withKind("ImageStreamTag")
186193
.withName(outputImageStreamTag)
@@ -261,9 +268,19 @@ private String updateBuildConfig(OpenShiftClient client, String buildName, Build
261268
return buildName;
262269
}
263270

264-
private BuildStrategy createBuildStrategy(ImageConfiguration imageConfig, OpenShiftBuildStrategy osBuildStrategy) {
271+
private BuildStrategy createBuildStrategy(ImageConfiguration imageConfig, OpenShiftBuildStrategy osBuildStrategy, String openshiftPullSecret) {
265272
if (osBuildStrategy == OpenShiftBuildStrategy.docker) {
266-
return new BuildStrategyBuilder().withType("Docker").build();
273+
BuildStrategy buildStrategy = new BuildStrategyBuilder().withType("Docker")
274+
.withNewDockerStrategy()
275+
.endDockerStrategy().build();
276+
277+
if (openshiftPullSecret != null) {
278+
buildStrategy.getDockerStrategy().setPullSecret(new LocalObjectReferenceBuilder()
279+
.withName(openshiftPullSecret)
280+
.build());
281+
}
282+
283+
return buildStrategy;
267284
} else if (osBuildStrategy == OpenShiftBuildStrategy.s2i) {
268285
BuildImageConfiguration buildConfig = imageConfig.getBuildConfiguration();
269286
Map<String, String> fromExt = buildConfig.getFromExt();
@@ -272,7 +289,7 @@ private BuildStrategy createBuildStrategy(ImageConfiguration imageConfig, OpenSh
272289
String fromKind = getMapValueWithDefault(fromExt, OpenShiftBuildStrategy.SourceStrategy.kind, "DockerImage");
273290
String fromNamespace = getMapValueWithDefault(fromExt, OpenShiftBuildStrategy.SourceStrategy.namespace, "ImageStreamTag".equals(fromKind) ? "openshift" : null);
274291

275-
return new BuildStrategyBuilder()
292+
BuildStrategy buildStrategy = new BuildStrategyBuilder()
276293
.withType("Source")
277294
.withNewSourceStrategy()
278295
.withNewFrom()
@@ -282,11 +299,123 @@ private BuildStrategy createBuildStrategy(ImageConfiguration imageConfig, OpenSh
282299
.endFrom()
283300
.endSourceStrategy()
284301
.build();
302+
if (openshiftPullSecret != null) {
303+
buildStrategy.getSourceStrategy().setPullSecret(new LocalObjectReferenceBuilder()
304+
.withName(openshiftPullSecret)
305+
.build());
306+
}
307+
308+
return buildStrategy;
309+
285310
} else {
286311
throw new IllegalArgumentException("Unsupported BuildStrategy " + osBuildStrategy);
287312
}
288313
}
289314

315+
private Boolean checkOrCreatePullSecret(BuildServiceConfig config, OpenShiftClient client, KubernetesListBuilder builder, String pullSecretName, ImageConfiguration imageConfig)
316+
throws MojoExecutionException, UnsupportedEncodingException {
317+
io.fabric8.maven.docker.service.BuildService.BuildContext dockerBuildContext = config.getDockerBuildContext();
318+
BuildImageConfiguration buildConfig = imageConfig.getBuildConfiguration();
319+
320+
String fromImage;
321+
if (buildConfig.isDockerFileMode()) {
322+
fromImage = extractBaseFromDockerfile(buildConfig, dockerBuildContext);
323+
} else {
324+
fromImage = extractBaseFromConfiguration(buildConfig);
325+
}
326+
327+
String pullRegistry = EnvUtil.findRegistry(new ImageName(fromImage).getRegistry(), dockerBuildContext.getPullRegistry(), dockerBuildContext.getRegistryConfig().getRegistry());;
328+
329+
if (pullRegistry != null) {
330+
RegistryService.RegistryConfig registryConfig = dockerBuildContext.getRegistryConfig();
331+
AuthConfig authConfig = registryConfig.getAuthConfigFactory().createAuthConfig(false, registryConfig.isSkipExtendedAuth(), registryConfig.getAuthConfig(),
332+
registryConfig.getSettings(), null, pullRegistry);
333+
334+
if (authConfig != null) {
335+
336+
JSONObject auths = new JSONObject();
337+
JSONObject auth = new JSONObject();
338+
JSONObject item = new JSONObject();
339+
340+
String authString = authConfig.getUsername() + ":" + authConfig.getPassword();
341+
item.put("auth", Base64.encodeBase64String(authString.getBytes("UTF-8")));
342+
auth.put(pullRegistry, item);
343+
auths.put("auths", auth);
344+
345+
String credentials = Base64.encodeBase64String(auths.toString().getBytes("UTF-8"));
346+
347+
Map<String, String> data = new HashMap<>();
348+
data.put(".dockerconfigjson", credentials);
349+
350+
boolean hasPullSecret = client.secrets().withName(pullSecretName).get() != null;
351+
352+
if (!hasPullSecret) {
353+
log.info("Creating Secret %s", hasPullSecret);
354+
builder.addNewSecretItem()
355+
.withNewMetadata()
356+
.withName(pullSecretName)
357+
.endMetadata()
358+
.withData(data)
359+
.withType("kubernetes.io/dockerconfigjson")
360+
.endSecretItem();
361+
} else {
362+
log.info("Adding to Secret %s", pullSecretName);
363+
return updateSecret(client, pullSecretName, data);
364+
}
365+
366+
return true;
367+
} else {
368+
return false;
369+
}
370+
}
371+
return false;
372+
}
373+
374+
private boolean updateSecret(OpenShiftClient client, String pullSecretName, Map<String, String> data) {
375+
if (!Objects.equals(data, client.secrets().withName(pullSecretName).get().getData())) {
376+
client.secrets().withName(pullSecretName).edit()
377+
.editMetadata()
378+
.withName(pullSecretName)
379+
.endMetadata()
380+
.withData(data)
381+
.withType("kubernetes.io/dockerconfigjson")
382+
.done();
383+
log.info("Updating Secret %s", pullSecretName);
384+
} else {
385+
log.info("Using Secret %s", pullSecretName);
386+
}
387+
return true;
388+
}
389+
390+
391+
private String extractBaseFromConfiguration(BuildImageConfiguration buildConfig) {
392+
String fromImage;
393+
fromImage = buildConfig.getFrom();
394+
if (fromImage == null) {
395+
AssemblyConfiguration assemblyConfig = buildConfig.getAssemblyConfiguration();
396+
if (assemblyConfig == null) {
397+
fromImage = DockerAssemblyManager.DEFAULT_DATA_BASE_IMAGE;
398+
}
399+
}
400+
return fromImage;
401+
}
402+
403+
private String extractBaseFromDockerfile(BuildImageConfiguration buildConfig, io.fabric8.maven.docker.service.BuildService.BuildContext buildContext) {
404+
String fromImage;
405+
try {
406+
File fullDockerFilePath = buildConfig.getAbsoluteDockerFilePath(buildContext.getMojoParameters());
407+
fromImage = DockerFileUtil.extractBaseImage(
408+
fullDockerFilePath,
409+
buildContext.getMojoParameters().getProject().getProperties(),
410+
buildConfig.getFilter());
411+
} catch (IOException e) {
412+
// Cant extract base image, so we wont try an auto pull. An error will occur later anyway when
413+
// building the image, so we are passive here.
414+
fromImage = null;
415+
}
416+
return fromImage;
417+
}
418+
290419
private void checkOrCreateImageStream(BuildServiceConfig config, OpenShiftClient client, KubernetesListBuilder builder, String imageStreamName) {
291420
boolean hasImageStream = client.imageStreams().withName(imageStreamName).get() != null;
292421
if (hasImageStream && config.getBuildRecreateMode().isImageStream()) {

0 commit comments

Comments
 (0)