Skip to content

Commit

Permalink
feat: conditional database (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosthe19916 authored Oct 8, 2024
1 parent 0209206 commit 54a603c
Show file tree
Hide file tree
Showing 16 changed files with 265 additions and 88 deletions.
1 change: 1 addition & 0 deletions src/main/java/org/trustify/operator/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class Constants {
public static final String DB_SECRET_USERNAME = "username";
public static final String DB_SECRET_PASSWORD = "password";
public static final String DB_NAME = "trustify";
public static final Integer DB_PORT= 5432;

public static final String POSTGRESQL_PVC_SIZE = "10G";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import io.fabric8.kubernetes.api.model.LocalObjectReference;
import io.fabric8.kubernetes.api.model.SecretKeySelector;

import java.util.List;

Expand Down Expand Up @@ -50,12 +51,29 @@ public TrustifySpec() {
}

public record DatabaseSpec(
@JsonPropertyDescription("Size of the PVC to create.")
String size,
@JsonPropertyDescription("Use external database.")
boolean externalDatabase,

@JsonProperty("resourceLimits")
@JsonPropertyDescription("In this section you can configure resource limits settings.")
ResourcesLimitSpec resourceLimitSpec
@JsonPropertyDescription("Size of the PVC to create. Valid only if externalDatabase=false")
String pvcSize,

@JsonPropertyDescription("In this section you can configure resource limits settings. Valid only if externalDatabase=false")
ResourcesLimitSpec resourceLimits,

@JsonPropertyDescription("The reference to a secret holding the username of the database user.")
SecretKeySelector usernameSecret,

@JsonPropertyDescription("The reference to a secret holding the password of the database user.")
SecretKeySelector passwordSecret,

@JsonPropertyDescription("The host of the database.")
String host,

@JsonPropertyDescription("The port of the database.")
String port,

@JsonPropertyDescription("The database name.")
String name
) {
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.trustify.operator.cdrs.v2alpha1.db;

import org.trustify.operator.cdrs.v2alpha1.Trustify;
import org.trustify.operator.cdrs.v2alpha1.TrustifySpec;

import java.util.Optional;

public abstract class DBActivationCondition {

protected boolean isMet(Trustify cr) {
return !Optional.ofNullable(cr.getSpec().databaseSpec())
.map(TrustifySpec.DatabaseSpec::externalDatabase)
.orElse(false);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
public class DBDeployment extends CRUDKubernetesDependentResource<Deployment, Trustify>
implements Matcher<Deployment, Trustify>, Condition<Deployment, Trustify> {

public static final String LABEL_SELECTOR="app.kubernetes.io/managed-by=trustify-operator,component=db";
public static final String LABEL_SELECTOR = "app.kubernetes.io/managed-by=trustify-operator,component=db";

@Inject
Config config;
Expand Down Expand Up @@ -98,7 +98,7 @@ private DeploymentSpec getDeploymentSpec(Trustify cr, Context<Trustify> context)
String image = Optional.ofNullable(cr.getSpec().dbImage()).orElse(config.dbImage());
String imagePullPolicy = Optional.ofNullable(cr.getSpec().imagePullPolicy()).orElse(config.imagePullPolicy());

TrustifySpec.ResourcesLimitSpec resourcesLimitSpec = CRDUtils.getValueFromSubSpec(cr.getSpec().databaseSpec(), TrustifySpec.DatabaseSpec::resourceLimitSpec)
TrustifySpec.ResourcesLimitSpec resourcesLimitSpec = CRDUtils.getValueFromSubSpec(cr.getSpec().databaseSpec(), TrustifySpec.DatabaseSpec::resourceLimits)
.orElse(null);

return new DeploymentSpecBuilder()
Expand Down Expand Up @@ -130,7 +130,7 @@ private DeploymentSpec getDeploymentSpec(Trustify cr, Context<Trustify> context)
.withPorts(new ContainerPortBuilder()
.withName("tcp")
.withProtocol(Constants.SERVICE_PROTOCOL)
.withContainerPort(5432)
.withContainerPort(getDatabasePort(cr))
.build()
)
.withLivenessProbe(new ProbeBuilder()
Expand Down Expand Up @@ -194,33 +194,70 @@ private List<EnvVar> getEnvVars(Trustify cr) {
return Arrays.asList(
new EnvVarBuilder()
.withName("POSTGRESQL_USER")
.withNewValueFrom()
.withNewSecretKeyRef()
.withName(DBSecret.getSecretName(cr))
.withKey(Constants.DB_SECRET_USERNAME)
.withOptional(false)
.endSecretKeyRef()
.endValueFrom()
.withValueFrom(new EnvVarSourceBuilder()
.withSecretKeyRef(getUsernameSecretKeySelector(cr))
.build()
)
.build(),
new EnvVarBuilder()
.withName("POSTGRESQL_PASSWORD")
.withNewValueFrom()
.withNewSecretKeyRef()
.withName(DBSecret.getSecretName(cr))
.withKey(Constants.DB_SECRET_PASSWORD)
.withOptional(false)
.endSecretKeyRef()
.endValueFrom()
.withValueFrom(new EnvVarSourceBuilder()
.withSecretKeyRef(getPasswordSecretKeySelector(cr))
.build()
)
.build(),

new EnvVarBuilder()
new EnvVarBuilder()
.withName("POSTGRESQL_DATABASE")
.withValue(Constants.DB_NAME)
.withValue(getDatabaseName(cr))
.build()
);
}

public static String getDeploymentName(Trustify cr) {
return cr.getMetadata().getName() + Constants.DB_DEPLOYMENT_SUFFIX;
}

public static SecretKeySelector getUsernameSecretKeySelector(Trustify cr) {
return Optional.ofNullable(cr.getSpec().databaseSpec())
.map(TrustifySpec.DatabaseSpec::usernameSecret)
.map(secret -> new SecretKeySelectorBuilder()
.withName(secret.getName())
.withKey(secret.getKey())
.withOptional(false)
.build()
)
.orElseGet(() -> new SecretKeySelectorBuilder()
.withName(DBSecret.getSecretName(cr))
.withKey(Constants.DB_SECRET_USERNAME)
.withOptional(false)
.build()
);
}

public static SecretKeySelector getPasswordSecretKeySelector(Trustify cr) {
return Optional.ofNullable(cr.getSpec().databaseSpec())
.map(TrustifySpec.DatabaseSpec::passwordSecret)
.map(secret -> new SecretKeySelectorBuilder()
.withName(secret.getName())
.withKey(secret.getKey())
.withOptional(false)
.build()
)
.orElseGet(() -> new SecretKeySelectorBuilder()
.withName(DBSecret.getSecretName(cr))
.withKey(Constants.DB_SECRET_PASSWORD)
.withOptional(false)
.build()
);
}

public static String getDatabaseName(Trustify cr) {
return Optional.ofNullable(cr.getSpec().databaseSpec())
.map(TrustifySpec.DatabaseSpec::name)
.orElse(Constants.DB_NAME);
}

public static Integer getDatabasePort(Trustify cr) {
return Constants.DB_PORT;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.trustify.operator.cdrs.v2alpha1.db;

import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource;
import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition;
import jakarta.enterprise.context.ApplicationScoped;
import org.trustify.operator.cdrs.v2alpha1.Trustify;

@ApplicationScoped
public class DBDeploymentActivationCondition extends DBActivationCondition implements Condition<Deployment, Trustify> {

@Override
public boolean isMet(DependentResource<Deployment, Trustify> resource, Trustify cr, Context<Trustify> context) {
return super.isMet(cr);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class DBDeploymentDiscriminator implements ResourceDiscriminator<Deployme
public Optional<Deployment> distinguish(Class<Deployment> resource, Trustify cr, Context<Trustify> context) {
String deploymentName = DBDeployment.getDeploymentName(cr);
ResourceID resourceID = new ResourceID(deploymentName, cr.getMetadata().getNamespace());
var informerEventSource = (InformerEventSource<Deployment, Trustify>) context.eventSourceRetriever().getResourceEventSourceFor(Deployment.class);
var informerEventSource = (InformerEventSource<Deployment, Trustify>) context.eventSourceRetriever().getResourceEventSourceFor(Deployment.class, "db-deployment");
return informerEventSource.get(resourceID);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ private PersistentVolumeClaim newPersistentVolumeClaim(Trustify cr, Context<Trus
final var labels = (Map<String, String>) context.managedDependentResourceContext()
.getMandatory(Constants.CONTEXT_LABELS_KEY, Map.class);

String pvcStorageSize = CRDUtils.getValueFromSubSpec(cr.getSpec().databaseSpec(), TrustifySpec.DatabaseSpec::size)
String pvcStorageSize = CRDUtils.getValueFromSubSpec(cr.getSpec().databaseSpec(), TrustifySpec.DatabaseSpec::pvcSize)
.orElse(Constants.POSTGRESQL_PVC_SIZE);

return new PersistentVolumeClaimBuilder()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.trustify.operator.cdrs.v2alpha1.db;

import io.fabric8.kubernetes.api.model.PersistentVolumeClaim;
import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource;
import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition;
import jakarta.enterprise.context.ApplicationScoped;
import org.trustify.operator.cdrs.v2alpha1.Trustify;

@ApplicationScoped
public class DBPersistentVolumeClaimActivationCondition extends DBActivationCondition implements Condition<PersistentVolumeClaim, Trustify> {

@Override
public boolean isMet(DependentResource<PersistentVolumeClaim, Trustify> resource, Trustify cr, Context<Trustify> context) {
return super.isMet(cr);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.trustify.operator.cdrs.v2alpha1.db;

import io.fabric8.kubernetes.api.model.Secret;
import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource;
import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition;
import jakarta.enterprise.context.ApplicationScoped;
import org.trustify.operator.cdrs.v2alpha1.Trustify;

import java.util.Optional;

@ApplicationScoped
public class DBSecretActivationCondition extends DBActivationCondition implements Condition<Secret, Trustify> {

@Override
public boolean isMet(DependentResource<Secret, Trustify> resource, Trustify cr, Context<Trustify> context) {
boolean databaseRequired = super.isMet(cr);

boolean manualSecretIsNotSet = Optional.ofNullable(cr.getSpec().databaseSpec())
.map(databaseSpec -> databaseSpec.usernameSecret() == null || databaseSpec.passwordSecret() == null)
.orElse(true);

return databaseRequired && manualSecretIsNotSet;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ private Service newService(Trustify cr, Context<Trustify> context) {
private ServiceSpec getServiceSpec(Trustify cr) {
return new ServiceSpecBuilder()
.addNewPort()
.withPort(5432)
.withPort(DBDeployment.getDatabasePort(cr))
.withProtocol(Constants.SERVICE_PROTOCOL)
.endPort()
.withSelector(Constants.DB_SELECTOR_LABELS)
Expand All @@ -61,13 +61,4 @@ public static String getServiceName(Trustify cr) {
return cr.getMetadata().getName() + Constants.DB_SERVICE_SUFFIX;
}

public static String getJdbcUrl(Trustify cr) {
return String.format(
"jdbc:postgresql://%s:%s/%s",
cr.getMetadata().getName() + Constants.DB_SERVICE_SUFFIX,
5432,
Constants.DB_NAME
);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.trustify.operator.cdrs.v2alpha1.db;

import io.fabric8.kubernetes.api.model.Service;
import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource;
import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition;
import jakarta.enterprise.context.ApplicationScoped;
import org.trustify.operator.cdrs.v2alpha1.Trustify;

@ApplicationScoped
public class DBServiceActivationCondition extends DBActivationCondition implements Condition<Service, Trustify> {

@Override
public boolean isMet(DependentResource<Service, Trustify> resource, Trustify cr, Context<Trustify> context) {
return super.isMet(cr);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class DBServiceDiscriminator implements ResourceDiscriminator<Service, Tr
public Optional<Service> distinguish(Class<Service> resource, Trustify cr, Context<Trustify> context) {
String serviceName = DBService.getServiceName(cr);
ResourceID resourceID = new ResourceID(serviceName, cr.getMetadata().getNamespace());
var informerEventSource = (InformerEventSource<Service, Trustify>) context.eventSourceRetriever().getResourceEventSourceFor(Service.class);
var informerEventSource = (InformerEventSource<Service, Trustify>) context.eventSourceRetriever().getResourceEventSourceFor(Service.class, "db-service");
return informerEventSource.get(resourceID);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.javaoperatorsdk.operator.processing.event.ResourceID;
import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource;
import org.trustify.operator.cdrs.v2alpha1.Trustify;
import org.trustify.operator.controllers.TrustifyReconciler;

import java.util.Optional;

Expand All @@ -14,7 +15,7 @@ public class ServerDeploymentDiscriminator implements ResourceDiscriminator<Depl
public Optional<Deployment> distinguish(Class<Deployment> resource, Trustify cr, Context<Trustify> context) {
String deploymentName = ServerDeployment.getDeploymentName(cr);
ResourceID resourceID = new ResourceID(deploymentName, cr.getMetadata().getNamespace());
var informerEventSource = (InformerEventSource<Deployment, Trustify>) context.eventSourceRetriever().getResourceEventSourceFor(Deployment.class);
var informerEventSource = (InformerEventSource<Deployment, Trustify>) context.eventSourceRetriever().getResourceEventSourceFor(Deployment.class, TrustifyReconciler.SERVER_DEPLOYMENT_EVENT_SOURCE);
return informerEventSource.get(resourceID);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.javaoperatorsdk.operator.processing.event.ResourceID;
import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource;
import org.trustify.operator.cdrs.v2alpha1.Trustify;
import org.trustify.operator.controllers.TrustifyReconciler;

import java.util.Optional;

Expand All @@ -14,7 +15,7 @@ public class ServerServiceDiscriminator implements ResourceDiscriminator<Service
public Optional<Service> distinguish(Class<Service> resource, Trustify cr, Context<Trustify> context) {
String serviceName = ServerService.getServiceName(cr);
ResourceID resourceID = new ResourceID(serviceName, cr.getMetadata().getNamespace());
var informerEventSource = (InformerEventSource<Service, Trustify>) context.eventSourceRetriever().getResourceEventSourceFor(Service.class);
var informerEventSource = (InformerEventSource<Service, Trustify>) context.eventSourceRetriever().getResourceEventSourceFor(Service.class, TrustifyReconciler.SERVER_SERVICE_EVENT_SOURCE);
return informerEventSource.get(resourceID);
}
}
Loading

0 comments on commit 54a603c

Please sign in to comment.