func (ac *actionContext) GetImageInfo(imageName string) (api.ImageInfo, bool) {
	status, _ := ac.context.GetStatus()
	return status.Images.GetByImage(imageName)
}
GetImageInfo returns the image info for an image with given name.
Returns: (info, infoFound)
package reconcile
import (
	"context"
	"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/arangomember"
	"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/persistentvolumeclaim"
	"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/pod"
	"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/poddisruptionbudget"
	"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/secret"
	"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/service"
	"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/serviceaccount"
	"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/servicemonitor"
	"github.com/arangodb/kube-arangodb/pkg/deployment/resources"
	inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
	"github.com/arangodb/kube-arangodb/pkg/util/errors"
	backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1"
	"github.com/arangodb/go-driver/agency"
	"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
	core "k8s.io/api/core/v1"
	"github.com/arangodb/arangosync-client/client"
	driver "github.com/arangodb/go-driver"
	"github.com/rs/zerolog"
	"github.com/rs/zerolog/log"
	api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
)
type ActionContext interface {
	resources.DeploymentStatusUpdate
	resources.DeploymentAgencyMaintenance
	resources.ArangoMemberContext
	resources.DeploymentPodRenderer
	resources.DeploymentModInterfaces
	resources.DeploymentCachedStatus
	GetAPIObject() k8sutil.APIObject
	GetMode() api.DeploymentMode
	GetDatabaseClient(ctx context.Context) (driver.Client, error)
	GetServerClient(ctx context.Context, group api.ServerGroup, id string) (driver.Client, error)
	GetAgencyClients(ctx context.Context) ([]driver.Connection, error)
	GetAgency(ctx context.Context) (agency.Agency, error)
	GetSyncServerClient(ctx context.Context, group api.ServerGroup, id string) (client.API, error)
	CreateEvent(evt *k8sutil.Event)
	GetMemberStatusByID(id string) (api.MemberStatus, bool)
	GetMemberStatusAndGroupByID(id string) (api.MemberStatus, api.ServerGroup, bool)
	CreateMember(ctx context.Context, group api.ServerGroup, id string, mods ...CreateMemberMod) (string, error)
	UpdateMember(ctx context.Context, member api.MemberStatus) error
	RemoveMemberByID(ctx context.Context, id string) error
	GetPod(ctx context.Context, podName string) (*core.Pod, error)
	DeletePod(ctx context.Context, podName string) error
	DeletePvc(ctx context.Context, pvcName string) error
	GetPvc(ctx context.Context, pvcName string) (*core.PersistentVolumeClaim, error)
	UpdatePvc(ctx context.Context, pvc *core.PersistentVolumeClaim) error
	RemovePodFinalizers(ctx context.Context, podName string) error
	DeleteTLSKeyfile(ctx context.Context, group api.ServerGroup, member api.MemberStatus) error
	DeleteTLSCASecret(ctx context.Context) error
	GetImageInfo(imageName string) (api.ImageInfo, bool)
	GetCurrentImageInfo() (api.ImageInfo, bool)
	SetCurrentImage(ctx context.Context, imageInfo api.ImageInfo) error
	GetDeploymentHealth() (driver.ClusterHealth, error)
	GetShardSyncStatus() bool
	InvalidateSyncStatus()
	GetSpec() api.DeploymentSpec
	GetStatus() api.DeploymentStatus
	DisableScalingCluster(ctx context.Context) error
	EnableScalingCluster(ctx context.Context) error
	UpdateClusterCondition(ctx context.Context, conditionType api.ConditionType, status bool, reason, message string) error
	GetBackup(ctx context.Context, backup string) (*backupApi.ArangoBackup, error)
	GetName() string
	SelectImage(spec api.DeploymentSpec, status api.DeploymentStatus) (api.ImageInfo, bool)
}
func newActionContext(log zerolog.Logger, context Context, cachedStatus inspectorInterface.Inspector) ActionContext {
	return &actionContext{
		log:          log,
		context:      context,
		cachedStatus: cachedStatus,
	}
}
type actionContext struct {
	context      Context
	log          zerolog.Logger
	cachedStatus inspectorInterface.Inspector
}
func (ac *actionContext) RenderPodForMemberFromCurrent(ctx context.Context, cachedStatus inspectorInterface.Inspector, memberID string) (*core.Pod, error) {
	return ac.context.RenderPodForMemberFromCurrent(ctx, cachedStatus, memberID)
}
func (ac *actionContext) RenderPodTemplateForMemberFromCurrent(ctx context.Context, cachedStatus inspectorInterface.Inspector, memberID string) (*core.PodTemplateSpec, error) {
	return ac.context.RenderPodTemplateForMemberFromCurrent(ctx, cachedStatus, memberID)
}
func (ac *actionContext) GetAgencyMaintenanceMode(ctx context.Context) (bool, error) {
	return ac.context.GetAgencyMaintenanceMode(ctx)
}
func (ac *actionContext) SetAgencyMaintenanceMode(ctx context.Context, enabled bool) error {
	return ac.context.SetAgencyMaintenanceMode(ctx, enabled)
}
func (ac *actionContext) WithArangoMemberUpdate(ctx context.Context, namespace, name string, action resources.ArangoMemberUpdateFunc) error {
	return ac.context.WithArangoMemberUpdate(ctx, namespace, name, action)
}
func (ac *actionContext) WithArangoMemberStatusUpdate(ctx context.Context, namespace, name string, action resources.ArangoMemberStatusUpdateFunc) error {
	return ac.context.WithArangoMemberStatusUpdate(ctx, namespace, name, action)
}
func (ac *actionContext) RenderPodForMember(ctx context.Context, cachedStatus inspectorInterface.Inspector, spec api.DeploymentSpec, status api.DeploymentStatus, memberID string, imageInfo api.ImageInfo) (*core.Pod, error) {
	return ac.context.RenderPodForMember(ctx, cachedStatus, spec, status, memberID, imageInfo)
}
func (ac *actionContext) RenderPodTemplateForMember(ctx context.Context, cachedStatus inspectorInterface.Inspector, spec api.DeploymentSpec, status api.DeploymentStatus, memberID string, imageInfo api.ImageInfo) (*core.PodTemplateSpec, error) {
	return ac.context.RenderPodTemplateForMember(ctx, cachedStatus, spec, status, memberID, imageInfo)
}
func (ac *actionContext) SelectImage(spec api.DeploymentSpec, status api.DeploymentStatus) (api.ImageInfo, bool) {
	return ac.context.SelectImage(spec, status)
}
func (ac *actionContext) GetCachedStatus() inspectorInterface.Inspector {
	return ac.cachedStatus
}
func (ac *actionContext) GetName() string {
	return ac.context.GetName()
}
func (ac *actionContext) GetStatus() api.DeploymentStatus {
	a, _ := ac.context.GetStatus()
	s := a.DeepCopy()
	return *s
}
func (ac *actionContext) GetBackup(ctx context.Context, backup string) (*backupApi.ArangoBackup, error) {
	return ac.context.GetBackup(ctx, backup)
}
func (ac *actionContext) WithStatusUpdateErr(ctx context.Context, action resources.DeploymentStatusUpdateErrFunc, force ...bool) error {
	return ac.context.WithStatusUpdateErr(ctx, action, force...)
}
func (ac *actionContext) WithStatusUpdate(ctx context.Context, action resources.DeploymentStatusUpdateFunc, force ...bool) error {
	return ac.context.WithStatusUpdate(ctx, action, force...)
}
func (ac *actionContext) SecretsModInterface() secret.ModInterface {
	return ac.context.SecretsModInterface()
}
func (ac *actionContext) PodsModInterface() pod.ModInterface {
	return ac.context.PodsModInterface()
}
func (ac *actionContext) ServiceAccountsModInterface() serviceaccount.ModInterface {
	return ac.context.ServiceAccountsModInterface()
}
func (ac *actionContext) ServicesModInterface() service.ModInterface {
	return ac.context.ServicesModInterface()
}
func (ac *actionContext) PersistentVolumeClaimsModInterface() persistentvolumeclaim.ModInterface {
	return ac.context.PersistentVolumeClaimsModInterface()
}
func (ac *actionContext) PodDisruptionBudgetsModInterface() poddisruptionbudget.ModInterface {
	return ac.context.PodDisruptionBudgetsModInterface()
}
func (ac *actionContext) ServiceMonitorsModInterface() servicemonitor.ModInterface {
	return ac.context.ServiceMonitorsModInterface()
}
func (ac *actionContext) ArangoMembersModInterface() arangomember.ModInterface {
	return ac.context.ArangoMembersModInterface()
}
func (ac *actionContext) GetShardSyncStatus() bool {
	return ac.context.GetShardSyncStatus()
}
func (ac *actionContext) UpdateClusterCondition(ctx context.Context, conditionType api.ConditionType, status bool, reason, message string) error {
	return ac.context.WithStatusUpdate(ctx, func(s *api.DeploymentStatus) bool {
		return s.Conditions.Update(conditionType, status, reason, message)
	})
}
func (ac *actionContext) GetAPIObject() k8sutil.APIObject {
	return ac.context.GetAPIObject()
}
func (ac *actionContext) UpdatePvc(ctx context.Context, pvc *core.PersistentVolumeClaim) error {
	return ac.context.UpdatePvc(ctx, pvc)
}
func (ac *actionContext) CreateEvent(evt *k8sutil.Event) {
	ac.context.CreateEvent(evt)
}
func (ac *actionContext) GetPvc(ctx context.Context, pvcName string) (*core.PersistentVolumeClaim, error) {
	return ac.context.GetPvc(ctx, pvcName)
}
func (ac *actionContext) GetMode() api.DeploymentMode {
	return ac.context.GetSpec().GetMode()
}
func (ac *actionContext) GetSpec() api.DeploymentSpec {
	return ac.context.GetSpec()
}
func (ac *actionContext) GetDeploymentHealth() (driver.ClusterHealth, error) {
	return ac.context.GetDeploymentHealth()
}
func (ac *actionContext) GetDatabaseClient(ctx context.Context) (driver.Client, error) {
	c, err := ac.context.GetDatabaseClient(ctx)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return c, nil
}
func (ac *actionContext) GetServerClient(ctx context.Context, group api.ServerGroup, id string) (driver.Client, error) {
	c, err := ac.context.GetServerClient(ctx, group, id)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return c, nil
}
func (ac *actionContext) GetAgencyClients(ctx context.Context) ([]driver.Connection, error) {
	c, err := ac.context.GetAgencyClients(ctx, nil)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return c, nil
}
func (ac *actionContext) GetAgency(ctx context.Context) (agency.Agency, error) {
	a, err := ac.context.GetAgency(ctx)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return a, nil
}
func (ac *actionContext) GetSyncServerClient(ctx context.Context, group api.ServerGroup, id string) (client.API, error) {
	c, err := ac.context.GetSyncServerClient(ctx, group, id)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return c, nil
}
func (ac *actionContext) GetMemberStatusByID(id string) (api.MemberStatus, bool) {
	status, _ := ac.context.GetStatus()
	m, _, ok := status.Members.ElementByID(id)
	return m, ok
}
func (ac *actionContext) GetMemberStatusAndGroupByID(id string) (api.MemberStatus, api.ServerGroup, bool) {
	status, _ := ac.context.GetStatus()
	return status.Members.ElementByID(id)
}
func (ac *actionContext) CreateMember(ctx context.Context, group api.ServerGroup, id string, mods ...CreateMemberMod) (string, error) {
	result, err := ac.context.CreateMember(ctx, group, id, mods...)
	if err != nil {
		return "", errors.WithStack(err)
	}
	return result, nil
}
func (ac *actionContext) UpdateMember(ctx context.Context, member api.MemberStatus) error {
	status, lastVersion := ac.context.GetStatus()
	_, group, found := status.Members.ElementByID(member.ID)
	if !found {
		return errors.WithStack(errors.Newf("Member %s not found", member.ID))
	}
	if err := status.Members.Update(member, group); err != nil {
		return errors.WithStack(err)
	}
	if err := ac.context.UpdateStatus(ctx, status, lastVersion); err != nil {
		log.Debug().Err(err).Msg("Updating CR status failed")
		return errors.WithStack(err)
	}
	return nil
}
func (ac *actionContext) RemoveMemberByID(ctx context.Context, id string) error {
	status, lastVersion := ac.context.GetStatus()
	_, group, found := status.Members.ElementByID(id)
	if !found {
		return nil
	}
	if err := status.Members.RemoveByID(id, group); err != nil {
		log.Debug().Err(err).Str("group", group.AsRole()).Msg("Failed to remove member")
		return errors.WithStack(err)
	}
	if err := ac.context.UpdateStatus(ctx, status, lastVersion); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (ac *actionContext) GetPod(ctx context.Context, podName string) (*core.Pod, error) {
	if pod, err := ac.context.GetPod(ctx, podName); err != nil {
		return nil, errors.WithStack(err)
	} else {
		return pod, nil
	}
}
func (ac *actionContext) DeletePod(ctx context.Context, podName string) error {
	if err := ac.context.DeletePod(ctx, podName); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (ac *actionContext) DeletePvc(ctx context.Context, pvcName string) error {
	if err := ac.context.DeletePvc(ctx, pvcName); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (ac *actionContext) RemovePodFinalizers(ctx context.Context, podName string) error {
	if err := ac.context.RemovePodFinalizers(ctx, podName); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (ac *actionContext) DeleteTLSKeyfile(ctx context.Context, group api.ServerGroup, member api.MemberStatus) error {
	if err := ac.context.DeleteTLSKeyfile(ctx, group, member); err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func (ac *actionContext) DeleteTLSCASecret(ctx context.Context) error {
	spec := ac.context.GetSpec().TLS
	if !spec.IsSecure() {
		return nil
	}
	secretName := spec.GetCASecretName()
	if secretName == "" {
		return nil
	}
	status, lastVersion := ac.context.GetStatus()
	if status.SecretHashes != nil {
		status.SecretHashes.TLSCA = ""
		if err := ac.context.UpdateStatus(ctx, status, lastVersion); err != nil {
			return errors.WithStack(err)
		}
	}
	if err := ac.context.DeleteSecret(secretName); err != nil {
		return errors.WithStack(err)
	}
	return nil
}