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

Ingress and Route generation refactor. #1730

Merged
merged 2 commits into from
Jan 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ public class ResourceConfig {
@Parameter
private List<ServiceAccountConfig> serviceAccounts;

private List<IngressRule> ingressRules;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this wrongfully in my previous PR here: dc5b213#diff-9238e96d57160d3b61190b609607b2d8R95

hence, removing it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove import above too

/**
* Host/domain for Route/Ingress.
*/
private String routeDomain;

public Optional<Map<String, String>> getEnv() {
return Optional.ofNullable(env);
Expand Down Expand Up @@ -167,9 +170,11 @@ public ConfigMap getConfigMap() {
public List<String> getRemotes() {
return remotes;
}

public List<String> getCrdContexts() { return customResourceDefinitions; }

public List<IngressRule> getIngressRules() { return ingressRules; }
public String getRouteDomain() { return routeDomain; }

// =============================================================================================

public static class Builder {
Expand Down Expand Up @@ -197,7 +202,7 @@ public Builder(ResourceConfig config) {
this.config.metrics = config.getMetrics();
this.config.namespace = config.getNamespace();
this.config.remotes = config.getRemotes();
this.config.ingressRules = config.getIngressRules();
this.config.routeDomain= config.getRouteDomain();
}
}

Expand Down Expand Up @@ -256,11 +261,6 @@ public Builder withRemotes(List<String> remotes) {
return this;
}

public Builder withIngressRules(List<IngressRule> ingressRules) {
config.ingressRules = ingressRules;
return this;
}

public Builder withNamespace(String s) {
config.namespace = s;
return this;
Expand All @@ -271,6 +271,11 @@ public Builder withCustomResourceDefinitions(List<String> customResourceDefiniti
return this;
}

public Builder withRouteDomain(String routeDomain) {
config.routeDomain = routeDomain;
return this;
}

public ResourceConfig build() {
return config;
}
Expand Down Expand Up @@ -302,4 +307,4 @@ public ResourceConfig build() {
// fabric8.namespaceEnvVar

// fabric8.provider
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@
- fmp-image
- fmp-project-label
- fmp-debug
- fmp-namespace
- fmp-metadata
- fmp-controller-from-configuration
- fmp-openshift-deploymentconfig
- fmp-openshift-project
- fmp-openshift-service-expose
- fmp-openshift-route
- fmp-ingress
- fmp-namespace
1 change: 1 addition & 0 deletions doc/src/main/asciidoc/inc/_profiles.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ A profile can also extend another profile to avoid repetition e.g of generators
- fmp-openshift-project
- fmp-openshift-service-expose
- fmp-openshift-route
- fmp-ingress

----
one then would not need to repeat all generators as they are inherited from the `default` profile.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import io.fabric8.maven.enricher.api.MavenEnricherContext;
import io.fabric8.openshift.api.model.Project;
import io.fabric8.openshift.api.model.ProjectBuilder;
import io.fabric8.openshift.api.model.ProjectStatus;

import java.util.Arrays;

Expand Down Expand Up @@ -132,14 +133,18 @@ public void visit(ObjectMetaBuilder metaBuilder) {
builder.accept(new TypedVisitor<NamespaceBuilder>() {
@Override
public void visit(NamespaceBuilder builder) {
builder.withNewStatus("active").editMetadata().withNamespace(null).endMetadata().build();
if (builder.getStatus().equals("active")) {
builder.editOrNewStatus().endStatus().build();
}
}
});

builder.accept(new TypedVisitor<ProjectBuilder>() {
@Override
public void visit(ProjectBuilder builder) {
builder.withNewStatus("active").editMetadata().withNamespace(null).endMetadata().build();
if (builder.getStatus().equals(new ProjectStatus("active"))) {
builder.editOrNewStatus().endStatus().build();
}
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,24 @@
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.Ingress;
import io.fabric8.kubernetes.api.model.extensions.HTTPIngressPath;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I thought intellij does that automatically. need to check my ide configuration

import io.fabric8.kubernetes.api.model.extensions.HTTPIngressPathBuilder;
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 io.fabric8.maven.core.config.PlatformMode;
import io.fabric8.maven.core.config.ResourceConfig;
import io.fabric8.maven.core.util.FileUtil;
import io.fabric8.maven.core.util.kubernetes.Fabric8Annotations;
import io.fabric8.maven.core.util.kubernetes.KubernetesHelper;
import io.fabric8.maven.enricher.api.BaseEnricher;
import io.fabric8.maven.enricher.api.MavenEnricherContext;
import org.apache.commons.lang3.StringUtils;

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

/**
Expand All @@ -48,42 +53,63 @@ public IngressEnricher(MavenEnricherContext buildContext) {
super(buildContext, "fmp-ingress");
}

private String routeDomainPostfix;

@Override
public void create(PlatformMode platformMode, final KubernetesListBuilder listBuilder) {
ResourceConfig resourceConfig = getConfiguration().getResource().orElse(null);
manusa marked this conversation as resolved.
Show resolved Hide resolved

if (resourceConfig != null && resourceConfig.getRouteDomain() != null) {
routeDomainPostfix = resourceConfig.getRouteDomain();
}

if (platformMode == PlatformMode.kubernetes) {
final List<Ingress> ingresses = new ArrayList<>();
listBuilder.accept(new TypedVisitor<ServiceBuilder>() {
@Override
public void visit(ServiceBuilder serviceBuilder) {
addIngress(listBuilder, serviceBuilder);
}
});

}
}

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

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.getMetadata()));

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());
}

listBuilder.addToIngressItems(ingressBuilder.build());
}
}
}
Expand Down Expand Up @@ -126,13 +152,23 @@ public void visit(IngressBuilder builder) {
return answer.get();
}

private boolean isExposedService(ServiceBuilder serviceBuilder) {
Service service = serviceBuilder.build();
return isExposedService(service);
private ObjectMeta removeExposeLabel(ObjectMeta metadata) {
Map<String, String> labels = null;
if (metadata != null) {
labels = metadata.getLabels();
if (labels != null) {
if ("true".equals(labels.get("expose"))) {
labels.remove("expose");
}
if("true".equals(labels.get(Fabric8Annotations.SERVICE_EXPOSE_URL.value()))) {
labels.remove(Fabric8Annotations.SERVICE_EXPOSE_URL.value());
}
}
}
return metadata;
}

private boolean isExposedService(Service service) {
ObjectMeta metadata = service.getMetadata();
private boolean isExposedService(ObjectMeta metadata) {
if (metadata != null) {
Map<String, String> labels = metadata.getLabels();
if (labels != null) {
Expand All @@ -141,8 +177,39 @@ private boolean isExposedService(Service service) {
}
}
} else {
log.info("No Metadata for service! " + service);
log.info("No Metadata for service! " + metadata.getName());
}
return false;
}

/**
* Should we try to create an external URL for the given service?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either complete this javadoc or remove it.

* <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 boolean shouldCreateExternalURLForService(ServiceBuilder service) {
String serviceName = service.getMetadata().getName();
if ("kubernetes".equals(serviceName) || "kubernetes-ro".equals(serviceName)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we comparing Service names here like this? Do we even generate kubernetes service while resource processing? What's with this kubernetes-ro service?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these are the prefixes for the potential services generated by kubernetes system itself. I took it from the apply mojo.

return false;
}
ServiceSpec spec = service.getSpec();
List<ServicePort> ports = spec.getPorts();
log.debug("Service " + serviceName + " has ports: " + ports);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is dumping whole object into log statement fine?

[DEBUG] F8: fmp-ingress: Service fabric8-maven-sample-spring-boot has ports: [ServicePort(name=http, nodePort=null, port=8080, protocol=TCP, targetPort=IntOrString(IntVal=8080, Kind=0, StrVal=null, additionalProperties={}), additionalProperties={})]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought its appropriate for log.debug.

if (ports.size() == 1) {
String type = null;
if (spec != null) {
type = spec.getType();
if (Objects.equals(type, "LoadBalancer")) {
return true;
}
}
log.info("Not generating Ingress for service " + serviceName + " type is not LoadBalancer: " + type);
return false;
} else {
log.info("Not generating Ingress for service " + serviceName + " as only single port services are supported. Has ports: " + ports);
return false;
}
}
}
Loading