Skip to content

Commit

Permalink
Reconcile service cert first
Browse files Browse the repository at this point in the history
  • Loading branch information
kabicin committed Oct 30, 2024
1 parent 71d9131 commit 3fd1802
Showing 1 changed file with 75 additions and 52 deletions.
127 changes: 75 additions & 52 deletions internal/controller/experimental.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"strings"
"sync"
"time"

olv1 "github.com/OpenLiberty/open-liberty-operator/api/v1"
lutils "github.com/OpenLiberty/open-liberty-operator/utils"
Expand Down Expand Up @@ -121,7 +122,7 @@ func (r *ReconcileOpenLiberty) reconcileLTPAKeySharingEnabled(instance *olv1.Ope
func (r *ReconcileOpenLiberty) reconcilePasswordEncryptionKeySharingEnabled(instance *olv1.OpenLibertyApplication, instanceMutex *sync.Mutex, reconcileResultChan chan<- ReconcileResult, passwordEncryptionMetadataChan chan<- *lutils.PasswordEncryptionMetadata) {
// Reconciles the shared password encryption key state for the instance namespace only if the shared key already exists
var passwordEncryptionMetadataList *lutils.PasswordEncryptionMetadataList
passwordEncryptionMetadata := &lutils.PasswordEncryptionMetadata{Name: ""}
passwordEncryptionMetadata := &lutils.PasswordEncryptionMetadata{}
expectedMetadataLength := 1
instanceMutex.Lock()
if r.isUsingPasswordEncryptionKeySharing(instance, passwordEncryptionMetadata) {
Expand Down Expand Up @@ -422,10 +423,7 @@ func (r *ReconcileOpenLiberty) reconcileBindings(instance *olv1.OpenLibertyAppli
func (r *ReconcileOpenLiberty) reconcilePasswordEncryptionKeyConcurrent(instance *olv1.OpenLibertyApplication, instanceMutex *sync.Mutex, passwordEncryptionMetadata *lutils.PasswordEncryptionMetadata, sharedResourceReconcileResultChan chan<- ReconcileResult, lastRotationChan chan<- string, encryptionSecretNameChan chan<- string) {
// Manage the shared password encryption key Secret if it exists
instanceMutex.Lock()
namespaceLocks, _ := namespaceLockMap.Load(instance.GetNamespace())
namespaceLocks.([]*sync.Mutex)[2].Lock()
message, encryptionSecretName, passwordEncryptionKeyLastRotation, err := r.reconcilePasswordEncryptionKey(instance, passwordEncryptionMetadata)
namespaceLocks.([]*sync.Mutex)[2].Unlock()
instanceMutex.Unlock()
lastRotationChan <- passwordEncryptionKeyLastRotation
encryptionSecretNameChan <- encryptionSecretName
Expand All @@ -439,10 +437,7 @@ func (r *ReconcileOpenLiberty) reconcilePasswordEncryptionKeyConcurrent(instance
func (r *ReconcileOpenLiberty) reconcileLTPAKeysConcurrent(instance *olv1.OpenLibertyApplication, instanceMutex *sync.Mutex, ltpaKeysMetadata *lutils.LTPAMetadata, ltpaConfigMetadata *lutils.LTPAMetadata, reconcileResultChan chan<- ReconcileResult, lastRotationChan chan<- string, ltpaSecretNameChan chan<- string, ltpaKeysLastRotationChan chan<- string) {
// Create and manage the shared LTPA keys Secret if the feature is enabled
instanceMutex.Lock()
namespaceLocks, _ := namespaceLockMap.Load(instance.GetNamespace())
namespaceLocks.([]*sync.Mutex)[0].Lock()
message, ltpaSecretName, ltpaKeysLastRotation, err := r.reconcileLTPAKeys(instance, ltpaKeysMetadata, ltpaConfigMetadata)
namespaceLocks.([]*sync.Mutex)[0].Unlock()
instanceMutex.Unlock()
ltpaSecretNameChan <- ltpaSecretName
lastRotationChan <- ltpaKeysLastRotation
Expand Down Expand Up @@ -483,10 +478,7 @@ func (r *ReconcileOpenLiberty) reconcileLTPAConfigConcurrent(instance *olv1.Open

// Using the LTPA keys and config metadata, create and manage the shared LTPA Liberty server XML if the feature is enabled
instanceMutex.Lock()
namespaceLocks, _ := namespaceLockMap.Load(instance.GetNamespace())
namespaceLocks.([]*sync.Mutex)[1].Lock()
message, ltpaXMLSecretName, err := r.reconcileLTPAConfig(instance, ltpaKeysMetadata, ltpaConfigMetadata, passwordEncryptionMetadata, ltpaKeysLastRotation, lastKeyRelatedRotation)
namespaceLocks.([]*sync.Mutex)[1].Unlock()
instanceMutex.Unlock()
ltpaXMLSecretNameChan <- ltpaXMLSecretName
if err != nil {
Expand Down Expand Up @@ -907,23 +899,26 @@ func (r *ReconcileOpenLiberty) concurrentReconcile(ba common.BaseComponent, inst
reconcileResultChan := make(chan ReconcileResult, 9)
instanceMutex := &sync.Mutex{}

go r.reconcileImageStream(instance, instanceMutex, reconcileResultChan) // STATE: {reconcileResultChan: 1}
useCertManagerChan := make(chan bool, 1)
serviceCertificateReconcileResultChan := make(chan ReconcileResult, 1)
go r.reconcileServiceCertificate(ba, instance, instanceMutex, serviceCertificateReconcileResultChan, useCertManagerChan) // STATE: {useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}

go r.reconcileImageStream(instance, instanceMutex, reconcileResultChan) // STATE: {reconcileResultChan: 1, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}

// obtain ltpa keys and config metadata
ltpaMetadataChan := make(chan *lutils.LTPAMetadata, 2)
go r.reconcileLTPAKeySharingEnabled(instance, instanceMutex, reconcileResultChan, ltpaMetadataChan) // STATE: {reconcileResultChan: 2, ltpaMetadataChan: 2}
go r.reconcileLTPAKeySharingEnabled(instance, instanceMutex, reconcileResultChan, ltpaMetadataChan) // STATE: {reconcileResultChan: 2, ltpaMetadataChan: 2, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}

// The if statement below depends on instance.Status.ImageReference being possibly set in reconcileImageStream, so it must block for the first reconcile result
reconcileResult := <-reconcileResultChan // STATE: {reconcileResultChan: 1, ltpaMetadataChan: 2}
reconcileResult := <-reconcileResultChan // STATE: {reconcileResultChan: 1, ltpaMetadataChan: 2, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}
if reconcileResult.err != nil {
return r.ManageError(reconcileResult.err, reconcileResult.condition, instance)
}

// Everything done from here on out will be with an invalid image so this should terminate the parent reconcile and pull all channel data
ltpaKeysMetadata := <-ltpaMetadataChan
instanceMutex.Lock()
if imageReferenceOld != instance.Status.ImageReference {
// STATE: {reconcileResultChan: 1, ltpaMetadataChan: 1}
// STATE: {reconcileResultChan: 1, ltpaMetadataChan: 1, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}

// Trigger a new Semeru Cloud Compiler generation
createNewSemeruGeneration(instance)
Expand All @@ -935,7 +930,8 @@ func (r *ReconcileOpenLiberty) concurrentReconcile(ba common.BaseComponent, inst
// block to clear channels before exiting
<-reconcileResultChan
<-ltpaMetadataChan
instanceMutex.Unlock()
<-useCertManagerChan
<-serviceCertificateReconcileResultChan
return r.ManageError(err, common.StatusConditionTypeReconciled, instance)
}
}
Expand All @@ -947,11 +943,11 @@ func (r *ReconcileOpenLiberty) concurrentReconcile(ba common.BaseComponent, inst
// block to clear channels before exiting
<-reconcileResultChan
<-ltpaMetadataChan
instanceMutex.Unlock()
<-useCertManagerChan
<-serviceCertificateReconcileResultChan
return r.ManageError(err, common.StatusConditionTypeReconciled, instance)
}
}
instanceMutex.Unlock()

// obtain password encryption metadata
passwordEncryptionMetadataChan := make(chan *lutils.PasswordEncryptionMetadata, 1)
Expand All @@ -967,9 +963,11 @@ func (r *ReconcileOpenLiberty) concurrentReconcile(ba common.BaseComponent, inst
res, err := r.reconcileKnativeServiceSequential(defaultMeta, instance, instanceMutex, reqLogger, isKnativeSupported)
if err != nil {
// block to pull from all go routines before exiting reconcile
<-ltpaMetadataChan // STATE: {reconcileResultChan: 4, passwordEncryptionMetadataChan: 1, semeruMarkedForDeletionChan: 1}
<-passwordEncryptionMetadataChan // STATE: {reconcileResultChan: 4, semeruMarkedForDeletionChan: 1}
<-semeruMarkedForDeletionChan // STATE: {reconcileResultChan: 4}
<-ltpaMetadataChan // STATE: {reconcileResultChan: 4, passwordEncryptionMetadataChan: 1, semeruMarkedForDeletionChan: 1, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}
<-passwordEncryptionMetadataChan // STATE: {reconcileResultChan: 4, semeruMarkedForDeletionChan: 1, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}
<-semeruMarkedForDeletionChan // STATE: {reconcileResultChan: 4, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}
<-useCertManagerChan // STATE: {reconcileResultChan: 4, serviceCertificateReconcileResultChan: 1}
<-serviceCertificateReconcileResultChan // STATE: {reconcileResultChan: 4}

reconcileResults := 4
foundFirstError := false
Expand All @@ -988,13 +986,9 @@ func (r *ReconcileOpenLiberty) concurrentReconcile(ba common.BaseComponent, inst
return res, err
}

useCertManagerChan := make(chan bool, 1)
serviceCertificateReconcileResultChan := make(chan ReconcileResult, 1)
go r.reconcileServiceCertificate(ba, instance, instanceMutex, serviceCertificateReconcileResultChan, useCertManagerChan) // STATE: {reconcileResultChan: 4, ltpaMetadataChan: 2, passwordEncryptionMetadataChan: 1, semeruMarkedForDeletionChan: 1, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}
go r.reconcileService(defaultMeta, ba, instance, instanceMutex, reconcileResultChan, serviceCertificateReconcileResultChan, useCertManagerChan) // STATE: {reconcileResultChan: 5, ltpaMetadataChan: 2, passwordEncryptionMetadataChan: 1, semeruMarkedForDeletionChan: 1}
go r.reconcileNetworkPolicy(defaultMeta, instance, instanceMutex, reconcileResultChan) // STATE: {reconcileResultChan: 6, ltpaMetadataChan: 2, passwordEncryptionMetadataChan: 1, semeruMarkedForDeletionChan: 1}
go r.reconcileServiceability(instance, instanceMutex, reqLogger, reconcileResultChan) // STATE: {reconcileResultChan: 7, ltpaMetadataChan: 2, passwordEncryptionMetadataChan: 1, semeruMarkedForDeletionChan: 1}
go r.reconcileBindings(instance, instanceMutex, reconcileResultChan) // STATE: {reconcileResultChan: 8, ltpaMetadataChan: 2, passwordEncryptionMetadataChan: 1, semeruMarkedForDeletionChan: 1}
go r.reconcileNetworkPolicy(defaultMeta, instance, instanceMutex, reconcileResultChan) // STATE: {reconcileResultChan: 5, ltpaMetadataChan: 2, passwordEncryptionMetadataChan: 1, semeruMarkedForDeletionChan: 1, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}
go r.reconcileServiceability(instance, instanceMutex, reqLogger, reconcileResultChan) // STATE: {reconcileResultChan: 6, ltpaMetadataChan: 2, passwordEncryptionMetadataChan: 1, semeruMarkedForDeletionChan: 1, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}
go r.reconcileBindings(instance, instanceMutex, reconcileResultChan) // STATE: {reconcileResultChan: 7, ltpaMetadataChan: 2, passwordEncryptionMetadataChan: 1, semeruMarkedForDeletionChan: 1, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}

ltpaKeysLastRotationChan := make(chan string, 1)
lastRotationChan := make(chan string, 2) // order doesn't matter, just need the latest rotation time
Expand All @@ -1011,15 +1005,22 @@ func (r *ReconcileOpenLiberty) concurrentReconcile(ba common.BaseComponent, inst
sharedResourceHandoffReconcileResultChan := make(chan ReconcileResult,
1) // reconcileLTPAConfigConcurrent() reads from sharedResourceReconcileResultChan and writes to this chan

go r.reconcilePasswordEncryptionKeyConcurrent(instance, instanceMutex, passwordEncryptionMetadata, sharedResourceReconcileResultChan, lastRotationChan, encryptionSecretNameChan) // STATE: {reconcileResultChan: 8, semeruMarkedForDeletionChan: 1, sharedResourceReconcileResultChan: 1, lastRotationChan: 1, encryptionSecretNameChan: 1}
go r.reconcileLTPAKeysConcurrent(instance, instanceMutex, ltpaKeysMetadata, ltpaConfigMetadata, sharedResourceReconcileResultChan, lastRotationChan, ltpaSecretNameChan, ltpaKeysLastRotationChan) // STATE: {reconcileResultChan: 8, semeruMarkedForDeletionChan: 1, sharedResourceReconcileResultChan: 2, lastRotationChan: 2, ltpaKeysLastRotationChan: 1, encryptionSecretNameChan: 1, ltpaSecretNameChan: 1}
go r.reconcilePasswordEncryptionKeyConcurrent(instance, instanceMutex, passwordEncryptionMetadata, sharedResourceReconcileResultChan, lastRotationChan, encryptionSecretNameChan) // STATE: {reconcileResultChan: 7, semeruMarkedForDeletionChan: 1, sharedResourceReconcileResultChan: 1, lastRotationChan: 1, encryptionSecretNameChan: 1, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}
go r.reconcileLTPAKeysConcurrent(instance, instanceMutex, ltpaKeysMetadata, ltpaConfigMetadata, sharedResourceReconcileResultChan, lastRotationChan, ltpaSecretNameChan, ltpaKeysLastRotationChan) // STATE: {reconcileResultChan: 7, semeruMarkedForDeletionChan: 1, sharedResourceReconcileResultChan: 2, lastRotationChan: 2, ltpaKeysLastRotationChan: 1, encryptionSecretNameChan: 1, ltpaSecretNameChan: 1, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}
go r.reconcileLTPAConfigConcurrent(instance, instanceMutex, ltpaKeysMetadata, ltpaConfigMetadata, passwordEncryptionMetadata, sharedResourceHandoffReconcileResultChan, sharedResourceReconcileResultChan,
lastRotationChan, ltpaKeysLastRotationChan, ltpaXMLSecretNameChan) // STATE: {reconcileResultChan: 8, semeruMarkedForDeletionChan: 1, sharedResourceHandoffReconcileResultChan: 1, encryptionSecretNameChan: 1, ltpaSecretNameChan: 1, ltpaXMLSecretNameChan: 1}
go r.reconcileStatefulSetDeployment(defaultMeta, instance, instanceMutex, ltpaConfigMetadata, passwordEncryptionMetadata, reconcileResultChan, sharedResourceHandoffReconcileResultChan, encryptionSecretNameChan, ltpaSecretNameChan, ltpaXMLSecretNameChan) // STATE: {reconcileResultChan: 9, semeruMarkedForDeletionChan: 1}
lastRotationChan, ltpaKeysLastRotationChan, ltpaXMLSecretNameChan) // STATE: {reconcileResultChan: 7, semeruMarkedForDeletionChan: 1, sharedResourceHandoffReconcileResultChan: 1, encryptionSecretNameChan: 1, ltpaSecretNameChan: 1, ltpaXMLSecretNameChan: 1, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}
go r.reconcileStatefulSetDeployment(defaultMeta, instance, instanceMutex, ltpaConfigMetadata, passwordEncryptionMetadata, reconcileResultChan, sharedResourceHandoffReconcileResultChan, encryptionSecretNameChan, ltpaSecretNameChan, ltpaXMLSecretNameChan) // STATE: {reconcileResultChan: 8, semeruMarkedForDeletionChan: 1, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}

go r.reconcileAutoscaling(defaultMeta, instance, instanceMutex, reconcileResultChan) // STATE: {semeruMarkedForDeletionChan: 1, reconcileResultChan: 9, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}
go r.reconcileRouteIngress(defaultMeta, ba, instance, instanceMutex, reqLogger, reconcileResultChan) // STATE: {semeruMarkedForDeletionChan: 1, reconcileResultChan: 10, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}
go r.reconcileServiceMonitor(defaultMeta, instance, instanceMutex, reqLogger, reconcileResultChan) // STATE: {semeruMarkedForDeletionChan: 1, reconcileResultChan: 11, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}
go r.reconcileSemeruCloudCompilerCleanup(instance, instanceMutex, reconcileResultChan, semeruMarkedForDeletionChan) // STATE: {reconcileResultChan: 12, useCertManagerChan: 1, serviceCertificateReconcileResultChan: 1}

go r.reconcileService(defaultMeta, ba, instance, instanceMutex, reconcileResultChan, serviceCertificateReconcileResultChan, useCertManagerChan) // STATE: {reconcileResultChan: 13}

// FRONTIER: past this point, it doesn't make sense to manage the route when the statefulset/deployment might possibly not exist, so block until completion
// STATE: {semeruMarkedForDeletionChan: 1, reconcileResultChan: 9}
reconcileResults := 9
// STATE: {reconcileResultChan: 13}
reconcileResults := 13
foundFirstError := false
var firstErroringReconcileResult ReconcileResult
for i := 0; i < reconcileResults; i++ {
Expand All @@ -1031,34 +1032,56 @@ func (r *ReconcileOpenLiberty) concurrentReconcile(ba common.BaseComponent, inst
}
}

// STATE: {semeruMarkedForDeletionChan: 1}
// STATE: {}
if foundFirstError {
<-semeruMarkedForDeletionChan // STATE: {}
// <-semeruMarkedForDeletionChan // STATE: {}
return r.ManageError(firstErroringReconcileResult.err, firstErroringReconcileResult.condition, instance)
}
// STATE: {semeruMarkedForDeletionChan: 1}
go r.reconcileAutoscaling(defaultMeta, instance, instanceMutex, reconcileResultChan) // STATE: {semeruMarkedForDeletionChan: 1, reconcileResultChan: 1}
go r.reconcileRouteIngress(defaultMeta, ba, instance, instanceMutex, reqLogger, reconcileResultChan) // STATE: {semeruMarkedForDeletionChan: 1, reconcileResultChan: 2}
go r.reconcileServiceMonitor(defaultMeta, instance, instanceMutex, reqLogger, reconcileResultChan) // STATE: {semeruMarkedForDeletionChan: 1, reconcileResultChan: 3}
go r.reconcileSemeruCloudCompilerCleanup(instance, instanceMutex, reconcileResultChan, semeruMarkedForDeletionChan) // STATE: {reconcileResultChan: 4}
// go r.reconcileAutoscaling(defaultMeta, instance, instanceMutex, reconcileResultChan) // STATE: {semeruMarkedForDeletionChan: 1, reconcileResultChan: 1}
// go r.reconcileRouteIngress(defaultMeta, ba, instance, instanceMutex, reqLogger, reconcileResultChan) // STATE: {semeruMarkedForDeletionChan: 1, reconcileResultChan: 2}
// go r.reconcileServiceMonitor(defaultMeta, instance, instanceMutex, reqLogger, reconcileResultChan) // STATE: {semeruMarkedForDeletionChan: 1, reconcileResultChan: 3}
// go r.reconcileSemeruCloudCompilerCleanup(instance, instanceMutex, reconcileResultChan, semeruMarkedForDeletionChan) // STATE: {reconcileResultChan: 4}
// FRONTIER: pull from all remaining channels to manage success
reconcileResults = 4
foundFirstError = false
for i := 0; i < reconcileResults; i++ {
reconcileResult := <-reconcileResultChan
if !foundFirstError && reconcileResult.err != nil {
foundFirstError = true
firstErroringReconcileResult = reconcileResult
}
}
// reconcileResults = 4
// foundFirstError = false
// for i := 0; i < reconcileResults; i++ {
// reconcileResult := <-reconcileResultChan
// if !foundFirstError && reconcileResult.err != nil {
// foundFirstError = true
// firstErroringReconcileResult = reconcileResult
// }
// }

// STATE: {}
if foundFirstError {
return r.ManageError(firstErroringReconcileResult.err, firstErroringReconcileResult.condition, instance)
}
// if foundFirstError {
// return r.ManageError(firstErroringReconcileResult.err, firstErroringReconcileResult.condition, instance)
// }

instance.Status.ObservedGeneration = instance.GetObjectMeta().GetGeneration()
instance.Status.Versions.Reconciled = lutils.OperandVersion
reqLogger.Info("Reconcile OpenLibertyApplication - completed")
return r.ManageSuccess(common.StatusConditionTypeReconciled, instance)
}

func (r ReconcileOpenLiberty) customLog(instance *olv1.OpenLibertyApplication, msg string) {
// if instance.Name == "hello-world-1" {
// fmt.Println("HELLO: " + msg)
// }
}

func (r ReconcileOpenLiberty) customTimerStart(instance *olv1.OpenLibertyApplication, msg string) time.Time {
if instance.Name == "hello-world-1" {
fmt.Println("START TIMER: " + msg)
}
return time.Now()
}

func (r ReconcileOpenLiberty) customTimerStop(instance *olv1.OpenLibertyApplication, startTime time.Time, msg string) {
if instance.Name == "hello-world-1" {
t := time.Now()
elapsed := t.Sub(startTime)

fmt.Printf("STOP TIMER: elapsed time is %fs: %s \n", elapsed.Seconds(), msg)
}
}

0 comments on commit 3fd1802

Please sign in to comment.