Generate load balancer service instead of unspecific service.
This commit is contained in:
parent
f4e8318b6e
commit
4ed5168591
6 changed files with 44 additions and 29 deletions
|
|
@ -924,9 +924,9 @@ spec:
|
||||||
update:
|
update:
|
||||||
type: boolean
|
type: boolean
|
||||||
default: true
|
default: true
|
||||||
additionalServiceMetadata:
|
loadBalancerService:
|
||||||
description: >-
|
description: >-
|
||||||
Data to be merged with the additionalServiceMetadata
|
Data to be merged with the loadBalancerService
|
||||||
defined in the manager's configuration. Values
|
defined in the manager's configuration. Values
|
||||||
specified here override values from the manager's
|
specified here override values from the manager's
|
||||||
configuration. If the value of a label or an annotation
|
configuration. If the value of a label or an annotation
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ spec:
|
||||||
path: vmoperator/org.jdrupes.vmoperator.runner.qemu-arch
|
path: vmoperator/org.jdrupes.vmoperator.runner.qemu-arch
|
||||||
pullPolicy: Always
|
pullPolicy: Always
|
||||||
|
|
||||||
additionalServiceMetadata:
|
loadBalancerService:
|
||||||
labels:
|
labels:
|
||||||
test2: null
|
test2: null
|
||||||
test3: added
|
test3: added
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,13 @@
|
||||||
# the resource properties.
|
# the resource properties.
|
||||||
ramOvercommit: 1.5
|
ramOvercommit: 1.5
|
||||||
|
|
||||||
# Additional metadata (labels and annotations) to be merged
|
# If defined, causes a load balancer service to be created.
|
||||||
# into the service. Must be provided as nested YAML
|
# May be a boolean or a string with nested yaml that
|
||||||
# additionalServiceMetadata: |
|
# defines additional labels or annotations to be merged
|
||||||
|
# into the service.
|
||||||
|
# loadBalancerService: |
|
||||||
# labels: {}
|
# labels: {}
|
||||||
# annotations: {}
|
# annotations: {}
|
||||||
|
|
||||||
# Only for development:
|
# Explicitly specify the namespace to be managed (only for development).
|
||||||
# namespace: vmop-dev
|
# namespace: vmop-dev
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,10 @@ metadata:
|
||||||
controller: false
|
controller: false
|
||||||
|
|
||||||
spec:
|
spec:
|
||||||
|
type: LoadBalancer
|
||||||
ports:
|
ports:
|
||||||
- name: spice
|
- name: spice
|
||||||
port: ${ cr.spec.vm.display.spice.port.asInt?c }
|
port: ${ cr.spec.vm.display.spice.port.asInt?c }
|
||||||
clusterIP: None
|
|
||||||
selector:
|
selector:
|
||||||
app.kubernetes.io/name: ${ cr.metadata.name.asString }
|
app.kubernetes.io/name: ${ constants.APP_NAME }
|
||||||
app.kubernetes.io/instance: ${ cr.metadata.name.asString }
|
app.kubernetes.io/instance: ${ cr.metadata.name.asString }
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ import io.kubernetes.client.util.generic.dynamic.DynamicKubernetesObject;
|
||||||
import io.kubernetes.client.util.generic.dynamic.Dynamics;
|
import io.kubernetes.client.util.generic.dynamic.Dynamics;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.util.HashMap;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
@ -41,8 +41,9 @@ import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||||
* Delegee for reconciling the service
|
* Delegee for reconciling the service
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("PMD.DataflowAnomalyAnalysis")
|
@SuppressWarnings("PMD.DataflowAnomalyAnalysis")
|
||||||
/* default */ class ServiceReconciler {
|
/* default */ class LoadBalancerReconciler {
|
||||||
|
|
||||||
|
private static final String LOAD_BALANCER_SERVICE = "loadBalancerService";
|
||||||
private static final String METADATA
|
private static final String METADATA
|
||||||
= V1APIService.SERIALIZED_NAME_METADATA;
|
= V1APIService.SERIALIZED_NAME_METADATA;
|
||||||
private static final String LABELS = V1ObjectMeta.SERIALIZED_NAME_LABELS;
|
private static final String LABELS = V1ObjectMeta.SERIALIZED_NAME_LABELS;
|
||||||
|
|
@ -56,7 +57,7 @@ import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||||
*
|
*
|
||||||
* @param fmConfig the fm config
|
* @param fmConfig the fm config
|
||||||
*/
|
*/
|
||||||
public ServiceReconciler(Configuration fmConfig) {
|
public LoadBalancerReconciler(Configuration fmConfig) {
|
||||||
this.fmConfig = fmConfig;
|
this.fmConfig = fmConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,41 +74,53 @@ import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||||
public void reconcile(VmDefChanged event,
|
public void reconcile(VmDefChanged event,
|
||||||
Map<String, Object> model, VmChannel channel)
|
Map<String, Object> model, VmChannel channel)
|
||||||
throws IOException, TemplateException, ApiException {
|
throws IOException, TemplateException, ApiException {
|
||||||
// Get API
|
// Check if to be generated
|
||||||
DynamicKubernetesApi svcApi = new DynamicKubernetesApi("", "v1",
|
@SuppressWarnings("unchecked")
|
||||||
"services", channel.client());
|
var lbs = Optional.of(model)
|
||||||
|
.map(m -> (Map<String, Object>) m.get("config"))
|
||||||
|
.map(c -> c.get(LOAD_BALANCER_SERVICE)).orElse(Boolean.FALSE);
|
||||||
|
if (lbs instanceof Boolean isOn && !isOn) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!(lbs instanceof String)) {
|
||||||
|
logger.warning(() -> "\"" + LOAD_BALANCER_SERVICE
|
||||||
|
+ "\" in configuration must be boolean or string but is "
|
||||||
|
+ lbs.getClass() + ".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Combine template and data and parse result
|
// Combine template and data and parse result
|
||||||
var fmTemplate = fmConfig.getTemplate("runnerService.ftl.yaml");
|
var fmTemplate = fmConfig.getTemplate("runnerLoadBalancer.ftl.yaml");
|
||||||
StringWriter out = new StringWriter();
|
StringWriter out = new StringWriter();
|
||||||
fmTemplate.process(model, out);
|
fmTemplate.process(model, out);
|
||||||
// Avoid Yaml.load due to
|
// Avoid Yaml.load due to
|
||||||
// https://github.com/kubernetes-client/java/issues/2741
|
// https://github.com/kubernetes-client/java/issues/2741
|
||||||
var svcDef = Dynamics.newFromYaml(
|
var svcDef = Dynamics.newFromYaml(
|
||||||
new Yaml(new SafeConstructor(new LoaderOptions())), out.toString());
|
new Yaml(new SafeConstructor(new LoaderOptions())), out.toString());
|
||||||
mergeMetadata(svcDef, model, channel);
|
mergeMetadata(svcDef, lbs, channel);
|
||||||
|
|
||||||
// Apply
|
// Apply
|
||||||
|
DynamicKubernetesApi svcApi = new DynamicKubernetesApi("", "v1",
|
||||||
|
"services", channel.client());
|
||||||
K8s.apply(svcApi, svcDef, svcDef.getRaw().toString());
|
K8s.apply(svcApi, svcDef, svcDef.getRaw().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private void mergeMetadata(DynamicKubernetesObject svcDef,
|
private void mergeMetadata(DynamicKubernetesObject svcDef,
|
||||||
Map<String, Object> model, VmChannel channel) {
|
Object lbsConfig, VmChannel channel) {
|
||||||
// Get metadata from config
|
// Get metadata from config
|
||||||
@SuppressWarnings("unchecked")
|
Map<String, Object> asmData = Collections.emptyMap();
|
||||||
var asmData = Optional.of(model)
|
if (lbsConfig instanceof String config) {
|
||||||
.map(m -> (Map<String, Object>) m.get("config"))
|
asmData = (Map<String, Object>) new Yaml(
|
||||||
.map(c -> (String) c.get("additionalServiceMetadata"))
|
new SafeConstructor(new LoaderOptions())).load(config);
|
||||||
.map(y -> (Map<String, Object>) new Yaml(
|
}
|
||||||
new SafeConstructor(new LoaderOptions())).load(y))
|
|
||||||
.orElseGet(() -> new HashMap<String, Object>());
|
|
||||||
var json = channel.client().getJSON();
|
var json = channel.client().getJSON();
|
||||||
JsonObject cfgMeta
|
JsonObject cfgMeta
|
||||||
= json.deserialize(json.serialize(asmData), JsonObject.class);
|
= json.deserialize(json.serialize(asmData), JsonObject.class);
|
||||||
|
|
||||||
// Get metadata from VM definition
|
// Get metadata from VM definition
|
||||||
var vmMeta = GsonPtr.to(channel.vmDefinition()).to("spec")
|
var vmMeta = GsonPtr.to(channel.vmDefinition()).to("spec")
|
||||||
.get(JsonObject.class, "additionalServiceMetadata")
|
.get(JsonObject.class, LOAD_BALANCER_SERVICE)
|
||||||
.map(JsonObject::deepCopy).orElseGet(() -> new JsonObject());
|
.map(JsonObject::deepCopy).orElseGet(() -> new JsonObject());
|
||||||
|
|
||||||
// Merge Data from VM definition into config data
|
// Merge Data from VM definition into config data
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ public class Reconciler extends Component {
|
||||||
private final Configuration fmConfig;
|
private final Configuration fmConfig;
|
||||||
private final CmReconciler cmReconciler;
|
private final CmReconciler cmReconciler;
|
||||||
private final StsReconciler stsReconciler;
|
private final StsReconciler stsReconciler;
|
||||||
private final ServiceReconciler serviceReconciler;
|
private final LoadBalancerReconciler lbReconciler;
|
||||||
@SuppressWarnings("PMD.UseConcurrentHashMap")
|
@SuppressWarnings("PMD.UseConcurrentHashMap")
|
||||||
private final Map<String, Object> config = new HashMap<>();
|
private final Map<String, Object> config = new HashMap<>();
|
||||||
|
|
||||||
|
|
@ -84,7 +84,7 @@ public class Reconciler extends Component {
|
||||||
|
|
||||||
cmReconciler = new CmReconciler(fmConfig);
|
cmReconciler = new CmReconciler(fmConfig);
|
||||||
stsReconciler = new StsReconciler(fmConfig);
|
stsReconciler = new StsReconciler(fmConfig);
|
||||||
serviceReconciler = new ServiceReconciler(fmConfig);
|
lbReconciler = new LoadBalancerReconciler(fmConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -137,7 +137,7 @@ public class Reconciler extends Component {
|
||||||
var configMap = cmReconciler.reconcile(event, model, channel);
|
var configMap = cmReconciler.reconcile(event, model, channel);
|
||||||
model.put("cm", configMap.getRaw());
|
model.put("cm", configMap.getRaw());
|
||||||
stsReconciler.reconcile(event, model, channel);
|
stsReconciler.reconcile(event, model, channel);
|
||||||
serviceReconciler.reconcile(event, model, channel);
|
lbReconciler.reconcile(event, model, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Object> prepareModel(JsonObject vmDef)
|
private Map<String, Object> prepareModel(JsonObject vmDef)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue