More resources used by both runner and manager.
This commit is contained in:
parent
d9c2f6edd3
commit
2b471f3852
12 changed files with 62 additions and 22 deletions
|
|
@ -32,6 +32,9 @@ import java.io.IOException;
|
|||
import java.io.StringWriter;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
import static org.jdrupes.vmoperator.manager.Constants.APP_NAME;
|
||||
import static org.jdrupes.vmoperator.util.Constants.VM_OP_NAME;
|
||||
import org.jdrupes.vmoperator.util.K8s;
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
|
|
@ -98,8 +101,8 @@ import org.yaml.snakeyaml.constructor.SafeConstructor;
|
|||
DynamicKubernetesObject newCm) {
|
||||
ListOptions listOpts = new ListOptions();
|
||||
listOpts.setLabelSelector(
|
||||
"app.kubernetes.io/managed-by=" + Constants.VM_OP_NAME + ","
|
||||
+ "app.kubernetes.io/name=" + Constants.APP_NAME);
|
||||
"app.kubernetes.io/managed-by=" + VM_OP_NAME + ","
|
||||
+ "app.kubernetes.io/name=" + APP_NAME);
|
||||
// Get pod, selected by label
|
||||
var podApi = new DynamicKubernetesApi("", "v1", "pods", client);
|
||||
var pods = podApi
|
||||
|
|
|
|||
|
|
@ -23,15 +23,6 @@ package org.jdrupes.vmoperator.manager;
|
|||
*/
|
||||
public class Constants {
|
||||
|
||||
/** The Constant VM_OP_NAME. */
|
||||
public static final String VM_OP_NAME = "vm-operator";
|
||||
|
||||
/** The Constant VM_OP_GROUP. */
|
||||
public static final String VM_OP_GROUP = "vmoperator.jdrupes.org";
|
||||
|
||||
/** The Constant VM_OP_KIND_VM. */
|
||||
public static final String VM_OP_KIND_VM = "VirtualMachine";
|
||||
|
||||
/** The Constant APP_NAME. */
|
||||
public static final String APP_NAME = "vm-runner";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,275 +0,0 @@
|
|||
/*
|
||||
* VM-Operator
|
||||
* Copyright (C) 2023 Michael N. Lipp
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.jdrupes.vmoperator.manager;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Utility class for pointing to elements on a Gson (Json) tree.
|
||||
*/
|
||||
@SuppressWarnings({ "PMD.DataflowAnomalyAnalysis",
|
||||
"PMD.ClassWithOnlyPrivateConstructorsShouldBeFinal" })
|
||||
public class GsonPtr {
|
||||
|
||||
private final JsonElement position;
|
||||
|
||||
private GsonPtr(JsonElement root) {
|
||||
this.position = root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance pointing to the given element.
|
||||
*
|
||||
* @param root the root
|
||||
* @return the Gson pointer
|
||||
*/
|
||||
@SuppressWarnings("PMD.ShortMethodName")
|
||||
public static GsonPtr to(JsonElement root) {
|
||||
return new GsonPtr(root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance pointing to the {@link JsonElement}
|
||||
* selected by the given selectors. If a selector of type
|
||||
* {@link String} denotes a non-existant member of a
|
||||
* {@link JsonObject}, a new member (of type {@link JsonObject}
|
||||
* is added.
|
||||
*
|
||||
* @param selectors the selectors
|
||||
* @return the Gson pointer
|
||||
*/
|
||||
@SuppressWarnings({ "PMD.ShortMethodName", "PMD.PreserveStackTrace" })
|
||||
public GsonPtr to(Object... selectors) {
|
||||
JsonElement element = position;
|
||||
for (Object sel : selectors) {
|
||||
if (element instanceof JsonObject obj
|
||||
&& sel instanceof String member) {
|
||||
element = Optional.ofNullable(obj.get(member)).orElseGet(() -> {
|
||||
@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
|
||||
var child = new JsonObject();
|
||||
obj.add(member, child);
|
||||
return child;
|
||||
});
|
||||
continue;
|
||||
}
|
||||
if (element instanceof JsonArray arr
|
||||
&& sel instanceof Integer index) {
|
||||
try {
|
||||
element = arr.get(index);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
throw new IllegalStateException("Selected array index"
|
||||
+ " may not be empty.");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
throw new IllegalStateException("Invalid selection");
|
||||
}
|
||||
return new GsonPtr(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link JsonElement} that the pointer points to.
|
||||
*
|
||||
* @return the result
|
||||
*/
|
||||
public JsonElement get() {
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link JsonElement} that the pointer points to,
|
||||
* casted to the given type.
|
||||
*
|
||||
* @param <T> the generic type
|
||||
* @param cls the cls
|
||||
* @return the result
|
||||
*/
|
||||
@SuppressWarnings({ "PMD.AvoidBranchingStatementAsLastInLoop" })
|
||||
public <T extends JsonElement> T get(Class<T> cls) {
|
||||
if (cls.isAssignableFrom(position.getClass())) {
|
||||
return cls.cast(position);
|
||||
}
|
||||
throw new IllegalArgumentException("Not positioned at element"
|
||||
+ " of desired type.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the selected {@link JsonElement}, cast to the class
|
||||
* specified.
|
||||
*
|
||||
* @param <T> the generic type
|
||||
* @param cls the cls
|
||||
* @param selectors the selectors
|
||||
* @return the optional
|
||||
*/
|
||||
@SuppressWarnings({ "PMD.AvoidBranchingStatementAsLastInLoop" })
|
||||
public <T extends JsonElement> Optional<T>
|
||||
get(Class<T> cls, Object... selectors) {
|
||||
JsonElement element = position;
|
||||
for (Object sel : selectors) {
|
||||
if (element instanceof JsonObject obj
|
||||
&& sel instanceof String member) {
|
||||
element = obj.get(member);
|
||||
if (element == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (element instanceof JsonArray arr
|
||||
&& sel instanceof Integer index) {
|
||||
try {
|
||||
element = arr.get(index);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
if (cls.isAssignableFrom(element.getClass())) {
|
||||
return Optional.of(cls.cast(element));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the String value of the selected {@link JsonPrimitive}.
|
||||
*
|
||||
* @param selectors the selectors
|
||||
* @return the as string
|
||||
*/
|
||||
public Optional<String> getAsString(Object... selectors) {
|
||||
return get(JsonPrimitive.class, selectors)
|
||||
.map(JsonPrimitive::getAsString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Integer value of the selected {@link JsonPrimitive}.
|
||||
*
|
||||
* @param selectors the selectors
|
||||
* @return the as string
|
||||
*/
|
||||
public Optional<Integer> getAsInt(Object... selectors) {
|
||||
return get(JsonPrimitive.class, selectors)
|
||||
.map(JsonPrimitive::getAsInt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Long value of the selected {@link JsonPrimitive}.
|
||||
*
|
||||
* @param selectors the selectors
|
||||
* @return the as string
|
||||
*/
|
||||
public Optional<Long> getAsLong(Object... selectors) {
|
||||
return get(JsonPrimitive.class, selectors)
|
||||
.map(JsonPrimitive::getAsLong);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selected value. This pointer must point to a
|
||||
* {@link JsonObject} or {@link JsonArray}. The selector must
|
||||
* be a {@link String} or an integer respectively.
|
||||
*
|
||||
* @param selector the selector
|
||||
* @param value the value
|
||||
* @return the Gson pointer
|
||||
*/
|
||||
public GsonPtr set(Object selector, JsonElement value) {
|
||||
if (position instanceof JsonObject obj
|
||||
&& selector instanceof String member) {
|
||||
obj.add(member, value);
|
||||
return this;
|
||||
}
|
||||
if (position instanceof JsonArray arr
|
||||
&& selector instanceof Integer index) {
|
||||
if (index >= arr.size()) {
|
||||
arr.add(value);
|
||||
} else {
|
||||
arr.set(index, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
throw new IllegalStateException("Invalid selection");
|
||||
}
|
||||
|
||||
/**
|
||||
* Short for `set(selector, new JsonPrimitive(value))`.
|
||||
*
|
||||
* @param selector the selector
|
||||
* @param value the value
|
||||
* @return the gson ptr
|
||||
* @see #set(Object, JsonElement)
|
||||
*/
|
||||
public GsonPtr set(Object selector, String value) {
|
||||
return set(selector, new JsonPrimitive(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #set(Object, JsonElement)}, but sets the value
|
||||
* only if it doesn't exist yet, else returns the existing value.
|
||||
* If this pointer points to a {@link JsonArray} and the selector
|
||||
* if larger than or equal to the size of the array, the supplied
|
||||
* value will be appended.
|
||||
*
|
||||
* @param <T> the generic type
|
||||
* @param selector the selector
|
||||
* @param supplier the supplier of the missing value
|
||||
* @return the existing or supplied value
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends JsonElement> T
|
||||
computeIfAbsent(Object selector, Supplier<T> supplier) {
|
||||
if (position instanceof JsonObject obj
|
||||
&& selector instanceof String member) {
|
||||
return Optional.ofNullable((T) obj.get(member)).orElseGet(() -> {
|
||||
var res = supplier.get();
|
||||
obj.add(member, res);
|
||||
return res;
|
||||
});
|
||||
}
|
||||
if (position instanceof JsonArray arr
|
||||
&& selector instanceof Integer index) {
|
||||
if (index >= arr.size()) {
|
||||
var res = supplier.get();
|
||||
arr.add(res);
|
||||
return res;
|
||||
}
|
||||
return (T) arr.get(index);
|
||||
}
|
||||
throw new IllegalStateException("Invalid selection");
|
||||
}
|
||||
|
||||
/**
|
||||
* Short for `computeIfAbsent(selector, () -> new JsonPrimitive(value))`.
|
||||
*
|
||||
* @param selector the selector
|
||||
* @param value the value
|
||||
* @return the Gson pointer
|
||||
*/
|
||||
public GsonPtr getOrSet(Object selector, String value) {
|
||||
computeIfAbsent(selector, () -> new JsonPrimitive(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
/*
|
||||
* VM-Operator
|
||||
* Copyright (C) 2023 Michael N. Lipp
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.jdrupes.vmoperator.manager;
|
||||
|
||||
import io.kubernetes.client.common.KubernetesListObject;
|
||||
import io.kubernetes.client.common.KubernetesObject;
|
||||
import io.kubernetes.client.custom.V1Patch;
|
||||
import io.kubernetes.client.openapi.ApiClient;
|
||||
import io.kubernetes.client.openapi.ApiException;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMap;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMapList;
|
||||
import io.kubernetes.client.openapi.models.V1ObjectMeta;
|
||||
import io.kubernetes.client.openapi.models.V1PersistentVolumeClaim;
|
||||
import io.kubernetes.client.openapi.models.V1PersistentVolumeClaimList;
|
||||
import io.kubernetes.client.openapi.models.V1Pod;
|
||||
import io.kubernetes.client.openapi.models.V1PodList;
|
||||
import io.kubernetes.client.util.generic.GenericKubernetesApi;
|
||||
import io.kubernetes.client.util.generic.options.DeleteOptions;
|
||||
import io.kubernetes.client.util.generic.options.PatchOptions;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Helpers for K8s API.
|
||||
*/
|
||||
@SuppressWarnings({ "PMD.ShortClassName", "PMD.UseUtilityClass" })
|
||||
public class K8s {
|
||||
|
||||
/**
|
||||
* Given a groupVersion, returns only the version.
|
||||
*
|
||||
* @param groupVersion the group version
|
||||
* @return the string
|
||||
*/
|
||||
public static String version(String groupVersion) {
|
||||
return groupVersion.substring(groupVersion.lastIndexOf('/') + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get PVC API.
|
||||
*
|
||||
* @param client the client
|
||||
* @return the generic kubernetes api
|
||||
*/
|
||||
public static GenericKubernetesApi<V1PersistentVolumeClaim,
|
||||
V1PersistentVolumeClaimList> pvcApi(ApiClient client) {
|
||||
return new GenericKubernetesApi<>(V1PersistentVolumeClaim.class,
|
||||
V1PersistentVolumeClaimList.class, "", "v1",
|
||||
"persistentvolumeclaims", client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config map API.
|
||||
*
|
||||
* @param client the client
|
||||
* @return the generic kubernetes api
|
||||
*/
|
||||
public static GenericKubernetesApi<V1ConfigMap,
|
||||
V1ConfigMapList> cmApi(ApiClient client) {
|
||||
return new GenericKubernetesApi<>(V1ConfigMap.class,
|
||||
V1ConfigMapList.class, "", "v1", "configmaps", client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get pod API.
|
||||
*
|
||||
* @param client the client
|
||||
* @return the generic kubernetes api
|
||||
*/
|
||||
public static GenericKubernetesApi<V1Pod, V1PodList>
|
||||
podApi(ApiClient client) {
|
||||
return new GenericKubernetesApi<>(V1Pod.class, V1PodList.class, "",
|
||||
"v1", "pods", client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object from its metadata.
|
||||
*
|
||||
* @param <T> the generic type
|
||||
* @param <LT> the generic type
|
||||
* @param api the api
|
||||
* @param meta the meta
|
||||
* @return the object
|
||||
*/
|
||||
public static <T extends KubernetesObject, LT extends KubernetesListObject>
|
||||
Optional<T>
|
||||
get(GenericKubernetesApi<T, LT> api, V1ObjectMeta meta) {
|
||||
var response = api.get(meta.getNamespace(), meta.getName());
|
||||
if (response.isSuccess()) {
|
||||
return Optional.of(response.getObject());
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an object.
|
||||
*
|
||||
* @param <T> the generic type
|
||||
* @param <LT> the generic type
|
||||
* @param api the api
|
||||
* @param object the object
|
||||
*/
|
||||
public static <T extends KubernetesObject, LT extends KubernetesListObject>
|
||||
void delete(GenericKubernetesApi<T, LT> api, T object)
|
||||
throws ApiException {
|
||||
api.delete(object.getMetadata().getNamespace(),
|
||||
object.getMetadata().getName()).throwsApiException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an object.
|
||||
*
|
||||
* @param <T> the generic type
|
||||
* @param <LT> the generic type
|
||||
* @param api the api
|
||||
* @param object the object
|
||||
*/
|
||||
public static <T extends KubernetesObject, LT extends KubernetesListObject>
|
||||
void delete(GenericKubernetesApi<T, LT> api, T object,
|
||||
DeleteOptions options) throws ApiException {
|
||||
api.delete(object.getMetadata().getNamespace(),
|
||||
object.getMetadata().getName(), options).throwsApiException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the given patch data.
|
||||
*
|
||||
* @param <T> the generic type
|
||||
* @param <LT> the generic type
|
||||
* @param api the api
|
||||
* @param existing the existing
|
||||
* @param update the update
|
||||
* @throws ApiException the api exception
|
||||
*/
|
||||
public static <T extends KubernetesObject, LT extends KubernetesListObject>
|
||||
T apply(GenericKubernetesApi<T, LT> api, T existing, String update)
|
||||
throws ApiException {
|
||||
PatchOptions opts = new PatchOptions();
|
||||
opts.setForce(true);
|
||||
opts.setFieldManager("kubernetes-java-kubectl-apply");
|
||||
var response = api.patch(existing.getMetadata().getNamespace(),
|
||||
existing.getMetadata().getName(), V1Patch.PATCH_FORMAT_APPLY_YAML,
|
||||
new V1Patch(update), opts).throwsApiException();
|
||||
return response.getObject();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -33,6 +33,8 @@ import java.util.Collections;
|
|||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Logger;
|
||||
import org.jdrupes.vmoperator.util.GsonPtr;
|
||||
import org.jdrupes.vmoperator.util.K8s;
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import org.apache.commons.cli.CommandLineParser;
|
|||
import org.apache.commons.cli.DefaultParser;
|
||||
import org.apache.commons.cli.Option;
|
||||
import org.apache.commons.cli.Options;
|
||||
import static org.jdrupes.vmoperator.manager.Constants.VM_OP_NAME;
|
||||
import static org.jdrupes.vmoperator.util.Constants.VM_OP_NAME;
|
||||
import org.jdrupes.vmoperator.util.FsdUtils;
|
||||
import org.jgrapes.core.Component;
|
||||
import org.jgrapes.core.Components;
|
||||
|
|
|
|||
|
|
@ -43,10 +43,12 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import static org.jdrupes.vmoperator.manager.Constants.VM_OP_GROUP;
|
||||
import org.jdrupes.vmoperator.manager.VmDefChanged.Type;
|
||||
import static org.jdrupes.vmoperator.util.Constants.VM_OP_GROUP;
|
||||
import org.jdrupes.vmoperator.util.Convertions;
|
||||
import org.jdrupes.vmoperator.util.ExtendedObjectWrapper;
|
||||
import org.jdrupes.vmoperator.util.GsonPtr;
|
||||
import org.jdrupes.vmoperator.util.K8s;
|
||||
import org.jgrapes.core.Channel;
|
||||
import org.jgrapes.core.Component;
|
||||
import org.jgrapes.core.annotation.Handler;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ import java.io.IOException;
|
|||
import java.io.StringWriter;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
import org.jdrupes.vmoperator.util.GsonPtr;
|
||||
import org.jdrupes.vmoperator.util.K8s;
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
|
|
|
|||
|
|
@ -44,9 +44,11 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import static org.jdrupes.vmoperator.manager.Constants.VM_OP_GROUP;
|
||||
import static org.jdrupes.vmoperator.manager.Constants.VM_OP_KIND_VM;
|
||||
import static org.jdrupes.vmoperator.manager.Constants.APP_NAME;
|
||||
import org.jdrupes.vmoperator.manager.VmDefChanged.Type;
|
||||
import static org.jdrupes.vmoperator.util.Constants.VM_OP_GROUP;
|
||||
import static org.jdrupes.vmoperator.util.Constants.VM_OP_KIND_VM;
|
||||
import static org.jdrupes.vmoperator.util.Constants.VM_OP_NAME;
|
||||
import org.jgrapes.core.Channel;
|
||||
import org.jgrapes.core.Component;
|
||||
import org.jgrapes.core.Components;
|
||||
|
|
@ -132,7 +134,7 @@ public class VmWatcher extends Component {
|
|||
for (var version : vmOpApiVersions) {
|
||||
coa.getAPIResources(VM_OP_GROUP, version)
|
||||
.getResources().stream()
|
||||
.filter(r -> Constants.VM_OP_KIND_VM.equals(r.getKind()))
|
||||
.filter(r -> VM_OP_KIND_VM.equals(r.getKind()))
|
||||
.findFirst()
|
||||
.ifPresent(crd -> watchVmDefs(crd, version));
|
||||
}
|
||||
|
|
@ -148,15 +150,15 @@ public class VmWatcher extends Component {
|
|||
// Get all known CR instances.
|
||||
coa.getAPIResources(VM_OP_GROUP, version)
|
||||
.getResources().stream()
|
||||
.filter(r -> Constants.VM_OP_KIND_VM.equals(r.getKind()))
|
||||
.filter(r -> VM_OP_KIND_VM.equals(r.getKind()))
|
||||
.findFirst()
|
||||
.ifPresent(crd -> known.addAll(getKnown(client, crd, version)));
|
||||
}
|
||||
|
||||
ListOptions opts = new ListOptions();
|
||||
opts.setLabelSelector(
|
||||
"app.kubernetes.io/managed-by=" + Constants.VM_OP_NAME + ","
|
||||
+ "app.kubernetes.io/name=" + Constants.APP_NAME);
|
||||
"app.kubernetes.io/managed-by=" + VM_OP_NAME + ","
|
||||
+ "app.kubernetes.io/name=" + APP_NAME);
|
||||
for (String resource : List.of("apps/v1/statefulsets",
|
||||
"v1/configmaps", "v1/secrets")) {
|
||||
var resParts = new LinkedList<>(List.of(resource.split("/")));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue