Skip to content

Commit

Permalink
Kubernetes HostAliases property
Browse files Browse the repository at this point in the history
Allow the generation of hostAliases property from Deployment

Signed-off-by: Vincent Sourtin <[email protected]>
  • Loading branch information
Vinche59 authored and iocanel committed Sep 18, 2020
1 parent 2f56d63 commit cfecb0c
Show file tree
Hide file tree
Showing 11 changed files with 374 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,11 @@
* The image pull secret
*/
String[] imagePullSecrets() default {};

/**
* The hostAliases
*/
HostAlias[] hostAliases() default {};

/**
* The liveness probe.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import io.dekorate.kubernetes.config.Container;
import io.dekorate.kubernetes.config.Env;
import io.dekorate.kubernetes.config.BaseConfig;
import io.dekorate.kubernetes.config.HostAlias;
import io.dekorate.kubernetes.config.Label;
import io.dekorate.kubernetes.config.Mount;
import io.dekorate.kubernetes.config.PersistentVolumeClaimVolume;
Expand All @@ -40,6 +41,7 @@
import io.dekorate.kubernetes.decorator.AddCommitIdAnnotationDecorator;
import io.dekorate.kubernetes.decorator.AddConfigMapVolumeDecorator;
import io.dekorate.kubernetes.decorator.AddEnvVarDecorator;
import io.dekorate.kubernetes.decorator.AddHostAliasesDecorator;
import io.dekorate.kubernetes.decorator.AddImagePullSecretDecorator;
import io.dekorate.kubernetes.decorator.AddLabelDecorator;
import io.dekorate.kubernetes.decorator.AddLivenessProbeDecorator;
Expand Down Expand Up @@ -129,6 +131,10 @@ protected void addDecorators(String group, C config) {
resources.decorate(group, new AddImagePullSecretDecorator(config.getName(), imagePullSecret));
}

for (HostAlias hostAlias : config.getHostAliases()) {
resources.decorate(new AddHostAliasesDecorator(config.getName(), hostAlias));
}

for (Container container : config.getSidecars()) {
resources.decorate(group, new AddSidecarDecorator(config.getName(), container));
}
Expand Down Expand Up @@ -200,7 +206,7 @@ protected void addDecorators(String group, C config) {
if (Strings.isNotNullOrEmpty(config.getRequestResources() .getMemory())) {
resources.decorate(group, new ApplyRequestsMemoryDecorator(config.getName(), config.getName(), config.getRequestResources() .getMemory()));
}

}

private static void validateVolume(SecretVolume volume) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,13 @@
* The image pull secret
*/
String[] imagePullSecrets() default {};

/**
* Host aliases
*
* @return The host aliases
*/
HostAlias[] hostAliases() default {};

/**
* The liveness probe.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* 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.kubernetes.annotation;

public @interface HostAlias {

/**
* Ip address to resolve to.
* @return the ip address.
*/
String ip() default "";

/**
* List of hostnames (comma separated)
* @return the hostnames
*/
String hostnames() default "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* 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.kubernetes.decorator;

import io.dekorate.kubernetes.config.HostAlias;
import io.dekorate.utils.Strings;
import io.fabric8.kubernetes.api.builder.Predicate;
import io.fabric8.kubernetes.api.model.HostAliasBuilder;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.kubernetes.api.model.PodSpecFluent;

import java.util.Arrays;
import java.util.Objects;

public class AddHostAliasesDecorator extends NamedResourceDecorator<PodSpecFluent<?>> {

private final HostAlias hostAlias;

public AddHostAliasesDecorator(String deploymentName, HostAlias hostAlias) {
super(deploymentName);
this.hostAlias = hostAlias;
}

public void andThenVisit(PodSpecFluent<?> podSpec, ObjectMeta resourceMeta) {
if (Strings.isNotNullOrEmpty(hostAlias.getIp()) && Strings.isNotNullOrEmpty(hostAlias.getHostnames())) {
Predicate<HostAliasBuilder> matchingHostAlias = host -> {
if (host.getIp() != null)
return host.getIp().equals(hostAlias.getIp());
return false;
};

podSpec.removeMatchingFromHostAliases(matchingHostAlias);

podSpec.addNewHostAlias()
.withIp(hostAlias.getIp())
.withHostnames(Arrays.asList(hostAlias.getHostnames().split(",")))
.endHostAlias();
}
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AddHostAliasesDecorator that = (AddHostAliasesDecorator) o;
return Objects.equals(hostAlias, that.hostAlias);
}

@Override
public int hashCode() {
return Objects.hash(hostAlias);
}
}
4 changes: 4 additions & 0 deletions examples/kubernetes-example-with-hostaliases/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM openjdk:8u171-alpine3.7
RUN apk --no-cache add curl
COPY target/*.jar kubernetes-example-with-hostaliases.jar
CMD java ${JAVA_OPTS} -jar kubernetes-example-with-hostaliases.jar
78 changes: 78 additions & 0 deletions examples/kubernetes-example-with-hostaliases/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<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">
<parent>
<artifactId>examples</artifactId>
<groupId>io.dekorate</groupId>
<version>0.12-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<groupId>io.dekorate</groupId>
<artifactId>kubernetes-example-with-hostaliases</artifactId>
<name>Dekorate :: Examples :: Kubernetes with hostAliases</name>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>

<version.spring-boot>2.1.13.RELEASE</version.spring-boot>
</properties>

<dependencies>
<dependency>
<groupId>io.dekorate</groupId>
<artifactId>kubernetes-annotations</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>io.dekorate</groupId>
<artifactId>kubernetes-junit-starter</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${version.spring-boot}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>


</project>
60 changes: 60 additions & 0 deletions examples/kubernetes-example-with-hostaliases/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Add hostAliases property Example

An example that demonstrates the use of `@KubernetesApplication` in order to add hostAliases property to a deployment.
To access the `@KubernetesApplication` annotation you just need to have the following dependency in your
class path:

<dependency>
<groupId>io.dekorate</groupId>
<artifactId>kubernetes-annotations</artifactId>
<version>${project.version}</version>
</dependency>

So as to add the hostAliases section of the Deployment specification you need pass the `hostAliases` parameter containing the ip address and the list of hostnames (comma separated values) to the `@KubernetesApplication` in the Spring Boot annotated class. The code would look as follow:

```
@KubernetesApplication(hostAliases = {@HostAlias(ip = "127.0.0.1", hostnames = "foo.org,bar.com")})
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
```
You can pass multiple `@HostAlias` annotation depending of your needs.

Check, if necessary, the [Main.java](src/main/java/io/dekorate/examples/kubernetes/Main.java).

Compile the project using:

mvn clean install

You can find the generated deployment under: `target/classes/META-INF/dekorate/kubernetes.yml` that should look like:
```---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: kubernetes-example-with-hostaliases
app.kubernetes.io/version: 0.12-SNAPSHOT
name: kubernetes-example-with-hostaliases
spec:
replicas: 1
template:
metadata:
labels:
app.kubernetes.io/name: kubernetes-example-with-hostaliases
app.kubernetes.io/version: 0.12-SNAPSHOT
spec:
hostAliases:
- hostnames:
- foo.org
- bar.com
ip: 127.0.0.1
- hostnames:
- test.com
ip: 10.0.0.1
```


Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* 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.examples.kubernetes;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Controller {

@RequestMapping("/")
public String hello() {
return "Hello world";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* 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.examples.kubernetes;

import io.dekorate.kubernetes.annotation.HostAlias;
import io.dekorate.kubernetes.annotation.KubernetesApplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@KubernetesApplication(hostAliases = {@HostAlias(ip = "127.0.0.1", hostnames = "foo.org,bar.com"),
@HostAlias(ip = "10.0.0.1", hostnames = "test.com")})
@SpringBootApplication
public class Main {

public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
Loading

0 comments on commit cfecb0c

Please sign in to comment.