func createCARenewalPlan(ctx context.Context,
	log zerolog.Logger, apiObject k8sutil.APIObject,
	spec api.DeploymentSpec, status api.DeploymentStatus,
	cachedStatus inspectorInterface.Inspector, context PlanBuilderContext) api.Plan {
	if !spec.TLS.IsSecure() {
		return nil
	}
	caSecret, exists := cachedStatus.Secret(spec.TLS.GetCASecretName())
	if !exists {
		log.Warn().Str("secret", spec.TLS.GetCASecretName()).Msg("CA Secret does not exists")
		return nil
	}
	if !k8sutil.IsOwner(apiObject.AsOwner(), caSecret) {
		log.Debug().Str("secret", spec.TLS.GetCASecretName()).Msg("CA Secret is not owned by Operator, we wont do anything")
		return nil
	}
	cas, _, err := resources.GetKeyCertFromSecret(log, caSecret, resources.CACertName, resources.CAKeyName)
	if err != nil {
		log.Warn().Err(err).Str("secret", spec.TLS.GetCASecretName()).Msg("CA Secret does not contains Cert")
		return nil
	}
	for _, ca := range cas {
		if time.Now().Add(CertificateRenewalMargin).After(ca.NotAfter) {
			return api.Plan{api.NewAction(api.ActionTypeRenewTLSCACertificate, api.ServerGroupUnknown, "", "Renew CA Certificate")}
		}
	}
	return nil
}
createCARenewalPlan creates plan to renew CA
package reconcile
import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"net/http"
	"net/url"
	"reflect"
	"time"
	memberTls "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/tls"
	"github.com/arangodb/go-driver"
	"github.com/arangodb/kube-arangodb/pkg/deployment/features"
	"github.com/arangodb/kube-arangodb/pkg/deployment/client"
	"github.com/arangodb/kube-arangodb/pkg/util/constants"
	inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
	api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
	"github.com/arangodb/kube-arangodb/pkg/deployment/resources"
	"github.com/arangodb/kube-arangodb/pkg/util"
	"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
	"github.com/rs/zerolog"
)
const CertificateRenewalMargin = 7 * 24 * time.Hour
func createTLSStatusPropagatedFieldUpdate(ctx context.Context,
	log zerolog.Logger, apiObject k8sutil.APIObject,
	spec api.DeploymentSpec, status api.DeploymentStatus,
	cachedStatus inspectorInterface.Inspector, context PlanBuilderContext, w WithPlanBuilder, builders ...planBuilder) api.Plan {
	if !spec.TLS.IsSecure() {
		return nil
	}
	var plan api.Plan
	for _, builder := range builders {
		if !plan.IsEmpty() {
			continue
		}
		if p := w.Apply(builder); !p.IsEmpty() {
			plan = append(plan, p...)
		}
	}
	if plan.IsEmpty() {
		return nil
	}
	if status.Hashes.TLS.Propagated {
		plan = append(api.Plan{
			api.NewAction(api.ActionTypeTLSPropagated, api.ServerGroupUnknown, "", "Change propagated flag to false").AddParam(propagated, conditionFalse),
		}, plan...)
	}
	return plan
}
func createTLSStatusUpdate(ctx context.Context,
	log zerolog.Logger, apiObject k8sutil.APIObject,
	spec api.DeploymentSpec, status api.DeploymentStatus,
	cachedStatus inspectorInterface.Inspector, context PlanBuilderContext) api.Plan {
	if !spec.TLS.IsSecure() {
		return nil
	}
	if createTLSStatusUpdateRequired(log, apiObject, spec, status, cachedStatus) {
		return api.Plan{api.NewAction(api.ActionTypeTLSKeyStatusUpdate, api.ServerGroupUnknown, "", "Update status")}
	}
	return nil
}
func createTLSStatusPropagated(ctx context.Context,
	log zerolog.Logger, apiObject k8sutil.APIObject,
	spec api.DeploymentSpec, status api.DeploymentStatus,
	cachedStatus inspectorInterface.Inspector, context PlanBuilderContext) api.Plan {
	if !spec.TLS.IsSecure() {
		return nil
	}
	if !status.Hashes.TLS.Propagated {
		return api.Plan{
			api.NewAction(api.ActionTypeTLSPropagated, api.ServerGroupUnknown, "", "Change propagated flag to true").AddParam(propagated, conditionTrue),
		}
	}
	return nil
}
func createTLSStatusUpdateRequired(log zerolog.Logger, apiObject k8sutil.APIObject, spec api.DeploymentSpec,
	status api.DeploymentStatus, cachedStatus inspectorInterface.Inspector) bool {
	if !spec.TLS.IsSecure() {
		return false
	}
	trusted, exists := cachedStatus.Secret(resources.GetCASecretName(apiObject))
	if !exists {
		log.Warn().Str("secret", resources.GetCASecretName(apiObject)).Msg("Folder with secrets does not exist")
		return false
	}
	keyHashes := secretKeysToListWithPrefix(trusted)
	if len(keyHashes) == 0 {
		return false
	}
	if len(keyHashes) == 1 {
		if status.Hashes.TLS.CA == nil {
			return true
		}
		if *status.Hashes.TLS.CA != keyHashes[0] {
			return true
		}
	}
	if !util.CompareStringArray(status.Hashes.TLS.Truststore, keyHashes) {
		return true
	}
	return false
}
func createCAAppendPlan(ctx context.Context,
	log zerolog.Logger, apiObject k8sutil.APIObject,
	spec api.DeploymentSpec, status api.DeploymentStatus,
	cachedStatus inspectorInterface.Inspector, context PlanBuilderContext) api.Plan {
	if !spec.TLS.IsSecure() {
		return nil
	}
	caSecret, exists := cachedStatus.Secret(spec.TLS.GetCASecretName())
	if !exists {
		log.Warn().Str("secret", spec.TLS.GetCASecretName()).Msg("CA Secret does not exists")
		return nil
	}
	ca, _, err := resources.GetKeyCertFromSecret(log, caSecret, resources.CACertName, resources.CAKeyName)
	if err != nil {
		log.Warn().Err(err).Str("secret", spec.TLS.GetCASecretName()).Msg("CA Secret does not contains Cert")
		return nil
	}
	if len(ca) == 0 {
		log.Warn().Str("secret", spec.TLS.GetCASecretName()).Msg("CA does not contain any certs")
		return nil
	}
	trusted, exists := cachedStatus.Secret(resources.GetCASecretName(apiObject))
	if !exists {
		log.Warn().Str("secret", resources.GetCASecretName(apiObject)).Msg("Folder with secrets does not exist")
		return nil
	}
	caData, err := ca.ToPem()
	if err != nil {
		log.Warn().Err(err).Str("secret", spec.TLS.GetCASecretName()).Msg("Unable to parse cert")
		return nil
	}
	certSha := util.SHA256(caData)
	if _, exists := trusted.Data[certSha]; !exists {
		return api.Plan{api.NewAction(api.ActionTypeAppendTLSCACertificate, api.ServerGroupUnknown, "", "Append CA to truststore").
			AddParam(checksum, certSha)}
	}
	return nil
}