Search in sources :

Example 1 with ReconciliationResult

use of io.stackgres.operatorframework.reconciliation.ReconciliationResult in project stackgres by ongres.

the class ClusterControllerReconciliator method reconcile.

@SuppressFBWarnings(value = "REC_CATCH_EXCEPTION", justification = "False positives")
@Override
protected ReconciliationResult<?> reconcile(KubernetesClient client, StackGresClusterContext context) throws Exception {
    ReconciliationResult<Boolean> extensionReconciliationResult = extensionReconciliator.reconcile(client, context);
    if (extensionReconciliationResult.result().orElse(false)) {
        final String podName = propertyContext.getString(ClusterControllerProperty.CLUSTER_CONTROLLER_POD_NAME);
        final StackGresCluster cluster = context.getCluster();
        final StackGresClusterStatus status = cluster.getStatus();
        String clusterName = cluster.getMetadata().getName();
        String namespace = cluster.getMetadata().getNamespace();
        clusterFinder.findByNameAndNamespace(clusterName, namespace).ifPresent(savedCluster -> {
            var newPodStatus = findPodStatus(status.getPodStatuses(), podName).orElseThrow();
            Optional.ofNullable(savedCluster.getStatus()).ifPresentOrElse(savedStatus -> Optional.ofNullable(savedStatus.getPodStatuses()).ifPresentOrElse(savedPodStatuses -> findPodStatus(savedPodStatuses, podName).ifPresentOrElse(savedPodStatus -> applyPodStatusChanges(newPodStatus, savedPodStatus), () -> savedPodStatuses.add(newPodStatus)), () -> savedStatus.setPodStatuses(status.getPodStatuses())), () -> savedCluster.setStatus(status));
            clusterScheduler.updateStatus(savedCluster);
        });
    }
    return extensionReconciliationResult;
}
Also used : StackGresClusterStatus(io.stackgres.common.crd.sgcluster.StackGresClusterStatus) ClusterControllerProperty(io.stackgres.common.ClusterControllerProperty) StackGresCluster(io.stackgres.common.crd.sgcluster.StackGresCluster) ReconciliationResult(io.stackgres.operatorframework.reconciliation.ReconciliationResult) Reconciliator(io.stackgres.operatorframework.reconciliation.Reconciliator) ClusterControllerPropertyContext(io.stackgres.cluster.configuration.ClusterControllerPropertyContext) Inject(javax.inject.Inject) CdiUtil(io.stackgres.common.CdiUtil) List(java.util.List) Dependent(javax.enterprise.context.Dependent) CustomResourceScheduler(io.stackgres.common.resource.CustomResourceScheduler) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) Optional(java.util.Optional) CustomResourceFinder(io.stackgres.common.resource.CustomResourceFinder) ApplicationScoped(javax.enterprise.context.ApplicationScoped) StackGresClusterContext(io.stackgres.cluster.common.StackGresClusterContext) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) StackGresClusterPodStatus(io.stackgres.common.crd.sgcluster.StackGresClusterPodStatus) StackGresCluster(io.stackgres.common.crd.sgcluster.StackGresCluster) StackGresClusterStatus(io.stackgres.common.crd.sgcluster.StackGresClusterStatus) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings)

Example 2 with ReconciliationResult

use of io.stackgres.operatorframework.reconciliation.ReconciliationResult in project stackgres by ongres.

the class DistributedLogsClusterReconciliator method reconcile.

