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

Commit 26431c1

Browse files
authored
feat: wildcard version support (#57)
1 parent 33d255d commit 26431c1

File tree

8 files changed

+131
-28
lines changed

8 files changed

+131
-28
lines changed

core/src/main/java/io/javaoperatorsdk/jenvtest/KubeAPIServerConfig.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ public class KubeAPIServerConfig {
1111
private final String jenvtestDir;
1212

1313
/**
14-
* If not set the latest binary will be selected automatically. Sample: 1.26.1, 1.25.0.
14+
* If not set the latest binary will be selected automatically. Sample: '1.26.1', '1.25.0'.
15+
* Wildcards for patch version is supported, like: '1.25.*'. In this case latest patch version is
16+
* used.
1517
*/
1618
private final String apiServerVersion;
1719

core/src/main/java/io/javaoperatorsdk/jenvtest/Utils.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import io.javaoperatorsdk.jenvtest.binary.OSInfo;
1313

1414
public class Utils {
15+
public static final String WILDCARD_SUFFIX = ".*";
1516

1617
private Utils() {}
1718

@@ -60,4 +61,13 @@ public static int findFreePort() {
6061
}
6162
return -1;
6263
}
64+
65+
public static boolean isWildcardVersion(String version) {
66+
return version.endsWith(WILDCARD_SUFFIX);
67+
}
68+
69+
public static String wildcardToPrefix(String wildcardVersion) {
70+
return wildcardVersion.substring(0, wildcardVersion.lastIndexOf("."));
71+
}
72+
6373
}

core/src/main/java/io/javaoperatorsdk/jenvtest/binary/BinaryDownloader.java

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.io.IOException;
77
import java.nio.file.Files;
88
import java.util.stream.Collectors;
9+
import java.util.stream.Stream;
910

1011
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
1112
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
@@ -56,6 +57,11 @@ public File downloadLatest() {
5657
return download(latest);
5758
}
5859

60+
public File downloadLatestWildcard(String wildcardVersion) {
61+
String latest = findLatestOfWildcard(wildcardVersion);
62+
return download(latest);
63+
}
64+
5965
private void extractFiles(File tempFile, File dir) {
6066
try (TarArchiveInputStream tarIn = new TarArchiveInputStream(
6167
new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(tempFile))))) {
@@ -101,8 +107,28 @@ private File createDirForBinaries(String version) {
101107
}
102108

103109
public String findLatestVersion() {
110+
var allRelevantVersions =
111+
listAllRelevantVersions().sorted(Utils.SEMVER_COMPARATOR).collect(Collectors.toList());
112+
if (allRelevantVersions.isEmpty()) {
113+
throw new JenvtestException("Cannot find relevant version to download");
114+
}
115+
return allRelevantVersions.get(allRelevantVersions.size() - 1);
116+
}
117+
118+
public String findLatestOfWildcard(String wildcardVersion) {
119+
var allRelevantVersions = listAllRelevantVersions()
120+
.filter(v -> v.startsWith(Utils.wildcardToPrefix(wildcardVersion)))
121+
.sorted(Utils.SEMVER_COMPARATOR).collect(Collectors.toList());
122+
if (allRelevantVersions.isEmpty()) {
123+
throw new JenvtestException(
124+
"Cannot find relevant version to download for wildcard version: " + wildcardVersion);
125+
}
126+
return allRelevantVersions.get(allRelevantVersions.size() - 1);
127+
}
128+
129+
private Stream<String> listAllRelevantVersions() {
104130
var objects = binaryRepo.listObjectNames();
105-
var allRelevantVersions = objects.filter(o -> o.contains(osInfoProvider.getOSName())
131+
return objects.filter(o -> o.contains(osInfoProvider.getOSName())
106132
&& o.contains(osInfoProvider.getOSArch()))
107133
.map(o -> {
108134
String stripped = o.replace(OBJECT_TAR_PREFIX, "");
@@ -111,10 +137,6 @@ public String findLatestVersion() {
111137
version = version.substring(1);
112138
}
113139
return version;
114-
}).sorted(Utils.SEMVER_COMPARATOR).collect(Collectors.toList());
115-
if (allRelevantVersions.isEmpty()) {
116-
throw new JenvtestException("Cannot find relevant version to download");
117-
}
118-
return allRelevantVersions.get(allRelevantVersions.size() - 1);
140+
});
119141
}
120142
}

