Skip to content

Commit

Permalink
Refactor DefaultControllerEnricher (fabric8io#1451)
Browse files Browse the repository at this point in the history
  • Loading branch information
rohanKanojia authored and rhuss committed Dec 14, 2018
1 parent 5578f14 commit fe2247f
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 55 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ After this we will switch probably to real [Semantic Versioning 2.0.0](http://se
* Fix 10: Make VolumeConfiguration more flexible
* Fix 1326: Fixes overridding of Selector Label by the project enrichers entries.
* Fix 839: Sets Spring Boot generator color config property as String (http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/ansi/AnsiOutput.Enabled.html)
* Fix 401: Refactor DefaultControllerEnricher
* Fix 1412: mvn deploy fails when using a Dockerfile during S2I build
* Fix 1386: Allow @sha256 digest for tags in FROM
* Fix 796: Remove workaround to produce both .yaml and .json files
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/**
* Copyright 2016 Red Hat, Inc.
*
* Red Hat licenses this file to you 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 io.fabric8.maven.enricher.standard;

import io.fabric8.kubernetes.api.builder.TypedVisitor;
import io.fabric8.kubernetes.api.model.KubernetesListBuilder;
import io.fabric8.kubernetes.api.model.PodSpec;
import io.fabric8.kubernetes.api.model.PodSpecBuilder;
import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder;
import io.fabric8.kubernetes.api.model.apps.DeploymentFluent;
import io.fabric8.kubernetes.api.model.apps.DeploymentSpec;
import io.fabric8.kubernetes.api.model.apps.StatefulSetBuilder;
import io.fabric8.kubernetes.api.model.apps.StatefulSetFluent;
import io.fabric8.kubernetes.api.model.apps.StatefulSetSpec;
import io.fabric8.maven.core.config.ResourceConfig;
import io.fabric8.maven.core.handler.DeploymentHandler;
import io.fabric8.maven.core.handler.HandlerHub;
import io.fabric8.maven.core.handler.StatefulSetHandler;
import io.fabric8.maven.core.util.Configs;
import io.fabric8.maven.core.util.MavenUtil;
import io.fabric8.maven.core.util.kubernetes.KubernetesResourceUtil;
import io.fabric8.maven.docker.config.ImageConfiguration;
import io.fabric8.maven.enricher.api.BaseEnricher;
import io.fabric8.maven.enricher.api.MavenEnricherContext;

import java.util.Collections;
import java.util.List;

public class ControllerViaPluginConfigurationEnricher extends BaseEnricher {
protected static final String[] POD_CONTROLLER_KINDS =
{ "ReplicationController", "ReplicaSet", "Deployment", "DeploymentConfig", "StatefulSet", "DaemonSet", "Job" };

private final DeploymentHandler deployHandler;
private final StatefulSetHandler statefulSetHandler;

// Available configuration keys
private enum Config implements Configs.Key {
name,
pullPolicy {{ d = "IfNotPresent"; }},
type {{ d = "deployment"; }},
replicaCount {{ d = "1"; }};

public String def() { return d; } protected String d;
}

public ControllerViaPluginConfigurationEnricher(MavenEnricherContext context) {
super(context, "fmp-controller-from-configuration");
HandlerHub handlers = new HandlerHub(
getContext().getGav(), getContext().getConfiguration().getProperties());
deployHandler = handlers.getDeploymentHandler();
statefulSetHandler = handlers.getStatefulSetHandler();
}

@Override
public void addMissingResources(KubernetesListBuilder builder) {
final String name = getConfig(Config.name, MavenUtil.createDefaultResourceName(getContext().getGav().getSanitizedArtifactId()));
final ResourceConfig config = new ResourceConfig.Builder()
.controllerName(name)
.imagePullPolicy(getConfig(Config.pullPolicy))
.withReplicas(Configs.asInt(getConfig(Config.replicaCount)))
.build();

final List<ImageConfiguration> images = getImages().orElse(Collections.emptyList());

// Check if at least a replica set is added. If not add a default one
if (KubernetesResourceUtil.checkForKind(builder, POD_CONTROLLER_KINDS)) {
// At least one image must be present, otherwise the resulting config will be invalid
if (KubernetesResourceUtil.checkForKind(builder, "StatefulSet")) {
final StatefulSetSpec spec = statefulSetHandler.getStatefulSet(config, images).getSpec();
if (spec != null) {
builder.accept(new TypedVisitor<StatefulSetBuilder>() {
@Override
public void visit(StatefulSetBuilder statefulSetBuilder) {
statefulSetBuilder.editOrNewSpec().editOrNewTemplate().editOrNewSpec().endSpec().endTemplate().endSpec();
mergeStatefulSetSpec(statefulSetBuilder, spec);
}
});

if (spec.getTemplate() != null && spec.getTemplate().getSpec() != null) {
final PodSpec podSpec = spec.getTemplate().getSpec();
builder.accept(new TypedVisitor<PodSpecBuilder>() {
@Override
public void visit(PodSpecBuilder builder) {
KubernetesResourceUtil.mergePodSpec(builder, podSpec, name);
}
});
}
}
} else {
final DeploymentSpec spec = deployHandler.getDeployment(config, images).getSpec();
if (spec != null) {
builder.accept(new TypedVisitor<DeploymentBuilder>() {
@Override
public void visit(DeploymentBuilder deploymentBuilder) {
deploymentBuilder.editOrNewSpec().editOrNewTemplate().editOrNewSpec().endSpec().endTemplate().endSpec();
mergeDeploymentSpec(deploymentBuilder, spec);
}
});

if (spec.getTemplate() != null && spec.getTemplate().getSpec() != null) {
final PodSpec podSpec = spec.getTemplate().getSpec();
builder.accept(new TypedVisitor<PodSpecBuilder>() {
@Override
public void visit(PodSpecBuilder builder) {
KubernetesResourceUtil.mergePodSpec(builder, podSpec, name);
}
});
}
}
}
}
}

private void mergeDeploymentSpec(DeploymentBuilder builder, DeploymentSpec spec) {
DeploymentFluent.SpecNested<DeploymentBuilder> specBuilder = builder.editSpec();
KubernetesResourceUtil.mergeSimpleFields(specBuilder, spec);
specBuilder.endSpec();
}

private void mergeStatefulSetSpec(StatefulSetBuilder builder, StatefulSetSpec spec) {
StatefulSetFluent.SpecNested<StatefulSetBuilder> specBuilder = builder.editSpec();
KubernetesResourceUtil.mergeSimpleFields(specBuilder, spec);
specBuilder.endSpec();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -130,64 +130,9 @@ public void addMissingResources(KubernetesListBuilder builder) {
builder.addToJobItems(jobHandler.getJob(config, images));
}
}
} else if (KubernetesResourceUtil.checkForKind(builder, "StatefulSet")) {
final StatefulSetSpec spec = statefulSetHandler.getStatefulSet(config, images).getSpec();
if (spec != null) {
builder.accept(new TypedVisitor<StatefulSetBuilder>() {
@Override
public void visit(StatefulSetBuilder statefulSetBuilder) {
statefulSetBuilder.editOrNewSpec().editOrNewTemplate().editOrNewSpec().endSpec().endTemplate().endSpec();
mergeStatefulSetSpec(statefulSetBuilder, spec);
}
});

if (spec.getTemplate() != null && spec.getTemplate().getSpec() != null) {
final PodSpec podSpec = spec.getTemplate().getSpec();
builder.accept(new TypedVisitor<PodSpecBuilder>() {
@Override
public void visit(PodSpecBuilder builder) {
KubernetesResourceUtil.mergePodSpec(builder, podSpec, name);
}
});
}
}
} else {
final DeploymentSpec spec = deployHandler.getDeployment(config, images).getSpec();
if (spec != null) {
builder.accept(new TypedVisitor<DeploymentBuilder>() {
@Override
public void visit(DeploymentBuilder deploymentBuilder) {
deploymentBuilder.editOrNewSpec().editOrNewTemplate().editOrNewSpec().endSpec().endTemplate().endSpec();
mergeDeploymentSpec(deploymentBuilder, spec);
}
});

if (spec.getTemplate() != null && spec.getTemplate().getSpec() != null) {
final PodSpec podSpec = spec.getTemplate().getSpec();
builder.accept(new TypedVisitor<PodSpecBuilder>() {
@Override
public void visit(PodSpecBuilder builder) {
KubernetesResourceUtil.mergePodSpec(builder, podSpec, name);
}
});
}
}
}
}

private void mergeDeploymentSpec(DeploymentBuilder builder, DeploymentSpec spec) {
DeploymentFluent.SpecNested<DeploymentBuilder> specBuilder = builder.editSpec();
KubernetesResourceUtil.mergeSimpleFields(specBuilder, spec);
specBuilder.endSpec();
}

private void mergeStatefulSetSpec(StatefulSetBuilder builder, StatefulSetSpec spec) {
StatefulSetFluent.SpecNested<StatefulSetBuilder> specBuilder = builder.editSpec();
KubernetesResourceUtil.mergeSimpleFields(specBuilder, spec);
specBuilder.endSpec();
}


static {
KubernetesResourceUtil.SIMPLE_FIELD_TYPES.add(String.class);
KubernetesResourceUtil.SIMPLE_FIELD_TYPES.add(Double.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,6 @@ io.fabric8.maven.enricher.standard.openshift.RouteEnricher

# Add an "expose" label to every service (TODO: Combine this with a Route/Ingress enricher)
io.fabric8.maven.enricher.standard.openshift.ExposeEnricher

# Enhance a given controller with the configuration information presented in the plugin configuration.
io.fabric8.maven.enricher.standard.ControllerViaPluginConfigurationEnricher
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
includes:
- fmp-name
- fmp-controller
- fmp-controller-from-configuration
- fmp-service
- fmp-image
- fmp-portname
Expand Down

0 comments on commit fe2247f

Please sign in to comment.