@SuppressFBWarnings(value = "REC_CATCH_EXCEPTION", justification = "False positives")
protected ReconciliationResult<Boolean> reconcile(KubernetesClient client, StackGresDistributedLogsContext context) throws Exception {
    StackGresDistributedLogs distributedLogs = context.getDistributedLogs();
    if (distributedLogs.getStatus() == null || !isPatroniReady(context)) {
        LOGGER.warn("Waiting for distributedlogs cluster to become ready...");
        return new ReconciliationResult<>(false);
    }
    final ImmutableList.Builder<Exception> exceptions = ImmutableList.builder();
    boolean statusUpdated = false;
    for (StackGresDistributedLogsStatusCluster cluster : distributedLogs.getStatus().getConnectedClusters()) {
        String database = FluentdUtil.databaseName(cluster.getNamespace(), cluster.getName());
        try {
            if (!databaseManager.existsDatabase(context, database)) {
                LOGGER.info("Creating database {}", database);
                databaseManager.createDatabase(context, database);
            }
        } catch (Exception ex) {
            exceptions.add(ex);
            handleException(client, distributedLogs, cluster, ex);
            continue;
        }
        String retention = cluster.getConfig().getRetention();
        if (!Optional.of(distributedLogs.getStatus().getDatabases()).flatMap(databases -> databases.stream().filter(databaseStatus -> databaseStatus.getName().equals(database)).findAny()).map(StackGresDistributedLogsStatusDatabase::getRetention).map(currentRetention -> Objects.equals(retention, currentRetention)).orElse(false)) {
            for (String table : Seq.of(Tables.values()).map(Tables::getTableName)) {
                LOGGER.info("Updating retention window for database {} and table to {}", database, retention);
                try {
                    databaseManager.updateRetention(context, database, retention, table);
                } catch (Exception ex) {
                    exceptions.add(ex);
                    handleException(client, distributedLogs, cluster, ex);
                    continue;
                }
            }
        }
        if (retention != null) {
            for (String table : Seq.of(Tables.values()).map(Tables::getTableName)) {
                try {
                    databaseManager.reconcileRetention(context, database, retention, table).stream().forEach(output -> LOGGER.info("Reconcile retention for database {} and table {}: {}", database, table, output));
                } catch (Exception ex) {
                    exceptions.add(ex);
                    handleException(client, distributedLogs, cluster, ex);
                    continue;
                }
            }
        }
        statusUpdated = statusUpdated || updateStatus(distributedLogs, database, retention);
    }
    String fluentdConfigHash = configManager.getFluentdConfigHash();
    if (!Objects.equals(distributedLogs.getStatus().getFluentdConfigHash(), fluentdConfigHash)) {
        LOGGER.info("Reloading fluentd configuration");
        configManager.reloadFluentdConfiguration();
        distributedLogs.getStatus().setFluentdConfigHash(fluentdConfigHash);
    }
    return new ReconciliationResult<>(statusUpdated, exceptions.build());
}
Also used : StackGresDistributedLogs(io.stackgres.common.crd.sgdistributedlogs.StackGresDistributedLogs) ReconciliationResult(io.stackgres.operatorframework.reconciliation.ReconciliationResult) ImmutableList(com.google.common.collect.ImmutableList) Tables(io.stackgres.common.distributedlogs.Tables) StackGresDistributedLogsStatusCluster(io.stackgres.common.crd.sgdistributedlogs.StackGresDistributedLogsStatusCluster) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings)

Example 3 with ReconciliationResult

use of io.stackgres.operatorframework.reconciliation.ReconciliationResult in project stackgres by ongres.

the class ExtensionReconciliator method reconcile.

