Skip to content
This repository was archived by the owner on Apr 10, 2024. It is now read-only.

Commit fa42821

Browse files
authored
feat: inject kube config (#72)
1 parent cd1e7c0 commit fa42821

File tree

6 files changed

+152
-8
lines changed

6 files changed

+152
-8
lines changed

core/src/main/java/io/javaoperatorsdk/jenvtest/junit/KubeAPIServerExtension.java

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.javaoperatorsdk.jenvtest.junit;
22

33
import java.lang.reflect.AnnotatedElement;
4+
import java.lang.reflect.Field;
45
import java.util.Arrays;
56
import java.util.List;
67
import java.util.Optional;
@@ -26,7 +27,7 @@ public class KubeAPIServerExtension
2627

2728
@Override
2829
public void beforeAll(ExtensionContext extensionContext) {
29-
startIfAnnotationPresent(extensionContext);
30+
initialize(extensionContext, true);
3031
}
3132

3233
@Override
@@ -36,23 +37,69 @@ public void afterAll(ExtensionContext extensionContext) {
3637

3738
@Override
3839
public void beforeEach(ExtensionContext extensionContext) {
39-
startIfAnnotationPresent(extensionContext);
40+
initialize(extensionContext, false);
4041
}
4142

4243
@Override
4344
public void afterEach(ExtensionContext extensionContext) {
4445
stopIfAnnotationPresent(extensionContext);
4546
}
4647

47-
private void startIfAnnotationPresent(ExtensionContext extensionContext) {
48+
49+
private void initialize(ExtensionContext extensionContext, boolean staticContext) {
50+
var kubeConfigField = getFieldForKubeConfigInjection(extensionContext, staticContext);
51+
startIfAnnotationPresent(extensionContext, kubeConfigField.isEmpty());
52+
kubeConfigField.ifPresent(f -> setKubeConfigYamlToField(extensionContext, f));
53+
}
54+
55+
private void setKubeConfigYamlToField(ExtensionContext extensionContext, Field kubeConfigField) {
56+
try {
57+
var target = extensionContext.getTestInstance()
58+
.orElseGet(() -> extensionContext.getTestClass().orElseThrow());
59+
kubeConfigField.setAccessible(true);
60+
kubeConfigField.set(target,
61+
kubeApiServer.getKubeConfigYaml());
62+
} catch (IllegalAccessException e) {
63+
throw new JenvtestException(e);
64+
}
65+
}
66+
67+
private Optional<Field> getFieldForKubeConfigInjection(ExtensionContext extensionContext,
68+
boolean findStatic) {
69+
Class<?> clazz = extensionContext.getTestClass().orElseThrow();
70+
var kubeConfigFields = Arrays.stream(clazz.getDeclaredFields())
71+
.filter(f -> f.getAnnotationsByType(KubeConfig.class).length > 0)
72+
.collect(Collectors.toList());
73+
if (kubeConfigFields.isEmpty()) {
74+
return Optional.empty();
75+
}
76+
if (kubeConfigFields.size() > 1) {
77+
throw new JenvtestException(
78+
"More fields annotation with @" + KubeConfig.class.getSimpleName() + " annotation");
79+
}
80+
var field = kubeConfigFields.get(0);
81+
if (!field.getType().equals(String.class)) {
82+
throw new JenvtestException(
83+
"Field annotated with @" + KubeConfig.class.getSimpleName() + " is not a String");
84+
}
85+
86+
if (java.lang.reflect.Modifier.isStatic(field.getModifiers()) != findStatic) {
87+
return Optional.empty();
88+
} else {
89+
return Optional.of(field);
90+
}
91+
}
92+
93+
private void startIfAnnotationPresent(ExtensionContext extensionContext,
94+
boolean updateKubeConfig) {
4895
extensionContext.getElement().ifPresent(ae -> {
4996
var annotation = getExtensionAnnotationInstance(ae);
50-
annotation.ifPresent(this::startApiServer);
97+
annotation.ifPresent(a -> startApiServer(a, updateKubeConfig));
5198
});
5299
}
53100

54-
private void startApiServer(EnableKubeAPIServer annotation) {
55-
kubeApiServer = new KubeAPIServer(annotationToConfig(annotation));
101+
private void startApiServer(EnableKubeAPIServer annotation, boolean updateKubeConfig) {
102+
kubeApiServer = new KubeAPIServer(annotationToConfig(annotation, updateKubeConfig));
56103
kubeApiServer.start();
57104
}
58105

@@ -64,7 +111,8 @@ private void stopIfAnnotationPresent(ExtensionContext extensionContext) {
64111
});
65112
}
66113

67-
private KubeAPIServerConfig annotationToConfig(EnableKubeAPIServer annotation) {
114+
private KubeAPIServerConfig annotationToConfig(EnableKubeAPIServer annotation,
115+
boolean updateKubeConfig) {
68116
var builder = KubeAPIServerConfigBuilder.anAPIServerConfig();
69117
var version = annotation.kubeAPIVersion();
70118
if (!NOT_SET.equals(version)) {
@@ -73,6 +121,7 @@ private KubeAPIServerConfig annotationToConfig(EnableKubeAPIServer annotation) {
73121
if (annotation.apiServerFlags().length > 0) {
74122
builder.withApiServerFlags(List.of(annotation.apiServerFlags()));
75123
}
124+
builder.withUpdateKubeConfig(updateKubeConfig);
76125
return builder.build();
77126
}
78127

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.javaoperatorsdk.jenvtest.junit;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.Target;
5+
6+
import static java.lang.annotation.ElementType.*;
7+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
8+
9+
/**
10+
* Used to annotate String field in JUnit test to inject Kube Config yaml.
11+
*/
12+
@Target({FIELD})
13+
@Retention(RUNTIME)
14+
public @interface KubeConfig {
15+
16+
}

samples/src/test/java/io/javaoperatorsdk/jenvtest/JUnitExtensionOnMethodTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,9 @@ void testCommunication() {
1414
simpleTest();
1515
}
1616

17+
@Test
18+
@EnableKubeAPIServer
19+
void testCommunication2() {
20+
simpleTest();
21+
}
1722
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package io.javaoperatorsdk.jenvtest;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import io.fabric8.kubernetes.client.Config;
6+
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
7+
import io.javaoperatorsdk.jenvtest.junit.EnableKubeAPIServer;
8+
import io.javaoperatorsdk.jenvtest.junit.KubeConfig;
9+
10+
import static io.javaoperatorsdk.jenvtest.TestUtils.simpleTest;
11+
12+
class JUnitInjectKubeConfigPerTestMethod {
13+
14+
@KubeConfig
15+
String kubeConfigYaml;
16+
17+
@Test
18+
@EnableKubeAPIServer
19+
void testCommunication1() {
20+
testWithClientFromGeneratedYaml();
21+
}
22+
23+
@Test
24+
@EnableKubeAPIServer
25+
void testCommunication2() {
26+
testWithClientFromGeneratedYaml();
27+
}
28+
29+
private void testWithClientFromGeneratedYaml() {
30+
var client = new KubernetesClientBuilder()
31+
.withConfig(Config.fromKubeconfig(kubeConfigYaml))
32+
.build();
33+
simpleTest(client);
34+
}
35+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package io.javaoperatorsdk.jenvtest;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import io.fabric8.kubernetes.client.Config;
6+
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
7+
import io.javaoperatorsdk.jenvtest.junit.EnableKubeAPIServer;
8+
import io.javaoperatorsdk.jenvtest.junit.KubeConfig;
9+
10+
import static io.javaoperatorsdk.jenvtest.TestUtils.simpleTest;
11+
12+
@EnableKubeAPIServer
13+
class JUnitInjectKubeConfigTest {
14+
15+
/**
16+
* Needs to be static if shared between tests. If present in the test, the "~/kube/config" is not
17+
* updated
18+
*/
19+
@KubeConfig
20+
static String kubeConfigYaml;
21+
22+
@Test
23+
void testCommunication1() {
24+
testWithClientFromGeneratedYaml();
25+
}
26+
27+
@Test
28+
void testCommunication2() {
29+
testWithClientFromGeneratedYaml();
30+
}
31+
32+
private static void testWithClientFromGeneratedYaml() {
33+
var client = new KubernetesClientBuilder()
34+
.withConfig(Config.fromKubeconfig(kubeConfigYaml))
35+
.build();
36+
simpleTest(client);
37+
}
38+
}

samples/src/test/java/io/javaoperatorsdk/jenvtest/TestUtils.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ public static void simpleTest() {
3333
}
3434

3535
public static void simpleTest(KubernetesClient client) {
36-
3736
client.resource(TestUtils.testConfigMap()).create();
3837
var cm = client.resource(TestUtils.testConfigMap()).get();
3938

4039
Assertions.assertThat(cm).isNotNull();
40+
41+
client.resource(cm).delete();
4142
}
4243

4344
}

0 commit comments

Comments
 (0)