Skip to content

Commit

Permalink
Fix eclipse-jkube#184: IngressEnricher seems to be broken
Browse files Browse the repository at this point in the history
  • Loading branch information
rohanKanojia committed Jun 4, 2020
1 parent 3f5c783 commit 19c800c
Show file tree
Hide file tree
Showing 22 changed files with 583 additions and 404 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Usage:
### 1.0.0-SNAPSHOT
* Fix #173: Use OpenShift compliant git/vcs annotations
* Fix #182: Assembly is never null
* Fix #184: IngressEnricher seems to be broken, Port of fabric8io/fabric8-maven-plugin#1730
* Fix #198: Wildfly works in OpenShift with S2I binary build (Docker)
* Fix #199: BaseGenerator retrieves runtime mode from context (not from missing properties)
* Fix #201: Webapp-Wildfly supports S2I source builds too (3 modes Docker, OpenShift-Docker, OpenShift-S2I)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ public class ResourceConfig {
@Singular
private List<IngressRule> ingressRules;
private OpenshiftBuildConfig openshiftBuildConfig;
private String routeDomain;

public static ResourceConfigBuilder toBuilder(ResourceConfig original) {
return Optional.ofNullable(original).orElse(new ResourceConfig()).toBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public class BaseEnricher implements Enricher {
public static final String ENRICH_ALL_WITH_IMAGE_TRIGGERS = "jkube.openshift.enrichAllWithImageChangeTrigger";
public static final String OPENSHIFT_DEPLOY_TIMEOUT_SECONDS = "jkube.openshift.deployTimeoutSeconds";
private static final String SWITCH_TO_DEPLOYMENT = "jkube.build.switchToDeployment";
public static final String CREATE_EXTERNAL_URLS = "jkube.createExternalUrls";
public static final String JKUBE_DOMAIN = "jkube.domain";
protected static final String GENERATE_ROUTE = "jkube.openshift.generateRoute";

protected KitLogger log;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@
public class Constants {
public static final String RESOURCE_SOURCE_URL_ANNOTATION = "maven.jkube.io/source-url";
public static final String RESOURCE_APP_CATALOG_ANNOTATION = "maven.jkube.io/app-catalog";
public static final String EXPOSE_LABEL = "expose";
}

Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,16 @@
import org.eclipse.jkube.kit.common.util.ResourceUtil;
import org.eclipse.jkube.kit.config.image.ImageName;
import org.eclipse.jkube.kit.config.resource.GroupArtifactVersion;
import org.eclipse.jkube.kit.config.resource.JKubeAnnotations;
import org.eclipse.jkube.kit.config.resource.PlatformMode;
import org.eclipse.jkube.kit.config.resource.ResourceVersioning;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.eclipse.jkube.kit.enricher.api.util.Constants.EXPOSE_LABEL;

/**
* Utility class for handling Kubernetes resource descriptors
*
Expand Down Expand Up @@ -881,6 +884,34 @@ public static HasMetadata mergeResources(HasMetadata item1, HasMetadata item2, K
return item1;
}

public static boolean isExposedService(ObjectMeta metadata, KitLogger log) {
if (metadata != null && metadata.getLabels() != null) {
Map<String, String> labels = metadata.getLabels();
return "true".equals(labels.get(EXPOSE_LABEL)) || "true".equals(labels.get(JKubeAnnotations.SERVICE_EXPOSE_URL.value()));
} else {
log.info("No Metadata for service! " + (metadata != null ? metadata.getName() : null));
}
return false;
}

public static ObjectMeta removeExposeLabel(ObjectMeta metadata) {
Map<String, String> labels;
if (metadata != null) {
labels = metadata.getLabels();
if (labels != null) {
if ("true".equals(labels.get(EXPOSE_LABEL))) {
labels.remove(EXPOSE_LABEL);
}
if("true".equals(labels.get(JKubeAnnotations.SERVICE_EXPOSE_URL.value()))) {
labels.remove(JKubeAnnotations.SERVICE_EXPOSE_URL.value());
}
}
}
return metadata;
}



protected static HasMetadata mergeConfigMaps(ConfigMap cm1, ConfigMap cm2, KitLogger log, boolean switchOnLocalCustomisation) {
ConfigMap cm1OrCopy = cm1;
if (!switchOnLocalCustomisation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,18 +127,22 @@ public void visit(ObjectMetaBuilder metaBuilder) {
});

// Removing namespace annotation from the namespace and project objects being generated.
// to avoid unncessary trouble while applying these resources.
// to avoid unnecessary trouble while applying these resources.
builder.accept(new TypedVisitor<NamespaceBuilder>() {
@Override
public void visit(NamespaceBuilder builder) {
builder.withNewStatus().withPhase("Active").endStatus().editMetadata().withNamespace(null).endMetadata().build();
if (builder.buildStatus().getPhase().equals("active")) {
builder.editOrNewStatus().endStatus().build();
}
}
});

builder.accept(new TypedVisitor<ProjectBuilder>() {
@Override
public void visit(ProjectBuilder builder) {
builder.withNewStatus().withPhase("Active").endStatus().editMetadata().withNamespace(null).endMetadata().build();
if (builder.buildStatus().getPhase().equals("active")) {
builder.editOrNewStatus().endStatus().build();
}
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,30 @@
import io.fabric8.kubernetes.api.builder.TypedVisitor;
import io.fabric8.kubernetes.api.model.KubernetesListBuilder;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.api.model.ServiceBuilder;
import io.fabric8.kubernetes.api.model.ServicePort;
import io.fabric8.kubernetes.api.model.ServiceSpec;
import io.fabric8.kubernetes.api.model.extensions.HTTPIngressPathBuilder;
import io.fabric8.kubernetes.api.model.extensions.Ingress;
import io.fabric8.kubernetes.api.model.extensions.IngressBackendBuilder;
import io.fabric8.kubernetes.api.model.extensions.IngressBuilder;
import io.fabric8.kubernetes.api.model.extensions.IngressSpecBuilder;
import org.eclipse.jkube.kit.config.resource.JKubeAnnotations;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jkube.kit.common.KitLogger;
import org.eclipse.jkube.kit.common.util.FileUtil;
import org.eclipse.jkube.kit.common.util.KubernetesHelper;
import org.eclipse.jkube.kit.config.resource.PlatformMode;
import org.eclipse.jkube.kit.config.resource.ResourceConfig;
import org.eclipse.jkube.kit.enricher.api.BaseEnricher;
import org.eclipse.jkube.kit.enricher.api.JKubeEnricherContext;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;

import static org.eclipse.jkube.kit.enricher.api.util.KubernetesResourceUtil.isExposedService;
import static org.eclipse.jkube.kit.enricher.api.util.KubernetesResourceUtil.removeExposeLabel;

/**
* Enricher which generates an Ingress for each exposed Service
*/
Expand All @@ -44,49 +51,73 @@ public IngressEnricher(JKubeEnricherContext buildContext) {

@Override
public void create(PlatformMode platformMode, final KubernetesListBuilder listBuilder) {
ResourceConfig resourceConfig = getConfiguration().getResource();
Boolean shouldCreateIngress = getValueFromConfig(CREATE_EXTERNAL_URLS, false);
if (shouldCreateIngress.equals(Boolean.FALSE)) {
return;
}

if (platformMode == PlatformMode.kubernetes) {
listBuilder.accept(new TypedVisitor<ServiceBuilder>() {
@Override
public void visit(ServiceBuilder serviceBuilder) {
addIngress(listBuilder, serviceBuilder);
Ingress ingress = addIngress(listBuilder, serviceBuilder, getRouteDomain(resourceConfig), log);
if (ingress != null) {
listBuilder.addToItems(ingress);
}
}
});

}
}

private void addIngress(KubernetesListBuilder listBuilder, ServiceBuilder serviceBuilder) {
ObjectMeta metadata = serviceBuilder.getMetadata();
if (metadata != null && isExposedService(serviceBuilder)) {
String name = metadata.getName();
if (!hasIngress(listBuilder, name)) {
protected static Ingress addIngress(KubernetesListBuilder listBuilder, ServiceBuilder serviceBuilder, String routeDomainPostfix, KitLogger log) {
ObjectMeta serviceMetadata = serviceBuilder.buildMetadata();
if (serviceMetadata != null && isExposedService(serviceMetadata, log) && shouldCreateExternalURLForService(serviceBuilder, log)) {
String serviceName = serviceMetadata.getName();
if (!hasIngress(listBuilder, serviceName)) {
Integer servicePort = getServicePort(serviceBuilder);
if (servicePort != null) {
ResourceConfig resourceConfig = getConfiguration().getResource();

IngressBuilder ingressBuilder = new IngressBuilder().
withMetadata(serviceBuilder.getMetadata()).
withMetadata(serviceMetadata).
withNewSpec().

endSpec();
IngressSpecBuilder specBuilder = new IngressSpecBuilder().withBackend(new IngressBackendBuilder().
withNewServiceName(name).
withNewServicePort(getServicePort(serviceBuilder)).
build());

if (resourceConfig != null) {
specBuilder.addAllToRules(resourceConfig.getIngressRules());
// removing `expose : true` label from metadata.
ingressBuilder.withNewMetadataLike(removeExposeLabel(ingressBuilder.buildMetadata()));

if (StringUtils.isNotBlank(routeDomainPostfix)) {
routeDomainPostfix = serviceName + "." + FileUtil.stripPrefix(routeDomainPostfix, ".");
ingressBuilder = ingressBuilder.withSpec(new IngressSpecBuilder().addNewRule().
withHost(routeDomainPostfix).
withNewHttp().
withPaths(new HTTPIngressPathBuilder()
.withNewBackend()
.withServiceName(serviceName)
.withServicePort(KubernetesHelper.createIntOrString(getServicePort(serviceBuilder)))
.endBackend()
.build())
.endHttp().
endRule().build());
} else {
ingressBuilder.withSpec(new IngressSpecBuilder().withBackend(new IngressBackendBuilder().
withNewServiceName(serviceName)
.withNewServicePort(getServicePort(serviceBuilder))
.build()).build());
}

return ingressBuilder.build();
}
}
}
return null;
}

private Integer getServicePort(ServiceBuilder serviceBuilder) {
ServiceSpec spec = serviceBuilder.getSpec();
private static Integer getServicePort(ServiceBuilder serviceBuilder) {
ServiceSpec spec = serviceBuilder.buildSpec();
if (spec != null) {
List<ServicePort> ports = spec.getPorts();
if (ports != null && ports.size() > 0) {
if (ports != null && !ports.isEmpty()) {
for (ServicePort port : ports) {
if (port.getName().equals("http") || port.getProtocol().equals("http")) {
return port.getPort();
Expand All @@ -98,19 +129,19 @@ private Integer getServicePort(ServiceBuilder serviceBuilder) {
}
}
}
return null;
return 0;
}

/**
* Returns true if we already have a route created for the given name
*/
private boolean hasIngress(final KubernetesListBuilder listBuilder, final String name) {
private static boolean hasIngress(final KubernetesListBuilder listBuilder, final String name) {
final AtomicBoolean answer = new AtomicBoolean(false);
listBuilder.accept(new TypedVisitor<IngressBuilder>() {

@Override
public void visit(IngressBuilder builder) {
ObjectMeta metadata = builder.getMetadata();
ObjectMeta metadata = builder.buildMetadata();
if (metadata != null && name.equals(metadata.getName())) {
answer.set(true);
}
Expand All @@ -119,23 +150,44 @@ public void visit(IngressBuilder builder) {
return answer.get();
}

private boolean isExposedService(ServiceBuilder serviceBuilder) {
Service service = serviceBuilder.build();
return isExposedService(service);
}

private boolean isExposedService(Service service) {
ObjectMeta metadata = service.getMetadata();
if (metadata != null) {
Map<String, String> labels = metadata.getLabels();
if (labels != null) {
if ("true".equals(labels.get("expose")) || "true".equals(labels.get(JKubeAnnotations.SERVICE_EXPOSE_URL.value()))) {
/**
* Should we try to create an external URL for the given service?
* <p>
* By default lets ignore the kubernetes services and any service which does not expose ports 80 and 443
*
* @return true if we should create an Ingress for this service.
*/
private static boolean shouldCreateExternalURLForService(ServiceBuilder service, KitLogger log) {
String serviceName = service.buildMetadata().getName();
ServiceSpec spec = service.buildSpec();
if (spec != null && !isKuberentesSystemService(serviceName)) {
List<ServicePort> ports = spec.getPorts();
log.debug("Service " + serviceName + " has ports: " + ports);
if (ports.size() == 1) {
String type = spec.getType();
if (Objects.equals(type, "LoadBalancer")) {
return true;
}
log.info("Not generating Ingress for service " + serviceName + " type is not LoadBalancer: " + type);
} else {
log.info("Not generating Ingress for service " + serviceName + " as only single port services are supported. Has ports: " + ports);
}
} else {
log.info("No Metadata for service! " + service);
}
return false;
}

private static boolean isKuberentesSystemService(String serviceName) {
return "kubernetes".equals(serviceName) || "kubernetes-ro".equals(serviceName);
}

private String getRouteDomain(ResourceConfig resourceConfig) {
if (resourceConfig != null && resourceConfig.getRouteDomain() != null) {
return resourceConfig.getRouteDomain();
}
String routeDomainFromProperties = getValueFromConfig(JKUBE_DOMAIN, "");
if (StringUtils.isNotEmpty(routeDomainFromProperties)) {
return routeDomainFromProperties;
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import java.util.Map;
import java.util.Set;

import static org.eclipse.jkube.kit.enricher.api.util.Constants.EXPOSE_LABEL;

/**
* Enricher for enabling exposing of HTTP / HTTPS based services
*/
Expand All @@ -41,8 +43,6 @@ public ExposeEnricher(JKubeEnricherContext buildContext) {

private Set<Integer> webPorts = new HashSet<>(Arrays.asList(80, 443, 8080, 9080, 9090, 9443));

public static final String EXPOSE_LABEL = "expose";

@Override
public void create(PlatformMode platformMode, KubernetesListBuilder builder) {
List<HasMetadata> items = builder.getItems();
Expand Down
Loading

0 comments on commit 19c800c

Please sign in to comment.