@SuppressFBWarnings(value = "REC_CATCH_EXCEPTION", justification = "False positives")
public ReconciliationResult<Boolean> reconcile(KubernetesClient client, T context) throws Exception {
    final ImmutableList.Builder<Exception> exceptions = ImmutableList.builder();
    final StackGresCluster cluster = context.getCluster();
    final ImmutableList<StackGresClusterInstalledExtension> extensions = context.getExtensions();
    if (cluster.getStatus() == null) {
        cluster.setStatus(new StackGresClusterStatus());
    }
    if (cluster.getStatus().getPodStatuses() == null) {
        cluster.getStatus().setPodStatuses(new ArrayList<>());
    }
    if (cluster.getStatus().getPodStatuses().stream().noneMatch(podStatus -> podStatus.getName().equals(podName))) {
        StackGresClusterPodStatus podStatus = new StackGresClusterPodStatus();
        podStatus.setName(podName);
        podStatus.setInstalledPostgresExtensions(new ArrayList<>());
        cluster.getStatus().getPodStatuses().add(podStatus);
    }
    final StackGresClusterPodStatus podStatus = cluster.getStatus().getPodStatuses().stream().filter(status -> status.getName().equals(podName)).findAny().get();
    if (podStatus.getInstalledPostgresExtensions() == null) {
        podStatus.setInstalledPostgresExtensions(new ArrayList<>());
    }
    final List<StackGresClusterInstalledExtension> installedExtensions = podStatus.getInstalledPostgresExtensions();
    LOGGER.info("Reconcile postgres extensions...");
    boolean clusterUpdated = false;
    final List<StackGresClusterInstalledExtension> extensionToUninstall = installedExtensions.stream().filter(installedExtension -> extensions.stream().noneMatch(installedExtension::same)).collect(Collectors.toList());
    for (StackGresClusterInstalledExtension installedExtension : extensionToUninstall) {
        ExtensionUninstaller extensionUninstaller = extensionManager.getExtensionUninstaller(context, installedExtension);
        try {
            if (!skipSharedLibrariesOverwrites) {
                if (extensionUninstaller.isExtensionInstalled()) {
                    LOGGER.info("Removing extension {}", ExtensionUtil.getDescription(installedExtension));
                    extensionEventEmitter.emitExtensionRemoved(installedExtension);
                    extensionUninstaller.uninstallExtension();
                }
                installedExtensions.remove(installedExtension);
                clusterUpdated = true;
            } else {
                LOGGER.info("Skip uninstallation of extension {}", ExtensionUtil.getDescription(installedExtension));
                if (!Optional.ofNullable(podStatus.getPendingRestart()).orElse(false)) {
                    podStatus.setPendingRestart(true);
                    clusterUpdated = true;
                }
            }
        } catch (Exception ex) {
            exceptions.add(ex);
            onUninstallException(client, cluster, ExtensionUtil.getDescription(installedExtension), podName, ex);
        }
    }
    for (StackGresClusterInstalledExtension extension : extensions) {
        try {
            final ExtensionInstaller extensionInstaller = Optional.ofNullable(extensionManager.getExtensionInstaller(context, extension)).orElseThrow(() -> new IllegalStateException("Can not find extension " + ExtensionUtil.getDescription(extension)));
            if (!extensionInstaller.isExtensionInstalled() && (!skipSharedLibrariesOverwrites || !extensionInstaller.isExtensionPendingOverwrite())) {
                LOGGER.info("Download extension {}", ExtensionUtil.getDescription(extension));
                extensionEventEmitter.emitExtensionDownloading(extension);
                extensionInstaller.downloadAndExtract();
                LOGGER.info("Verify extension {}", ExtensionUtil.getDescription(extension));
                extensionInstaller.verify();
                if (skipSharedLibrariesOverwrites && extensionInstaller.doesInstallOverwriteAnySharedLibrary()) {
                    LOGGER.info("Skip installation of extension {}", ExtensionUtil.getDescription(extension));
                    if (!extensionInstaller.isExtensionPendingOverwrite()) {
                        extensionInstaller.setExtensionAsPending();
                    }
                    if (!Optional.ofNullable(podStatus.getPendingRestart()).orElse(false)) {
                        extensionEventEmitter.emitExtensionDeployedRestart(extension);
                        podStatus.setPendingRestart(true);
                        clusterUpdated = true;
                    }
                } else {
                    LOGGER.info("Install extension {}", ExtensionUtil.getDescription(extension));
                    extensionInstaller.installExtension();
                    extensionEventEmitter.emitExtensionDeployed(extension);
                }
            } else {
                if (!extensionInstaller.isLinksCreated()) {
                    LOGGER.info("Create links for extension {}", ExtensionUtil.getDescription(extension));
                    extensionInstaller.createExtensionLinks();
                }
            }
            if (installedExtensions.stream().noneMatch(anInstalledExtension -> anInstalledExtension.equals(extension))) {
                installedExtensions.stream().filter(anInstalledExtension -> anInstalledExtension.same(extension)).peek(previousInstalledExtension -> LOGGER.info("Extension upgraded from {} to {}", ExtensionUtil.getDescription(previousInstalledExtension), ExtensionUtil.getDescription(extension))).peek(previousInstalledExtension -> extensionEventEmitter.emitExtensionChanged(previousInstalledExtension, extension)).findAny().ifPresent(installedExtensions::remove);
                installedExtensions.add(extension);
                clusterUpdated = true;
            }
        } catch (Exception ex) {
            exceptions.add(ex);
            onInstallException(client, cluster, ExtensionUtil.getDescription(extension), podName, ex);
        }
    }
    if (!skipSharedLibrariesOverwrites && Optional.ofNullable(podStatus.getPendingRestart()).orElse(false)) {
        podStatus.setPendingRestart(false);
        clusterUpdated = true;
    }
    LOGGER.info("Reconciliation of postgres extensions completed");
    return new ReconciliationResult<>(clusterUpdated, exceptions.build());
}
Also used : StackGresClusterStatus(io.stackgres.common.crd.sgcluster.StackGresClusterStatus) ExtensionInstaller(io.stackgres.common.extension.ExtensionManager.ExtensionInstaller) Logger(org.slf4j.Logger) StackGresCluster(io.stackgres.common.crd.sgcluster.StackGresCluster) ReconciliationResult(io.stackgres.operatorframework.reconciliation.ReconciliationResult) LoggerFactory(org.slf4j.LoggerFactory) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) List(java.util.List) ExtensionUninstaller(io.stackgres.common.extension.ExtensionManager.ExtensionUninstaller) ImmutableList(com.google.common.collect.ImmutableList) StackGresClusterInstalledExtension(io.stackgres.common.crd.sgcluster.StackGresClusterInstalledExtension) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) Optional(java.util.Optional) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) StackGresClusterPodStatus(io.stackgres.common.crd.sgcluster.StackGresClusterPodStatus) ImmutableList(com.google.common.collect.ImmutableList) StackGresClusterInstalledExtension(io.stackgres.common.crd.sgcluster.StackGresClusterInstalledExtension) ReconciliationResult(io.stackgres.operatorframework.reconciliation.ReconciliationResult) StackGresClusterPodStatus(io.stackgres.common.crd.sgcluster.StackGresClusterPodStatus) ExtensionInstaller(io.stackgres.common.extension.ExtensionManager.ExtensionInstaller) StackGresCluster(io.stackgres.common.crd.sgcluster.StackGresCluster) StackGresClusterStatus(io.stackgres.common.crd.sgcluster.StackGresClusterStatus) ExtensionUninstaller(io.stackgres.common.extension.ExtensionManager.ExtensionUninstaller) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings)

