1616
1717package 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 ;
2321import java .util .List ;
2422import java .util .Map ;
2523import java .util .Objects ;
4139import io .fabric8 .maven .core .util .KubernetesClientUtil ;
4240import io .fabric8 .maven .core .util .KubernetesResourceUtil ;
4341import io .fabric8 .maven .core .util .ResourceFileType ;
42+ import io .fabric8 .maven .docker .access .AuthConfig ;
4443import io .fabric8 .maven .docker .assembly .ArchiverCustomizer ;
44+ import io .fabric8 .maven .docker .assembly .DockerAssemblyManager ;
45+ import io .fabric8 .maven .docker .config .AssemblyConfiguration ;
4546import io .fabric8 .maven .docker .config .BuildImageConfiguration ;
4647import io .fabric8 .maven .docker .config .ImageConfiguration ;
48+ import io .fabric8 .maven .docker .service .RegistryService ;
4749import 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 .*;
5852import io .fabric8 .openshift .client .OpenShiftClient ;
5953
54+ import org .apache .commons .codec .binary .Base64 ;
6055import org .apache .commons .lang3 .StringUtils ;
6156import org .apache .maven .plugin .MojoExecutionException ;
6257import 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