Newer
Older
AnthosCertManager / pkg / api / util / conditions.go
package util

import (
	acmapi "gitbucket.jerxie.com/yangyangxie/AnthosCertManager/pkg/apis/anthoscertmanager/v1"
	acmmeta "gitbucket.jerxie.com/yangyangxie/AnthosCertManager/pkg/apis/meta/v1"

	logf "gitbucket.jerxie.com/yangyangxie/AnthosCertManager/pkg/logs"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/utils/clock"
)

// Clock is defined as a package var so it can be stubbed out during tests.
var Clock clock.Clock = clock.RealClock{}

// CertificateHasCondition will return true if the given Certificate has a
// condition matching the provided CertificateCondition.
// Only the Type and Status field will be used in the comparison, meaning that
// this function will return 'true' even if the Reason, Message and
// LastTransitionTime fields do not match.
func CertificateHasCondition(crt *acmapi.Certificate, c acmapi.CertificateCondition) bool {
	if crt == nil {
		return false
	}
	existingConditions := crt.Status.Conditions
	for _, cond := range existingConditions {
		if c.Type == cond.Type && c.Status == cond.Status {
			return true
		}
	}
	return false
}

// RemoveCertificateCondition will remove any condition with this condition type
func RemoveCertificateCondition(crt *acmapi.Certificate, conditionType acmapi.CertificateConditionType) {
	var updatedConditions []acmapi.CertificateCondition
	for _, cond := range crt.Status.Conditions {
		if cond.Type != conditionType {
			// Only add the unrelated conditions
			updatedConditions = append(updatedConditions, cond)
		}
	}
	// Add the other conditions back.
	crt.Status.Conditions = updatedConditions

}

// IssuerHasCondition will return true if the given GenericIssuer has a
// condition matching the provided IssuerCondition.
// Only the Type and Status field will be used in the comparison, meaning that
// this function will return 'true' even if the Reason, Message and
// LastTransitionTime fields do not match.
func IssuerHasCondition(i acmapi.GenericIssuer, c acmapi.IssuerCondition) bool {
	if i == nil {
		return false
	}
	existingConditions := i.GetStatus().Conditions
	for _, cond := range existingConditions {
		if c.Type == cond.Type && c.Status == cond.Status {
			return true
		}
	}
	return false
}

// SetIssuerCondition will set a 'condition' on the given GenericIssuer.
//   - If no condition of the same type already exists, the condition will be
//     inserted with the LastTransitionTime set to the current time.
//   - If a condition of the same type and state already exists, the condition
//     will be updated but the LastTransitionTime will not be modified.
//   - If a condition of the same type and different state already exists, the
//     condition will be updated and the LastTransitionTime set to the current
//     time.
//
// This function works with both Issuer and ClusterIssuer resources.
func SetIssuerCondition(i acmapi.GenericIssuer, observedGeneration int64, conditionType acmapi.IssuerConditionType, status acmmeta.ConditionStatus, reason, message string) {
	newCondition := acmapi.IssuerCondition{
		Type:    conditionType,
		Status:  status,
		Reason:  reason,
		Message: message,
	}

	nowTime := metav1.NewTime(Clock.Now())
	newCondition.LastTransitionTime = &nowTime

	// Set the condition generation
	newCondition.ObservedGeneration = observedGeneration

	// Search through existing conditions
	for idx, cond := range i.GetStatus().Conditions {
		// Skip unrelated conditions
		if cond.Type != conditionType {
			continue
		}

		// If this update doesn't contain a state transition, we don't update
		// the conditions LastTransitionTime to Now()
		if cond.Status == status {
			newCondition.LastTransitionTime = cond.LastTransitionTime
		} else {
			logf.V(logf.InfoLevel).Infof("Found status change for Issuer %q condition %q: %q -> %q; setting lastTransitionTime to %v", i.GetObjectMeta().Name, conditionType, cond.Status, status, nowTime.Time)
		}

		// Overwrite the existing condition
		i.GetStatus().Conditions[idx] = newCondition
		return
	}

	// If we've not found an existing condition of this type, we simply insert
	// the new condition into the slice.
	i.GetStatus().Conditions = append(i.GetStatus().Conditions, newCondition)
	logf.V(logf.InfoLevel).Infof("Setting lastTransitionTime for Issuer %q condition %q to %v", i.GetObjectMeta().Name, conditionType, nowTime.Time)
}