Aggregations

SuppressFBWarnings (edu.umd.cs.findbugs.annotations.SuppressFBWarnings)3 ReconciliationResult (io.stackgres.operatorframework.reconciliation.ReconciliationResult)3 ImmutableList (com.google.common.collect.ImmutableList)2 KubernetesClient (io.fabric8.kubernetes.client.KubernetesClient)2 StackGresCluster (io.stackgres.common.crd.sgcluster.StackGresCluster)2 StackGresClusterPodStatus (io.stackgres.common.crd.sgcluster.StackGresClusterPodStatus)2 StackGresClusterStatus (io.stackgres.common.crd.sgcluster.StackGresClusterStatus)2 List (java.util.List)2 Optional (java.util.Optional)2 StackGresClusterContext (io.stackgres.cluster.common.StackGresClusterContext)1 ClusterControllerPropertyContext (io.stackgres.cluster.configuration.ClusterControllerPropertyContext)1 CdiUtil (io.stackgres.common.CdiUtil)1 ClusterControllerProperty (io.stackgres.common.ClusterControllerProperty)1 StackGresClusterInstalledExtension (io.stackgres.common.crd.sgcluster.StackGresClusterInstalledExtension)1 StackGresDistributedLogs (io.stackgres.common.crd.sgdistributedlogs.StackGresDistributedLogs)1 StackGresDistributedLogsStatusCluster (io.stackgres.common.crd.sgdistributedlogs.StackGresDistributedLogsStatusCluster)1 Tables (io.stackgres.common.distributedlogs.Tables)1 ExtensionInstaller (io.stackgres.common.extension.ExtensionManager.ExtensionInstaller)1 ExtensionUninstaller (io.stackgres.common.extension.ExtensionManager.ExtensionUninstaller)1 CustomResourceFinder (io.stackgres.common.resource.CustomResourceFinder)1