-
Notifications
You must be signed in to change notification settings - Fork 115
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
one stop for all the upgrade scenarios
Signed-off-by: vivekr-splunk <94569031+vivekr-splunk@users.noreply.github.com>
- Loading branch information
1 parent
b37eb45
commit d9ced24
Showing
1 changed file
with
316 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,316 @@ | ||
package enterprise | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
enterpriseApi "github.com/splunk/splunk-operator/api/v4" | ||
splcommon "github.com/splunk/splunk-operator/pkg/splunk/common" | ||
appsv1 "k8s.io/api/apps/v1" | ||
k8serrors "k8s.io/apimachinery/pkg/api/errors" | ||
"k8s.io/apimachinery/pkg/types" | ||
rclient "sigs.k8s.io/controller-runtime/pkg/client" | ||
"sigs.k8s.io/controller-runtime/pkg/log" | ||
) | ||
|
||
|
||
func upgradePathValidation(ctx context.Context, c splcommon.ControllerClient, cr splcommon.MetaObject, spec enterpriseApi.CommonSplunkSpec, mgr *indexerClusterPodManager) (bool, error) { | ||
reqLogger := log.FromContext(ctx) | ||
scopedLog := reqLogger.WithName("isClusterManagerReadyForUpgrade").WithValues("name", cr.GetName(), "namespace", cr.GetNamespace()) | ||
eventPublisher, _ := newK8EventPublisher(c, cr) | ||
goto Standalone | ||
|
||
Standalone: | ||
if cr.GroupVersionKind().Kind == "Standalone" { | ||
return true, nil | ||
} else { | ||
goto LicenseManager | ||
} | ||
LicenseManager: | ||
if cr.GroupVersionKind().Kind == "LicenseManager" { | ||
return true , nil | ||
} else { | ||
licenseManagerRef := spec.LicenseManagerRef | ||
if licenseManagerRef.Name == "" { | ||
goto ClusterManager | ||
} | ||
|
||
namespacedName := types.NamespacedName{Namespace: cr.GetNamespace(), Name: licenseManagerRef.Name} | ||
licenseManager := &enterpriseApi.LicenseManager{} | ||
// get the license manager referred in CR | ||
err := c.Get(ctx, namespacedName, licenseManager) | ||
if err != nil { | ||
if k8serrors.IsNotFound(err) { | ||
goto ClusterManager | ||
} | ||
return false, err | ||
} | ||
|
||
lmImage, err := getCurrentImage(ctx, c, licenseManager, SplunkLicenseManager) | ||
if err != nil { | ||
eventPublisher.Warning(ctx, "isClusterManagerReadyForUpgrade", fmt.Sprintf("Could not get the License Manager Image. Reason %v", err)) | ||
scopedLog.Error(err, "Unable to get licenseManager current image") | ||
return false, err | ||
} | ||
if licenseManager.Status.Phase != enterpriseApi.PhaseReady || lmImage != spec.Image { | ||
return false, err | ||
} | ||
goto ClusterManager | ||
} | ||
ClusterManager: | ||
if cr.GroupVersionKind().Kind == "ClusterManager" { | ||
|
||
licenseManagerRef := spec.LicenseManagerRef | ||
if licenseManagerRef.Name == "" { | ||
return true, nil | ||
} | ||
namespacedName := types.NamespacedName{ | ||
Namespace: cr.GetNamespace(), | ||
Name: GetSplunkStatefulsetName(SplunkClusterManager, cr.GetName()), | ||
} | ||
|
||
// check if the stateful set is created at this instance | ||
statefulSet := &appsv1.StatefulSet{} | ||
err := c.Get(ctx, namespacedName, statefulSet) | ||
if err != nil && k8serrors.IsNotFound(err) { | ||
return true, nil | ||
} | ||
return false, nil | ||
} else { | ||
// check if a LicenseManager is attached to the instance | ||
clusterManagerRef := spec.ClusterManagerRef | ||
if clusterManagerRef.Name == "" { | ||
goto MonitoringConsole | ||
} | ||
|
||
namespacedName := types.NamespacedName{Namespace: cr.GetNamespace(), Name: clusterManagerRef.Name} | ||
clusterManager := &enterpriseApi.ClusterManager{} | ||
|
||
// get the cluster manager referred in monitoring console | ||
err := c.Get(ctx, namespacedName, clusterManager) | ||
if err != nil { | ||
eventPublisher.Warning(ctx, "isMonitoringConsoleReadyForUpgrade", fmt.Sprintf("Could not find the Cluster Manager. Reason %v", err)) | ||
scopedLog.Error(err, "Unable to get clusterManager") | ||
goto MonitoringConsole | ||
} | ||
|
||
cmImage, err := getCurrentImage(ctx, c, cr, SplunkClusterManager) | ||
if err != nil { | ||
eventPublisher.Warning(ctx, "isMonitoringConsoleReadyForUpgrade", fmt.Sprintf("Could not get the Cluster Manager Image. Reason %v", err)) | ||
scopedLog.Error(err, "Unable to get clusterManager current image") | ||
return false, err | ||
} | ||
|
||
// check if an image upgrade is happening and whether CM has finished updating yet, return false to stop | ||
// further reconcile operations on MC until CM is ready | ||
if clusterManager.Status.Phase != enterpriseApi.PhaseReady || cmImage != spec.Image { | ||
return false, nil | ||
} | ||
goto MonitoringConsole | ||
} | ||
MonitoringConsole: | ||
if cr.GroupVersionKind().Kind == "MonitoringConsole" { | ||
|
||
|
||
namespacedName := types.NamespacedName{ | ||
Namespace: cr.GetNamespace(), | ||
Name: GetSplunkStatefulsetName(SplunkMonitoringConsole, cr.GetName()), | ||
} | ||
|
||
// check if the stateful set is created at this instance | ||
statefulSet := &appsv1.StatefulSet{} | ||
err := c.Get(ctx, namespacedName, statefulSet) | ||
if err != nil && k8serrors.IsNotFound(err) { | ||
return true, nil | ||
} | ||
|
||
mcImage, err := getCurrentImage(ctx, c, cr, SplunkMonitoringConsole) | ||
if err != nil { | ||
eventPublisher.Warning(ctx, "isMonitoringConsolerReadyForUpgrade", fmt.Sprintf("Could not get the Monitoring Console Image. Reason %v", err)) | ||
scopedLog.Error(err, "Unable to get monitoring console current image") | ||
return false, err | ||
} | ||
|
||
// check if an image upgrade is happening and whether CM has finished updating yet, return false to stop | ||
// further reconcile operations on MC until CM is ready | ||
if spec.Image != mcImage{ | ||
return true, nil | ||
} | ||
|
||
return true, nil | ||
} else { | ||
|
||
// check if a MonitoringConsole is attached to the instance | ||
monitoringConsoleRef := spec.MonitoringConsoleRef | ||
if monitoringConsoleRef.Name == "" { | ||
goto SearchHeadCluster | ||
} | ||
|
||
namespacedName := types.NamespacedName{Namespace: cr.GetNamespace(), Name: monitoringConsoleRef.Name} | ||
monitoringConsole := &enterpriseApi.MonitoringConsole{} | ||
|
||
// get the monitoring console referred in search head cluster | ||
err := c.Get(ctx, namespacedName, monitoringConsole) | ||
if err != nil { | ||
if k8serrors.IsNotFound(err) { | ||
goto SearchHeadCluster | ||
} | ||
eventPublisher.Warning(ctx, "isSearchHeadReadyForUpgrade", fmt.Sprintf("Could not find the Monitoring Console. Reason %v", err)) | ||
scopedLog.Error(err, "Unable to get Monitoring Console") | ||
return false, err | ||
} | ||
|
||
mcImage, err := getCurrentImage(ctx, c, monitoringConsole, SplunkMonitoringConsole) | ||
if err != nil { | ||
eventPublisher.Warning(ctx, "isSearchHeadReadyForUpgrade", fmt.Sprintf("Could not get the Monitoring Console Image. Reason %v", err)) | ||
scopedLog.Error(err, "Unable to get Monitoring Console current image") | ||
return false, err | ||
} | ||
|
||
// check if an image upgrade is happening and whether the SearchHeadCluster is ready for the upgrade | ||
if monitoringConsole.Status.Phase != enterpriseApi.PhaseReady || mcImage != spec.Image { | ||
return false, nil | ||
} | ||
|
||
goto SearchHeadCluster | ||
} | ||
SearchHeadCluster: | ||
if cr.GroupVersionKind().Kind == "SearchHeadCluster" { | ||
|
||
namespacedName := types.NamespacedName{ | ||
Namespace: cr.GetNamespace(), | ||
Name: GetSplunkStatefulsetName(SplunkSearchHead, cr.GetName()), | ||
} | ||
|
||
// check if the stateful set is created at this instance | ||
statefulSet := &appsv1.StatefulSet{} | ||
err := c.Get(ctx, namespacedName, statefulSet) | ||
if err != nil && k8serrors.IsNotFound(err) { | ||
return true, nil | ||
} | ||
|
||
shcImage, err := getCurrentImage(ctx, c, cr, SplunkSearchHead) | ||
if err != nil { | ||
eventPublisher.Warning(ctx, "isSearchHeadReadyForUpgrade", fmt.Sprintf("Could not get the Search Head Image. Reason %v", err)) | ||
scopedLog.Error(err, "Unable to get Search Head current image") | ||
return false, err | ||
} | ||
|
||
// check if an image upgrade is happening and whether the SearchHeadCluster is ready for the upgrade | ||
if spec.Image != shcImage { | ||
return true, nil | ||
} | ||
return true, nil | ||
} else { | ||
|
||
// get the clusterManagerRef attached to the instance | ||
clusterManagerRef := spec.ClusterManagerRef | ||
|
||
// check if a search head cluster exists with the same ClusterManager instance attached | ||
searchHeadClusterInstance := enterpriseApi.SearchHeadCluster{} | ||
opts := []rclient.ListOption{ | ||
rclient.InNamespace(cr.GetNamespace()), | ||
} | ||
searchHeadList, err := getSearchHeadClusterList(ctx, c, cr, opts) | ||
if err != nil { | ||
if err.Error() == "NotFound" { | ||
goto IndexerCluster | ||
} | ||
return false, err | ||
} | ||
if len(searchHeadList.Items) == 0 { | ||
goto IndexerCluster | ||
} | ||
|
||
// check if instance has the required ClusterManagerRef | ||
for _, shc := range searchHeadList.Items { | ||
if shc.Spec.ClusterManagerRef.Name == clusterManagerRef.Name { | ||
searchHeadClusterInstance = shc | ||
break | ||
} | ||
} | ||
if len(searchHeadClusterInstance.GetName()) == 0 { | ||
goto IndexerCluster | ||
} | ||
|
||
shcImage, err := getCurrentImage(ctx, c, &searchHeadClusterInstance, SplunkSearchHead) | ||
if err != nil { | ||
eventPublisher.Warning(ctx, "isIndexerClusterReadyForUpgrade", fmt.Sprintf("Could not get the Search Head Cluster Image. Reason %v", err)) | ||
scopedLog.Error(err, "Unable to get SearchHeadCluster current image") | ||
return false, err | ||
} | ||
|
||
idxImage, err := getCurrentImage(ctx, c, cr, SplunkIndexer) | ||
if err != nil { | ||
eventPublisher.Warning(ctx, "isIndexerClusterReadyForUpgrade", fmt.Sprintf("Could not get the Indexer Cluster Image. Reason %v", err)) | ||
scopedLog.Error(err, "Unable to get IndexerCluster current image") | ||
return false, err | ||
} | ||
|
||
// check if an image upgrade is happening and whether SHC has finished updating yet, return false to stop | ||
// further reconcile operations on IDX until SHC is ready | ||
if (spec.Image != idxImage) && (searchHeadClusterInstance.Status.Phase != enterpriseApi.PhaseReady || shcImage != spec.Image) { | ||
return false, nil | ||
} | ||
goto IndexerCluster | ||
} | ||
IndexerCluster: | ||
if cr.GroupVersionKind().Kind == "IndexerCluster" { | ||
|
||
if mgr.c == nil { | ||
mgr.c = c | ||
} | ||
|
||
cm := mgr.getClusterManagerClient(ctx) | ||
clusterInfo, err := cm.GetClusterInfo(false) | ||
if err != nil { | ||
return false, fmt.Errorf("could not get cluster info from cluster manager") | ||
} | ||
if clusterInfo.MultiSite == "true" { | ||
opts := []rclient.ListOption{ | ||
rclient.InNamespace(cr.GetNamespace()), | ||
} | ||
indexerList, err := getIndexerClusterList(ctx, c, cr, opts) | ||
if err != nil { | ||
return false, err | ||
} | ||
sortedList, err := getIndexerClusterSortedSiteList(ctx, c, spec.ClusterManagerRef, indexerList) | ||
|
||
preIdx := enterpriseApi.IndexerCluster{} | ||
|
||
for i, v := range sortedList.Items { | ||
if &v == cr { | ||
if i > 0 { | ||
preIdx = sortedList.Items[i-1] | ||
} | ||
break | ||
|
||
} | ||
} | ||
if len(preIdx.Name) != 0 { | ||
image, _ := getCurrentImage(ctx, c, &preIdx, SplunkIndexer) | ||
if preIdx.Status.Phase != enterpriseApi.PhaseReady || image != spec.Image { | ||
return false, nil | ||
} | ||
} | ||
|
||
} | ||
|
||
idxImage, err := getCurrentImage(ctx, c, cr, SplunkIndexer) | ||
if err != nil { | ||
eventPublisher.Warning(ctx, "isIndexerClusterReadyForUpgrade", fmt.Sprintf("Could not get the Indexer Cluster Image. Reason %v", err)) | ||
scopedLog.Error(err, "Unable to get IndexerCluster current image") | ||
return false, err | ||
} | ||
|
||
if (spec.Image != idxImage) { | ||
return false, nil | ||
} | ||
return true, nil | ||
} else { | ||
goto EndLabel | ||
} | ||
EndLabel: | ||
return true, nil | ||
|
||
} |