Skip to content

Commit

Permalink
Split the route decorator to allow custom resources
Browse files Browse the repository at this point in the history
  • Loading branch information
Sgitario committed Dec 16, 2022
1 parent 5d4b6ed commit 49f4eb4
Show file tree
Hide file tree
Showing 13 changed files with 419 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* Copyright 2018 The original authors.
*
* Licensed 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.dekorate.openshift.decorator;

import static io.dekorate.openshift.decorator.AddRouteDecorator.KIND_ROUTE;

import java.util.Arrays;
import java.util.List;

import io.dekorate.ConfigReference;
import io.dekorate.WithConfigReferences;
import io.dekorate.doc.Description;
import io.dekorate.kubernetes.decorator.Decorator;
import io.dekorate.kubernetes.decorator.NamedResourceDecorator;
import io.dekorate.openshift.config.OpenshiftConfig;
import io.dekorate.utils.Strings;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.openshift.api.model.RouteSpecFluent;

@Description("Add the host to the Route resource.")
public class AddHostToRouteDecorator extends NamedResourceDecorator<RouteSpecFluent<?>> implements WithConfigReferences {

private final OpenshiftConfig config;

public AddHostToRouteDecorator(OpenshiftConfig config) {
super(KIND_ROUTE, config.getName());
this.config = config;
}

@Override
public void andThenVisit(RouteSpecFluent<?> spec, ObjectMeta resourceMeta) {
if (!spec.hasHost() && config.getRoute() != null && Strings.isNotNullOrEmpty(config.getRoute().getHost())) {
spec.withHost(config.getRoute().getHost());
}
}

@Override
public Class<? extends Decorator>[] after() {
return new Class[] { AddRouteDecorator.class };
}

@Override
public List<ConfigReference> getConfigReferences() {
return Arrays.asList(buildConfigReferenceHost());
}

private ConfigReference buildConfigReferenceHost() {
String property = "host";
String path = "(kind == Route && metadata.name == " + getName() + ").spec.host";
return new ConfigReference(property, path);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* Copyright 2018 The original authors.
*
* Licensed 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.dekorate.openshift.decorator;

import static io.dekorate.utils.Ports.getHttpPort;
import static io.dekorate.utils.Ports.getPortByFilter;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

import io.dekorate.ConfigReference;
import io.dekorate.WithConfigReferences;
import io.dekorate.doc.Description;
import io.dekorate.kubernetes.config.Port;
import io.dekorate.kubernetes.decorator.Decorator;
import io.dekorate.kubernetes.decorator.NamedResourceDecorator;
import io.dekorate.openshift.config.OpenshiftConfig;
import io.dekorate.utils.Strings;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.openshift.api.model.RouteSpecFluent;

@Description("Add the port to the Route resource.")
public class AddPortToRouteDecorator extends NamedResourceDecorator<RouteSpecFluent<?>> implements WithConfigReferences {

private final OpenshiftConfig config;

public AddPortToRouteDecorator(OpenshiftConfig config) {
this.config = config;
}

@Override
public void andThenVisit(RouteSpecFluent<?> spec, ObjectMeta resourceMeta) {
Optional<Port> port = getNamedHttpPort(config);
if (!port.isPresent()) {
return;
}

if (!spec.hasPath()) {
spec.withPath(port.get().getPath());
}

if (!spec.hasPort()) {
spec.editOrNewPort()
.withNewTargetPort(port.get().getName())
.endPort();
}
}

private Optional<Port> getNamedHttpPort(OpenshiftConfig config) {
String namedPortName = config.getRoute().getTargetPort();
if (Strings.isNotNullOrEmpty(namedPortName)) {
Optional<Port> port = getPortByFilter(p -> Strings.equals(p.getName(), namedPortName), config);
if (port.isPresent()) {
return port;
}

// Set the named port to the one provided by the user even though it was not found in the configured ports.
return Optional.of(Port.newBuilder().withName(namedPortName).build());
}

return getHttpPort(config);
}

@Override
public Class<? extends Decorator>[] after() {
return new Class[] { AddRouteDecorator.class };
}

@Override
public List<ConfigReference> getConfigReferences() {
return Arrays.asList(buildConfigReferencePath());
}

private ConfigReference buildConfigReferencePath() {
String property = "path";
String path = "(kind == Route && metadata.name == " + getName() + ").spec.path";
return new ConfigReference(property, path);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,20 @@

package io.dekorate.openshift.decorator;

import static io.dekorate.utils.Ports.getHttpPort;
import static io.dekorate.utils.Ports.getPortByFilter;

import java.util.Optional;

import io.dekorate.doc.Description;
import io.dekorate.kubernetes.config.Port;
import io.dekorate.kubernetes.decorator.AddServiceResourceDecorator;
import io.dekorate.kubernetes.decorator.Decorator;
import io.dekorate.kubernetes.decorator.ResourceProvidingDecorator;
import io.dekorate.openshift.config.OpenshiftConfig;
import io.dekorate.utils.Labels;
import io.dekorate.utils.Strings;
import io.fabric8.kubernetes.api.model.KubernetesListBuilder;
import io.fabric8.openshift.api.model.RouteBuilder;

@Description("Add a route to the list.")
public class AddRouteDecorator extends ResourceProvidingDecorator<KubernetesListBuilder> {

public static final String KIND_ROUTE = "Route";

private final OpenshiftConfig config;

public AddRouteDecorator(OpenshiftConfig config) {
Expand All @@ -46,49 +41,20 @@ public void visit(KubernetesListBuilder list) {
return;
}

Optional<Port> port = getNamedHttpPort(config);
if (!port.isPresent()) {
return;
}

if (contains(list, "route.openshift.io/v1", "Route", config.getName())) {
if (contains(list, "route.openshift.io/v1", KIND_ROUTE, config.getName())) {
return;
}

list.addToItems(new RouteBuilder()
.withNewMetadata()
.withName(config.getName())
.withLabels(Labels.createLabelsAsMap(config, "Route"))
.withLabels(Labels.createLabelsAsMap(config, KIND_ROUTE))
.endMetadata()
.withNewSpec()
.withHost(config.getRoute().getHost())
.withPath(port.get().getPath())
.withNewTo()
.withKind("Service")
.withName(config.getName())
.endTo()
.withNewPort()
.withNewTargetPort(port.get().getName())
.endPort()
.endSpec()
.build());
}

private Optional<Port> getNamedHttpPort(OpenshiftConfig config) {
String namedPortName = config.getRoute().getTargetPort();
if (Strings.isNotNullOrEmpty(namedPortName)) {
Optional<Port> port = getPortByFilter(p -> Strings.equals(p.getName(), namedPortName), config);
if (port.isPresent()) {
return port;
}

// Set the named port to the one provided by the user even though it was not found in the configured ports.
return Optional.of(Port.newBuilder().withName(namedPortName).build());
}

return getHttpPort(config);
}

@Override
public Class<? extends Decorator>[] after() {
return new Class[] { AddServiceResourceDecorator.class };
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* Copyright 2018 The original authors.
*
* Licensed 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.dekorate.openshift.decorator;

import static io.dekorate.openshift.decorator.AddRouteDecorator.KIND_ROUTE;

import io.dekorate.doc.Description;
import io.dekorate.kubernetes.decorator.Decorator;
import io.dekorate.kubernetes.decorator.NamedResourceDecorator;
import io.dekorate.openshift.config.OpenshiftConfig;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.openshift.api.model.RouteSpecFluent;

@Description("Add the service to the Route resource.")
public class AddServiceToRouteDecorator extends NamedResourceDecorator<RouteSpecFluent<?>> {

private final OpenshiftConfig config;

public AddServiceToRouteDecorator(OpenshiftConfig config) {
super(KIND_ROUTE, config.getName());
this.config = config;
}

@Override
public void andThenVisit(RouteSpecFluent<?> spec, ObjectMeta resourceMeta) {
if (!spec.hasTo()) {
spec.withNewTo()
.withKind("Service")
.withName(config.getName())
.endTo();
}
}

@Override
public Class<? extends Decorator>[] after() {
return new Class[] { AddRouteDecorator.class };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@
import io.dekorate.openshift.config.EditableOpenshiftConfig;
import io.dekorate.openshift.config.OpenshiftConfig;
import io.dekorate.openshift.config.OpenshiftConfigBuilder;
import io.dekorate.openshift.decorator.AddHostToRouteDecorator;
import io.dekorate.openshift.decorator.AddPortToRouteDecorator;
import io.dekorate.openshift.decorator.AddRouteDecorator;
import io.dekorate.openshift.decorator.AddServiceToRouteDecorator;
import io.dekorate.openshift.decorator.ApplyDeploymentTriggerDecorator;
import io.dekorate.openshift.decorator.ApplyReplicasToDeploymentConfigDecorator;
import io.dekorate.option.config.VcsConfig;
Expand Down Expand Up @@ -122,6 +125,9 @@ protected void addDecorators(String group, OpenshiftConfig config) {
resourceRegistry.decorate(group,
new ApplyDeploymentTriggerDecorator(config.getName(), imageConfig.getName() + ":" + imageConfig.getVersion()));
resourceRegistry.decorate(group, new AddRouteDecorator(config));
resourceRegistry.decorate(group, new AddHostToRouteDecorator(config));
resourceRegistry.decorate(group, new AddPortToRouteDecorator(config));
resourceRegistry.decorate(group, new AddServiceToRouteDecorator(config));

if (config.hasAttribute(RUNTIME_TYPE)) {
resourceRegistry.decorate(group, new AddLabelDecorator(config.getName(),
Expand Down
3 changes: 2 additions & 1 deletion docs/documentation/helm.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ By default, Dekorate will generate the Helm values file (`values.yaml`) by mappi
- The Kubernetes/OpenShift health checks for Readiness, Liveness and Startup probes
- The Kubernetes/OpenShift service type
- The Kubernetes ingress host
- The Openshift S2i builder image
- The OpenShift S2i builder image
- The OpenShift route host/path

For example, if you set 3 replicas for your deployment:

Expand Down
72 changes: 72 additions & 0 deletions tests/issue-existing-route-resource/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<artifactId>dekorate-tests</artifactId>
<groupId>io.dekorate</groupId>
<version>3.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>

<groupId>io.dekorate</groupId>
<artifactId>issue-existitng-route-resource</artifactId>
<name>Dekorate :: Tests :: Annotations :: Existing route resources</name>

<dependencies>
<dependency>
<groupId>io.dekorate</groupId>
<artifactId>openshift-annotations</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.dekorate</groupId>
<artifactId>dekorate-spring-boot</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${version.spring-boot}</version>
</dependency>

<!-- Testing -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${version.junit-jupiter}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${version.junit-jupiter}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${version.spring-boot}</version>
</plugin>
</plugins>
</build>
</project>
Loading

0 comments on commit 49f4eb4

Please sign in to comment.