core/src/main/java/io/javaoperatorsdk/jenvtest/binary/BinaryManager.java

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
package io.javaoperatorsdk.jenvtest.binary;
22

33
import java.io.File;
4+
import java.util.Collections;
45
import java.util.List;
56
import java.util.Optional;
67
import java.util.stream.Collectors;
8+
import java.util.stream.Stream;
79

810
import io.javaoperatorsdk.jenvtest.JenvtestException;
911
import io.javaoperatorsdk.jenvtest.KubeAPIServerConfig;
1012
import io.javaoperatorsdk.jenvtest.Utils;
1113

14+
import static io.javaoperatorsdk.jenvtest.Utils.isWildcardVersion;
15+
1216
public class BinaryManager {
1317

1418
public static final String BINARY_LIST_DIR = "k8s";
@@ -26,18 +30,31 @@ public BinaryManager(KubeAPIServerConfig config) {
2630

2731
public void initAndDownloadIfRequired() {
2832
Optional<File> maybeBinaryDir = findTargetBinariesIfAvailable();
29-
File binaryDir = maybeBinaryDir.orElse(null);
30-
33+
File binaryDir;
3134
if (maybeBinaryDir.isEmpty()) {
3235
if (config.isOfflineMode()) {
3336
throw new JenvtestException("Binaries cannot be found, and download is turned off");
3437
}
35-
binaryDir = config.getApiServerVersion().isEmpty() ? downloader.downloadLatest()
36-
: downloader.download(config.getApiServerVersion().get());
38+
binaryDir = downloadBinary();
39+
} else {
40+
binaryDir = maybeBinaryDir.orElseThrow();
3741
}
3842
initBinariesPojo(binaryDir);
3943
}
4044

45+
private File downloadBinary() {
46+
if (config.getApiServerVersion().isEmpty()) {
47+
return downloader.downloadLatest();
48+
} else {
49+
String version = config.getApiServerVersion().orElseThrow();
50+
if (Utils.isWildcardVersion(version)) {
51+
return downloader.downloadLatestWildcard(version);
52+
} else {
53+
return downloader.download(version);
54+
}
55+
}
56+
}
57+
4158
private void initBinariesPojo(File binaryDir) {
4259
this.binaries = new Binaries(new File(binaryDir, Binaries.ETCD_BINARY_NAME),
4360
new File(binaryDir, Binaries.API_SERVER_BINARY_NAME),
@@ -64,29 +81,55 @@ public Binaries binaries() {
6481

6582
private Optional<File> findTargetBinariesIfAvailable() {
6683
var platformSuffix = Utils.platformSuffix(osInfo);
67-
if (config.getApiServerVersion().isPresent()) {
84+
var apiServerVersion = config.getApiServerVersion().orElse(null);
85+
if (apiServerVersion != null) {
86+
if (isWildcardVersion(apiServerVersion)) {
87+
var targetWildcardVersion = findLatestVersionForWildcard(apiServerVersion);
88+
if (targetWildcardVersion.isEmpty()) {
89+
return Optional.empty();
90+
} else {
91+
apiServerVersion = targetWildcardVersion.orElseThrow();
92+
}
93+
}
6894
var targetVersionDir = new File(config.getJenvtestDir(), BINARY_LIST_DIR
69-
+ File.separator + config.getApiServerVersion().get() + platformSuffix);
95+
+ File.separator + apiServerVersion + platformSuffix);
7096
if (targetVersionDir.exists()) {
7197
return Optional.of(targetVersionDir);
7298
} else {
7399
return Optional.empty();
74100
}
75101
}
76102
File binariesListDir = new File(config.getJenvtestDir(), BINARY_LIST_DIR);
77-
if (!binariesListDir.exists()) {
78-
return Optional.empty();
79-
}
80-
var dirVersionList = List.of(binariesListDir.list((dir, name) -> name != null
81-
&& name.endsWith(platformSuffix)))
82-
.stream().map(s -> s.substring(0, s.indexOf(platformSuffix)))
83-
.collect(Collectors.toList());
84-
103+
var dirVersionList = listBinaryDirectories();
85104
if (dirVersionList.isEmpty()) {
86105
return Optional.empty();
87106
}
88107
String latest = Utils.getLatestVersion(dirVersionList) + platformSuffix;
89108
return Optional.of(new File(binariesListDir, latest));
90109
}
91110

111+
private Optional<String> findLatestVersionForWildcard(String wildcardVersion) {
112+
var targetPrefix = Utils.wildcardToPrefix(wildcardVersion);
113+
var dirs = listBinaryDirectories();
114+
var filteredDirs =
115+
dirs.stream().filter(d -> d.startsWith(targetPrefix)).collect(Collectors.toList());
116+
if (filteredDirs.isEmpty()) {
117+
return Optional.empty();
118+
}
119+
return Optional.of(Utils.getLatestVersion(filteredDirs));
120+
}
121+
122+
private List<String> listBinaryDirectories() {
123+
var platformSuffix = Utils.platformSuffix(osInfo);
124+
File binariesListDir = new File(config.getJenvtestDir(), BINARY_LIST_DIR);
125+
if (!binariesListDir.exists()) {
126+
return Collections.emptyList();
127+
}
128+
return Stream
129+
.of(binariesListDir.list((dir, name) -> name != null && name.endsWith(platformSuffix)))
130+
.map(s -> s.substring(0, s.indexOf(platformSuffix)))
131+
.collect(Collectors.toList());
132+
}
133+
134+
92135
}

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,17 @@
1010
import static java.lang.annotation.ElementType.*;
1111
import static java.lang.annotation.RetentionPolicy.RUNTIME;
1212

13+
/**
14+
* For docs of attributes see {@link KubeAPIServerConfig}.
15+
*/
1316
@ExtendWith(KubeAPIServerExtension.class)
1417
@Target({TYPE, METHOD, ANNOTATION_TYPE})
1518
@Retention(RUNTIME)
1619
public @interface EnableKubeAPIServer {
1720

1821
String NOT_SET = "NOT_SET";
1922

20-
/**
21-
* The target Kube API Version. Sample: 1.26.1
22-
*/
2323
String kubeAPIVersion() default NOT_SET;
2424

25-
/**
26-
* See {@link KubeAPIServerConfig} docs for details.
27-
*/
2825
String[] apiServerFlags() default {};
2926
}

core/src/main/java/io/javaoperatorsdk/jenvtest/process/KubeAPIServerProcess.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ public int startApiServer(int etcdPort) {
7373
}
7474
return null;
7575
});
76-
log.debug("Kube API Server started on port: {}", apiServerPort);
76+
log.debug("Kube API Server started on port: {} using binaries: {}", apiServerPort,
77+
apiServerBinary);
7778
return apiServerPort;
7879
} catch (IOException e) {
7980
throw new JenvtestException(e);

core/src/test/java/io/javaoperatorsdk/jenvtest/UtilsTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,16 @@ void getsLatestVersion() {
1717
assertThat(Utils.getLatestVersion(new ArrayList<>(List.of("1.22", "1.23.1", "1.24"))))
1818
.isEqualTo("1.24");
1919
}
20+
21+
@Test
22+
void checksIfVersionIsWildcard() {
23+
assertThat(Utils.isWildcardVersion("1.25.*")).isTrue();
24+
assertThat(Utils.isWildcardVersion("1.26.2")).isFalse();
25+
}
26+
27+
@Test
28+
void wildcardToPrefix() {
29+
assertThat(Utils.wildcardToPrefix("1.25.*")).isEqualTo("1.25");
30+
}
31+
2032
}

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
import org.junit.jupiter.api.Test;
44

5+
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
6+
57
import static io.javaoperatorsdk.jenvtest.TestUtils.NON_LATEST_API_SERVER_VERSION;
68
import static io.javaoperatorsdk.jenvtest.TestUtils.simpleTest;
9+
import static org.assertj.core.api.Assertions.assertThat;
710

811
class KubeApiServerTest {
912

@@ -19,6 +22,19 @@ void apiServerWithSpecificVersion() {
1922
.build()));
2023
}
2124

25+
@Test
26+
void usingWildcardVersion() {
27+
var kubeApi = new KubeAPIServer(KubeAPIServerConfigBuilder.anAPIServerConfig()
28+
.withApiServerVersion("1.26.*")
29+
.build());
30+
kubeApi.start();
31+
32+
var client = new KubernetesClientBuilder().build();
33+
TestUtils.simpleTest(client);
34+
assertThat(client.getKubernetesVersion().getMinor()).isEqualTo("26");
35+
36+
kubeApi.stop();
37+
}
2238

2339
void testWithAPIServer(KubeAPIServer kubeApi) {
2440
kubeApi.start();

0 commit comments

Comments
 (0)