use of com.enonic.kubernetes.client.v1.xp7deployment.Xp7Deployment in project xp-operator by enonic.
the class MutationApi method ensureOwnerReference.
private void ensureOwnerReference(MutationRequest mt) {
HasMetadata obj = (HasMetadata) mt.getAdmissionReview().getRequest().getObject();
if (obj.getMetadata().getOwnerReferences() != null && !obj.getMetadata().getOwnerReferences().isEmpty()) {
return;
}
Optional<Xp7Deployment> xp7Deployments = getXp7Deployment(obj);
if (xp7Deployments.isEmpty()) {
return;
}
patch(mt, false, "/metadata/ownerReferences", null, Collections.singletonList(createOwnerReference(xp7Deployments.get())));
}
use of com.enonic.kubernetes.client.v1.xp7deployment.Xp7Deployment in project xp-operator by enonic.
the class MutationApi method xp7deployment.
private void xp7deployment(MutationRequest mt) {
// Collect old and new object
Xp7Deployment oldR = (Xp7Deployment) mt.getAdmissionReview().getRequest().getOldObject();
Xp7Deployment newR = (Xp7Deployment) mt.getAdmissionReview().getRequest().getObject();
// Create default status
Xp7DeploymentStatus defStatus = new Xp7DeploymentStatus().withMessage("Waiting for pods").withState(Xp7DeploymentStatus.State.PENDING).withXp7DeploymentStatusFields(new Xp7DeploymentStatusFields().withXp7DeploymentStatusFieldsPods(new LinkedList<>()));
if (newR.getSpec() != null && newR.getSpec().getEnabled() != null && !newR.getSpec().getEnabled()) {
defStatus.setState(Xp7DeploymentStatus.State.STOPPED);
defStatus.setMessage("XP deployment stopped");
}
// Get OP
AdmissionOperation op = getOperation(mt.getAdmissionReview());
// Ensure status
switch(op) {
case // Always set the default status on new objects
CREATE:
patch(mt, true, "/status", newR.getStatus(), defStatus);
break;
case UPDATE:
if (newR.getSpec() != null && !newR.getSpec().equals(oldR.getSpec())) {
// On any change change, set default status
patch(mt, true, "/status", newR.getStatus(), defStatus);
} else {
// Else make sure the old status is not removed
patch(mt, false, "/status", newR.getStatus(), oldR.getStatus());
}
break;
case DELETE:
// Do nothing
break;
}
List<Xp7DeploymentSpecNodesPreinstalledApps> preInstall = newR.getSpec().getNodesPreinstalledApps();
if (preInstall == null || preInstall.isEmpty()) {
patch(mt, true, "/spec/nodesPreinstalledApps", newR.getSpec().getNodesPreinstalledApps(), preInstalledApps);
} else {
List<String> names = preInstall.stream().map(Xp7DeploymentSpecNodesPreinstalledApps::getName).collect(Collectors.toList());
List<Xp7DeploymentSpecNodesPreinstalledApps> newList = new LinkedList<>(preInstall);
preInstalledApps.stream().filter(a -> !names.contains(a.getName())).forEach(newList::add);
patch(mt, true, "/spec/nodesPreinstalledApps", newR.getSpec().getNodesPreinstalledApps(), newList);
}
}
use of com.enonic.kubernetes.client.v1.xp7deployment.Xp7Deployment in project xp-operator by enonic.
the class OperatorXp7DeploymentStatus method handle.
private void handle(final Pod pod) {
Optional<Xp7Deployment> xp7Deployment = searchers.xp7Deployment().find(inSameNamespaceAs(pod));
if (xp7Deployment.isEmpty()) {
return;
}
// Get current status
Xp7DeploymentStatus currentStatus = xp7Deployment.get().getStatus();
int oldStatusHash = currentStatus.hashCode();
// Get all pods in deployment
List<Pod> pods = searchers.pod().stream().filter(isEnonicManaged()).filter(isPartOfDeployment(xp7Deployment.get())).collect(Collectors.toList());
// Set pod fields
currentStatus.setXp7DeploymentStatusFields(buildFields(pods));
// Get expected number of pods
int expectedNumberOfPods = expectedNumberOfPods(xp7Deployment.get());
// If pod count does not match
if (pods.size() != expectedNumberOfPods) {
updateOnChange(xp7Deployment.get(), oldStatusHash, currentStatus.withState(Xp7DeploymentStatus.State.PENDING).withMessage("Pod count mismatch"));
return;
}
// If deployment is disabled
if (!xp7Deployment.get().getSpec().getEnabled()) {
updateOnChange(xp7Deployment.get(), oldStatusHash, currentStatus.withState(Xp7DeploymentStatus.State.STOPPED).withMessage("OK"));
return;
}
// Iterate over pods and check status
List<String> waitingForPods = new LinkedList<>();
for (Xp7DeploymentStatusFieldsPod p : currentStatus.getXp7DeploymentStatusFields().getXp7DeploymentStatusFieldsPods()) {
if (!p.getPhase().equals("Running") || !p.getReady()) {
waitingForPods.add(p.getName());
}
}
// If we are still waiting
if (!waitingForPods.isEmpty()) {
waitingForPods.sort(String::compareTo);
updateOnChange(xp7Deployment.get(), oldStatusHash, currentStatus.withState(Xp7DeploymentStatus.State.PENDING).withMessage(String.format("Waiting for pods: %s", waitingForPods.stream().collect(Collectors.joining(", ")))));
return;
}
// Return OK
updateOnChange(xp7Deployment.get(), oldStatusHash, currentStatus.withState(Xp7DeploymentStatus.State.RUNNING).withMessage("OK"));
}
use of com.enonic.kubernetes.client.v1.xp7deployment.Xp7Deployment in project xp-operator by enonic.
the class AdmissionApi method xp7deployment.
private void xp7deployment(AdmissionReview admissionReview) {
AdmissionOperation op = getOperation(admissionReview);
Xp7Deployment newDeployment = (Xp7Deployment) admissionReview.getRequest().getObject();
if (op != AdmissionOperation.DELETE) {
// Check spec
Preconditions.checkState(newDeployment.getSpec() != null, "'spec' cannot be null");
Preconditions.checkState(newDeployment.getSpec().getEnabled() != null, "'spec.enabled' cannot be null");
Preconditions.checkState(newDeployment.getSpec().getXpVersion() != null, "'spec.xpVersion' cannot be null");
Preconditions.checkState(newDeployment.getSpec().getXp7DeploymentSpecNodesSharedDisks() != null, "'spec.nodesSharedDisks' cannot be null");
Preconditions.checkState(newDeployment.getSpec().getXp7DeploymentSpecNodeGroups() != null, "'spec.nodeGroups' cannot be null");
// Check status
Preconditions.checkState(newDeployment.getStatus() != null, "'status' cannot be null");
Preconditions.checkState(newDeployment.getStatus().getMessage() != null, "'status.message' cannot be null");
Preconditions.checkState(newDeployment.getStatus().getState() != null, "'status.state' cannot be null");
Preconditions.checkState(newDeployment.getStatus().getXp7DeploymentStatusFields() != null, "'status.fields' cannot be null");
Preconditions.checkState(newDeployment.getStatus().getXp7DeploymentStatusFields().getXp7DeploymentStatusFieldsPods() != null, "'status.fields.pods' cannot be null");
// Check node groups
int nrOfMasterNodes = 0;
int i = 0;
for (Xp7DeploymentSpecNodeGroup ng : newDeployment.getSpec().getXp7DeploymentSpecNodeGroups()) {
Preconditions.checkState(ng.getName() != null, "'spec.nodeGroups[" + i + "].name' cannot be null");
Preconditions.checkState(!ng.getName().equals(cfgStr("operator.charts.values.allNodesKey")), "'spec.nodeGroups[" + i + "].name' cannot be " + cfgStr("operator.charts.values.allNodesKey"));
dns1123("spec.nodeGroups[" + i + "].name", ng.getName());
Preconditions.checkState(ng.getData() != null, "'spec.nodeGroups[" + i + "].data' cannot be null");
Preconditions.checkState(ng.getMaster() != null, "'spec.nodeGroups[" + i + "].master' cannot be null");
Preconditions.checkState(ng.getReplicas() != null, "'spec.nodeGroups[" + i + "].replicas' cannot be null");
Preconditions.checkState(ng.getReplicas() >= 0, "'spec.nodeGroups[" + i + "].replicas' has to be >= 0");
Preconditions.checkState(ng.getXp7DeploymentSpecNodeGroupEnvironment() != null, "'spec.nodeGroups[" + i + "].env' cannot be null");
Preconditions.checkState(ng.getXp7DeploymentSpecNodeGroupResources() != null, "'spec.nodeGroups[" + i + "].resources' cannot be null");
Preconditions.checkState(ng.getXp7DeploymentSpecNodeGroupResources().getCpu() != null, "'spec.nodeGroups[" + i + "].resources.cpu' cannot be null");
Preconditions.checkState(ng.getXp7DeploymentSpecNodeGroupResources().getMemory() != null, "'spec.nodeGroups[" + i + "].resources.memory' cannot be null");
Preconditions.checkState(ng.getXp7DeploymentSpecNodeGroupResources().getMemory().contains("Mi") || ng.getXp7DeploymentSpecNodeGroupResources().getMemory().contains("Gi"), "'spec.nodeGroups[" + i + "].resources.memory' can only be defined with Gi or Mi");
Preconditions.checkState(ng.getXp7DeploymentSpecNodeGroupResources().getXp7DeploymentSpecNodeGroupDisks() != null, "'spec.nodeGroups[" + i + "].resources.disks' cannot be null");
// Check disks
if (ng.getData()) {
Preconditions.checkState(ng.getXp7DeploymentSpecNodeGroupResources().getXp7DeploymentSpecNodeGroupDisks().stream().anyMatch(d -> d.getName().equals("index")), "nodes with data=true must have disk 'index' defined");
}
if (ng.getMaster()) {
nrOfMasterNodes += ng.getReplicas();
}
i++;
}
// Check replicas
Preconditions.checkState(nrOfMasterNodes > 0, "some nodeGroups must have master=true");
Preconditions.checkState(nrOfMasterNodes % 2 == 1, "number of master nodes has to be an odd number");
}
// Strict label and name validation
cfgIfBool("operator.deployment.xp.labels.strictValidation", () -> {
Preconditions.checkState(newDeployment.getMetadata() != null, "'metadata' cannot be null");
Preconditions.checkState(newDeployment.getMetadata().getLabels() != null, "'metadata.labels' cannot be null");
String cloud = newDeployment.getMetadata().getLabels().get(cfgStr("operator.deployment.xp.labels.cloud"));
String solution = newDeployment.getMetadata().getLabels().get(cfgStr("operator.deployment.xp.labels.solution"));
String environment = newDeployment.getMetadata().getLabels().get(cfgStr("operator.deployment.xp.labels.environment"));
String service = newDeployment.getMetadata().getLabels().get(cfgStr("operator.deployment.xp.labels.service"));
Preconditions.checkState(cloud != null, String.format("'metadata.labels.%s' cannot be null", cfgStr("operator.deployment.xp.labels.cloud")));
Preconditions.checkState(solution != null, String.format("'metadata.labels.%s' cannot be null", cfgStr("operator.deployment.xp.labels.solution")));
Preconditions.checkState(environment != null, String.format("'metadata.labels.%s' cannot be null", cfgStr("operator.deployment.xp.labels.environment")));
Preconditions.checkState(service != null, String.format("'metadata.labels.%s' cannot be null", cfgStr("operator.deployment.xp.labels.service")));
String name = String.format("%s-%s-%s-%s", cloud, solution, environment, service);
Preconditions.checkState(newDeployment.getMetadata().getName().equals(name), String.format("Xp7Deployment name must be equal to <Cloud>-<Solution>-<Environment>-<Service> according to labels, i.e: '%s'", name));
});
if (op == AdmissionOperation.CREATE) {
Optional<Xp7Deployment> xp7Deployments = getXp7Deployment(admissionReview.getRequest().getObject());
Preconditions.checkState(xp7Deployments.isEmpty(), "There is already an Xp7Deployment in NS '%s'", newDeployment.getMetadata().getNamespace());
// Assert version is > 7.7.X, if we cant parse version, just let it go
ComparableVersion currentVersion = new ComparableVersion("7.7.0");
try {
if (newDeployment.getSpec().getXpVersion().startsWith("7.")) {
currentVersion = new ComparableVersion(newDeployment.getSpec().getXpVersion());
} else if (newDeployment.getSpec().getXpVersion().startsWith("enonic/xp:7.")) {
String pattern = "^enonic\\/xp:([0-9]+\\.[0-9]+\\.[0-9]+)";
Matcher m = Pattern.compile(pattern).matcher(newDeployment.getSpec().getXpVersion());
if (m.find()) {
currentVersion = new ComparableVersion(m.group(1));
}
}
} catch (Exception e) {
// Just ignore
}
Preconditions.checkState(currentVersion.compareTo(new ComparableVersion("7.6.100")) > 0, "Operator only supports XP version 7.7 and higher");
}
}
use of com.enonic.kubernetes.client.v1.xp7deployment.Xp7Deployment in project xp-operator by enonic.
the class HandlerStatus method updateStatus.
private boolean updateStatus(final Optional<Xp7App> optionalApp, final Optional<Xp7Deployment> optionalDeployment, final Optional<AppInfo> optionalAppInfo, final Optional<String> error) {
if (optionalApp.isEmpty()) {
// This can happen if apps are installed in XP but not with the operator
return false;
}
Xp7App app = optionalApp.get();
if (error.isPresent()) {
return setStatus(app, Xp7AppStatus.State.ERROR, error.get(), optionalAppInfo);
}
if (optionalDeployment.isEmpty()) {
return setStatus(app, Xp7AppStatus.State.ERROR, "XP deployment not found", optionalAppInfo);
}
Xp7Deployment deployment = optionalDeployment.get();
// Deployment is stopped
if (!deployment.getSpec().getEnabled()) {
return setStatus(app, Xp7AppStatus.State.STOPPED, "XP deployment stopped", optionalAppInfo);
}
// lets not change that until we have some app info
if (notSuccessfullyInstalled().test(app) && optionalAppInfo.isEmpty() && app.getStatus().getState() == Xp7AppStatus.State.ERROR) {
return false;
}
// No app info
if (optionalAppInfo.isEmpty()) {
return setStatus(app, Xp7AppStatus.State.PENDING, "Waiting for XP to start", optionalAppInfo);
}
AppInfo appInfo = optionalAppInfo.get();
switch(appInfo.state()) {
case "started":
if (app.getSpec().getEnabled()) {
return setStatus(app, Xp7AppStatus.State.RUNNING, "OK", optionalAppInfo);
} else {
return setStatus(app, Xp7AppStatus.State.PENDING, "Has not been stopped", optionalAppInfo);
}
case "stopped":
if (app.getSpec().getEnabled()) {
return setStatus(app, Xp7AppStatus.State.PENDING, "Has not been started", optionalAppInfo);
} else {
return setStatus(app, Xp7AppStatus.State.STOPPED, "OK", optionalAppInfo);
}
default:
return setStatus(app, Xp7AppStatus.State.ERROR, String.format("Invalid app state '%s'", appInfo.state()), optionalAppInfo);
}
}
Aggregations