Skip to content

Commit

Permalink
Support overwrite values from existing init-containers
Browse files Browse the repository at this point in the history
  • Loading branch information
Sgitario committed May 17, 2023
1 parent 3d1b808 commit e3282c4
Show file tree
Hide file tree
Showing 8 changed files with 235 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import io.dekorate.doc.Description;
import io.dekorate.kubernetes.adapter.ContainerAdapter;
import io.dekorate.kubernetes.config.Container;
import io.fabric8.kubernetes.api.model.ContainerBuilder;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.kubernetes.api.model.PodSpecBuilder;

Expand All @@ -36,6 +37,54 @@ public AddInitContainerDecorator(String deployment, Container container) {

@Override
public void andThenVisit(PodSpecBuilder podSpec, ObjectMeta resourceMeta) {
podSpec.addToInitContainers(ContainerAdapter.adapt(container));
var resource = ContainerAdapter.adapt(container);
if (podSpec.hasMatchingInitContainer(this::existsContainerByName)) {
update(podSpec, resource);
} else {
add(podSpec, resource);
}
}

private void add(PodSpecBuilder podSpec, io.fabric8.kubernetes.api.model.Container resource) {
podSpec.addToInitContainers(resource);
}

private void update(PodSpecBuilder podSpec, io.fabric8.kubernetes.api.model.Container resource) {
var matching = podSpec.editMatchingInitContainer(this::existsContainerByName);

if (resource.getImage() != null) {
matching.withImage(resource.getImage());
}

if (resource.getWorkingDir() != null) {
matching.withWorkingDir(resource.getWorkingDir());
}

if (resource.getCommand() != null && !resource.getCommand().isEmpty()) {
matching.withCommand(resource.getCommand());
}

if (resource.getArgs() != null && !resource.getArgs().isEmpty()) {
matching.withArgs(resource.getArgs());
}

if (resource.getReadinessProbe() != null) {
matching.withReadinessProbe(resource.getReadinessProbe());
}

if (resource.getLivenessProbe() != null) {
matching.withLivenessProbe(resource.getLivenessProbe());
}

matching.addAllToEnv(resource.getEnv());
if (resource.getPorts() != null && !resource.getPorts().isEmpty()) {
matching.withPorts(resource.getPorts());
}

matching.endInitContainer();
}

private boolean existsContainerByName(ContainerBuilder containerBuilder) {
return containerBuilder.getName().equals(container.getName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ public ApplyRequestsCpuDecorator(String deploymentName, String containerName, St

@Override
public void andThenVisit(ContainerFluent<?> container) {
System.out.println("Apply requests cpu to:" + container.getName());
container.editOrNewResources().addToRequests(CPU, new Quantity(amount)).endResources();
}
}
72 changes: 72 additions & 0 deletions tests/feat-overwrite-init-containers/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.6-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>

<groupId>io.dekorate</groupId>
<artifactId>feat-overwrite-init-containers</artifactId>
<name>Dekorate :: Tests :: Annotations :: Allow to overwrite existing init container</name>

<dependencies>
<dependency>
<groupId>io.dekorate</groupId>
<artifactId>kubernetes-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>
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.annotationless;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

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

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* 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.annotationless;

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

@RestController
public class HelloController {

private static final String HELLO = "hello world!";

@RequestMapping("/")
public String hello() {
return HELLO;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dekorate.kubernetes.init-containers[0].name=foo
dekorate.kubernetes.init-containers[1].name=foo
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* 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.example;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.util.Optional;

import org.junit.jupiter.api.Test;

import io.dekorate.utils.Serialization;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.KubernetesList;
import io.fabric8.kubernetes.api.model.apps.Deployment;

public class FeatOverwriteInitContainersTest {

@Test
public void shouldContainOnlyOneInitContainer() {
KubernetesList list = Serialization
.unmarshalAsList(getClass().getClassLoader().getResourceAsStream("META-INF/dekorate/kubernetes.yml"));
assertNotNull(list);
Deployment s = findFirst(list, Deployment.class).orElseThrow(() -> new IllegalStateException());
assertEquals("feat-overwrite-init-containers", s.getMetadata().getName());
assertEquals(1, s.getSpec().getTemplate().getSpec().getInitContainers().size());
assertEquals("foo", s.getSpec().getTemplate().getSpec().getInitContainers().get(0).getName());
}

<T extends HasMetadata> Optional<T> findFirst(KubernetesList list, Class<T> t) {
return (Optional<T>) list.getItems().stream()
.filter(i -> t.isInstance(i))
.findFirst();
}
}
1 change: 1 addition & 0 deletions tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
<module>issue-1158-spring-boot-certmanager-with-annotations</module>
<module>feat-openshift-secure-routes</module>
<module>issue-knative-probes-helm</module>
<module>feat-overwrite-init-containers</module>
</modules>

</project>

0 comments on commit e3282c4

Please sign in to comment.