diff --git a/samples/pom.xml b/samples/pom.xml
index 4859499..6be24ef 100644
--- a/samples/pom.xml
+++ b/samples/pom.xml
@@ -17,5 +17,6 @@
spring-boot-auto-config
common
+ webpage
diff --git a/samples/spring-boot-auto-config/pom.xml b/samples/spring-boot-auto-config/pom.xml
index 5407079..8c9eff3 100644
--- a/samples/spring-boot-auto-config/pom.xml
+++ b/samples/spring-boot-auto-config/pom.xml
@@ -11,7 +11,7 @@
operator-framework-spring-boot-starter-samples-auto-configuration
jar
Java Operator SDK Spring Boot Starter - Samples - Auto Configuration
- Sample usage with Spring Boot
+ Webapp Sample with Spring Boot
diff --git a/samples/webpage/k8s/webpage.yaml b/samples/webpage/k8s/webpage.yaml
new file mode 100644
index 0000000..1aa41ff
--- /dev/null
+++ b/samples/webpage/k8s/webpage.yaml
@@ -0,0 +1,18 @@
+apiVersion: "sample.javaoperatorsdk/v1"
+kind: WebPage
+metadata:
+# Use labels to match the resource with different reconciler implementations:
+# labels:
+# low-level: "true"
+ name: hellows
+spec:
+ exposed: false
+ html: |
+
+
+ Hello Operator World
+
+
+ Hello World!
+
+
diff --git a/samples/webpage/pom.xml b/samples/webpage/pom.xml
new file mode 100644
index 0000000..f5a78d5
--- /dev/null
+++ b/samples/webpage/pom.xml
@@ -0,0 +1,67 @@
+
+
+ 4.0.0
+
+
+ io.javaoperatorsdk
+ operator-framework-spring-boot-starter-samples-parent
+ 6.1.1-SNAPSHOT
+
+
+ operator-framework-spring-boot-starter-samples-webpage
+ jar
+ Java Operator SDK Spring Boot Starter - Samples - WebPage
+ Sample usage with Spring Boot
+
+
+
+ io.javaoperatorsdk
+ operator-framework-spring-boot-starter
+
+
+ io.javaoperatorsdk
+ operator-framework
+ compile
+
+
+ io.fabric8
+ crd-generator-apt
+ ${fabric8-client.version}
+ compile
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+
+
+ org.springframework.boot
+ spring-boot-starter-logging
+
+
+ org.skyscreamer
+ jsonassert
+
+
+
+
+
+ io.javaoperatorsdk
+ operator-framework-spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/SpringBootStarterSampleApplication.java b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/SpringBootStarterSampleApplication.java
new file mode 100644
index 0000000..6379288
--- /dev/null
+++ b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/SpringBootStarterSampleApplication.java
@@ -0,0 +1,13 @@
+package io.javaoperatorsdk.operator.springboot.starter.sample.webpage;
+
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SpringBootStarterSampleApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringBootStarterSampleApplication.class, args);
+ }
+}
diff --git a/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/Utils.java b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/Utils.java
new file mode 100644
index 0000000..d54ad86
--- /dev/null
+++ b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/Utils.java
@@ -0,0 +1,67 @@
+package io.javaoperatorsdk.operator.springboot.starter.sample.webpage;
+
+import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
+import io.fabric8.kubernetes.api.model.networking.v1.Ingress;
+import io.javaoperatorsdk.operator.api.reconciler.ErrorStatusUpdateControl;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.customresource.WebPage;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.customresource.WebPageStatus;
+
+import static io.javaoperatorsdk.operator.ReconcilerUtils.loadYaml;
+
+public class Utils {
+
+ private Utils() {}
+
+ public static WebPage createWebPageForStatusUpdate(WebPage webPage, String configMapName) {
+ WebPage res = new WebPage();
+ res.setMetadata(
+ new ObjectMetaBuilder()
+ .withName(webPage.getMetadata().getName())
+ .withNamespace(webPage.getMetadata().getNamespace())
+ .build());
+ res.setStatus(createStatus(configMapName));
+ return res;
+ }
+
+ public static WebPageStatus createStatus(String configMapName) {
+ WebPageStatus status = new WebPageStatus();
+ status.setHtmlConfigMap(configMapName);
+ status.setAreWeGood(true);
+ status.setErrorMessage(null);
+ return status;
+ }
+
+ public static String configMapName(WebPage nginx) {
+ return nginx.getMetadata().getName() + "-html";
+ }
+
+ public static String deploymentName(WebPage nginx) {
+ return nginx.getMetadata().getName();
+ }
+
+ public static String serviceName(WebPage webPage) {
+ return webPage.getMetadata().getName();
+ }
+
+ public static ErrorStatusUpdateControl handleError(WebPage resource, Exception e) {
+ resource.getStatus().setErrorMessage("Error: " + e.getMessage());
+ return ErrorStatusUpdateControl.patchStatus(resource);
+ }
+
+ public static Ingress makeDesiredIngress(WebPage webPage) {
+ Ingress ingress = loadYaml(Ingress.class, Utils.class, "ingress.yaml");
+ ingress.getMetadata().setName(webPage.getMetadata().getName());
+ ingress.getMetadata().setNamespace(webPage.getMetadata().getNamespace());
+ ingress
+ .getSpec()
+ .getRules()
+ .get(0)
+ .getHttp()
+ .getPaths()
+ .get(0)
+ .getBackend()
+ .getService()
+ .setName(serviceName(webPage));
+ return ingress;
+ }
+}
diff --git a/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/WebPageManagedDependentsReconciler.java b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/WebPageManagedDependentsReconciler.java
new file mode 100644
index 0000000..9791849
--- /dev/null
+++ b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/WebPageManagedDependentsReconciler.java
@@ -0,0 +1,77 @@
+package io.javaoperatorsdk.operator.springboot.starter.sample.webpage;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import io.fabric8.kubernetes.api.model.ConfigMap;
+import io.javaoperatorsdk.operator.api.reconciler.Cleaner;
+import io.javaoperatorsdk.operator.api.reconciler.Context;
+import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration;
+import io.javaoperatorsdk.operator.api.reconciler.DeleteControl;
+import io.javaoperatorsdk.operator.api.reconciler.ErrorStatusUpdateControl;
+import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
+import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
+import io.javaoperatorsdk.operator.api.reconciler.Workflow;
+import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.customresource.WebPage;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.customresource.WebPageStatus;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.dependentresource.ConfigMapDependentResource;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.dependentresource.DeploymentDependentResource;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.dependentresource.ExposedIngressCondition;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.dependentresource.IngressDependentResource;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.dependentresource.ServiceDependentResource;
+
+import static io.javaoperatorsdk.operator.springboot.starter.sample.webpage.Utils.createWebPageForStatusUpdate;
+
+/** Shows how to implement a reconciler with managed dependent resources. */
+@Workflow(
+ dependents = {
+ @Dependent(type = ConfigMapDependentResource.class),
+ @Dependent(type = DeploymentDependentResource.class),
+ @Dependent(type = ServiceDependentResource.class),
+ @Dependent(
+ type = IngressDependentResource.class,
+ reconcilePrecondition = ExposedIngressCondition.class)
+ })
+@Component
+@ControllerConfiguration(name = "webpage")
+public class WebPageManagedDependentsReconciler implements Reconciler, Cleaner {
+
+ public static final String SELECTOR = "managed";
+
+ private static final Logger log =
+ LoggerFactory.getLogger(WebPageManagedDependentsReconciler.class);
+
+ @Override
+ public ErrorStatusUpdateControl updateErrorStatus(
+ WebPage resource, Context context, Exception e) {
+ return handleError(resource, e);
+ }
+
+ @Override
+ public UpdateControl reconcile(WebPage webPage, Context context) {
+ final var name =
+ context.getSecondaryResource(ConfigMap.class).orElseThrow().getMetadata().getName();
+
+ log.info("Reconciled webpage with name: {} namespace: {}",
+ webPage.getMetadata().getName(), webPage.getMetadata().getNamespace());
+
+ return UpdateControl.patchStatus(createWebPageForStatusUpdate(webPage, name));
+ }
+
+ private static ErrorStatusUpdateControl handleError(WebPage resource, Exception e) {
+ if (resource.getStatus() == null) {
+ resource.setStatus(new WebPageStatus());
+ }
+ resource.getStatus().setErrorMessage("Error: " + e.getMessage());
+ return ErrorStatusUpdateControl.patchStatus(resource);
+ }
+
+ @Override
+ public DeleteControl cleanup(WebPage resource, Context context) {
+ return DeleteControl.defaultDelete();
+ }
+
+
+}
diff --git a/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/customresource/WebPage.java b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/customresource/WebPage.java
new file mode 100644
index 0000000..43500bf
--- /dev/null
+++ b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/customresource/WebPage.java
@@ -0,0 +1,16 @@
+package io.javaoperatorsdk.operator.springboot.starter.sample.webpage.customresource;
+
+import io.fabric8.kubernetes.api.model.Namespaced;
+import io.fabric8.kubernetes.client.CustomResource;
+import io.fabric8.kubernetes.model.annotation.Group;
+import io.fabric8.kubernetes.model.annotation.Version;
+
+@Group("sample.javaoperatorsdk")
+@Version("v1")
+public class WebPage extends CustomResource implements Namespaced {
+
+ @Override
+ public String toString() {
+ return "WebPage{" + "spec=" + spec + ", status=" + status + '}';
+ }
+}
diff --git a/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/customresource/WebPageSpec.java b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/customresource/WebPageSpec.java
new file mode 100644
index 0000000..8890c1a
--- /dev/null
+++ b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/customresource/WebPageSpec.java
@@ -0,0 +1,29 @@
+package io.javaoperatorsdk.operator.springboot.starter.sample.webpage.customresource;
+
+public class WebPageSpec {
+
+ private String html;
+ private Boolean exposed = false;
+
+ public String getHtml() {
+ return html;
+ }
+
+ public void setHtml(String html) {
+ this.html = html;
+ }
+
+ public Boolean getExposed() {
+ return exposed;
+ }
+
+ public WebPageSpec setExposed(Boolean exposed) {
+ this.exposed = exposed;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "WebPageSpec{" + "html='" + html + '\'' + '}';
+ }
+}
diff --git a/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/customresource/WebPageStatus.java b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/customresource/WebPageStatus.java
new file mode 100644
index 0000000..3ee29e9
--- /dev/null
+++ b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/customresource/WebPageStatus.java
@@ -0,0 +1,50 @@
+package io.javaoperatorsdk.operator.springboot.starter.sample.webpage.customresource;
+
+public class WebPageStatus {
+
+ private String htmlConfigMap;
+
+ private Boolean areWeGood;
+
+ private String errorMessage;
+
+ public String getHtmlConfigMap() {
+ return htmlConfigMap;
+ }
+
+ public void setHtmlConfigMap(String htmlConfigMap) {
+ this.htmlConfigMap = htmlConfigMap;
+ }
+
+ public Boolean getAreWeGood() {
+ return areWeGood;
+ }
+
+ public void setAreWeGood(Boolean areWeGood) {
+ this.areWeGood = areWeGood;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public WebPageStatus setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "WebPageStatus{"
+ + "htmlConfigMap='"
+ + htmlConfigMap
+ + '\''
+ + ", areWeGood='"
+ + areWeGood
+ + '\''
+ + ", errorMessage='"
+ + errorMessage
+ + '\''
+ + '}';
+ }
+}
diff --git a/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/dependentresource/ConfigMapDependentResource.java b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/dependentresource/ConfigMapDependentResource.java
new file mode 100644
index 0000000..77b42b5
--- /dev/null
+++ b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/dependentresource/ConfigMapDependentResource.java
@@ -0,0 +1,39 @@
+package io.javaoperatorsdk.operator.springboot.starter.sample.webpage.dependentresource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import io.fabric8.kubernetes.api.model.ConfigMap;
+import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
+import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
+import io.javaoperatorsdk.operator.api.config.informer.Informer;
+import io.javaoperatorsdk.operator.api.reconciler.Context;
+import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource;
+import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.customresource.WebPage;
+
+import static io.javaoperatorsdk.operator.springboot.starter.sample.webpage.Utils.configMapName;
+import static io.javaoperatorsdk.operator.springboot.starter.sample.webpage.WebPageManagedDependentsReconciler.SELECTOR;
+
+// this annotation only activates when using managed dependents and is not otherwise needed
+@KubernetesDependent(informer = @Informer(labelSelector = SELECTOR))
+public class ConfigMapDependentResource
+ extends CRUDKubernetesDependentResource {
+
+ @Override
+ protected ConfigMap desired(WebPage webPage, Context context) {
+ Map data = new HashMap<>();
+ data.put("index.html", webPage.getSpec().getHtml());
+ Map labels = new HashMap<>();
+ labels.put(SELECTOR, "true");
+ return new ConfigMapBuilder()
+ .withMetadata(
+ new ObjectMetaBuilder()
+ .withName(configMapName(webPage))
+ .withNamespace(webPage.getMetadata().getNamespace())
+ .withLabels(labels)
+ .build())
+ .withData(data)
+ .build();
+ }
+}
diff --git a/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/dependentresource/DeploymentDependentResource.java b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/dependentresource/DeploymentDependentResource.java
new file mode 100644
index 0000000..a5c0af6
--- /dev/null
+++ b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/dependentresource/DeploymentDependentResource.java
@@ -0,0 +1,47 @@
+package io.javaoperatorsdk.operator.springboot.starter.sample.webpage.dependentresource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import io.fabric8.kubernetes.api.model.ConfigMapVolumeSourceBuilder;
+import io.fabric8.kubernetes.api.model.apps.Deployment;
+import io.javaoperatorsdk.operator.api.config.informer.Informer;
+import io.javaoperatorsdk.operator.api.reconciler.Context;
+import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource;
+import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.Utils;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.customresource.WebPage;
+
+import static io.javaoperatorsdk.operator.ReconcilerUtils.loadYaml;
+import static io.javaoperatorsdk.operator.springboot.starter.sample.webpage.Utils.configMapName;
+import static io.javaoperatorsdk.operator.springboot.starter.sample.webpage.WebPageManagedDependentsReconciler.SELECTOR;
+
+// this annotation only activates when using managed dependents and is not otherwise needed
+@KubernetesDependent(informer = @Informer(labelSelector = SELECTOR))
+public class DeploymentDependentResource
+ extends CRUDKubernetesDependentResource {
+
+ @Override
+ protected Deployment desired(WebPage webPage, Context context) {
+ Map labels = new HashMap<>();
+ labels.put(SELECTOR, "true");
+ var deploymentName =
+ io.javaoperatorsdk.operator.springboot.starter.sample.webpage.Utils.deploymentName(webPage);
+ Deployment deployment = loadYaml(Deployment.class, Utils.class, "deployment.yaml");
+ deployment.getMetadata().setName(deploymentName);
+ deployment.getMetadata().setNamespace(webPage.getMetadata().getNamespace());
+ deployment.getMetadata().setLabels(labels);
+ deployment.getSpec().getSelector().getMatchLabels().put("app", deploymentName);
+
+ deployment.getSpec().getTemplate().getMetadata().getLabels().put("app", deploymentName);
+ deployment
+ .getSpec()
+ .getTemplate()
+ .getSpec()
+ .getVolumes()
+ .get(0)
+ .setConfigMap(new ConfigMapVolumeSourceBuilder().withName(configMapName(webPage)).build());
+
+ return deployment;
+ }
+}
diff --git a/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/dependentresource/ExposedIngressCondition.java b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/dependentresource/ExposedIngressCondition.java
new file mode 100644
index 0000000..ad5445a
--- /dev/null
+++ b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/dependentresource/ExposedIngressCondition.java
@@ -0,0 +1,19 @@
+package io.javaoperatorsdk.operator.springboot.starter.sample.webpage.dependentresource;
+
+import io.fabric8.kubernetes.api.model.networking.v1.Ingress;
+import io.javaoperatorsdk.operator.api.reconciler.Context;
+import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource;
+import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.customresource.WebPage;
+
+
+public class ExposedIngressCondition implements Condition {
+
+ @Override
+ public boolean isMet(
+ DependentResource dependentResource,
+ WebPage primary,
+ Context context) {
+ return primary.getSpec().getExposed();
+ }
+}
diff --git a/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/dependentresource/IngressDependentResource.java b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/dependentresource/IngressDependentResource.java
new file mode 100644
index 0000000..5e2ad9d
--- /dev/null
+++ b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/dependentresource/IngressDependentResource.java
@@ -0,0 +1,23 @@
+package io.javaoperatorsdk.operator.springboot.starter.sample.webpage.dependentresource;
+
+import io.fabric8.kubernetes.api.model.networking.v1.Ingress;
+import io.javaoperatorsdk.operator.api.config.informer.Informer;
+import io.javaoperatorsdk.operator.api.reconciler.Context;
+import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource;
+import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.WebPageManagedDependentsReconciler;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.customresource.WebPage;
+
+import static io.javaoperatorsdk.operator.springboot.starter.sample.webpage.Utils.makeDesiredIngress;
+
+
+// this annotation only activates when using managed dependents and is not otherwise needed
+@KubernetesDependent(
+ informer = @Informer(labelSelector = WebPageManagedDependentsReconciler.SELECTOR))
+public class IngressDependentResource extends CRUDKubernetesDependentResource {
+
+ @Override
+ protected Ingress desired(WebPage webPage, Context context) {
+ return makeDesiredIngress(webPage);
+ }
+}
diff --git a/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/dependentresource/ServiceDependentResource.java b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/dependentresource/ServiceDependentResource.java
new file mode 100644
index 0000000..5860621
--- /dev/null
+++ b/samples/webpage/src/main/java/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/dependentresource/ServiceDependentResource.java
@@ -0,0 +1,38 @@
+package io.javaoperatorsdk.operator.springboot.starter.sample.webpage.dependentresource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import io.fabric8.kubernetes.api.model.Service;
+import io.javaoperatorsdk.operator.api.config.informer.Informer;
+import io.javaoperatorsdk.operator.api.reconciler.Context;
+import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.Utils;
+import io.javaoperatorsdk.operator.springboot.starter.sample.webpage.customresource.WebPage;
+
+import static io.javaoperatorsdk.operator.ReconcilerUtils.loadYaml;
+import static io.javaoperatorsdk.operator.springboot.starter.sample.webpage.Utils.deploymentName;
+import static io.javaoperatorsdk.operator.springboot.starter.sample.webpage.Utils.serviceName;
+import static io.javaoperatorsdk.operator.springboot.starter.sample.webpage.WebPageManagedDependentsReconciler.SELECTOR;
+
+
+// this annotation only activates when using managed dependents and is not otherwise needed
+@KubernetesDependent(informer = @Informer(labelSelector = SELECTOR))
+public class ServiceDependentResource
+ extends
+ io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource {
+
+ @Override
+ protected Service desired(WebPage webPage, Context context) {
+ Map serviceLabels = new HashMap<>();
+ serviceLabels.put(SELECTOR, "true");
+ Service service = loadYaml(Service.class, Utils.class, "service.yaml");
+ service.getMetadata().setName(serviceName(webPage));
+ service.getMetadata().setNamespace(webPage.getMetadata().getNamespace());
+ service.getMetadata().setLabels(serviceLabels);
+ Map labels = new HashMap<>();
+ labels.put("app", deploymentName(webPage));
+ service.getSpec().setSelector(labels);
+ return service;
+ }
+}
diff --git a/samples/webpage/src/main/resources/application.yaml b/samples/webpage/src/main/resources/application.yaml
new file mode 100644
index 0000000..b854fb0
--- /dev/null
+++ b/samples/webpage/src/main/resources/application.yaml
@@ -0,0 +1,9 @@
+javaoperatorsdk:
+ reconcilers:
+ webpage:
+ retry:
+ maxAttempts: 3
+
+logging:
+ level:
+ io.javaoperatorsdk: INFO
\ No newline at end of file
diff --git a/samples/webpage/src/main/resources/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/deployment.yaml b/samples/webpage/src/main/resources/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/deployment.yaml
new file mode 100644
index 0000000..f2d10d4
--- /dev/null
+++ b/samples/webpage/src/main/resources/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/deployment.yaml
@@ -0,0 +1,26 @@
+apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
+kind: Deployment
+metadata:
+ name: ""
+spec:
+ selector:
+ matchLabels:
+ app: ""
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: ""
+ spec:
+ containers:
+ - name: nginx
+ image: nginx:1.17.0
+ ports:
+ - containerPort: 80
+ volumeMounts:
+ - name: html-volume
+ mountPath: /usr/share/nginx/html
+ volumes:
+ - name: html-volume
+ configMap:
+ name: ""
\ No newline at end of file
diff --git a/samples/webpage/src/main/resources/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/ingress.yaml b/samples/webpage/src/main/resources/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/ingress.yaml
new file mode 100644
index 0000000..64a49bd
--- /dev/null
+++ b/samples/webpage/src/main/resources/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/ingress.yaml
@@ -0,0 +1,17 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: ""
+ annotations:
+ nginx.ingress.kubernetes.io/rewrite-target: /$1
+spec:
+ rules:
+ - http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: ""
+ port:
+ number: 80
\ No newline at end of file
diff --git a/samples/webpage/src/main/resources/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/service.yaml b/samples/webpage/src/main/resources/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/service.yaml
new file mode 100644
index 0000000..578fcd6
--- /dev/null
+++ b/samples/webpage/src/main/resources/io/javaoperatorsdk/operator/springboot/starter/sample/webpage/service.yaml
@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: ""
+spec:
+ selector:
+ app: ""
+ ports:
+ - protocol: TCP
+ port: 80
+ targetPort: 80
+ type: NodePort
\ No newline at end of file
diff --git a/starter/pom.xml b/starter/pom.xml
index 364c942..5f2b0d5 100644
--- a/starter/pom.xml
+++ b/starter/pom.xml
@@ -120,5 +120,9 @@
jenvtest-fabric8-client-support
test
+
+ org.springframework.boot
+ spring-boot-starter-log4j2
+