tt = Optional.empty();
try {
log.debug("beforeAll");
- // openShiftRecorderService().initFilters(extensionContext);
- Intersmash[] intersmashes = extensionContext.getRequiredTestClass().getAnnotationsByType(Intersmash.class);
- Intersmash intersmash;
- if (intersmashes.length > 0) {
- intersmash = intersmashes[0];
- } else {
+ // let's store the Intersmash definition in the extension context store
+ Intersmash intersmash = IntersmashExtensionHelper.getIntersmash(extensionContext);
+ if (intersmash == null) {
+ log.warn("No @Intersmah definition stored by Intersmash extensions");
return;
}
-
// we don't want to touch anything if the deployment phase is skipped
if (!IntersmashConfig.skipDeploy()) {
- if (Arrays.stream(intersmash.value())
- .anyMatch(app -> OpenShiftApplication.class.isAssignableFrom(app.value()))) {
- if (!IntersmashConfig.isOcp3x(OpenShifts.admin())) {
- operatorCleanup();
- log.debug("Deploy operatorgroup [{}] to enable operators subscription into tested namespace",
- OperatorGroup.SINGLE_NAMESPACE.getMetadata().getName());
- OpenShifts.adminBinary().execute("apply", "-f",
- OperatorGroup.SINGLE_NAMESPACE.save().getAbsolutePath());
+ if (IntersmashExtensionHelper.isIntersmashTargetingOperator(extensionContext)) {
+ final boolean cleanupKubernetes = IntersmashExtensionHelper
+ .isIntersmashTargetingKubernetes(extensionContext) && !IntersmashConfig.isOcp3x(OpenShifts.admin()),
+ cleanupOpenShift = IntersmashExtensionHelper.isIntersmashTargetingOpenShift(extensionContext)
+ && !IntersmashConfig.isOcp3x(OpenShifts.admin());
+ operatorCleanup(cleanupKubernetes, cleanupOpenShift);
+ deployOperatorGroup(extensionContext);
+
+ if (IntersmashExtensionHelper.isIntersmashTargetingOpenShift(extensionContext)) {
+ OpenShifts.master().clean().waitFor();
+ }
+ if (IntersmashExtensionHelper.isIntersmashTargetingKubernetes(extensionContext)) {
+ Kuberneteses.master().clean().waitFor();
}
- OpenShifts.master().clean().waitFor();
}
}
@@ -91,7 +87,7 @@ public void beforeAll(ExtensionContext extensionContext) throws Exception {
// store provisioners right now, those might be needed in each phase independently
Provisioner provisioner = ProvisionerManager.getProvisioner(application);
// keep the provisioner in the JUpiter Extension Store
- getProvisioners(extensionContext).put(application.getClass().getName(), provisioner);
+ IntersmashExtensionHelper.getProvisioners(extensionContext).put(application.getClass().getName(), provisioner);
if (!IntersmashConfig.skipDeploy()) {
deployApplication(provisioner);
}
@@ -104,6 +100,22 @@ public void beforeAll(ExtensionContext extensionContext) throws Exception {
}
}
+ private static void deployOperatorGroup(ExtensionContext extensionContext) throws IOException {
+ if (IntersmashExtensionHelper.isIntersmashTargetingKubernetes(extensionContext)) {
+ log.debug("Deploy operatorgroup [{}] to enable operators subscription into tested namespace",
+ new OperatorGroup(KubernetesConfig.namespace()).getMetadata().getName());
+ OpenShifts.adminBinary().execute("apply", "-f",
+ new OperatorGroup(KubernetesConfig.namespace()).save().getAbsolutePath());
+ }
+ if (IntersmashExtensionHelper.isIntersmashTargetingOpenShift(extensionContext)
+ && !IntersmashConfig.isOcp3x(OpenShifts.admin())) {
+ log.debug("Deploy operatorgroup [{}] to enable operators subscription into tested namespace",
+ new OperatorGroup(OpenShiftConfig.namespace()).getMetadata().getName());
+ OpenShifts.adminBinary().execute("apply", "-f",
+ new OperatorGroup(OpenShiftConfig.namespace()).save().getAbsolutePath());
+ }
+ }
+
private Application getApplicationFromService(Service service) {
try {
return service.value().getConstructor().newInstance();
@@ -141,32 +153,48 @@ public void afterAll(ExtensionContext extensionContext) {
if (IntersmashConfig.skipUndeploy()) {
log.info("Skipping the after test cleanup operations.");
} else {
- for (Provisioner provisioner : getProvisioners(extensionContext).values()) {
+ for (Provisioner provisioner : IntersmashExtensionHelper.getProvisioners(extensionContext).values()) {
undeployApplication(provisioner);
}
// operator group is not bound to a specific product
// no Operator support on OCP3 clusters, OLM doesn't run there
- if (!IntersmashConfig.isOcp3x(OpenShifts.admin())) {
- operatorCleanup();
+ if (IntersmashExtensionHelper.isIntersmashTargetingOperator(extensionContext)) {
+ final boolean cleanupKubernetes = IntersmashExtensionHelper.isIntersmashTargetingKubernetes(extensionContext)
+ && !IntersmashConfig.isOcp3x(OpenShifts.admin()),
+ cleanupOpenShift = IntersmashExtensionHelper.isIntersmashTargetingOpenShift(extensionContext)
+ && !IntersmashConfig.isOcp3x(OpenShifts.admin());
+ operatorCleanup(cleanupKubernetes, cleanupOpenShift);
}
// let's cleanup once we're done
- safetyCleanup();
+ safetyCleanup(extensionContext);
}
}
- private static void safetyCleanup() {
+ private static void safetyCleanup(ExtensionContext extensionContext) {
log.info("Cleaning up the remaining resources on the cluster.");
- OpenShifts.master().clean().waitFor();
+ if (IntersmashExtensionHelper.isIntersmashTargetingOpenShift(extensionContext)) {
+ OpenShifts.master().clean().waitFor();
+ }
+ if (IntersmashExtensionHelper.isIntersmashTargetingKubernetes(extensionContext)) {
+ Kuberneteses.master().clean().waitFor();
+ }
}
/**
* Clean all OLM related objects.
*
*/
- public static void operatorCleanup() {
- OpenShifts.adminBinary().execute("delete", "subscription", "--all");
- OpenShifts.adminBinary().execute("delete", "csvs", "--all");
- OpenShifts.adminBinary().execute("delete", "operatorgroup", "--all");
+ public static void operatorCleanup(final boolean cleanupKubernetes, final boolean cleanupOpenShift) {
+ if (cleanupKubernetes) {
+ Kuberneteses.adminBinary().execute("delete", "subscription", "--all");
+ Kuberneteses.adminBinary().execute("delete", "csvs", "--all");
+ Kuberneteses.adminBinary().execute("delete", "operatorgroup", "--all");
+ }
+ if (cleanupOpenShift) {
+ OpenShifts.adminBinary().execute("delete", "subscription", "--all");
+ OpenShifts.adminBinary().execute("delete", "csvs", "--all");
+ OpenShifts.adminBinary().execute("delete", "operatorgroup", "--all");
+ }
}
@Override
@@ -175,23 +203,13 @@ public void postProcessTestInstance(Object o, ExtensionContext extensionContext)
injectServiceProvisioner(o, extensionContext);
}
- private Map getProvisioners(ExtensionContext extensionContext) {
- Store store = extensionContext.getStore(NAMESPACE);
- Map provisioners = (Map) store.get(INTERSMASH_SERVICES);
- if (provisioners != null) {
- return provisioners;
- } else {
- store.put(INTERSMASH_SERVICES, new HashMap());
- return (Map) store.get(INTERSMASH_SERVICES);
- }
- }
-
private void injectServiceUrl(Object o, ExtensionContext extensionContext) throws Exception {
log.debug("injectServiceUrl");
List annotatedFields = AnnotationSupport.findAnnotatedFields(o.getClass(), ServiceUrl.class);
for (Field field : annotatedFields) {
ServiceUrl serviceUrl = field.getAnnotation(ServiceUrl.class);
- Provisioner provisioner = getProvisioners(extensionContext).get(serviceUrl.value().getName());
+ Provisioner provisioner = IntersmashExtensionHelper.getProvisioners(extensionContext)
+ .get(serviceUrl.value().getName());
URL url = provisioner.getURL();
if (String.class.isAssignableFrom(field.getType())) {
field.setAccessible(true);
@@ -211,7 +229,8 @@ private void injectServiceProvisioner(Object o, ExtensionContext extensionContex
List annotatedFields = AnnotationSupport.findAnnotatedFields(o.getClass(), ServiceProvisioner.class);
for (Field field : annotatedFields) {
ServiceProvisioner serviceProvisioner = field.getAnnotation(ServiceProvisioner.class);
- Provisioner provisioner = getProvisioners(extensionContext).get(serviceProvisioner.value().getName());
+ Provisioner provisioner = IntersmashExtensionHelper.getProvisioners(extensionContext)
+ .get(serviceProvisioner.value().getName());
if (Provisioner.class.isAssignableFrom(field.getType())) {
field.setAccessible(true);
field.set(o, provisioner);
diff --git a/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/junit5/IntersmashExtensionHelper.java b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/junit5/IntersmashExtensionHelper.java
new file mode 100644
index 00000000..c6a4ff3f
--- /dev/null
+++ b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/junit5/IntersmashExtensionHelper.java
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2023 Red Hat, Inc.
+ *
+ * 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 org.jboss.intersmash.tools.junit5;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.intersmash.tools.annotations.Intersmash;
+import org.jboss.intersmash.tools.application.k8s.KubernetesApplication;
+import org.jboss.intersmash.tools.application.openshift.OpenShiftApplication;
+import org.jboss.intersmash.tools.application.operator.OperatorApplication;
+import org.jboss.intersmash.tools.provision.Provisioner;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+public class IntersmashExtensionHelper {
+
+ private static final ExtensionContext.Namespace NAMESPACE = ExtensionContext.Namespace.create("org", "jboss", "intersmash",
+ "IntersmashExtension");
+ private static final String INTERSMASH_SERVICES = "INTERSMASH_SERVICES";
+ private static final String INTERSMASH = "INTERSMASH";
+
+ public static Map getProvisioners(ExtensionContext extensionContext) {
+ ExtensionContext.Store store = extensionContext.getStore(NAMESPACE);
+ Map provisioners = (Map) store.get(INTERSMASH_SERVICES);
+ if (provisioners != null) {
+ return provisioners;
+ } else {
+ store.put(INTERSMASH_SERVICES, new HashMap());
+ return (Map) store.get(INTERSMASH_SERVICES);
+ }
+ }
+
+ public static Intersmash getIntersmash(ExtensionContext extensionContext) {
+ ExtensionContext.Store store = extensionContext.getStore(NAMESPACE);
+ Intersmash result = (Intersmash) store.get(INTERSMASH);
+ if (result != null) {
+ return result;
+ } else {
+ Intersmash[] intersmashes = extensionContext.getRequiredTestClass().getAnnotationsByType(Intersmash.class);
+ if (intersmashes.length > 0) {
+ store.put(INTERSMASH, intersmashes[0]);
+ return (Intersmash) store.get(INTERSMASH);
+ }
+ return null;
+ }
+ }
+
+ public static Boolean isIntersmashTargetingOpenShift(ExtensionContext extensionContext) {
+ return Arrays.stream(getIntersmash(extensionContext).value())
+ .anyMatch(app -> OpenShiftApplication.class.isAssignableFrom(app.value()));
+ }
+
+ public static Boolean isIntersmashTargetingOperator(ExtensionContext extensionContext) {
+ return Arrays.stream(getIntersmash(extensionContext).value())
+ .anyMatch(app -> OperatorApplication.class.isAssignableFrom(app.value()));
+ }
+
+ public static Boolean isIntersmashTargetingKubernetes(ExtensionContext extensionContext) {
+ return Arrays.stream(getIntersmash(extensionContext).value())
+ .anyMatch(app -> KubernetesApplication.class.isAssignableFrom(app.value()));
+ }
+}
diff --git a/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/k8s/KubernetesProvisioner.java b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/k8s/KubernetesProvisioner.java
new file mode 100644
index 00000000..c981d63b
--- /dev/null
+++ b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/k8s/KubernetesProvisioner.java
@@ -0,0 +1,102 @@
+/**
+ * Copyright (C) 2023 Red Hat, Inc.
+ *
+ * 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 org.jboss.intersmash.tools.provision.k8s;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.intersmash.tools.application.Application;
+import org.jboss.intersmash.tools.application.openshift.HasConfigMaps;
+import org.jboss.intersmash.tools.application.openshift.HasSecrets;
+import org.jboss.intersmash.tools.k8s.client.Kubernetes;
+import org.jboss.intersmash.tools.k8s.client.Kuberneteses;
+import org.jboss.intersmash.tools.provision.Provisioner;
+import org.jboss.intersmash.tools.provision.openshift.HasPods;
+import org.jboss.intersmash.tools.provision.openshift.Scalable;
+
+import io.fabric8.kubernetes.api.model.Secret;
+import io.fabric8.kubernetes.api.model.SecretBuilder;
+
+/**
+ * Provisioner that is supposed to deploy an application on Kubernetes.
+ */
+public interface KubernetesProvisioner extends Provisioner, Scalable, HasPods {
+
+ Kubernetes kubernetes = Kuberneteses.master();
+
+ static Secret createTlsSecret(final String namespace, final String secretName, final Path key, final Path certificate)
+ throws IOException {
+ Map data = new HashMap<>();
+ String keyDerData = Files.readString(key);
+ String crtDerData = Files.readString(certificate);
+ data.put("tls.key", Base64.getEncoder().encodeToString(keyDerData.getBytes()));
+ data.put("tls.crt", Base64.getEncoder().encodeToString(crtDerData.getBytes()));
+ final Secret secret = new SecretBuilder()
+ .withNewMetadata().withName(secretName).endMetadata()
+ .withType("kubernetes.io/tls")
+ .withImmutable(false)
+ .addToData(data)
+ .build();
+ return kubernetes.secrets().inNamespace(namespace).createOrReplace(secret);
+ }
+
+ @Override
+ default void preDeploy() {
+ // create secrets
+ if (HasSecrets.class.isAssignableFrom(getApplication().getClass())) {
+ ((HasSecrets) getApplication()).getSecrets().forEach(s -> kubernetes.secrets().create(s));
+ }
+ // create configMaps
+ if (HasConfigMaps.class.isAssignableFrom(getApplication().getClass())) {
+ ((HasConfigMaps) getApplication()).getConfigMaps().forEach(c -> kubernetes.configMaps().create(c));
+ }
+ }
+
+ @Override
+ default void postUndeploy() {
+ // delete secrets
+ if (HasSecrets.class.isAssignableFrom(getApplication().getClass())) {
+ ((HasSecrets) getApplication()).getSecrets().forEach(s -> kubernetes.secrets().delete(s));
+ }
+ // delete configMaps
+ if (HasConfigMaps.class.isAssignableFrom(getApplication().getClass())) {
+ ((HasConfigMaps) getApplication()).getConfigMaps().forEach(c -> kubernetes.configMaps().delete(c));
+ }
+ }
+
+ // TODO - check (use a static class method like XTF OpenShift::generateHostName ?)
+ default String getUrl(String routeName, boolean secure) {
+ String protocol = secure ? "https" : "http";
+ return protocol + "://" + kubernetes.getMasterUrl() + "-" + routeName + "-"
+ + kubernetes.getConfiguration().getNamespace();
+ }
+
+ @Override
+ default URL getURL() {
+ try {
+ return new URL(getUrl(getApplication().getName(), false));
+ } catch (MalformedURLException ex) {
+ throw new RuntimeException(
+ String.format("Failed to get an URL for the \"%s\" route", this.getClass().getSimpleName()), ex);
+ }
+ }
+}
diff --git a/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/OpenShiftProvisioner.java b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/OpenShiftProvisioner.java
index d7f80a2b..6163c87e 100644
--- a/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/OpenShiftProvisioner.java
+++ b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/OpenShiftProvisioner.java
@@ -15,26 +15,50 @@
*/
package org.jboss.intersmash.tools.provision.openshift;
+import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+import org.jboss.intersmash.tools.application.Application;
import org.jboss.intersmash.tools.application.openshift.HasConfigMaps;
import org.jboss.intersmash.tools.application.openshift.HasSecrets;
-import org.jboss.intersmash.tools.application.openshift.OpenShiftApplication;
import org.jboss.intersmash.tools.provision.Provisioner;
import cz.xtf.core.openshift.OpenShift;
import cz.xtf.core.openshift.OpenShifts;
+import io.fabric8.kubernetes.api.model.Secret;
+import io.fabric8.kubernetes.api.model.SecretBuilder;
/**
* Provisioner that is supposed to deploy an application on OpenShift.
*/
-public interface OpenShiftProvisioner extends Provisioner, Scalable, HasPods {
+public interface OpenShiftProvisioner extends Provisioner, Scalable, HasPods {
String SCRIPT_DEBUG = "SCRIPT_DEBUG";
String APP_LABEL_KEY = "intersmash.app";
OpenShift openShift = OpenShifts.master();
+ static Secret createTlsSecret(final String namespace, final String secretName, final Path key, final Path certificate)
+ throws IOException {
+ Map data = new HashMap<>();
+ String keyDerData = Files.readString(key);
+ String crtDerData = Files.readString(certificate);
+ data.put("tls.key", Base64.getEncoder().encodeToString(keyDerData.getBytes()));
+ data.put("tls.crt", Base64.getEncoder().encodeToString(crtDerData.getBytes()));
+ final Secret secret = new SecretBuilder()
+ .withNewMetadata().withName(secretName).endMetadata()
+ .withType("kubernetes.io/tls")
+ .withImmutable(false)
+ .addToData(data)
+ .build();
+ return openShift.secrets().inNamespace(namespace).createOrReplace(secret);
+ }
+
@Override
default void preDeploy() {
// create secrets
diff --git a/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/WaitersUtil.java b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/WaitersUtil.java
index 2a1c5765..d2b53779 100644
--- a/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/WaitersUtil.java
+++ b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/WaitersUtil.java
@@ -21,6 +21,7 @@
import java.util.stream.Collectors;
import cz.xtf.core.http.Https;
+import cz.xtf.core.http.HttpsException;
import cz.xtf.core.openshift.OpenShift;
import cz.xtf.core.waiting.SimpleWaiter;
import cz.xtf.core.waiting.Waiter;
@@ -66,8 +67,13 @@ public static Waiter serviceEndpointsAreReady(OpenShift openShift, String servic
}
public static Waiter routeIsUp(String routeURL) {
- return new SimpleWaiter(
- () -> Https.getCode(routeURL) != 503)
- .reason("Wait until the route is ready to serve.");
+ return new SimpleWaiter(() ->
+ {
+ try {
+ return Https.getCode(routeURL) != 503;
+ } catch (HttpsException ex) {
+ return false;
+ }
+ }).reason("Wait until the route is ready to serve.");
}
}
diff --git a/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/operator/resources/CatalogSource.java b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/operator/resources/CatalogSource.java
index b7e30e59..48199818 100644
--- a/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/operator/resources/CatalogSource.java
+++ b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/operator/resources/CatalogSource.java
@@ -15,7 +15,6 @@
*/
package org.jboss.intersmash.tools.provision.openshift.operator.resources;
-import cz.xtf.core.openshift.OpenShifts;
import io.fabric8.openshift.api.model.operatorhub.v1alpha1.CatalogSourceBuilder;
public class CatalogSource extends io.fabric8.openshift.api.model.operatorhub.v1alpha1.CatalogSource
@@ -56,22 +55,9 @@ public CatalogSource load(CatalogSource loaded) {
return this;
}
- /**
- * Load CatalogSource by name from OpenShift cluster
- * @param catalogSourceName name of the CatalogSource e.g. certified-operators, community-operators,
- * redhat-marketplace, redhat-operators,...
- * @return CatalogSource
- */
- public CatalogSource load(String catalogSourceName, String catalogSourceNamespace) {
- io.fabric8.openshift.api.model.operatorhub.v1alpha1.CatalogSource catalogSource = OpenShifts
- .admin(catalogSourceNamespace).operatorHub()
- .catalogSources().list().getItems()
- .stream().filter(cs -> cs.getMetadata().getName().equalsIgnoreCase(catalogSourceName))
- .findFirst().orElseThrow(
- () -> new IllegalStateException(
- "Unable to retrieve CatalogSource " + catalogSourceName));
- this.setMetadata(catalogSource.getMetadata());
- this.setSpec(catalogSource.getSpec());
+ public CatalogSource load(io.fabric8.openshift.api.model.operatorhub.v1alpha1.CatalogSource loaded) {
+ this.setMetadata(loaded.getMetadata());
+ this.setSpec(loaded.getSpec());
return this;
}
}
diff --git a/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/operator/resources/OperatorGroup.java b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/operator/resources/OperatorGroup.java
index 700033f9..17e55f06 100644
--- a/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/operator/resources/OperatorGroup.java
+++ b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/operator/resources/OperatorGroup.java
@@ -21,7 +21,6 @@
import java.util.Map;
import java.util.Objects;
-import cz.xtf.core.config.OpenShiftConfig;
import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.model.annotation.Group;
import io.fabric8.kubernetes.model.annotation.Version;
@@ -35,7 +34,6 @@
@Group("operators.coreos.com")
@Version("v1")
public class OperatorGroup extends CustomResource implements OpenShiftResource {
- public static final OperatorGroup SINGLE_NAMESPACE = new OperatorGroup(OpenShiftConfig.namespace());
private Map> spec = new HashMap<>();
public OperatorGroup() {
diff --git a/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/operator/resources/Subscription.java b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/operator/resources/Subscription.java
index 2515d18a..01313774 100644
--- a/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/operator/resources/Subscription.java
+++ b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/operator/resources/Subscription.java
@@ -20,7 +20,6 @@
import org.assertj.core.util.Strings;
-import cz.xtf.core.config.OpenShiftConfig;
import io.fabric8.kubernetes.api.model.EnvVar;
import io.fabric8.openshift.api.model.operatorhub.v1alpha1.SubscriptionBuilder;
import io.fabric8.openshift.api.model.operatorhub.v1alpha1.SubscriptionFluent;
@@ -43,13 +42,13 @@ public Subscription() {
super();
}
- private SubscriptionFluent.SpecNested getConfiguredSubscriptionBuilder(String sourceNamespace,
- String source, String name, String channel,
- String installPlanApproval) {
+ private SubscriptionFluent.SpecNested getConfiguredSubscriptionBuilder(final String sourceNamespace,
+ final String source, final String name, final String channel, final String installPlanApproval,
+ final String targetNamespace) {
return new SubscriptionBuilder()
.withNewMetadata()
.withName(name)
- .withNamespace(OpenShiftConfig.namespace())
+ .withNamespace(targetNamespace)
.endMetadata()
.withNewSpec()
.withChannel(channel)
@@ -59,11 +58,12 @@ private SubscriptionFluent.SpecNested getConfiguredSubscrip
.withInstallPlanApproval(Strings.isNullOrEmpty(installPlanApproval) ? "Automatic" : installPlanApproval);
}
- public Subscription(String sourceNamespace, String source, String name, String channel, String installPlanApproval,
- Map envVariables) {
+ public Subscription(final String sourceNamespace, final String source, final String name, final String channel,
+ final String installPlanApproval,
+ final Map envVariables, final String targetNamespace) {
this();
io.fabric8.openshift.api.model.operatorhub.v1alpha1.Subscription loaded = getConfiguredSubscriptionBuilder(
- sourceNamespace, source, name, channel, installPlanApproval)
+ sourceNamespace, source, name, channel, installPlanApproval, targetNamespace)
.withNewConfig()
.addAllToEnv(
envVariables.entrySet().stream()
@@ -76,10 +76,11 @@ public Subscription(String sourceNamespace, String source, String name, String c
this.setSpec(loaded.getSpec());
}
- public Subscription(String sourceNamespace, String source, String name, String channel, String installPlanApproval) {
+ public Subscription(final String sourceNamespace, final String source, final String name, final String channel,
+ final String installPlanApproval, final String targetNamespace) {
this();
io.fabric8.openshift.api.model.operatorhub.v1alpha1.Subscription loaded = getConfiguredSubscriptionBuilder(
- sourceNamespace, source, name, channel, installPlanApproval)
+ sourceNamespace, source, name, channel, installPlanApproval, targetNamespace)
.endSpec()
.build();
this.setMetadata(loaded.getMetadata());
diff --git a/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/operator/OlmOperatorProvisioner.java b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/operator/OlmOperatorProvisioner.java
new file mode 100644
index 00000000..388b7cec
--- /dev/null
+++ b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/operator/OlmOperatorProvisioner.java
@@ -0,0 +1,67 @@
+package org.jboss.intersmash.tools.provision.operator;
+
+import java.util.List;
+
+import org.jboss.intersmash.tools.application.operator.OperatorApplication;
+import org.jboss.intersmash.tools.provision.Provisioner;
+import org.jboss.intersmash.tools.provision.openshift.HasPods;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import io.fabric8.kubernetes.api.model.Pod;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinitionList;
+import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
+import io.fabric8.kubernetes.client.dsl.Resource;
+import io.fabric8.openshift.api.model.operatorhub.lifecyclemanager.v1.PackageManifest;
+import io.fabric8.openshift.api.model.operatorhub.v1alpha1.CatalogSource;
+import io.fabric8.openshift.api.model.operatorhub.v1alpha1.CatalogSourceList;
+
+public interface OlmOperatorProvisioner
+ extends Provisioner, OlmOperatorProvisionerClientBinary, HasPods {
+
+ default PackageManifest getPackageManifest(String operatorName, String operatorNamespace) {
+ try {
+ return new ObjectMapper()
+ .readValue(this.execute("get", "packagemanifest", operatorName, "-n", operatorNamespace, "-o", "json"),
+ PackageManifest.class);
+ } catch (JsonProcessingException e) {
+ throw new IllegalStateException("Couldn't deserialize package manifest data: " + operatorName, e);
+ }
+ }
+
+ List retrievePods();
+
+ default List getCatalogSources(final String catalogSourceNamespace) {
+ try {
+ return new ObjectMapper().readValue(this.execute("get", "catsrc", "-n", catalogSourceNamespace, "-o", "json"),
+ CatalogSourceList.class).getItems();
+ } catch (JsonProcessingException e) {
+ throw new IllegalStateException("Couldn't deserialize catalog source data: " + catalogSourceNamespace, e);
+ }
+ }
+
+ default CatalogSource getCatalogSource(final String catalogSourceNamespace, final String catalogSourceName) {
+ io.fabric8.openshift.api.model.operatorhub.v1alpha1.CatalogSource loaded = getCatalogSources(catalogSourceNamespace)
+ .stream()
+ .filter(cs -> cs.getMetadata().getName().equalsIgnoreCase(catalogSourceName))
+ .findFirst().orElseThrow(
+ () -> new IllegalStateException(
+ "Unable to retrieve CatalogSource " + catalogSourceName));
+ CatalogSource catalogSource = new CatalogSource();
+ catalogSource.setMetadata(loaded.getMetadata());
+ catalogSource.setSpec(loaded.getSpec());
+ return catalogSource;
+ }
+
+ String execute(String... args);
+
+ NonNamespaceOperation> retrieveCustomResourceDefinitions();
+
+ boolean isSubscribed();
+
+ void subscribe();
+
+ void unsubscribe();
+}
diff --git a/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/operator/OlmOperatorProvisionerClientBinary.java b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/operator/OlmOperatorProvisionerClientBinary.java
new file mode 100644
index 00000000..795f2d96
--- /dev/null
+++ b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/operator/OlmOperatorProvisionerClientBinary.java
@@ -0,0 +1,6 @@
+package org.jboss.intersmash.tools.provision.operator;
+
+public interface OlmOperatorProvisionerClientBinary {
+
+ String execute(String... args);
+}
diff --git a/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/operator/OperatorProvisioner.java b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/operator/OperatorProvisioner.java
similarity index 81%
rename from tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/operator/OperatorProvisioner.java
rename to tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/operator/OperatorProvisioner.java
index fd795d61..e8a921a4 100644
--- a/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/openshift/operator/OperatorProvisioner.java
+++ b/tools/intersmash-tools-core/src/main/java/org/jboss/intersmash/tools/provision/operator/OperatorProvisioner.java
@@ -13,32 +13,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jboss.intersmash.tools.provision.openshift.operator;
+package org.jboss.intersmash.tools.provision.operator;
import java.io.IOException;
-import java.net.URL;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
-import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.BooleanSupplier;
import java.util.stream.Collectors;
import org.assertj.core.util.Strings;
import org.jboss.intersmash.tools.IntersmashConfig;
-import org.jboss.intersmash.tools.application.openshift.OperatorApplication;
-import org.jboss.intersmash.tools.provision.openshift.OpenShiftProvisioner;
-import org.jboss.intersmash.tools.provision.openshift.operator.resources.CatalogSource;
+import org.jboss.intersmash.tools.application.operator.OperatorApplication;
import org.jboss.intersmash.tools.provision.openshift.operator.resources.Subscription;
import org.slf4j.event.Level;
-import cz.xtf.core.config.OpenShiftConfig;
-import cz.xtf.core.openshift.OpenShift;
-import cz.xtf.core.openshift.OpenShiftBinary;
-import cz.xtf.core.openshift.OpenShiftWaiters;
-import cz.xtf.core.openshift.OpenShifts;
import cz.xtf.core.waiting.SimpleWaiter;
import cz.xtf.core.waiting.failfast.FailFastCheck;
import dev.failsafe.Failsafe;
@@ -46,6 +39,8 @@
import io.fabric8.openshift.api.model.operatorhub.lifecyclemanager.v1.PackageChannel;
import io.fabric8.openshift.api.model.operatorhub.lifecyclemanager.v1.PackageManifest;
import io.fabric8.openshift.api.model.operatorhub.v1alpha1.CRDDescription;
+import io.fabric8.openshift.api.model.operatorhub.v1alpha1.CatalogSource;
+import io.fabric8.openshift.api.model.operatorhub.v1alpha1.CatalogSourceBuilder;
import lombok.extern.slf4j.Slf4j;
/**
@@ -59,7 +54,7 @@
* oc get clusterserviceversion
*/
@Slf4j
-public abstract class OperatorProvisioner implements OpenShiftProvisioner {
+public abstract class OperatorProvisioner implements OlmOperatorProvisioner {
// cache the current csv and list of provided custom resource definitions
static String currentCSV;
final String packageManifestName;
@@ -68,8 +63,6 @@ public abstract class OperatorProvisioner impleme
private PackageManifest packageManifest;
private String operatorChannel;
protected FailFastCheck ffCheck = () -> false;
- private OpenShift adminShift;
- private OpenShiftBinary adminBinary;
private Set customResourceDefinitions;
private static final RetryPolicy RETRY_POLICY_LOOKUP_MATCHING_PACKAGE_MANIFEST = RetryPolicy
. builder()
@@ -86,9 +79,6 @@ public OperatorProvisioner(T operatorApplication, String packageManifestName) {
@Override
public void configure() {
- this.adminShift = OpenShifts.admin();
- this.adminBinary = OpenShifts.adminBinary();
-
// custom catalog source initialization
catalogSource = initCatalogSource();
@@ -123,17 +113,15 @@ public void configure() {
protected abstract String getOperatorChannel();
+ protected abstract String getOperatorNamespace();
+
/**
* The CatalogSource is in the "openshift-marketplace" namespace by default;
* When a custom operator image must be used, then a custom CatalogSource will be created in the current namespace; *
* @return namespace where the custom CatalogSource is located
*/
- private String getCatalogSourceNamespace() {
- String namespace = IntersmashConfig.defaultOperatorCatalogSourceNamespace(); // default namespace for CatalogSources
- if (!Strings.isNullOrEmpty(getOperatorIndexImage())) {
- namespace = OpenShiftConfig.namespace();
- }
- return namespace;
+ protected String getCatalogSourceNamespace() {
+ return IntersmashConfig.defaultOperatorCatalogSourceNamespace(); // default namespace for CatalogSources
}
/**
@@ -185,20 +173,28 @@ private CatalogSource initCatalogSource() {
catalogSourceName = operatorCatalogSource;
}
// create CatalogSource pointing to our custom IndexImage
- catalogSource = new CatalogSource(
- // a composite name is needed in order to avoid conflicts in case of multiple custom CatalogSources
- catalogSourceName,
- operatorCatalogSourceNamespace,
- "grpc",
- operatorIndexImage,
- catalogSourceName,
- "jboss-tests@redhat.com");
+ catalogSource = new CatalogSourceBuilder()
+ .withNewMetadata()
+ .withName(catalogSourceName)
+ .withNamespace(operatorCatalogSourceNamespace)
+ .endMetadata()
+ .withNewSpec()
+ .withSourceType("grpc")
+ .withImage(operatorIndexImage)
+ .withDisplayName(catalogSourceName)
+ .withPublisher("intersmash@intersmash.org")
+ .endSpec()
+ .build();
try {
- adminBinary.execute("apply", "-f", catalogSource.save().getAbsolutePath());
+ this.execute("apply", "-f",
+ new org.jboss.intersmash.tools.provision.openshift.operator.resources.CatalogSource()
+ .load(catalogSource)
+ .save()
+ .getAbsolutePath());
AtomicReference catalogSourceStatus = new AtomicReference<>();
new SimpleWaiter(() -> {
// oc get CatalogSource redhat-operators -n openshift-marketplace -o template --template {{.status.connectionState.lastObservedState}}
- catalogSourceStatus.set(adminBinary.execute("get", "CatalogSource", catalogSource.getMetadata().getName(),
+ catalogSourceStatus.set(this.execute("get", "CatalogSource", catalogSource.getMetadata().getName(),
"-n", operatorCatalogSourceNamespace,
"-o", "template", "--template",
"{{.status.connectionState.lastObservedState}}",
@@ -220,27 +216,22 @@ private CatalogSource initCatalogSource() {
}
} else {
// load CatalogSource by name from OpenShift cluster
- catalogSource = new CatalogSource();
- catalogSource.load(operatorCatalogSource,
- IntersmashConfig.defaultOperatorCatalogSourceNamespace());
+ catalogSource = getCatalogSource(IntersmashConfig.defaultOperatorCatalogSourceNamespace(), operatorCatalogSource);
}
return catalogSource;
}
private PackageManifest initPackageManifest() {
log.debug("Listing package manifests belonging to: " + this.catalogSource.getMetadata().getName());
- List catalogSourcePackageManifests = adminShift.operatorHub().packageManifests().list().getItems()
- .stream()
- .filter(pm -> this.catalogSource.getMetadata().getName().equals(pm.getStatus().getCatalogSource()))
- .collect(Collectors.toList());
- catalogSourcePackageManifests.stream()
- .forEach(pm -> log.debug("---> " + pm.getMetadata().getName()));
- return catalogSourcePackageManifests.stream()
- .filter(pm -> this.packageManifestName.equals(pm.getMetadata().getName()))
- .findFirst().orElseThrow(
- () -> new IllegalStateException(
- "Unable to retrieve PackageManifest " + this.packageManifestName + " in CatalogSource "
- + this.catalogSource.getMetadata().getName()));
+ PackageManifest catalogSourcePackageManifest = this.getPackageManifest(this.packageManifestName,
+ this.getOperatorNamespace());
+ if (catalogSourcePackageManifest == null) {
+ throw new IllegalStateException(
+ "Unable to retrieve PackageManifest " + this.packageManifestName + " in CatalogSource "
+ + this.catalogSource.getMetadata().getName());
+ }
+ log.debug("---> " + catalogSourcePackageManifest.getMetadata().getName());
+ return catalogSourcePackageManifest;
}
private PackageChannel initPackageChannel(String channelName) {
@@ -306,11 +297,11 @@ public void subscribe(String installPlanApproval, Map envVariabl
// oc get packagemanifest wildfly -o template --template {{.status.defaultChannel}}
Subscription operatorSubscription = (envVariables == null || envVariables.isEmpty())
? new Subscription(getCatalogSourceNamespace(), getOperatorCatalogSource(), packageManifestName,
- operatorChannel, installPlanApproval)
+ operatorChannel, installPlanApproval, getTargetNamespace())
: new Subscription(getCatalogSourceNamespace(), getOperatorCatalogSource(), packageManifestName,
- operatorChannel, installPlanApproval, envVariables);
+ operatorChannel, installPlanApproval, envVariables, getTargetNamespace());
try {
- adminBinary.execute("apply", "-f", operatorSubscription.save().getAbsolutePath());
+ this.execute("apply", "-f", operatorSubscription.save().getAbsolutePath());
} catch (IOException e) {
throw new RuntimeException(String.format("Failed to serialize the %s subscription object into a yaml file.",
operatorSubscription.getMetadata().getName()), e);
@@ -322,7 +313,7 @@ public void subscribe(String installPlanApproval, Map envVariabl
// wait for installPlan to be attached to the subscription
new SimpleWaiter(() -> {
// oc get subscription rhsso-operator -o template --template="{{.status.installplan.name}}"
- installPlan.set(adminBinary.execute("get", "subscription", operatorSubscription.getMetadata().getName(),
+ installPlan.set(this.execute("get", "subscription", operatorSubscription.getMetadata().getName(),
"-o", "template", "--template",
"{{ if .status.installPlanRef.name }}{{.status.installPlanRef.name}}{{ end }}",
"--ignore-not-found"));
@@ -336,7 +327,7 @@ public void subscribe(String installPlanApproval, Map envVariabl
.level(Level.DEBUG)
.failFast(getFailFastCheck())
.waitFor();
- String outcome = adminBinary.execute("patch", "InstallPlan", installPlan.get(),
+ String outcome = this.execute("patch", "InstallPlan", installPlan.get(),
"--type", "merge", "--patch", "{\"spec\":{\"approved\":true}}");
if (!Strings.isNullOrEmpty(outcome) && outcome.contains("patched")) {
log.info("Approved InstallPlan {} for subscription {}",
@@ -350,7 +341,7 @@ public void subscribe(String installPlanApproval, Map envVariabl
}
// oc get clusterserviceversion wildfly-operator.v1.0.0 -o template --template {{.status.phase}}
new SimpleWaiter(() -> {
- String clusterServicePhase = adminBinary.execute("get", "csvs", currentCSV, "-o", "template", "--template",
+ String clusterServicePhase = this.execute("get", "csvs", currentCSV, "-o", "template", "--template",
"{{.status.phase}}", "--ignore-not-found");
// this is the one where the operator image is pulled
return clusterServicePhase != null && clusterServicePhase.equals("Succeeded");
@@ -361,6 +352,8 @@ public void subscribe(String installPlanApproval, Map envVariabl
waitForOperatorPod();
}
+ protected abstract String getTargetNamespace();
+
/**
* Waits for the operator's POD to be ready;
*
@@ -397,7 +390,7 @@ public void subscribe(String installPlanApproval, Map envVariabl
protected void waitForOperatorPod() {
final String metadataNameLabelLegacyName = "name";
final String metadataNameLabelName = "app.kubernetes.io/name";
- String[] operatorSpecs = adminBinary.execute(
+ String[] operatorSpecs = this.execute(
"get",
"csvs",
currentCSV,
@@ -413,8 +406,14 @@ protected void waitForOperatorPod() {
if (operatorSpec.length != 3) {
throw new IllegalStateException("Failed to get operator deployment spec from csvs!");
}
- OpenShiftWaiters.get(openShift, getFailFastCheck())
- .areExactlyNPodsReady(Integer.valueOf(operatorSpec[0]), operatorSpec[1], operatorSpec[2]).level(Level.DEBUG)
+ BooleanSupplier bs = () -> retrievePods().stream()
+ .filter(p -> !com.google.common.base.Strings.isNullOrEmpty(p.getMetadata().getLabels().get(operatorSpec[1]))
+ && p.getMetadata().getLabels().get(operatorSpec[1]).equals(operatorSpec[2]))
+ .collect(Collectors.toList()).size() == Integer.valueOf(operatorSpec[0]);
+ String reason = "Waiting for exactly " + Integer.valueOf(operatorSpec[0]) + " pods with label \"app\"="
+ + getApplication().getName() + " to be ready.";
+ new SimpleWaiter(bs, TimeUnit.MINUTES, 2, reason)
+ .level(Level.DEBUG)
.waitFor();
}
}
@@ -428,45 +427,36 @@ protected FailFastCheck getFailFastCheck() {
* Documentation: https://docs.openshift.com/container-platform/4.4/operators/olm-deleting-operators-from-cluster.html#olm-deleting-operator-from-a-cluster-using-cli_olm-deleting-operators-from-a-cluster
*/
public void unsubscribe() {
- adminBinary.execute("delete", "subscription", packageManifestName, "--ignore-not-found");
- adminBinary.execute("delete", "csvs", currentCSV, "--ignore-not-found");
+ this.execute("delete", "subscription", packageManifestName, "--ignore-not-found");
+ this.execute("delete", "csvs", currentCSV, "--ignore-not-found");
for (String customResource : getCustomResourceDefinitions()) {
- final String crds = adminBinary.execute("get", "crd", customResource, "--ignore-not-found");
+ final String crds = this.execute("get", "crd", customResource, "--ignore-not-found");
if (crds != null && !crds.isEmpty()) {
log.info("CRD: {} is still defined on the cluster", customResource);
}
}
}
- @Override
- public URL getURL() {
- throw new UnsupportedOperationException("To be implemented!");
- }
-
/**
* @return true is there is an active subscription for the current operator
*/
- protected boolean isSubscribed() {
- return !Strings.isNullOrEmpty(adminBinary.execute("get", "subscription", packageManifestName,
+ public boolean isSubscribed() {
+ return !Strings.isNullOrEmpty(this.execute("get", "subscription", packageManifestName,
"-o", "template", "--template",
"{{ .status.state }}",
"--ignore-not-found"));
}
- protected static String getCurrentCSV() {
+ public String getCurrentCSV() {
return currentCSV;
}
- protected OpenShiftBinary getAdminBinary() {
- return adminBinary;
- }
-
@Override
public void dismiss() {
// let's remove any custom catalog source
if (Arrays.stream(IntersmashConfig.getKnownCatalogSources())
.noneMatch(cs -> this.catalogSource.getMetadata().getName().equals(cs))) {
- adminBinary.execute("delete", "catalogsource", catalogSource.getMetadata().getName(), "--ignore-not-found");
+ this.execute("delete", "catalogsource", catalogSource.getMetadata().getName(), "--ignore-not-found");
}
}
}
diff --git a/tools/intersmash-tools-core/src/test/java/org/jboss/intersmash/tools/provision/openshift/operator/resources/SubscriptionTest.java b/tools/intersmash-tools-core/src/test/java/org/jboss/intersmash/tools/provision/openshift/operator/resources/SubscriptionTest.java
index c35a6b19..05f2dac1 100644
--- a/tools/intersmash-tools-core/src/test/java/org/jboss/intersmash/tools/provision/openshift/operator/resources/SubscriptionTest.java
+++ b/tools/intersmash-tools-core/src/test/java/org/jboss/intersmash/tools/provision/openshift/operator/resources/SubscriptionTest.java
@@ -19,10 +19,11 @@
import java.io.IOException;
import java.util.Map;
-import org.jboss.intersmash.tools.provision.openshift.operator.OperatorProvisioner;
+import org.jboss.intersmash.tools.provision.operator.OperatorProvisioner;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import cz.xtf.core.config.OpenShiftConfig;
import io.fabric8.kubernetes.api.model.EnvVar;
public class SubscriptionTest {
@@ -43,7 +44,8 @@ public void testEnv() throws IOException {
"PROP_1", propertyValue,
"PROP_2", propertyValue,
"PROP_3", propertyValue,
- "PROP_4", "a different value"));
+ "PROP_4", "a different value"),
+ OpenShiftConfig.namespace());
File subscriptionFile = subscription.save();
Subscription loadedSubscription = new Subscription();
loadedSubscription.load(subscriptionFile);
diff --git a/tools/intersmash-tools-provisioners/pom.xml b/tools/intersmash-tools-provisioners/pom.xml
index 03f36a3c..c688c2ec 100644
--- a/tools/intersmash-tools-provisioners/pom.xml
+++ b/tools/intersmash-tools-provisioners/pom.xml
@@ -131,11 +131,6 @@
2.0.1.Final
-
- uk.org.webcompere
- system-stubs-jupiter
-
-
org.mockito
mockito-core
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/BinarySource.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/BinarySource.java
similarity index 92%
rename from tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/BinarySource.java
rename to tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/BinarySource.java
index dd568e4b..13dfcf37 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/BinarySource.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/BinarySource.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jboss.intersmash.tools.application.openshift.input;
+package org.jboss.intersmash.tools.application.input;
import java.nio.file.Path;
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/BinarySourceBuilder.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/BinarySourceBuilder.java
similarity index 92%
rename from tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/BinarySourceBuilder.java
rename to tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/BinarySourceBuilder.java
index 20aa3e78..b99d18e6 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/BinarySourceBuilder.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/BinarySourceBuilder.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jboss.intersmash.tools.application.openshift.input;
+package org.jboss.intersmash.tools.application.input;
import java.nio.file.Path;
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/BuildInput.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/BuildInput.java
similarity index 92%
rename from tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/BuildInput.java
rename to tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/BuildInput.java
index 710f2cd2..04fce25d 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/BuildInput.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/BuildInput.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jboss.intersmash.tools.application.openshift.input;
+package org.jboss.intersmash.tools.application.input;
/**
* Use the {@link BuildInputBuilder} to get instances implementing the {@link BuildInput} interface.
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/BuildInputBuilder.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/BuildInputBuilder.java
similarity index 97%
rename from tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/BuildInputBuilder.java
rename to tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/BuildInputBuilder.java
index 3d2ea565..07995310 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/BuildInputBuilder.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/BuildInputBuilder.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jboss.intersmash.tools.application.openshift.input;
+package org.jboss.intersmash.tools.application.input;
import java.io.File;
import java.io.IOException;
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/GitSource.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/GitSource.java
similarity index 92%
rename from tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/GitSource.java
rename to tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/GitSource.java
index 0602f152..1f3634d1 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/GitSource.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/GitSource.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jboss.intersmash.tools.application.openshift.input;
+package org.jboss.intersmash.tools.application.input;
/**
* {@link BuildInput} represented by Git URI and reference
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/GitSourceBuilder.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/GitSourceBuilder.java
similarity index 92%
rename from tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/GitSourceBuilder.java
rename to tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/GitSourceBuilder.java
index 98ba9598..ba8285fb 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/input/GitSourceBuilder.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/input/GitSourceBuilder.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jboss.intersmash.tools.application.openshift.input;
+package org.jboss.intersmash.tools.application.input;
public interface GitSourceBuilder {
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/BootableJarOpenShiftApplication.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/BootableJarOpenShiftApplication.java
index 57b08e49..24f1555a 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/BootableJarOpenShiftApplication.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/BootableJarOpenShiftApplication.java
@@ -18,7 +18,7 @@
import java.util.Collections;
import java.util.List;
-import org.jboss.intersmash.tools.application.openshift.input.BinarySource;
+import org.jboss.intersmash.tools.application.input.BinarySource;
import org.jboss.intersmash.tools.provision.openshift.WildflyBootableJarImageOpenShiftProvisioner;
import io.fabric8.kubernetes.api.model.EnvVar;
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/WildflyImageOpenShiftApplication.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/WildflyImageOpenShiftApplication.java
index d746313d..0222412c 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/WildflyImageOpenShiftApplication.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/WildflyImageOpenShiftApplication.java
@@ -21,10 +21,10 @@
import java.util.Map;
import java.util.Set;
-import org.jboss.intersmash.tools.application.openshift.input.BinarySourceBuilder;
-import org.jboss.intersmash.tools.application.openshift.input.BuildInput;
-import org.jboss.intersmash.tools.application.openshift.input.BuildInputBuilder;
-import org.jboss.intersmash.tools.application.openshift.input.GitSourceBuilder;
+import org.jboss.intersmash.tools.application.input.BinarySourceBuilder;
+import org.jboss.intersmash.tools.application.input.BuildInput;
+import org.jboss.intersmash.tools.application.input.BuildInputBuilder;
+import org.jboss.intersmash.tools.application.input.GitSourceBuilder;
import cz.xtf.builder.builders.pod.PersistentVolumeClaim;
import cz.xtf.builder.builders.pod.VolumeMount;
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/ActiveMQOperatorApplication.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/ActiveMQOperatorApplication.java
similarity index 85%
rename from tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/ActiveMQOperatorApplication.java
rename to tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/ActiveMQOperatorApplication.java
index 700abe6d..f2ae7db3 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/ActiveMQOperatorApplication.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/ActiveMQOperatorApplication.java
@@ -13,12 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jboss.intersmash.tools.application.openshift;
+package org.jboss.intersmash.tools.application.operator;
import java.util.List;
-import org.jboss.intersmash.tools.provision.openshift.ActiveMQOperatorProvisioner;
-
import io.amq.broker.v1beta1.ActiveMQArtemis;
import io.amq.broker.v1beta1.ActiveMQArtemisAddress;
@@ -27,7 +25,7 @@
*
* The application will be deployed by:
*
- * - {@link ActiveMQOperatorProvisioner}
+ * - {@link org.jboss.intersmash.tools.provision.operator.ActiveMQOperatorProvisioner}
*
*/
public interface ActiveMQOperatorApplication extends OperatorApplication {
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/HyperfoilOperatorApplication.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/HyperfoilOperatorApplication.java
similarity index 92%
rename from tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/HyperfoilOperatorApplication.java
rename to tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/HyperfoilOperatorApplication.java
index b9c25b23..e862a688 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/HyperfoilOperatorApplication.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/HyperfoilOperatorApplication.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jboss.intersmash.tools.application.openshift;
+package org.jboss.intersmash.tools.application.operator;
import io.hyperfoil.v1alpha2.Hyperfoil;
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/InfinispanOperatorApplication.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/InfinispanOperatorApplication.java
similarity index 85%
rename from tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/InfinispanOperatorApplication.java
rename to tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/InfinispanOperatorApplication.java
index 7324fc61..072f26a0 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/InfinispanOperatorApplication.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/InfinispanOperatorApplication.java
@@ -13,11 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jboss.intersmash.tools.application.openshift;
+package org.jboss.intersmash.tools.application.operator;
import java.util.List;
-import org.jboss.intersmash.tools.provision.openshift.InfinispanOperatorProvisioner;
import org.jboss.intersmash.tools.provision.openshift.operator.infinispan.cache.Cache;
import org.jboss.intersmash.tools.provision.openshift.operator.infinispan.infinispan.Infinispan;
@@ -26,7 +25,7 @@
*
* The application will be deployed by:
*
- * - {@link InfinispanOperatorProvisioner}
+ * - {@link org.jboss.intersmash.tools.provision.operator.InfinispanOperatorProvisioner}
*
*/
public interface InfinispanOperatorApplication extends OperatorApplication {
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/KafkaOperatorApplication.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/KafkaOperatorApplication.java
similarity index 91%
rename from tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/KafkaOperatorApplication.java
rename to tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/KafkaOperatorApplication.java
index ab9c0d9b..81e21888 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/KafkaOperatorApplication.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/KafkaOperatorApplication.java
@@ -13,12 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jboss.intersmash.tools.application.openshift;
+package org.jboss.intersmash.tools.application.operator;
import java.util.List;
-import org.jboss.intersmash.tools.provision.openshift.KafkaOperatorProvisioner;
-
import io.strimzi.api.kafka.model.Kafka;
import io.strimzi.api.kafka.model.KafkaTopic;
import io.strimzi.api.kafka.model.KafkaUser;
@@ -28,7 +26,7 @@
*
* The application will be deployed by:
*
- * - {@link KafkaOperatorProvisioner}
+ * - {@link org.jboss.intersmash.tools.provision.operator.KafkaOperatorProvisioner}
*
*/
public interface KafkaOperatorApplication extends OperatorApplication {
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/KeycloakOperatorApplication.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/KeycloakOperatorApplication.java
similarity index 90%
rename from tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/KeycloakOperatorApplication.java
rename to tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/KeycloakOperatorApplication.java
index 728f2fd2..66b39f7a 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/KeycloakOperatorApplication.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/KeycloakOperatorApplication.java
@@ -13,12 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jboss.intersmash.tools.application.openshift;
+package org.jboss.intersmash.tools.application.operator;
import java.util.Collections;
import java.util.List;
-import org.jboss.intersmash.tools.provision.openshift.KeycloakOperatorProvisioner;
import org.jboss.intersmash.tools.provision.openshift.operator.keycloak.backup.KeycloakBackup;
import org.jboss.intersmash.tools.provision.openshift.operator.keycloak.client.KeycloakClient;
import org.jboss.intersmash.tools.provision.openshift.operator.keycloak.keycloak.Keycloak;
@@ -30,7 +29,7 @@
*
* The application will be deployed by:
*
- * - {@link KeycloakOperatorProvisioner}
+ * - {@link org.jboss.intersmash.tools.provision.operator.KeycloakOperatorProvisioner}
*
*/
public interface KeycloakOperatorApplication extends OperatorApplication {
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/KeycloakRealmImportOperatorApplication.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/KeycloakRealmImportOperatorApplication.java
similarity index 87%
rename from tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/KeycloakRealmImportOperatorApplication.java
rename to tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/KeycloakRealmImportOperatorApplication.java
index 2af2c7ef..2b556ad5 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/KeycloakRealmImportOperatorApplication.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/KeycloakRealmImportOperatorApplication.java
@@ -13,12 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jboss.intersmash.tools.application.openshift;
+package org.jboss.intersmash.tools.application.operator;
import java.util.Collections;
import java.util.List;
-import org.jboss.intersmash.tools.provision.openshift.KeycloakRealmImportOperatorProvisioner;
+import org.jboss.intersmash.tools.provision.openshift.KeycloakRealmImportOpenShiftOperatorProvisioner;
import org.keycloak.k8s.v2alpha1.Keycloak;
import org.keycloak.k8s.v2alpha1.KeycloakRealmImport;
@@ -27,7 +27,7 @@
*
* The application will be deployed by:
*
- * - {@link KeycloakRealmImportOperatorProvisioner}
+ * - {@link KeycloakRealmImportOpenShiftOperatorProvisioner}
*
*/
public interface KeycloakRealmImportOperatorApplication extends OperatorApplication {
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/WildflyOperatorApplication.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/WildflyOperatorApplication.java
similarity index 84%
rename from tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/WildflyOperatorApplication.java
rename to tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/WildflyOperatorApplication.java
index 4104fdf5..63baff57 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/openshift/WildflyOperatorApplication.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/application/operator/WildflyOperatorApplication.java
@@ -13,9 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jboss.intersmash.tools.application.openshift;
+package org.jboss.intersmash.tools.application.operator;
-import org.jboss.intersmash.tools.provision.openshift.WildflyOperatorProvisioner;
import org.jboss.intersmash.tools.provision.openshift.operator.wildfly.WildFlyServer;
/**
@@ -23,7 +22,7 @@
*
* The application will be deployed by:
*
- * - {@link WildflyOperatorProvisioner}
+ * - {@link org.jboss.intersmash.tools.provision.operator.WildflyOperatorProvisioner}
*
*/
public interface WildflyOperatorApplication extends OperatorApplication {
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/k8s/HyperfoilKubernetesOperatorProvisioner.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/k8s/HyperfoilKubernetesOperatorProvisioner.java
new file mode 100644
index 00000000..4afbdd20
--- /dev/null
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/k8s/HyperfoilKubernetesOperatorProvisioner.java
@@ -0,0 +1,213 @@
+/**
+ * Copyright (C) 2023 Red Hat, Inc.
+ *
+ * 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 org.jboss.intersmash.tools.provision.k8s;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.List;
+import java.util.Objects;
+
+import org.assertj.core.util.Strings;
+import org.jboss.intersmash.tools.application.operator.HyperfoilOperatorApplication;
+import org.jboss.intersmash.tools.k8s.KubernetesConfig;
+import org.jboss.intersmash.tools.k8s.client.Kuberneteses;
+import org.jboss.intersmash.tools.provision.operator.HyperfoilOperatorProvisioner;
+import org.jboss.intersmash.tools.provision.operator.OperatorProvisioner;
+
+import io.fabric8.kubernetes.api.model.Pod;
+import io.fabric8.kubernetes.api.model.Service;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinitionList;
+import io.fabric8.kubernetes.api.model.networking.v1.Ingress;
+import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
+import io.fabric8.kubernetes.client.dsl.Resource;
+import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext;
+import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl;
+import io.hyperfoil.v1alpha2.Hyperfoil;
+import io.hyperfoil.v1alpha2.HyperfoilList;
+import lombok.NonNull;
+
+/**
+ * @see io.hyperfoil.v1alpha2 package-info.java
file, for details about how to create/update/delete an
+ * Hyperfoil Custom Resource
+ * @see org.jboss.intersmash.tools.provision.openshift.operator.hyperfoil.client.release021 package-info.java
+ * file, for details about how to interact with the Hyperfoil Server which is started by the Hyperfoil Operator
+ * when an Hyperfoil Custom Resource is created
+ */
+public class HyperfoilKubernetesOperatorProvisioner
+ // default Operator based provisioner behavior, which implements OLM workflow contract and leverage lifecycle as well
+ extends OperatorProvisioner
+ // leverage Hyperfoil common Operator based provisioner behavior
+ implements HyperfoilOperatorProvisioner,
+ // leverage common Kubernetes provisioning logic
+ KubernetesProvisioner {
+
+ protected static NonNamespaceOperation> HYPERFOIL_CUSTOM_RESOURCE_CLIENT;
+
+ public HyperfoilKubernetesOperatorProvisioner(@NonNull HyperfoilOperatorApplication hyperfoilOperatorApplication) {
+ super(hyperfoilOperatorApplication, HyperfoilOperatorProvisioner.operatorId());
+ }
+
+ public HasMetadataOperationsImpl hyperfoilCustomResourcesClient(
+ CustomResourceDefinitionContext crdc) {
+ return Kuberneteses
+ .master().customResources(crdc, Hyperfoil.class, HyperfoilList.class);
+ }
+
+ /**
+ * Get a client capable of working with {@link HyperfoilOperatorProvisioner#hyperfoilCustomResourceDefinitionName()} custom resource.
+ *
+ * @return client for operations with {@link HyperfoilOperatorProvisioner#hyperfoilCustomResourceDefinitionName()} custom resource
+ */
+ public NonNamespaceOperation> hyperfoilClient() {
+ if (HYPERFOIL_CUSTOM_RESOURCE_CLIENT == null) {
+ HYPERFOIL_CUSTOM_RESOURCE_CLIENT = buildHyperfoilClient().inNamespace(KubernetesConfig.namespace());
+ }
+ return HYPERFOIL_CUSTOM_RESOURCE_CLIENT;
+ }
+
+ @Override
+ public void deploy() {
+ // TODO routes/ingresses ?
+ HyperfoilOperatorProvisioner.super.deploy();
+ }
+
+ @Override
+ public void undeploy() {
+ // TODO routes/ingresses ?
+ HyperfoilOperatorProvisioner.super.undeploy();
+ }
+
+ @Override
+ protected String getCatalogSourceNamespace() {
+ String namespace = super.getCatalogSourceNamespace();
+ if (!Strings.isNullOrEmpty(getOperatorIndexImage())) {
+ namespace = KubernetesConfig.namespace();
+ }
+ return namespace;
+ }
+
+ @Override
+ public String execute(String... args) {
+ return Kuberneteses.adminBinary().execute(args);
+ }
+
+ @Override
+ public URL getURL() {
+ Ingress ingress = retrieveNamedIngress(getApplication().getHyperfoil().getMetadata().getName());
+ if (Objects.nonNull(ingress)) {
+ if (ingress.getSpec().getRules().get(0) != null
+ && ingress.getSpec().getRules().get(0).getHttp().getPaths().get(0) != null) {
+ String host = ingress.getSpec().getRules().get(0).getHost();
+ String url = String.format("%s://%s:%s/%s",
+ ingress.getSpec().getTls() != null ? "https" : "http",
+ host,
+ ingress.getSpec().getTls() != null ? "80" : "8443",
+ ingress.getSpec().getRules().get(0).getHttp().getPaths().get(0).getPath());
+ try {
+ return new URL(url);
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(String.format("Hyperfoil operator route \"%s\"is malformed.", url), e);
+ }
+ }
+ } else {
+ Service service = KubernetesProvisioner.kubernetes.services()
+ .withName(getApplication().getHyperfoil().getMetadata().getName()).get();
+ if (Objects.nonNull(service)) {
+ if (service.getSpec().getPorts().get(0) != null) {
+ // TODO - property for default hostname (e.g. INgresses can't have IP)?
+ final String url = String.format("http://%s:%d",
+ KubernetesProvisioner.kubernetes.generateHostname(),
+ service.getSpec().getPorts().get(0) != null ? service.getSpec().getPorts().get(0).getNodePort()
+ : "80");
+ try {
+ return new URL(url);
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(
+ String.format("Hyperfoil operator service NodePort \"%s\"is malformed.", url), e);
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Ingress retrieveNamedIngress(final String ingressName) {
+ return KubernetesProvisioner.kubernetes.network().v1().ingresses().withName(ingressName).get();
+ }
+
+ @Override
+ public List getPods() {
+ return HyperfoilOperatorProvisioner.super.getPods();
+ }
+
+ @Override
+ public void waitForOperatorPod() {
+ HyperfoilOperatorProvisioner.super.waitForOperatorPod();
+ }
+
+ @Override
+ public List retrieveNamespacePods() {
+ return KubernetesProvisioner.kubernetes.pods().inNamespace(KubernetesProvisioner.kubernetes.getNamespace()).list()
+ .getItems();
+ }
+
+ @Override
+ public Pod retrieveNamedPod(final String podName) {
+ return KubernetesProvisioner.kubernetes.pods().withName(podName).get();
+ }
+
+ public List retrievePods() {
+ return KubernetesProvisioner.kubernetes.pods().inNamespace(KubernetesProvisioner.kubernetes.getNamespace()).list()
+ .getItems();
+ }
+
+ @Override
+ public String getOperatorCatalogSource() {
+ return HyperfoilOperatorProvisioner.super.getOperatorCatalogSource();
+ }
+
+ @Override
+ public String getOperatorIndexImage() {
+ return HyperfoilOperatorProvisioner.super.getOperatorIndexImage();
+ }
+
+ @Override
+ public String getOperatorChannel() {
+ return HyperfoilOperatorProvisioner.super.getOperatorChannel();
+ }
+
+ @Override
+ protected String getOperatorNamespace() {
+ return "olm";
+ }
+
+ @Override
+ protected String getTargetNamespace() {
+ return KubernetesConfig.namespace();
+ }
+
+ @Override
+ public NonNamespaceOperation> retrieveCustomResourceDefinitions() {
+ return Kuberneteses.admin().apiextensions().v1().customResourceDefinitions();
+ }
+
+ @Override
+ public void scale(int replicas, boolean wait) {
+ throw new UnsupportedOperationException("To be implemented!");
+ }
+}
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/ActiveMQOpenShiftOperatorProvisioner.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/ActiveMQOpenShiftOperatorProvisioner.java
new file mode 100644
index 00000000..56f3d295
--- /dev/null
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/ActiveMQOpenShiftOperatorProvisioner.java
@@ -0,0 +1,168 @@
+/**
+ * Copyright (C) 2023 Red Hat, Inc.
+ *
+ * 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 org.jboss.intersmash.tools.provision.openshift;
+
+import java.util.List;
+
+import org.jboss.intersmash.tools.IntersmashConfig;
+import org.jboss.intersmash.tools.application.operator.ActiveMQOperatorApplication;
+import org.jboss.intersmash.tools.provision.openshift.operator.activemq.address.ActiveMQArtemisAddressList;
+import org.jboss.intersmash.tools.provision.openshift.operator.activemq.broker.ActiveMQArtemisList;
+import org.jboss.intersmash.tools.provision.operator.ActiveMQOperatorProvisioner;
+import org.jboss.intersmash.tools.provision.operator.OperatorProvisioner;
+
+import cz.xtf.core.config.OpenShiftConfig;
+import cz.xtf.core.openshift.OpenShifts;
+import io.amq.broker.v1beta1.ActiveMQArtemis;
+import io.amq.broker.v1beta1.ActiveMQArtemisAddress;
+import io.fabric8.kubernetes.api.model.Pod;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinitionList;
+import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
+import io.fabric8.kubernetes.client.dsl.Resource;
+import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext;
+import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl;
+import lombok.NonNull;
+
+/**
+ * ActiveMQ Operator based provisioner
+ */
+public class ActiveMQOpenShiftOperatorProvisioner
+ // default Operator based provisioner behavior, which implements OLM workflow contract and leverage lifecycle as well
+ extends OperatorProvisioner
+ // leverage ActiveMQ Artemis common Operator based provisioner behavior
+ implements ActiveMQOperatorProvisioner,
+ // leverage common OpenShift provisioning logic
+ OpenShiftProvisioner {
+ private static NonNamespaceOperation> ACTIVE_MQ_ARTEMISES_CLIENT;
+ private static NonNamespaceOperation> ACTIVE_MQ_ARTEMIS_ADDRESSES_CLIENT;
+
+ // private final static String ACTIVE_MQ_ARTEMIS_SCALEDOWN_RESOURCE = "activemqartemisscaledowns.broker.amq.io"; // TODO add on demand
+
+ private static final String OPERATOR_ID = IntersmashConfig.activeMQOperatorPackageManifest();
+
+ public ActiveMQOpenShiftOperatorProvisioner(@NonNull ActiveMQOperatorApplication activeMqOperatorApplication) {
+ super(activeMqOperatorApplication, ActiveMQOperatorProvisioner.operatorId());
+ }
+
+ @Override
+ public HasMetadataOperationsImpl activeMQArtemisAddressesCustomResourcesClient(
+ CustomResourceDefinitionContext crdc) {
+ return OpenShifts
+ .master().customResources(crdc, ActiveMQArtemisAddress.class, ActiveMQArtemisAddressList.class);
+ }
+
+ @Override
+ public HasMetadataOperationsImpl activeMQArtemisCustomResourcesClient(
+ CustomResourceDefinitionContext crdc) {
+ return OpenShifts
+ .master().customResources(crdc, ActiveMQArtemis.class, ActiveMQArtemisList.class);
+ }
+
+ /**
+ * Get a client capable of working with {@link ActiveMQOperatorProvisioner#activeMQCustomResourceDefinitionName()} custom resource.
+ *
+ * @return client for operations with {@link ActiveMQOperatorProvisioner#activeMQCustomResourceDefinitionName()} custom resource
+ */
+ public NonNamespaceOperation> activeMQArtemisAddressesClient() {
+ if (ACTIVE_MQ_ARTEMIS_ADDRESSES_CLIENT == null) {
+ ACTIVE_MQ_ARTEMIS_ADDRESSES_CLIENT = buildActiveMQArtemisAddressesClient().inNamespace(OpenShiftConfig.namespace());
+ }
+ return ACTIVE_MQ_ARTEMIS_ADDRESSES_CLIENT;
+ }
+
+ /**
+ * Get a client capable of working with {@link {@link ActiveMQOperatorProvisioner#activeMQCustomResourceDefinitionName()}} custom resource.
+ *
+ * @return client for operations with {@link {@link ActiveMQOperatorProvisioner#activeMQCustomResourceDefinitionName()}} custom resource
+ */
+ public NonNamespaceOperation> activeMQArtemisesClient() {
+ if (ACTIVE_MQ_ARTEMISES_CLIENT == null) {
+ ACTIVE_MQ_ARTEMISES_CLIENT = buildActiveMQArtemisesClient();
+ }
+ return ACTIVE_MQ_ARTEMISES_CLIENT;
+ }
+
+ /**
+ * Get a reference to activeMQArtemis object. Use get() to get the actual object, or null in case it does not
+ * exist on tested cluster.
+ * @return A concrete {@link Resource} instance representing the {@link ActiveMQArtemis} resource definition
+ */
+ public Resource activeMQArtemis() {
+ return activeMQArtemisesClient().withName(getApplication().getActiveMQArtemis().getMetadata().getName());
+ }
+
+ @Override
+ public String execute(String... args) {
+ return OpenShifts.adminBinary().execute(args);
+ }
+
+ @Override
+ public void scale(int replicas, boolean wait) {
+ ActiveMQOperatorProvisioner.super.scale(replicas, wait);
+ }
+
+ @Override
+ public List retrievePods() {
+ return OpenShiftProvisioner.openShift.pods().inNamespace(OpenShiftProvisioner.openShift.getNamespace()).list()
+ .getItems();
+ }
+
+ @Override
+ public NonNamespaceOperation> retrieveCustomResourceDefinitions() {
+ return OpenShifts.admin().apiextensions().v1().customResourceDefinitions();
+ }
+
+ /**
+ * Get the provisioned application service related Pods
+ *
+ * Currently blocked by the fact that Pod Status pod names do not reflect the reality
+ *
+ * Once these issues are resolved, we can use the ready pod names returned by
+ * {@code ActiveMQArtemisStatus.getPodStatus()} to create the List with pods maintained by the provisioner.
+ *
+ * @return A list of related {@link Pod} instances
+ */
+ @Override
+ public List getPods() {
+ throw new UnsupportedOperationException("To be implemented!");
+ }
+
+ @Override
+ public String getOperatorCatalogSource() {
+ return ActiveMQOperatorProvisioner.super.getOperatorCatalogSource();
+ }
+
+ @Override
+ public String getOperatorIndexImage() {
+ return ActiveMQOperatorProvisioner.super.getOperatorIndexImage();
+ }
+
+ @Override
+ public String getOperatorChannel() {
+ return ActiveMQOperatorProvisioner.super.getOperatorChannel();
+ }
+
+ @Override
+ protected String getOperatorNamespace() {
+ return "openshift-marketplace";
+ }
+
+ @Override
+ protected String getTargetNamespace() {
+ return OpenShiftConfig.namespace();
+ }
+}
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/ActiveMQOperatorProvisionerFactory.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/ActiveMQOperatorProvisionerFactory.java
index ecba25b6..5637c779 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/ActiveMQOperatorProvisionerFactory.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/ActiveMQOperatorProvisionerFactory.java
@@ -16,18 +16,18 @@
package org.jboss.intersmash.tools.provision.openshift;
import org.jboss.intersmash.tools.application.Application;
-import org.jboss.intersmash.tools.application.openshift.ActiveMQOperatorApplication;
+import org.jboss.intersmash.tools.application.operator.ActiveMQOperatorApplication;
import org.jboss.intersmash.tools.provision.ProvisionerFactory;
import lombok.extern.slf4j.Slf4j;
@Slf4j
-public class ActiveMQOperatorProvisionerFactory implements ProvisionerFactory {
+public class ActiveMQOperatorProvisionerFactory implements ProvisionerFactory {
@Override
- public ActiveMQOperatorProvisioner getProvisioner(Application application) {
+ public ActiveMQOpenShiftOperatorProvisioner getProvisioner(Application application) {
if (ActiveMQOperatorApplication.class.isAssignableFrom(application.getClass()))
- return new ActiveMQOperatorProvisioner((ActiveMQOperatorApplication) application);
+ return new ActiveMQOpenShiftOperatorProvisioner((ActiveMQOperatorApplication) application);
return null;
}
}
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/BootableJarImageOpenShiftProvisioner.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/BootableJarImageOpenShiftProvisioner.java
index 01ede174..140c298c 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/BootableJarImageOpenShiftProvisioner.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/BootableJarImageOpenShiftProvisioner.java
@@ -23,9 +23,9 @@
import java.util.stream.Collectors;
import org.jboss.intersmash.tools.IntersmashConfig;
+import org.jboss.intersmash.tools.application.input.BinarySource;
+import org.jboss.intersmash.tools.application.input.BuildInput;
import org.jboss.intersmash.tools.application.openshift.BootableJarOpenShiftApplication;
-import org.jboss.intersmash.tools.application.openshift.input.BinarySource;
-import org.jboss.intersmash.tools.application.openshift.input.BuildInput;
import org.slf4j.event.Level;
import cz.xtf.builder.builders.ApplicationBuilder;
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/HyperfoilOpenShiftOperatorProvisioner.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/HyperfoilOpenShiftOperatorProvisioner.java
new file mode 100644
index 00000000..24489358
--- /dev/null
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/HyperfoilOpenShiftOperatorProvisioner.java
@@ -0,0 +1,176 @@
+/**
+ * Copyright (C) 2023 Red Hat, Inc.
+ *
+ * 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 org.jboss.intersmash.tools.provision.openshift;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.List;
+import java.util.Objects;
+
+import org.assertj.core.util.Strings;
+import org.jboss.intersmash.tools.application.operator.HyperfoilOperatorApplication;
+import org.jboss.intersmash.tools.provision.operator.HyperfoilOperatorProvisioner;
+import org.jboss.intersmash.tools.provision.operator.OperatorProvisioner;
+
+import cz.xtf.core.config.OpenShiftConfig;
+import cz.xtf.core.openshift.OpenShifts;
+import io.fabric8.kubernetes.api.model.Pod;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinitionList;
+import io.fabric8.kubernetes.api.model.networking.v1.Ingress;
+import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
+import io.fabric8.kubernetes.client.dsl.Resource;
+import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext;
+import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl;
+import io.fabric8.openshift.api.model.Route;
+import io.hyperfoil.v1alpha2.Hyperfoil;
+import io.hyperfoil.v1alpha2.HyperfoilList;
+import lombok.NonNull;
+
+/**
+ * @see io.hyperfoil.v1alpha2 package-info.java
file, for details about how to create/update/delete an
+ * Hyperfoil Custom Resource
+ * @see org.jboss.intersmash.tools.provision.openshift.operator.hyperfoil.client.release021 package-info.java
+ * file, for details about how to interact with the Hyperfoil Server which is started by the Hyperfoil Operator
+ * when an Hyperfoil Custom Resource is created
+ */
+public class HyperfoilOpenShiftOperatorProvisioner
+ // default Operator based provisioner behavior, which implements OLM workflow contract and leverage lifecycle as well
+ extends OperatorProvisioner
+ // leverage Hyperfoil common Operator based provisioner behavior
+ implements HyperfoilOperatorProvisioner,
+ // leverage common OpenShift provisioning logic
+ OpenShiftProvisioner {
+
+ protected static NonNamespaceOperation> HYPERFOIL_CUSTOM_RESOURCE_CLIENT;
+
+ public HyperfoilOpenShiftOperatorProvisioner(@NonNull HyperfoilOperatorApplication hyperfoilOperatorApplication) {
+ super(hyperfoilOperatorApplication, HyperfoilOperatorProvisioner.operatorId());
+ }
+
+ public HasMetadataOperationsImpl hyperfoilCustomResourcesClient(
+ CustomResourceDefinitionContext crdc) {
+ return OpenShifts
+ .master().customResources(crdc, Hyperfoil.class, HyperfoilList.class);
+ }
+
+ /**
+ * Get a client capable of working with {@link HyperfoilOperatorProvisioner#hyperfoilCustomResourceDefinitionName()} custom resource.
+ *
+ * @return client for operations with {@link HyperfoilOperatorProvisioner#hyperfoilCustomResourceDefinitionName()} custom resource
+ */
+ public NonNamespaceOperation> hyperfoilClient() {
+ if (HYPERFOIL_CUSTOM_RESOURCE_CLIENT == null) {
+ HYPERFOIL_CUSTOM_RESOURCE_CLIENT = buildHyperfoilClient().inNamespace(OpenShiftConfig.namespace());
+ }
+ return HYPERFOIL_CUSTOM_RESOURCE_CLIENT;
+ }
+
+ @Override
+ public Ingress retrieveNamedIngress(final String ingressName) {
+ return OpenShiftProvisioner.openShift.network().v1().ingresses().withName(ingressName).get();
+ }
+
+ @Override
+ protected String getCatalogSourceNamespace() {
+ String namespace = super.getCatalogSourceNamespace();
+ if (!Strings.isNullOrEmpty(getOperatorIndexImage())) {
+ namespace = OpenShiftConfig.namespace();
+ }
+ return namespace;
+ }
+
+ @Override
+ public List getPods() {
+ return HyperfoilOperatorProvisioner.super.getPods();
+ }
+
+ @Override
+ public void waitForOperatorPod() {
+ HyperfoilOperatorProvisioner.super.waitForOperatorPod();
+ }
+
+ @Override
+ public String getOperatorCatalogSource() {
+ return HyperfoilOperatorProvisioner.super.getOperatorCatalogSource();
+ }
+
+ @Override
+ public String getOperatorIndexImage() {
+ return HyperfoilOperatorProvisioner.super.getOperatorIndexImage();
+ }
+
+ @Override
+ public String getOperatorChannel() {
+ return HyperfoilOperatorProvisioner.super.getOperatorChannel();
+ }
+
+ @Override
+ public List retrieveNamespacePods() {
+ return OpenShiftProvisioner.openShift.getPods();
+ }
+
+ @Override
+ public Pod retrieveNamedPod(final String podName) {
+ return OpenShiftProvisioner.openShift.pods().withName(podName).get();
+ }
+
+ public List retrievePods() {
+ return OpenShiftProvisioner.openShift.getPods();
+ }
+
+ @Override
+ public String execute(String... args) {
+ return OpenShifts.adminBinary().execute(args);
+ }
+
+ @Override
+ protected String getOperatorNamespace() {
+ return "openshift-marketplace";
+ }
+
+ @Override
+ protected String getTargetNamespace() {
+ return OpenShiftConfig.namespace();
+ }
+
+ @Override
+ public NonNamespaceOperation> retrieveCustomResourceDefinitions() {
+ return OpenShifts.admin().apiextensions().v1().customResourceDefinitions();
+ }
+
+ @Override
+ public void scale(int replicas, boolean wait) {
+ throw new UnsupportedOperationException("To be implemented!");
+ }
+
+ @Override
+ public URL getURL() {
+ Route route = OpenShiftProvisioner.openShift.getRoute(getApplication().getName());
+ if (Objects.nonNull(route)) {
+ String host = route.getSpec().getHost() != null ? route.getSpec().getHost()
+ : route.getStatus().getIngress().get(0).getHost();
+ String url = String.format("https://%s", host);
+ try {
+ return new URL(
+ url);
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(String.format("Hyperfoil operator route \"%s\"is malformed.", url), e);
+ }
+ }
+ return null;
+ }
+}
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/HyperfoilOperatorProvisioner.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/HyperfoilOperatorProvisioner.java
deleted file mode 100644
index 2047bba9..00000000
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/HyperfoilOperatorProvisioner.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/**
- * Copyright (C) 2023 Red Hat, Inc.
- *
- * 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 org.jboss.intersmash.tools.provision.openshift;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-import org.jboss.intersmash.tools.IntersmashConfig;
-import org.jboss.intersmash.tools.application.openshift.HyperfoilOperatorApplication;
-import org.jboss.intersmash.tools.provision.openshift.operator.OperatorProvisioner;
-import org.slf4j.event.Level;
-
-import cz.xtf.core.config.OpenShiftConfig;
-import cz.xtf.core.event.helpers.EventHelper;
-import cz.xtf.core.openshift.OpenShiftWaiters;
-import cz.xtf.core.openshift.OpenShifts;
-import cz.xtf.core.waiting.SimpleWaiter;
-import io.fabric8.kubernetes.api.model.DeletionPropagation;
-import io.fabric8.kubernetes.api.model.Pod;
-import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
-import io.fabric8.kubernetes.client.dsl.MixedOperation;
-import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
-import io.fabric8.kubernetes.client.dsl.Resource;
-import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext;
-import io.fabric8.openshift.api.model.Route;
-import io.hyperfoil.v1alpha2.Hyperfoil;
-import io.hyperfoil.v1alpha2.HyperfoilList;
-import lombok.NonNull;
-
-/**
- * @see io.hyperfoil.v1alpha2 package-info.java
file, for details about how to create/update/delete an
- * Hyperfoil Custom Resource
- * @see org.jboss.intersmash.tools.provision.openshift.operator.hyperfoil.client.release021 package-info.java
- * file, for details about how to interact with the Hyperfoil Server which is started by the Hyperfoil Operator
- * when an Hyperfoil Custom Resource is created
- */
-public class HyperfoilOperatorProvisioner extends OperatorProvisioner {
- // this is the name of the Hyperfoil CustomResourceDefinition
- // you can get it with command:
- // oc get crd hyperfoils.hyperfoil.io -o template --template='{{ .metadata.name }}'
- private final static String HYPERFOIL_CUSTOM_RESOURCE_DEFINITION = "hyperfoils.hyperfoil.io";
- private static NonNamespaceOperation> HYPERFOIL_CUSTOM_RESOURCE_CLIENT;
- // this is the packagemanifest for the hyperfoil operator;
- // you can get it with command:
- // oc get packagemanifest hyperfoil-bundle -o template --template='{{ .metadata.name }}'
- private static final String OPERATOR_ID = IntersmashConfig.hyperfoilOperatorPackageManifest();
-
- public HyperfoilOperatorProvisioner(@NonNull HyperfoilOperatorApplication hyperfoilOperatorApplication) {
- super(hyperfoilOperatorApplication, OPERATOR_ID);
- }
-
- public static String getOperatorId() {
- return OPERATOR_ID;
- }
-
- /**
- * Get a client capable of working with {@link #HYPERFOIL_CUSTOM_RESOURCE_DEFINITION} custom resource.
- *
- * @return client for operations with {@link #HYPERFOIL_CUSTOM_RESOURCE_DEFINITION} custom resource
- */
- NonNamespaceOperation> hyperfoilClient() {
- if (HYPERFOIL_CUSTOM_RESOURCE_CLIENT == null) {
- CustomResourceDefinition crd = OpenShifts.admin().apiextensions().v1().customResourceDefinitions()
- .withName(HYPERFOIL_CUSTOM_RESOURCE_DEFINITION).get();
- CustomResourceDefinitionContext crdc = CustomResourceDefinitionContext.fromCrd(crd);
- if (!getCustomResourceDefinitions().contains(HYPERFOIL_CUSTOM_RESOURCE_DEFINITION)) {
- throw new RuntimeException(String.format("[%s] custom resource is not provided by [%s] operator.",
- HYPERFOIL_CUSTOM_RESOURCE_DEFINITION, OPERATOR_ID));
- }
- MixedOperation> hyperfoilCrClient = OpenShifts
- .master().customResources(crdc, Hyperfoil.class, HyperfoilList.class);
- HYPERFOIL_CUSTOM_RESOURCE_CLIENT = hyperfoilCrClient.inNamespace(OpenShiftConfig.namespace());
- }
- return HYPERFOIL_CUSTOM_RESOURCE_CLIENT;
- }
-
- /**
- * Get a reference to Hyperfoil object. Use get() to get the actual object, or null in case it does not
- * exist on tested cluster.
- *
- * @return A concrete {@link Resource} instance representing the {@link Hyperfoil} resource definition
- */
- public Resource hyperfoil() {
- return hyperfoilClient().withName(getApplication().getName());
- }
-
- @Override
- public void deploy() {
- ffCheck = FailFastUtils.getFailFastCheck(EventHelper.timeOfLastEventBMOrTestNamespaceOrEpoch(),
- getApplication().getName());
- if (!isSubscribed()) {
- subscribe();
- }
- hyperfoilClient().createOrReplace(getApplication().getHyperfoil());
- new SimpleWaiter(() -> hyperfoil().get().getStatus() != null)
- .failFast(ffCheck)
- .reason("Wait for status field to be initialized.")
- .level(Level.DEBUG)
- .waitFor();
- new SimpleWaiter(() -> getPods().size() == 1)
- .failFast(ffCheck)
- .reason("Wait for expected number of replicas to be active.")
- .level(Level.DEBUG)
- .waitFor();
- WaitersUtil.routeIsUp(getURL().toExternalForm())
- .level(Level.DEBUG)
- .waitFor();
- }
-
- @Override
- public URL getURL() {
- Route route = OpenShiftProvisioner.openShift.getRoute(getApplication().getName());
- if (Objects.nonNull(route)) {
- String host = route.getSpec().getHost() != null ? route.getSpec().getHost()
- : route.getStatus().getIngress().get(0).getHost();
- String url = String.format("https://%s", host);
- try {
- return new URL(
- url);
- } catch (MalformedURLException e) {
- throw new RuntimeException(String.format("Hyperfoil operator route \"%s\"is malformed.", url), e);
- }
- }
- return null;
- }
-
- @Override
- public void undeploy() {
- undeploy(true);
- }
-
- public void undeploy(boolean unsubscribe) {
- hyperfoil().withPropagationPolicy(DeletionPropagation.FOREGROUND).delete();
- OpenShiftWaiters.get(OpenShiftProvisioner.openShift, ffCheck).areExactlyNPodsReady(0, "app", getApplication().getName())
- .level(Level.DEBUG).waitFor();
- if (unsubscribe) {
- unsubscribe();
- }
- }
-
- @Override
- public List getPods() {
- List pods = new ArrayList<>();
- Pod hyperfoilControllerPod = OpenShiftProvisioner.openShift
- .getPod(String.format("%s-controller", getApplication().getName()));
- if (isContainerReady(hyperfoilControllerPod, "controller")) {
- pods.add(hyperfoilControllerPod);
- }
- return pods;
- }
-
- /**
- * This method checks if the Operator's POD is actually running;
- * It's been tailored on the community-operators Cluster Service version format which is missing label
- * spec.install.spec.deployments.spec.template.metadata.labels."app.kubernetes.io/name"
which is used
- * in @see OperatorProvisioner#waitForOperatorPod() (see
- * https://github.com/operator-framework/community-operators/tree/master/community-operators/hyperfoil-bundle)
- */
- @Override
- protected void waitForOperatorPod() {
- String[] operatorSpecs = getAdminBinary().execute("get", "csvs", getCurrentCSV(), "-o", "template", "--template",
- "{{range .spec.install.spec.deployments}}{{printf \"%d|%s\\n\" .spec.replicas .name}}{{end}}")
- .split(System.lineSeparator());
- for (String spec : operatorSpecs) {
- String[] operatorSpec = spec.split("\\|");
- if (operatorSpec.length != 2) {
- throw new RuntimeException("Failed to get operator deployment spec from csvs!");
- }
- new SimpleWaiter(() -> OpenShiftProvisioner.openShift.getPods().stream().filter(
- pod -> (pod.getMetadata()
- .getName()
- .startsWith(operatorSpec[1])
- && pod.getStatus().getPhase().equalsIgnoreCase("Running")))
- .count() == Integer.valueOf(operatorSpec[0]))
- .failFast(ffCheck)
- .reason("Wait for expected number of replicas to be active.")
- .level(Level.DEBUG)
- .waitFor();
- }
- }
-
- /**
- * Tells if a specific container inside the pod is ready
- *
- * @param pod
- * @param containerName: name of the container
- * @return
- */
- private boolean isContainerReady(Pod pod, String containerName) {
- if (Objects.nonNull(pod)) {
- return pod.getStatus().getContainerStatuses().stream()
- .filter(containerStatus -> containerStatus.getName().equalsIgnoreCase(containerName)
- && containerStatus.getReady())
- .count() > 0;
- }
- return false;
- }
-
- @Override
- protected String getOperatorCatalogSource() {
- return IntersmashConfig.hyperfoilOperatorCatalogSource();
- }
-
- @Override
- protected String getOperatorIndexImage() {
- return IntersmashConfig.hyperfoilOperatorIndexImage();
- }
-
- @Override
- protected String getOperatorChannel() {
- return IntersmashConfig.hyperfoilOperatorChannel();
- }
-
- @Override
- public void scale(int replicas, boolean wait) {
- throw new UnsupportedOperationException("To be implemented!");
- }
-}
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/InfinispanOpenShiftOperatorProvisioner.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/InfinispanOpenShiftOperatorProvisioner.java
new file mode 100644
index 00000000..4223016e
--- /dev/null
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/InfinispanOpenShiftOperatorProvisioner.java
@@ -0,0 +1,156 @@
+/**
+ * Copyright (C) 2023 Red Hat, Inc.
+ *
+ * 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 org.jboss.intersmash.tools.provision.openshift;
+
+import java.net.URL;
+import java.util.List;
+
+import org.jboss.intersmash.tools.application.operator.InfinispanOperatorApplication;
+import org.jboss.intersmash.tools.provision.openshift.operator.infinispan.cache.Cache;
+import org.jboss.intersmash.tools.provision.openshift.operator.infinispan.cache.CacheList;
+import org.jboss.intersmash.tools.provision.openshift.operator.infinispan.infinispan.Infinispan;
+import org.jboss.intersmash.tools.provision.openshift.operator.infinispan.infinispan.InfinispanList;
+import org.jboss.intersmash.tools.provision.operator.InfinispanOperatorProvisioner;
+import org.jboss.intersmash.tools.provision.operator.OperatorProvisioner;
+
+import cz.xtf.core.config.OpenShiftConfig;
+import cz.xtf.core.openshift.OpenShifts;
+import io.fabric8.kubernetes.api.model.Pod;
+import io.fabric8.kubernetes.api.model.Service;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinitionList;
+import io.fabric8.kubernetes.api.model.apps.StatefulSet;
+import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
+import io.fabric8.kubernetes.client.dsl.Resource;
+import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext;
+import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl;
+import io.fabric8.openshift.api.model.Route;
+import lombok.NonNull;
+
+public class InfinispanOpenShiftOperatorProvisioner
+ // default Operator based provisioner behavior, which implements OLM workflow contract and leverage lifecycle as well
+ extends OperatorProvisioner
+ // leverage Hyperfoil common Operator based provisioner behavior
+ implements InfinispanOperatorProvisioner,
+ // leverage common OpenShift provisioning logic
+ OpenShiftProvisioner {
+ private static NonNamespaceOperation> INFINISPAN_CLIENT;
+ private static NonNamespaceOperation> INFINISPAN_CACHES_CLIENT;
+
+ public InfinispanOpenShiftOperatorProvisioner(
+ @NonNull InfinispanOperatorApplication infinispanOperatorApplication) {
+ super(infinispanOperatorApplication, InfinispanOperatorProvisioner.operatorId());
+ }
+
+ @Override
+ public URL getURL() {
+ return InfinispanOperatorProvisioner.super.getURL();
+ }
+
+ @Override
+ public StatefulSet retrieveNamedStatefulSet(final String statefulSetName) {
+ return OpenShiftProvisioner.openShift.getStatefulSet(statefulSetName);
+ }
+
+ @Override
+ public String execute(String... args) {
+ return OpenShifts.adminBinary().execute(args);
+ }
+
+ @Override
+ public void scale(int replicas, boolean wait) {
+ InfinispanOperatorProvisioner.super.scale(replicas, wait);
+ }
+
+ @Override
+ public List getPods() {
+ return InfinispanOperatorProvisioner.super.getPods();
+ }
+
+ @Override
+ public String getOperatorCatalogSource() {
+ return InfinispanOperatorProvisioner.super.getOperatorCatalogSource();
+ }
+
+ @Override
+ public String getOperatorIndexImage() {
+ return InfinispanOperatorProvisioner.super.getOperatorIndexImage();
+ }
+
+ @Override
+ public String getOperatorChannel() {
+ return InfinispanOperatorProvisioner.super.getOperatorChannel();
+ }
+
+ @Override
+ public Route retrieveNamedRoute(final String routeName) {
+ return OpenShiftProvisioner.openShift.getRoute(routeName);
+ }
+
+ @Override
+ public Service retrieveNamedService(final String serviceName) {
+ return OpenShiftProvisioner.openShift.getService(serviceName);
+ }
+
+ @Override
+ public HasMetadataOperationsImpl infinispanCustomResourcesClient(
+ CustomResourceDefinitionContext crdc) {
+ return OpenShifts
+ .master().customResources(crdc, Infinispan.class, InfinispanList.class);
+ }
+
+ @Override
+ public HasMetadataOperationsImpl cacheCustomResourcesClient(CustomResourceDefinitionContext crdc) {
+ return OpenShifts
+ .master().customResources(crdc, Cache.class, CacheList.class);
+ }
+
+ @Override
+ public NonNamespaceOperation> infinispansClient() {
+ if (INFINISPAN_CLIENT == null) {
+ INFINISPAN_CLIENT = buildInfinispansClient().inNamespace(OpenShiftConfig.namespace());
+ }
+ return INFINISPAN_CLIENT;
+ }
+
+ @Override
+ public NonNamespaceOperation> cachesClient() {
+ if (INFINISPAN_CACHES_CLIENT == null) {
+ INFINISPAN_CACHES_CLIENT = buildCachesClient().inNamespace(OpenShiftConfig.namespace());
+ }
+ return INFINISPAN_CACHES_CLIENT;
+ }
+
+ @Override
+ protected String getOperatorNamespace() {
+ return "openshift-marketplace";
+ }
+
+ @Override
+ protected String getTargetNamespace() {
+ return OpenShiftConfig.namespace();
+ }
+
+ @Override
+ public List retrievePods() {
+ return OpenShiftProvisioner.openShift.getPods();
+ }
+
+ @Override
+ public NonNamespaceOperation> retrieveCustomResourceDefinitions() {
+ return OpenShifts.admin().apiextensions().v1().customResourceDefinitions();
+ }
+}
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/InfinispanOperatorProvisionerFactory.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/InfinispanOperatorProvisionerFactory.java
index 2fee529d..af714f70 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/InfinispanOperatorProvisionerFactory.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/InfinispanOperatorProvisionerFactory.java
@@ -16,18 +16,18 @@
package org.jboss.intersmash.tools.provision.openshift;
import org.jboss.intersmash.tools.application.Application;
-import org.jboss.intersmash.tools.application.openshift.InfinispanOperatorApplication;
+import org.jboss.intersmash.tools.application.operator.InfinispanOperatorApplication;
import org.jboss.intersmash.tools.provision.ProvisionerFactory;
import lombok.extern.slf4j.Slf4j;
@Slf4j
-public class InfinispanOperatorProvisionerFactory implements ProvisionerFactory {
+public class InfinispanOperatorProvisionerFactory implements ProvisionerFactory {
@Override
- public InfinispanOperatorProvisioner getProvisioner(Application application) {
+ public InfinispanOpenShiftOperatorProvisioner getProvisioner(Application application) {
if (InfinispanOperatorApplication.class.isAssignableFrom(application.getClass()))
- return new InfinispanOperatorProvisioner((InfinispanOperatorApplication) application);
+ return new InfinispanOpenShiftOperatorProvisioner((InfinispanOperatorApplication) application);
return null;
}
}
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KafkaOpenShiftOperatorProvisioner.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KafkaOpenShiftOperatorProvisioner.java
new file mode 100644
index 00000000..3689e115
--- /dev/null
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KafkaOpenShiftOperatorProvisioner.java
@@ -0,0 +1,175 @@
+/**
+ * Copyright (C) 2023 Red Hat, Inc.
+ *
+ * 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 org.jboss.intersmash.tools.provision.openshift;
+
+import java.util.List;
+
+import org.jboss.intersmash.tools.IntersmashConfig;
+import org.jboss.intersmash.tools.application.operator.KafkaOperatorApplication;
+import org.jboss.intersmash.tools.provision.operator.KafkaOperatorProvisioner;
+import org.jboss.intersmash.tools.provision.operator.OperatorProvisioner;
+import org.slf4j.event.Level;
+
+import cz.xtf.core.config.OpenShiftConfig;
+import cz.xtf.core.openshift.OpenShifts;
+import io.fabric8.kubernetes.api.model.Pod;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinitionList;
+import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
+import io.fabric8.kubernetes.client.dsl.Resource;
+import io.strimzi.api.kafka.Crds;
+import io.strimzi.api.kafka.KafkaList;
+import io.strimzi.api.kafka.KafkaTopicList;
+import io.strimzi.api.kafka.KafkaUserList;
+import io.strimzi.api.kafka.model.Kafka;
+import io.strimzi.api.kafka.model.KafkaTopic;
+import io.strimzi.api.kafka.model.KafkaUser;
+import lombok.NonNull;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Deploys an application that implements {@link KafkaOperatorApplication} interface and which is extended by this
+ * class.
+ */
+@Slf4j
+public class KafkaOpenShiftOperatorProvisioner
+ // default Operator based provisioner behavior, which implements OLM workflow contract and leverage lifecycle as well
+ extends OperatorProvisioner
+ // leverage Kafka common Operator based provisioner behavior
+ implements KafkaOperatorProvisioner,
+ // leverage common OpenShift provisioning logic
+ OpenShiftProvisioner {
+
+ private static final String OPERATOR_ID = IntersmashConfig.kafkaOperatorPackageManifest();
+
+ public KafkaOpenShiftOperatorProvisioner(@NonNull KafkaOperatorApplication kafkaOperatorApplication) {
+ super(kafkaOperatorApplication, KafkaOperatorProvisioner.operatorId());
+ }
+
+ /**
+ * Get a client capable of working with {@link Kafka} custom resource on our OpenShift instance.
+ *
+ * @return client for operations with {@link Kafka} custom resource on our OpenShift instance
+ */
+ public NonNamespaceOperation> kafkasClient() {
+ return Crds.kafkaOperation(OpenShiftProvisioner.openShift).inNamespace(OpenShiftConfig.namespace());
+ }
+
+ /**
+ * Get a client capable of working with {@link KafkaUser} custom resource on our OpenShift instance.
+ *
+ * @return client for operations with {@link KafkaUser} custom resource on our OpenShift instance
+ */
+ public NonNamespaceOperation> kafkasUserClient() {
+ return Crds.kafkaUserOperation(OpenShiftProvisioner.openShift).inNamespace(OpenShiftConfig.namespace());
+ }
+
+ /**
+ * Get a client capable of working with {@link KafkaTopic} custom resource on our OpenShift instance.
+ *
+ * @return client for operations with {@link KafkaTopic} custom resource on our OpenShift instance
+ */
+ public NonNamespaceOperation> kafkasTopicClient() {
+ return Crds.topicOperation(OpenShiftProvisioner.openShift).inNamespace(OpenShiftConfig.namespace());
+ }
+
+ @Override
+ public String execute(String... args) {
+ return OpenShifts.adminBinary().execute(args);
+ }
+
+ @Override
+ public List getPods() {
+ return OpenShiftProvisioner.openShift.getLabeledPods("strimzi.io/cluster", getApplication().getName());
+ }
+
+ public List getClusterOperatorPods() {
+ return OpenShiftProvisioner.openShift.getLabeledPods("strimzi.io/kind", "cluster-operator");
+ }
+
+ @Override
+ public List retrieveKafkaPods() {
+ return OpenShiftProvisioner.openShift.getLabeledPods("app.kubernetes.io/name", "kafka");
+ }
+
+ @Override
+ public List retrieveKafkaZookeperPods() {
+ return OpenShiftProvisioner.openShift.getLabeledPods("app.kubernetes.io/name", "zookeeper");
+ }
+
+ @Override
+ public void scale(int replicas, boolean wait) {
+ KafkaOperatorProvisioner.super.scale(replicas, wait);
+ }
+
+ @Override
+ public String getOperatorCatalogSource() {
+ return IntersmashConfig.kafkaOperatorCatalogSource();
+ }
+
+ @Override
+ public String getOperatorIndexImage() {
+ return IntersmashConfig.kafkaOperatorIndexImage();
+ }
+
+ @Override
+ public String getOperatorChannel() {
+ return IntersmashConfig.kafkaOperatorChannel();
+ }
+
+ @Override
+ protected String getOperatorNamespace() {
+ return null;
+ }
+
+ @Override
+ protected String getTargetNamespace() {
+ return null;
+ }
+
+ @Override
+ public void logMessage(final String message, Level l) {
+ switch (l) {
+ case INFO:
+ log.info(message);
+ break;
+ case WARN:
+ log.warn(message);
+ break;
+ case ERROR:
+ log.error(message);
+ break;
+ case DEBUG:
+ log.debug(message);
+ break;
+ case TRACE:
+ log.trace(message);
+ break;
+ default:
+ throw new IllegalArgumentException(String.format("Unsupported log level: %s", l.name()));
+ }
+ }
+
+ @Override
+ public List retrievePods() {
+ return OpenShiftProvisioner.openShift.getPods();
+ }
+
+ @Override
+ public NonNamespaceOperation> retrieveCustomResourceDefinitions() {
+ return OpenShifts.admin().apiextensions().v1().customResourceDefinitions();
+ }
+}
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KafkaOperatorProvisionerFactory.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KafkaOperatorProvisionerFactory.java
index 8a83b3c1..92d99500 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KafkaOperatorProvisionerFactory.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KafkaOperatorProvisionerFactory.java
@@ -16,18 +16,18 @@
package org.jboss.intersmash.tools.provision.openshift;
import org.jboss.intersmash.tools.application.Application;
-import org.jboss.intersmash.tools.application.openshift.KafkaOperatorApplication;
+import org.jboss.intersmash.tools.application.operator.KafkaOperatorApplication;
import org.jboss.intersmash.tools.provision.ProvisionerFactory;
import lombok.extern.slf4j.Slf4j;
@Slf4j
-public class KafkaOperatorProvisionerFactory implements ProvisionerFactory {
+public class KafkaOperatorProvisionerFactory implements ProvisionerFactory {
@Override
- public KafkaOperatorProvisioner getProvisioner(Application application) {
+ public KafkaOpenShiftOperatorProvisioner getProvisioner(Application application) {
if (KafkaOperatorApplication.class.isAssignableFrom(application.getClass()))
- return new KafkaOperatorProvisioner((KafkaOperatorApplication) application);
+ return new KafkaOpenShiftOperatorProvisioner((KafkaOperatorApplication) application);
return null;
}
}
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KeycloakOpenShiftOperatorProvisioner.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KeycloakOpenShiftOperatorProvisioner.java
new file mode 100644
index 00000000..0ead3f98
--- /dev/null
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KeycloakOpenShiftOperatorProvisioner.java
@@ -0,0 +1,248 @@
+/**
+ * Copyright (C) 2023 Red Hat, Inc.
+ *
+ * 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 org.jboss.intersmash.tools.provision.openshift;
+
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+
+import org.assertj.core.util.Strings;
+import org.jboss.intersmash.tools.IntersmashConfig;
+import org.jboss.intersmash.tools.application.operator.KeycloakOperatorApplication;
+import org.jboss.intersmash.tools.provision.openshift.operator.keycloak.backup.KeycloakBackup;
+import org.jboss.intersmash.tools.provision.openshift.operator.keycloak.backup.KeycloakBackupList;
+import org.jboss.intersmash.tools.provision.openshift.operator.keycloak.client.KeycloakClient;
+import org.jboss.intersmash.tools.provision.openshift.operator.keycloak.client.KeycloakClientList;
+import org.jboss.intersmash.tools.provision.openshift.operator.keycloak.keycloak.Keycloak;
+import org.jboss.intersmash.tools.provision.openshift.operator.keycloak.keycloak.KeycloakList;
+import org.jboss.intersmash.tools.provision.openshift.operator.keycloak.realm.KeycloakRealm;
+import org.jboss.intersmash.tools.provision.openshift.operator.keycloak.realm.KeycloakRealmList;
+import org.jboss.intersmash.tools.provision.openshift.operator.keycloak.user.KeycloakUser;
+import org.jboss.intersmash.tools.provision.openshift.operator.keycloak.user.KeycloakUserList;
+import org.jboss.intersmash.tools.provision.operator.KeycloakOperatorProvisioner;
+import org.jboss.intersmash.tools.provision.operator.OperatorProvisioner;
+
+import cz.xtf.core.config.OpenShiftConfig;
+import cz.xtf.core.openshift.OpenShifts;
+import io.fabric8.kubernetes.api.model.Pod;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinitionList;
+import io.fabric8.kubernetes.api.model.apps.StatefulSet;
+import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
+import io.fabric8.kubernetes.client.dsl.Resource;
+import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext;
+import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl;
+import lombok.NonNull;
+
+/**
+ * Keycloak operator provisioner
+ */
+public class KeycloakOpenShiftOperatorProvisioner
+ // default Operator based provisioner behavior, which implements OLM workflow contract and leverage lifecycle as well
+ extends OperatorProvisioner
+ // leverage Wildfly common Operator based provisioner behavior
+ implements KeycloakOperatorProvisioner,
+ // leverage common OpenShift provisioning logic
+ OpenShiftProvisioner {
+ private static NonNamespaceOperation> KEYCLOAKS_CLIENT;
+ private static NonNamespaceOperation> KEYCLOAK_REALMS_CLIENT;
+ private static NonNamespaceOperation> KEYCLOAK_BACKUPS_CLIENT;
+ private static NonNamespaceOperation> KEYCLOAK_CLIENTS_CLIENT;
+ private static NonNamespaceOperation> KEYCLOAK_USERS_CLIENT;
+
+ public KeycloakOpenShiftOperatorProvisioner(@NonNull KeycloakOperatorApplication keycloakOperatorApplication) {
+ super(keycloakOperatorApplication, KeycloakOperatorProvisioner.operatorId());
+ }
+
+ @Override
+ public String execute(String... args) {
+ return OpenShifts.adminBinary().execute(args);
+ }
+
+ @Override
+ public URL getURL() {
+ return KeycloakOperatorProvisioner.super.getURL();
+ }
+
+ @Override
+ public String getOperatorCatalogSource() {
+ return IntersmashConfig.keycloakOperatorCatalogSource();
+ }
+
+ @Override
+ public String getOperatorIndexImage() {
+ return IntersmashConfig.keycloakOperatorIndexImage();
+ }
+
+ @Override
+ public String getOperatorChannel() {
+ return IntersmashConfig.keycloakOperatorChannel();
+ }
+
+ @Override
+ public void scale(int replicas, boolean wait) {
+ KeycloakOperatorProvisioner.super.scale(replicas, wait);
+ }
+
+ @Override
+ public List getPods() {
+ return KeycloakOperatorProvisioner.super.getPods();
+ }
+
+ @Override
+ public HasMetadataOperationsImpl keycloaksCustomResourcesClient(
+ CustomResourceDefinitionContext crdc) {
+ return OpenShifts
+ .master().customResources(crdc, Keycloak.class, KeycloakList.class);
+ }
+
+ @Override
+ protected String getOperatorNamespace() {
+ return "openshift-marketplace";
+ }
+
+ @Override
+ public List retrievePods() {
+ return OpenShiftProvisioner.openShift.getPods();
+ }
+
+ @Override
+ public NonNamespaceOperation> retrieveCustomResourceDefinitions() {
+ return OpenShifts.admin().apiextensions().v1().customResourceDefinitions();
+ }
+
+ @Override
+ public void subscribe() {
+ if (Strings.isNullOrEmpty(IntersmashConfig.keycloakImageURL())) {
+ super.subscribe();
+ } else {
+ // RELATED_IMAGE_RHSSO_OPENJ9 and RELATED_IMAGE_RHSSO_OPENJDK, determine the final value for RELATED_IMAGE_RHSSO
+ subscribe(
+ INSTALLPLAN_APPROVAL_MANUAL,
+ Map.of(
+ "RELATED_IMAGE_RHSSO", IntersmashConfig.keycloakImageURL(),
+ "PROFILE", "RHSSO"));
+ }
+ }
+
+ @Override
+ protected String getTargetNamespace() {
+ return OpenShiftConfig.namespace();
+ }
+
+ // keycloaks.keycloak.org
+
+ /**
+ * Get a client capable of working with {@link #KEYCLOAK_RESOURCE} custom resource.
+ *
+ * @return client for operations with {@link #KEYCLOAK_RESOURCE} custom resource
+ */
+ public NonNamespaceOperation> keycloaksClient() {
+ if (KEYCLOAKS_CLIENT == null) {
+ KEYCLOAKS_CLIENT = buildKeycloaksClient().inNamespace(OpenShiftConfig.namespace());
+ }
+ return KEYCLOAKS_CLIENT;
+ }
+
+ @Override
+ public HasMetadataOperationsImpl keycloakRealmsCustomResourcesClient(
+ CustomResourceDefinitionContext crdc) {
+ return OpenShifts
+ .master().customResources(crdc, KeycloakRealm.class, KeycloakRealmList.class);
+ }
+
+ // keycloakrealms.keycloak.org
+
+ /**
+ * Get a client capable of working with {@link #KEYCLOAK_REALM_RESOURCE} custom resource.
+ *
+ * @return client for operations with {@link #KEYCLOAK_REALM_RESOURCE} custom resource
+ */
+ public NonNamespaceOperation> keycloakRealmsClient() {
+ if (KEYCLOAK_REALMS_CLIENT == null) {
+ KEYCLOAK_REALMS_CLIENT = buildKeycloakRealmsClient().inNamespace(OpenShiftConfig.namespace());
+ }
+ return KEYCLOAK_REALMS_CLIENT;
+ }
+
+ @Override
+ public HasMetadataOperationsImpl keycloakBackupsCustomResourcesClient(
+ CustomResourceDefinitionContext crdc) {
+ return OpenShifts
+ .master().customResources(crdc, KeycloakBackup.class, KeycloakBackupList.class);
+ }
+
+ // keycloakbackups.keycloak.org
+
+ /**
+ * Get a client capable of working with {@link #KEYCLOAK_BACKUP_RESOURCE} custom resource.
+ *
+ * @return client for operations with {@link #KEYCLOAK_BACKUP_RESOURCE} custom resource
+ */
+ public NonNamespaceOperation> keycloakBackupsClient() {
+ if (KEYCLOAK_BACKUPS_CLIENT == null) {
+ KEYCLOAK_BACKUPS_CLIENT = buildKeycloakBackupsClient().inNamespace(OpenShiftConfig.namespace());
+ }
+ return KEYCLOAK_BACKUPS_CLIENT;
+ }
+
+ @Override
+ public HasMetadataOperationsImpl keycloakClientsCustomResourcesClient(
+ CustomResourceDefinitionContext crdc) {
+ return OpenShifts
+ .master().customResources(crdc, KeycloakClient.class, KeycloakClientList.class);
+ }
+
+ // keycloakclients.keycloak.org
+
+ /**
+ * Get a client capable of working with {@link #KEYCLOAK_CLIENT_RESOURCE} custom resource.
+ *
+ * @return client for operations with {@link #KEYCLOAK_CLIENT_RESOURCE} custom resource
+ */
+ public NonNamespaceOperation> keycloakClientsClient() {
+ if (KEYCLOAK_CLIENTS_CLIENT == null) {
+ KEYCLOAK_CLIENTS_CLIENT = buildKeycloakClientsClient().inNamespace(OpenShiftConfig.namespace());
+ }
+ return KEYCLOAK_CLIENTS_CLIENT;
+ }
+
+ @Override
+ public HasMetadataOperationsImpl keycloakUsersCustomResourcesClient(
+ CustomResourceDefinitionContext crdc) {
+ return OpenShifts
+ .master().customResources(crdc, KeycloakUser.class, KeycloakUserList.class);
+ }
+
+ // keycloakusers.keycloak.org
+
+ /**
+ * Get a client capable of working with {@link #KEYCLOAK_USER_RESOURCE} custom resource.
+ *
+ * @return client for operations with {@link #KEYCLOAK_USER_RESOURCE} custom resource
+ */
+ public NonNamespaceOperation> keycloakUsersClient() {
+ if (KEYCLOAK_USERS_CLIENT == null) {
+ KEYCLOAK_USERS_CLIENT = buildKeycloakUsersClient().inNamespace(OpenShiftConfig.namespace());
+ }
+ return KEYCLOAK_USERS_CLIENT;
+ }
+
+ @Override
+ public StatefulSet retrieveNamedStatefulSet(String statefulSetName) {
+ return OpenShiftProvisioner.openShift.getStatefulSet(statefulSetName);
+ }
+}
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KeycloakOperatorProvisionerFactory.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KeycloakOperatorProvisionerFactory.java
index ae7982fa..9bd1cd1e 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KeycloakOperatorProvisionerFactory.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KeycloakOperatorProvisionerFactory.java
@@ -16,18 +16,18 @@
package org.jboss.intersmash.tools.provision.openshift;
import org.jboss.intersmash.tools.application.Application;
-import org.jboss.intersmash.tools.application.openshift.KeycloakOperatorApplication;
+import org.jboss.intersmash.tools.application.operator.KeycloakOperatorApplication;
import org.jboss.intersmash.tools.provision.ProvisionerFactory;
import lombok.extern.slf4j.Slf4j;
@Slf4j
-public class KeycloakOperatorProvisionerFactory implements ProvisionerFactory {
+public class KeycloakOperatorProvisionerFactory implements ProvisionerFactory {
@Override
- public KeycloakOperatorProvisioner getProvisioner(Application application) {
+ public KeycloakOpenShiftOperatorProvisioner getProvisioner(Application application) {
if (KeycloakOperatorApplication.class.isAssignableFrom(application.getClass()))
- return new KeycloakOperatorProvisioner((KeycloakOperatorApplication) application);
+ return new KeycloakOpenShiftOperatorProvisioner((KeycloakOperatorApplication) application);
return null;
}
}
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KeycloakRealmImportOpenShiftOperatorProvisioner.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KeycloakRealmImportOpenShiftOperatorProvisioner.java
new file mode 100644
index 00000000..8a0b5d00
--- /dev/null
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KeycloakRealmImportOpenShiftOperatorProvisioner.java
@@ -0,0 +1,189 @@
+/**
+ * Copyright (C) 2023 Red Hat, Inc.
+ *
+ * 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 org.jboss.intersmash.tools.provision.openshift;
+
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Map;
+
+import io.fabric8.kubernetes.api.model.Secret;
+import org.assertj.core.util.Strings;
+import org.jboss.intersmash.tools.IntersmashConfig;
+import org.jboss.intersmash.tools.application.operator.KeycloakRealmImportOperatorApplication;
+import org.jboss.intersmash.tools.provision.operator.KeycloakRealmImportOperatorProvisioner;
+import org.jboss.intersmash.tools.provision.operator.OperatorProvisioner;
+import org.keycloak.k8s.v2alpha1.Keycloak;
+import org.keycloak.k8s.v2alpha1.KeycloakRealmImport;
+
+import cz.xtf.core.config.OpenShiftConfig;
+import cz.xtf.core.openshift.OpenShifts;
+import io.fabric8.kubernetes.api.model.KubernetesResourceList;
+import io.fabric8.kubernetes.api.model.Pod;
+import io.fabric8.kubernetes.api.model.Service;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinitionList;
+import io.fabric8.kubernetes.api.model.apps.StatefulSet;
+import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
+import io.fabric8.kubernetes.client.dsl.Resource;
+import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext;
+import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl;
+import io.fabric8.openshift.api.model.Route;
+import lombok.NonNull;
+
+/**
+ * Keycloak operator provisioner
+ */
+public class KeycloakRealmImportOpenShiftOperatorProvisioner
+ // default Operator based provisioner behavior, which implements OLM workflow contract and leverage lifecycle as well
+ extends OperatorProvisioner
+ // leverage Wildfly common Operator based provisioner behavior
+ implements KeycloakRealmImportOperatorProvisioner,
+ // leverage common OpenShift provisioning logic
+ OpenShiftProvisioner {
+
+ public KeycloakRealmImportOpenShiftOperatorProvisioner(@NonNull KeycloakRealmImportOperatorApplication application) {
+ super(application, KeycloakRealmImportOperatorProvisioner.OPERATOR_ID);
+ }
+
+ @Override
+ public String getOperatorCatalogSource() {
+
+ return KeycloakRealmImportOperatorProvisioner.super.getOperatorCatalogSource();
+ }
+
+ @Override
+ public String getOperatorIndexImage() {
+
+ return KeycloakRealmImportOperatorProvisioner.super.getOperatorIndexImage();
+ }
+
+ @Override
+ public String getOperatorChannel() {
+ return KeycloakRealmImportOperatorProvisioner.super.getOperatorChannel();
+ }
+
+ @Override
+ public Service retrieveNamedService(String serviceName) {
+ return OpenShiftProvisioner.openShift.getService(serviceName);
+ }
+
+ @Override
+ public StatefulSet retrieveNamedStatefulSet(String statefulSetName) {
+ return OpenShiftProvisioner.openShift.getStatefulSet(statefulSetName);
+ }
+
+ @Override
+ public List retrieveRoutes() {
+ return OpenShiftProvisioner.openShift.getRoutes();
+ }
+
+ @Override
+ public List retrieveNamespacePods() {
+ return OpenShiftProvisioner.openShift.getPods();
+ }
+
+ @Override
+ public void scale(int replicas, boolean wait) {
+ KeycloakRealmImportOperatorProvisioner.super.scale(replicas, wait);
+ }
+
+ @Override
+ public URL getURL() {
+ return KeycloakRealmImportOperatorProvisioner.super.getURL();
+ }
+
+ @Override
+ public HasMetadataOperationsImpl> keycloaksCustomResourcesClient(
+ CustomResourceDefinitionContext crdc) {
+ return OpenShifts
+ .master().customResources(crdc, Keycloak.class, KubernetesResourceList.class);
+ }
+
+ @Override
+ protected String getOperatorNamespace() {
+ return "openshift-marketplace";
+ }
+
+ @Override
+ public List retrievePods() {
+ return OpenShiftProvisioner.openShift.getPods();
+ }
+
+ @Override
+ public String execute(String... args) {
+ return OpenShifts.adminBinary().execute(args);
+ }
+
+ @Override
+ public NonNamespaceOperation> retrieveCustomResourceDefinitions() {
+ return OpenShifts.admin().apiextensions().v1().customResourceDefinitions();
+ }
+
+ @Override
+ public Secret createTlsSecret(final String namespace, final String tlsSecretName, final Path key, final Path certificate) {
+ try {
+ return OpenShiftProvisioner.createTlsSecret(OpenShifts.master().getNamespace(), tlsSecretName, key, certificate);
+ } catch (IOException e) {
+ throw new IllegalStateException("Couldn't create the required secret: " + tlsSecretName, e);
+ }
+ }
+
+ @Override
+ public void subscribe() {
+ if (Strings.isNullOrEmpty(IntersmashConfig.keycloakRealmImportImageURL())) {
+ super.subscribe();
+ } else {
+ subscribe(
+ INSTALLPLAN_APPROVAL_MANUAL,
+ Map.of(
+ // Custom Keycloak image to be used: overrides the Keycloak image at the operator level: all
+ // Keycloak instances will be spun out of this image
+ // e.g. OPERATOR_KEYCLOAK_IMAGE=quay.io/keycloak/keycloak:21.1.1 --> operator.keycloak.image
+ "OPERATOR_KEYCLOAK_IMAGE", IntersmashConfig.keycloakRealmImportImageURL()));
+ }
+ }
+
+ @Override
+ protected String getTargetNamespace() {
+ return OpenShiftConfig.namespace();
+ }
+
+ private static NonNamespaceOperation, Resource> KEYCLOAKS_CLIENT;
+ private static NonNamespaceOperation, Resource> KEYCLOAK_REALM_IMPORTS_CLIENT;
+
+ public NonNamespaceOperation, Resource> keycloakClient() {
+ if (KEYCLOAKS_CLIENT == null) {
+ KEYCLOAKS_CLIENT = buildKeycloakClient().inNamespace(OpenShiftConfig.namespace());
+ }
+ return KEYCLOAKS_CLIENT;
+ }
+
+ @Override
+ public HasMetadataOperationsImpl> keycloakRealmImportsCustomResourcesClient(
+ CustomResourceDefinitionContext crdc) {
+ return null;
+ }
+
+ public NonNamespaceOperation, Resource> keycloakRealmImportClient() {
+
+ if (KEYCLOAK_REALM_IMPORTS_CLIENT == null) {
+ KEYCLOAK_REALM_IMPORTS_CLIENT = buildKeycloakRealmImportClient().inNamespace(OpenShiftConfig.namespace());
+ }
+ return KEYCLOAK_REALM_IMPORTS_CLIENT;
+ }
+}
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KeycloakRealmImportOperatorProvisionerFactory.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KeycloakRealmImportOperatorProvisionerFactory.java
index 21906bc2..b8ae3f82 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KeycloakRealmImportOperatorProvisionerFactory.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/KeycloakRealmImportOperatorProvisionerFactory.java
@@ -16,19 +16,19 @@
package org.jboss.intersmash.tools.provision.openshift;
import org.jboss.intersmash.tools.application.Application;
-import org.jboss.intersmash.tools.application.openshift.KeycloakRealmImportOperatorApplication;
+import org.jboss.intersmash.tools.application.operator.KeycloakRealmImportOperatorApplication;
import org.jboss.intersmash.tools.provision.ProvisionerFactory;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class KeycloakRealmImportOperatorProvisionerFactory
- implements ProvisionerFactory {
+ implements ProvisionerFactory {
@Override
- public KeycloakRealmImportOperatorProvisioner getProvisioner(Application application) {
+ public KeycloakRealmImportOpenShiftOperatorProvisioner getProvisioner(Application application) {
if (KeycloakRealmImportOperatorApplication.class.isAssignableFrom(application.getClass()))
- return new KeycloakRealmImportOperatorProvisioner((KeycloakRealmImportOperatorApplication) application);
+ return new KeycloakRealmImportOpenShiftOperatorProvisioner((KeycloakRealmImportOperatorApplication) application);
return null;
}
}
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/WildflyImageOpenShiftProvisioner.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/WildflyImageOpenShiftProvisioner.java
index 0dee951b..bd24ef46 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/WildflyImageOpenShiftProvisioner.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/WildflyImageOpenShiftProvisioner.java
@@ -28,11 +28,11 @@
import org.assertj.core.util.Strings;
import org.jboss.intersmash.tools.IntersmashConfig;
+import org.jboss.intersmash.tools.application.input.BinarySource;
+import org.jboss.intersmash.tools.application.input.BuildInput;
+import org.jboss.intersmash.tools.application.input.GitSource;
import org.jboss.intersmash.tools.application.openshift.WildflyImageOpenShiftApplication;
import org.jboss.intersmash.tools.application.openshift.WildflyOpenShiftApplication;
-import org.jboss.intersmash.tools.application.openshift.input.BinarySource;
-import org.jboss.intersmash.tools.application.openshift.input.BuildInput;
-import org.jboss.intersmash.tools.application.openshift.input.GitSource;
import org.slf4j.event.Level;
import cz.xtf.builder.builders.ApplicationBuilder;
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/WildflyOpenShiftOperatorProvisioner.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/WildflyOpenShiftOperatorProvisioner.java
new file mode 100644
index 00000000..9d0ef090
--- /dev/null
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/WildflyOpenShiftOperatorProvisioner.java
@@ -0,0 +1,130 @@
+/**
+ * Copyright (C) 2023 Red Hat, Inc.
+ *
+ * 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 org.jboss.intersmash.tools.provision.openshift;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.List;
+
+import org.jboss.intersmash.tools.application.operator.WildflyOperatorApplication;
+import org.jboss.intersmash.tools.provision.openshift.operator.wildfly.WildFlyServer;
+import org.jboss.intersmash.tools.provision.openshift.operator.wildfly.WildFlyServerList;
+import org.jboss.intersmash.tools.provision.operator.OperatorProvisioner;
+import org.jboss.intersmash.tools.provision.operator.WildflyOperatorProvisioner;
+
+import cz.xtf.core.config.OpenShiftConfig;
+import cz.xtf.core.openshift.OpenShifts;
+import io.fabric8.kubernetes.api.model.Pod;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinitionList;
+import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
+import io.fabric8.kubernetes.client.dsl.Resource;
+import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext;
+import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl;
+import lombok.NonNull;
+
+public class WildflyOpenShiftOperatorProvisioner
+ // default Operator based provisioner behavior, which implements OLM workflow contract and leverage lifecycle as well
+ extends OperatorProvisioner
+ // leverage Wildfly common Operator based provisioner behavior
+ implements WildflyOperatorProvisioner,
+ // leverage common OpenShift provisioning logic
+ OpenShiftProvisioner {
+ private static NonNamespaceOperation> WILDFLY_SERVERS_CLIENT;
+
+ public WildflyOpenShiftOperatorProvisioner(@NonNull WildflyOperatorApplication wildflyOperatorApplication) {
+ super(wildflyOperatorApplication, WildflyOperatorProvisioner.operatorId());
+ }
+
+ @Override
+ public HasMetadataOperationsImpl wildflyCustomResourcesClient(
+ CustomResourceDefinitionContext crdc) {
+ return OpenShifts
+ .master().customResources(crdc, WildFlyServer.class, WildFlyServerList.class);
+ }
+
+ /**
+ * Get a client capable of working with {@link WildflyOperatorProvisioner#wildflyCustomResourceDefinitionName()} ()} custom resource.
+ *
+ * @return client for operations with {@link WildflyOperatorProvisioner#wildflyCustomResourceDefinitionName()} ()} custom resource
+ */
+ public NonNamespaceOperation> wildflyServersClient() {
+ if (WILDFLY_SERVERS_CLIENT == null) {
+ WILDFLY_SERVERS_CLIENT = buildWildflyClient().inNamespace(OpenShiftConfig.namespace());
+ }
+ return WILDFLY_SERVERS_CLIENT;
+ }
+
+ @Override
+ public String execute(String... args) {
+ return OpenShifts.adminBinary().execute(args);
+ }
+
+ @Override
+ public void scale(int replicas, boolean wait) {
+ WildflyOperatorProvisioner.super.scale(replicas, wait);
+ }
+
+ @Override
+ public URL getURL() {
+ String url = "http://" + wildFlyServer().get().getStatus().getHosts().get(0);
+ try {
+ return new URL(url);
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(String.format("WILDFLY operator route \"%s\"is malformed.", url), e);
+ }
+ }
+
+ @Override
+ public List retrievePods() {
+ return OpenShiftProvisioner.openShift.getPods();
+ }
+
+ @Override
+ public List getPods() {
+ return WildflyOperatorProvisioner.super.getPods();
+ }
+
+ @Override
+ public NonNamespaceOperation> retrieveCustomResourceDefinitions() {
+ return OpenShifts.admin().apiextensions().v1().customResourceDefinitions();
+ }
+
+ @Override
+ public String getOperatorCatalogSource() {
+ return WildflyOperatorProvisioner.super.getOperatorCatalogSource();
+ }
+
+ @Override
+ public String getOperatorIndexImage() {
+ return WildflyOperatorProvisioner.super.getOperatorIndexImage();
+ }
+
+ @Override
+ public String getOperatorChannel() {
+ return WildflyOperatorProvisioner.super.getOperatorChannel();
+ }
+
+ @Override
+ protected String getOperatorNamespace() {
+ return "openshift-marketplace";
+ }
+
+ @Override
+ protected String getTargetNamespace() {
+ return OpenShiftConfig.namespace();
+ }
+}
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/WildflyOperatorProvisionerFactory.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/WildflyOperatorProvisionerFactory.java
index 3710d1a0..1f5125f1 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/WildflyOperatorProvisionerFactory.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/WildflyOperatorProvisionerFactory.java
@@ -16,18 +16,18 @@
package org.jboss.intersmash.tools.provision.openshift;
import org.jboss.intersmash.tools.application.Application;
-import org.jboss.intersmash.tools.application.openshift.WildflyOperatorApplication;
+import org.jboss.intersmash.tools.application.operator.WildflyOperatorApplication;
import org.jboss.intersmash.tools.provision.ProvisionerFactory;
import lombok.extern.slf4j.Slf4j;
@Slf4j
-public class WildflyOperatorProvisionerFactory implements ProvisionerFactory {
+public class WildflyOperatorProvisionerFactory implements ProvisionerFactory {
@Override
- public WildflyOperatorProvisioner getProvisioner(Application application) {
+ public WildflyOpenShiftOperatorProvisioner getProvisioner(Application application) {
if (WildflyOperatorApplication.class.isAssignableFrom(application.getClass()))
- return new WildflyOperatorProvisioner((WildflyOperatorApplication) application);
+ return new WildflyOpenShiftOperatorProvisioner((WildflyOperatorApplication) application);
return null;
}
}
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/ActiveMQOperatorProvisioner.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/operator/ActiveMQOperatorProvisioner.java
similarity index 56%
rename from tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/ActiveMQOperatorProvisioner.java
rename to tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/operator/ActiveMQOperatorProvisioner.java
index 5bd009d7..909b26cc 100644
--- a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/openshift/ActiveMQOperatorProvisioner.java
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/operator/ActiveMQOperatorProvisioner.java
@@ -13,23 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jboss.intersmash.tools.provision.openshift;
+package org.jboss.intersmash.tools.provision.operator;
import java.util.List;
import java.util.stream.Collectors;
import org.jboss.intersmash.tools.IntersmashConfig;
-import org.jboss.intersmash.tools.application.openshift.ActiveMQOperatorApplication;
-import org.jboss.intersmash.tools.provision.openshift.operator.OperatorProvisioner;
+import org.jboss.intersmash.tools.application.operator.ActiveMQOperatorApplication;
+import org.jboss.intersmash.tools.provision.Provisioner;
+import org.jboss.intersmash.tools.provision.openshift.OpenShiftProvisioner;
import org.jboss.intersmash.tools.provision.openshift.operator.activemq.address.ActiveMQArtemisAddressList;
import org.jboss.intersmash.tools.provision.openshift.operator.activemq.broker.ActiveMQArtemisList;
import org.slf4j.event.Level;
-import cz.xtf.core.config.OpenShiftConfig;
-import cz.xtf.core.event.helpers.EventHelper;
import cz.xtf.core.openshift.OpenShiftWaiters;
-import cz.xtf.core.openshift.OpenShifts;
import cz.xtf.core.waiting.SimpleWaiter;
+import cz.xtf.core.waiting.failfast.FailFastCheck;
import io.amq.broker.v1beta1.ActiveMQArtemis;
import io.amq.broker.v1beta1.ActiveMQArtemisAddress;
import io.fabric8.kubernetes.api.model.DeletionPropagation;
@@ -39,50 +38,52 @@
import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
import io.fabric8.kubernetes.client.dsl.Resource;
import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext;
-import lombok.NonNull;
+import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl;
/**
* ActiveMQ Operator based provisioner
*/
-public class ActiveMQOperatorProvisioner extends OperatorProvisioner {
- private final static String ACTIVE_MQ_ARTEMIS_RESOURCE = "activemqartemises.broker.amq.io";
- private static NonNamespaceOperation> ACTIVE_MQ_ARTEMISES_CLIENT;
+public interface ActiveMQOperatorProvisioner extends
+ OlmOperatorProvisioner, Provisioner {
+
+ // this is the packagemanifest for the operator;
+ // you can get it with command:
+ // oc get packagemanifest -o template --template='{{ .metadata.name }}'
+ static String operatorId() {
+ return IntersmashConfig.activeMQOperatorPackageManifest();
+ }
- private final static String ACTIVE_MQ_ARTEMIS_ADDRESS_RESOURCE = "activemqartemisaddresses.broker.amq.io";
- private static NonNamespaceOperation> ACTIVE_MQ_ARTEMIS_ADDRESSES_CLIENT;
+ // this is the name of the CustomResourceDefinition(s)
+ // you can get it with command:
+ // oc get crd > -o template --template='{{ .metadata.name }}'
+ default String activeMQCustomResourceDefinitionName() {
+ return "activemqartemises.broker.amq.io";
+ }
- // private final static String ACTIVE_MQ_ARTEMIS_SCALEDOWN_RESOURCE = "activemqartemisscaledowns.broker.amq.io"; // TODO add on demand
+ HasMetadataOperationsImpl activeMQArtemisAddressesCustomResourcesClient(
+ CustomResourceDefinitionContext crdc);
- private static final String OPERATOR_ID = IntersmashConfig.activeMQOperatorPackageManifest();
+ HasMetadataOperationsImpl activeMQArtemisCustomResourcesClient(
+ CustomResourceDefinitionContext crdc);
- public ActiveMQOperatorProvisioner(@NonNull ActiveMQOperatorApplication activeMqOperatorApplication) {
- super(activeMqOperatorApplication, OPERATOR_ID);
- }
+ NonNamespaceOperation> activeMQArtemisAddressesClient();
- public static String getOperatorId() {
- return OPERATOR_ID;
- }
+ NonNamespaceOperation> activeMQArtemisesClient();
/**
- * Get a client capable of working with {@link #ACTIVE_MQ_ARTEMIS_ADDRESS_RESOURCE} custom resource.
+ * Get a client capable of working with {@link #activeMQCustomResourceDefinitionName()} custom resource.
*
- * @return client for operations with {@link #ACTIVE_MQ_ARTEMIS_ADDRESS_RESOURCE} custom resource
+ * @return client for operations with {@link #activeMQCustomResourceDefinitionName()} custom resource
*/
- public NonNamespaceOperation> activeMQArtemisAddressesClient() {
- if (ACTIVE_MQ_ARTEMIS_ADDRESSES_CLIENT == null) {
- CustomResourceDefinition crd = OpenShifts.admin().apiextensions().v1().customResourceDefinitions()
- .withName(ACTIVE_MQ_ARTEMIS_ADDRESS_RESOURCE).get();
- CustomResourceDefinitionContext crdc = CustomResourceDefinitionContext.fromCrd(crd);
- if (!getCustomResourceDefinitions().contains(ACTIVE_MQ_ARTEMIS_ADDRESS_RESOURCE)) {
- throw new RuntimeException(String.format("[%s] custom resource is not provided by [%s] operator.",
- ACTIVE_MQ_ARTEMIS_ADDRESS_RESOURCE, OPERATOR_ID));
- }
-
- MixedOperation> addressesClient = OpenShifts
- .master().customResources(crdc, ActiveMQArtemisAddress.class, ActiveMQArtemisAddressList.class);
- ACTIVE_MQ_ARTEMIS_ADDRESSES_CLIENT = addressesClient.inNamespace(OpenShiftConfig.namespace());
+ default MixedOperation> buildActiveMQArtemisAddressesClient() {
+ CustomResourceDefinition crd = retrieveCustomResourceDefinitions()
+ .withName(activeMQCustomResourceDefinitionName()).get();
+ CustomResourceDefinitionContext crdc = CustomResourceDefinitionContext.fromCrd(crd);
+ if (!retrieveCustomResourceDefinitions().list().getItems().contains(activeMQCustomResourceDefinitionName())) {
+ throw new RuntimeException(String.format("[%s] custom resource is not provided by [%s] operator.",
+ activeMQCustomResourceDefinitionName(), operatorId()));
}
- return ACTIVE_MQ_ARTEMIS_ADDRESSES_CLIENT;
+ return activeMQArtemisAddressesCustomResourcesClient(crdc);
}
/**
@@ -92,7 +93,7 @@ public NonNamespaceOperation activeMQArtemisAddress(String name) {
+ default Resource activeMQArtemisAddress(String name) {
return activeMQArtemisAddressesClient().withName(name);
}
@@ -103,7 +104,7 @@ public Resource activeMQArtemisAddress(String name) {
* Use get() to get the actual object, or null in case it does not exist on tested cluster.
* @return A list of {@link Resource} instances representing the {@link ActiveMQArtemisAddress} resource definitions
*/
- public List> activeMQArtemisAddresses() {
+ default List> activeMQArtemisAddresses() {
ActiveMQOperatorApplication activeMqOperatorApplication = getApplication();
return activeMqOperatorApplication.getActiveMQArtemisAddresses().stream()
.map(activeMQArtemisAddress -> activeMQArtemisAddress.getMetadata().getName())
@@ -112,25 +113,20 @@ public List> activeMQArtemisAddresses() {
}
/**
- * Get a client capable of working with {@link #ACTIVE_MQ_ARTEMIS_RESOURCE} custom resource.
+ * Get a client capable of working with {@link #activeMQCustomResourceDefinitionName()} custom resource.
*
- * @return client for operations with {@link #ACTIVE_MQ_ARTEMIS_RESOURCE} custom resource
+ * @return client for operations with {@link #activeMQCustomResourceDefinitionName()} custom resource
*/
- public NonNamespaceOperation> activeMQArtemisesClient() {
- if (ACTIVE_MQ_ARTEMISES_CLIENT == null) {
- CustomResourceDefinition crd = OpenShifts.admin().apiextensions().v1().customResourceDefinitions()
- .withName(ACTIVE_MQ_ARTEMIS_RESOURCE).get();
- CustomResourceDefinitionContext crdc = CustomResourceDefinitionContext.fromCrd(crd);
- if (!getCustomResourceDefinitions().contains(ACTIVE_MQ_ARTEMIS_RESOURCE)) {
- throw new RuntimeException(String.format("[%s] custom resource is not provided by [%s] operator.",
- ACTIVE_MQ_ARTEMIS_RESOURCE, OPERATOR_ID));
- }
-
- MixedOperation> amqClient = OpenShifts
- .master().customResources(crdc, ActiveMQArtemis.class, ActiveMQArtemisList.class);
- ACTIVE_MQ_ARTEMISES_CLIENT = amqClient.inNamespace(OpenShiftConfig.namespace());
+ default MixedOperation> buildActiveMQArtemisesClient() {
+ CustomResourceDefinition crd = retrieveCustomResourceDefinitions()
+ .withName(activeMQCustomResourceDefinitionName()).get();
+ CustomResourceDefinitionContext crdc = CustomResourceDefinitionContext.fromCrd(crd);
+ if (!retrieveCustomResourceDefinitions().list().getItems().contains(activeMQCustomResourceDefinitionName())) {
+ throw new RuntimeException(String.format("[%s] custom resource is not provided by [%s] operator.",
+ activeMQCustomResourceDefinitionName(), operatorId()));
}
- return ACTIVE_MQ_ARTEMISES_CLIENT;
+ return activeMQArtemisCustomResourcesClient(crdc);
+
}
/**
@@ -138,14 +134,13 @@ public NonNamespaceOperation activeMQArtemis() {
+ default Resource activeMQArtemis() {
return activeMQArtemisesClient().withName(getApplication().getActiveMQArtemis().getMetadata().getName());
}
@Override
- public void deploy() {
- ffCheck = FailFastUtils.getFailFastCheck(EventHelper.timeOfLastEventBMOrTestNamespaceOrEpoch(),
- getApplication().getName());
+ default void deploy() {
+ FailFastCheck ffCheck = () -> false;
subscribe();
int replicas = getApplication().getActiveMQArtemis().getSpec().getDeploymentPlan().getSize();
@@ -179,7 +174,8 @@ public void deploy() {
}
@Override
- public void undeploy() {
+ default void undeploy() {
+ FailFastCheck ffCheck = () -> false;
// delete the resources
activeMQArtemisAddresses().forEach(address -> address.withPropagationPolicy(DeletionPropagation.FOREGROUND).delete());
@@ -196,8 +192,8 @@ public void undeploy() {
unsubscribe();
}
- @Override
- public void scale(int replicas, boolean wait) {
+ default void scale(int replicas, boolean wait) {
+ FailFastCheck ffCheck = () -> false;
ActiveMQArtemis tmpBroker = activeMQArtemis().get();
tmpBroker.getSpec().getDeploymentPlan().setSize(replicas);
activeMQArtemis().replace(tmpBroker);
@@ -219,33 +215,17 @@ public void scale(int replicas, boolean wait) {
}
}
- /**
- * Get the provisioned application service related Pods
- *
- * Currently blocked by the fact that Pod Status pod names do not reflect the reality
- *
- * Once these issues are resolved, we can use the ready pod names returned by
- * {@code ActiveMQArtemisStatus.getPodStatus()} to create the List with pods maintained by the provisioner.
- *
- * @return A list of related {@link Pod} instances
- */
- @Override
- public List getPods() {
- throw new UnsupportedOperationException("To be implemented!");
- }
+ List getPods();
- @Override
- protected String getOperatorCatalogSource() {
+ default String getOperatorCatalogSource() {
return IntersmashConfig.activeMQOperatorCatalogSource();
}
- @Override
- protected String getOperatorIndexImage() {
+ default String getOperatorIndexImage() {
return IntersmashConfig.activeMQOperatorIndexImage();
}
- @Override
- protected String getOperatorChannel() {
+ default String getOperatorChannel() {
return IntersmashConfig.activeMQOperatorChannel();
}
}
diff --git a/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/operator/HyperfoilOperatorProvisioner.java b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/operator/HyperfoilOperatorProvisioner.java
new file mode 100644
index 00000000..6a5e17fd
--- /dev/null
+++ b/tools/intersmash-tools-provisioners/src/main/java/org/jboss/intersmash/tools/provision/operator/HyperfoilOperatorProvisioner.java
@@ -0,0 +1,194 @@
+package org.jboss.intersmash.tools.provision.operator;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BooleanSupplier;
+import java.util.stream.Collectors;
+
+import org.jboss.intersmash.tools.IntersmashConfig;
+import org.jboss.intersmash.tools.application.operator.HyperfoilOperatorApplication;
+import org.jboss.intersmash.tools.provision.Provisioner;
+import org.jboss.intersmash.tools.provision.openshift.WaitersUtil;
+import org.slf4j.event.Level;
+
+import com.google.common.base.Strings;
+
+import cz.xtf.core.waiting.SimpleWaiter;
+import cz.xtf.core.waiting.failfast.FailFastCheck;
+import io.fabric8.kubernetes.api.model.DeletionPropagation;
+import io.fabric8.kubernetes.api.model.Pod;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
+import io.fabric8.kubernetes.api.model.networking.v1.Ingress;
+import io.fabric8.kubernetes.client.dsl.MixedOperation;
+import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
+import io.fabric8.kubernetes.client.dsl.Resource;
+import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext;
+import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl;
+import io.hyperfoil.v1alpha2.Hyperfoil;
+import io.hyperfoil.v1alpha2.HyperfoilList;
+
+public interface HyperfoilOperatorProvisioner extends
+ OlmOperatorProvisioner, Provisioner,
+ OlmOperatorProvisionerClientBinary {
+
+ // this is the packagemanifest for the hyperfoil operator;
+ // you can get it with command:
+ // oc get packagemanifest hyperfoil-bundle -o template --template='{{ .metadata.name }}'
+ static String operatorId() {
+ return IntersmashConfig.hyperfoilOperatorPackageManifest();
+ }
+
+ // this is the name of the Hyperfoil CustomResourceDefinition
+ // you can get it with command:
+ // oc get crd hyperfoils.hyperfoil.io -o template --template='{{ .metadata.name }}'
+ default String hyperfoilCustomResourceDefinitionName() {
+ return "hyperfoils.hyperfoil.io";
+ }
+
+ HasMetadataOperationsImpl hyperfoilCustomResourcesClient(CustomResourceDefinitionContext crdc);
+
+ /**
+ * Get a client capable of working with {@link #hyperfoilCustomResourceDefinitionName} custom resource.
+ *
+ * @return client for operations with {@link #hyperfoilCustomResourceDefinitionName} custom resource
+ */
+ default MixedOperation> buildHyperfoilClient() {
+ CustomResourceDefinition crd = retrieveCustomResourceDefinitions()
+ .withName(hyperfoilCustomResourceDefinitionName()).get();
+ if (crd == null) {
+ throw new RuntimeException(String.format("[%s] custom resource is not provided by [%s] operator.",
+ hyperfoilCustomResourceDefinitionName(), operatorId()));
+ }
+ return hyperfoilCustomResourcesClient(CustomResourceDefinitionContext.fromCrd(crd));
+ }
+
+ NonNamespaceOperation> hyperfoilClient();
+
+ /**
+ * Get a reference to Hyperfoil object. Use get() to get the actual object, or null in case it does not
+ * exist on tested cluster.
+ *
+ * @return A concrete {@link Resource} instance representing the {@link Hyperfoil} resource definition
+ */
+ default Resource