func IsTerminationInProgress() Predicate {
	return func(d *Deploy) bool {
		return d.IsTerminationInProgress()
	}
}
IsTerminationInProgress checks for older replicas are waiting to
terminate or not. If Status.Replicas > Status.UpdatedReplicas then
some of the older replicas are in running state because newer
replicas are not in running state. It waits for newer replica to
come into running state then terminate.
package deployment
import (
	templatespec "github.com/openebs/dynamic-nfs-provisioner/pkg/kubernetes/api/core/v1/podtemplatespec"
	errors "github.com/pkg/errors"
	appsv1 "k8s.io/api/apps/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type Predicate func(*Deploy) bool
type Deploy struct {
	object *appsv1.Deployment
}
type Builder struct {
	deployment *Deploy      
	checks     []Predicate  
	errors     []error
}
type PredicateName string
const (
	PredicateProgressDeadlineExceeded PredicateName = "ProgressDeadlineExceeded"
	PredicateNotSpecSynced PredicateName = "NotSpecSynced"
	PredicateOlderReplicaActive PredicateName = "OlderReplicaActive"
	PredicateTerminationInProgress PredicateName = "TerminationInProgress"
	PredicateUpdateInProgress PredicateName = "UpdateInProgress"
)
func NewBuilder() *Builder {
	return &Builder{
		deployment: &Deploy{
			object: &appsv1.Deployment{},
		},
	}
}
func (b *Builder) WithName(name string) *Builder {
	if len(name) == 0 {
		b.errors = append(
			b.errors,
			errors.New("failed to build deployment: missing name"),
		)
		return b
	}
	b.deployment.object.Name = name
	return b
}
func (b *Builder) WithNamespace(namespace string) *Builder {
	if len(namespace) == 0 {
		b.errors = append(
			b.errors,
			errors.New("failed to build deployment: missing namespace"),
		)
		return b
	}
	b.deployment.object.Namespace = namespace
	return b
}
func (b *Builder) WithAnnotations(annotations map[string]string) *Builder {
	if len(annotations) == 0 {
		b.errors = append(
			b.errors,
			errors.New("failed to build deployment object: missing annotations"),
		)
		return b
	}
	if b.deployment.object.Annotations == nil {
		return b.WithAnnotationsNew(annotations)
	}
	for key, value := range annotations {
		b.deployment.object.Annotations[key] = value
	}
	return b
}
func (b *Builder) WithAnnotationsNew(annotations map[string]string) *Builder {
	if len(annotations) == 0 {
		b.errors = append(
			b.errors,
			errors.New("failed to build deployment object: no new annotations"),
		)
		return b
	}
	newannotations := map[string]string{}
	for key, value := range annotations {
		newannotations[key] = value
	}
	b.deployment.object.Annotations = newannotations
	return b
}
func (b *Builder) WithNodeSelector(selector map[string]string) *Builder {
	if len(selector) == 0 {
		b.errors = append(
			b.errors,
			errors.New("failed to build deployment object: no node selector"),
		)
		return b
	}
	if b.deployment.object.Spec.Template.Spec.NodeSelector == nil {
		return b.WithNodeSelectorNew(selector)
	}
	for key, value := range selector {
		b.deployment.object.Spec.Template.Spec.NodeSelector[key] = value
	}
	return b
}
func (b *Builder) WithNodeSelectorNew(selector map[string]string) *Builder {
	if len(selector) == 0 {
		b.errors = append(
			b.errors,
			errors.New("failed to build deployment object: no new node selector"),
		)
		return b
	}
	b.deployment.object.Spec.Template.Spec.NodeSelector = selector
	return b
}
func (b *Builder) WithOwnerReferenceNew(ownerRefernce []metav1.OwnerReference) *Builder {
	if len(ownerRefernce) == 0 {
		b.errors = append(
			b.errors,
			errors.New("failed to build deployment object: no new ownerRefernce"),
		)
		return b
	}
	b.deployment.object.OwnerReferences = ownerRefernce
	return b
}
func (b *Builder) WithLabels(labels map[string]string) *Builder {
	if len(labels) == 0 {
		b.errors = append(
			b.errors,
			errors.New("failed to build deployment object: missing labels"),
		)
		return b
	}
	if b.deployment.object.Labels == nil {
		return b.WithLabelsNew(labels)
	}
	for key, value := range labels {
		b.deployment.object.Labels[key] = value
	}
	return b
}
func (b *Builder) WithLabelsNew(labels map[string]string) *Builder {
	if len(labels) == 0 {
		b.errors = append(
			b.errors,
			errors.New("failed to build deployment object: no new labels"),
		)
		return b
	}
	newlbls := map[string]string{}
	for key, value := range labels {
		newlbls[key] = value
	}
	b.deployment.object.Labels = newlbls
	return b
}
func (b *Builder) WithSelectorMatchLabels(matchlabels map[string]string) *Builder {
	if len(matchlabels) == 0 {
		b.errors = append(
			b.errors,
			errors.New("failed to build deployment object: missing matchlabels"),
		)
		return b
	}
	if b.deployment.object.Spec.Selector == nil {
		return b.WithSelectorMatchLabelsNew(matchlabels)
	}
	for key, value := range matchlabels {
		b.deployment.object.Spec.Selector.MatchLabels[key] = value
	}
	return b
}
func (b *Builder) WithSelectorMatchLabelsNew(matchlabels map[string]string) *Builder {
	if len(matchlabels) == 0 {
		b.errors = append(
			b.errors,
			errors.New("failed to build deployment object: no new matchlabels"),
		)
		return b
	}
	newmatchlabels := map[string]string{}
	for key, value := range matchlabels {
		newmatchlabels[key] = value
	}
	newselector := &metav1.LabelSelector{
		MatchLabels: newmatchlabels,
	}
	b.deployment.object.Spec.Selector = newselector
	return b
}
func (b *Builder) WithReplicas(replicas *int32) *Builder {
	if replicas == nil {
		b.errors = append(
			b.errors,
			errors.New("failed to build deployment object: nil replicas"),
		)
		return b
	}
	newreplicas := *replicas
	if newreplicas < 0 {
		b.errors = append(
			b.errors,
			errors.Errorf(
				"failed to build deployment object: invalid replicas {%d}",
				newreplicas,
			),
		)
		return b
	}
	b.deployment.object.Spec.Replicas = &newreplicas
	return b
}
func (b *Builder) WithStrategyType(
	strategytype appsv1.DeploymentStrategyType,
) *Builder {
	if len(strategytype) == 0 {
		b.errors = append(
			b.errors,
			errors.New("failed to build deployment object: missing strategytype"),
		)
		return b
	}
	b.deployment.object.Spec.Strategy.Type = strategytype
	return b
}
func (b *Builder) WithStrategyTypeRecreate() *Builder {
	return b.WithStrategyType(appsv1.RecreateDeploymentStrategyType)
}
func (b *Builder) WithPodTemplateSpecBuilder(
	tmplbuilder *templatespec.Builder,
) *Builder {
	if tmplbuilder == nil {
		b.errors = append(
			b.errors,
			errors.New("failed to build deployment: nil templatespecbuilder"),
		)
		return b
	}
	templatespecObj, err := tmplbuilder.Build()
	if err != nil {
		b.errors = append(
			b.errors,
			errors.Wrap(
				err,
				"failed to build deployment",
			),
		)
		return b
	}
	b.deployment.object.Spec.Template = *templatespecObj.Object
	return b
}
type deployBuildOption func(*Deploy)
func NewForAPIObject(
	obj *appsv1.Deployment,
	opts ...deployBuildOption,
) *Deploy {
	d := &Deploy{object: obj}
	for _, o := range opts {
		o(d)
	}
	return d
}
func (b *Builder) Build() (*appsv1.Deployment, error) {
	err := b.validate()
	if err != nil {
		return nil, errors.Wrapf(err,
			"failed to build a deployment: %s",
			b.deployment.object.Name)
	}
	return b.deployment.object, nil
}
func (b *Builder) validate() error {
	if len(b.errors) != 0 {
		return errors.Errorf(
			"failed to validate: build errors were found: %+v",
			b.errors,
		)
	}
	return nil
}
func (d *Deploy) IsRollout() (PredicateName, bool) {
	for pk, p := range rolloutChecks {
		if p(d) {
			return pk, false
		}
	}
	return "", true
}
func (d *Deploy) FailedRollout(name PredicateName) *RolloutOutput {
	return &RolloutOutput{
		Message:     rolloutStatuses[name](d),
		IsRolledout: false,
	}
}
func (d *Deploy) SuccessRollout() *RolloutOutput {
	return &RolloutOutput{
		Message:     "deployment successfully rolled out",
		IsRolledout: true,
	}
}
func (d *Deploy) RolloutStatus() (op *RolloutOutput, err error) {
	pk, ok := d.IsRollout()
	if ok {
		return d.SuccessRollout(), nil
	}
	return d.FailedRollout(pk), nil
}
func (d *Deploy) RolloutStatusRaw() (op []byte, err error) {
	message, err := d.RolloutStatus()
	if err != nil {
		return nil, err
	}
	return NewRollout(
		withOutputObject(message)).
		Raw()
}
func (b *Builder) AddCheck(p Predicate) *Builder {
	b.checks = append(b.checks, p)
	return b
}
func (b *Builder) AddChecks(p []Predicate) *Builder {
	for _, check := range p {
		b.AddCheck(check)
	}
	return b
}
func IsProgressDeadlineExceeded() Predicate {
	return func(d *Deploy) bool {
		return d.IsProgressDeadlineExceeded()
	}
}
func (d *Deploy) IsProgressDeadlineExceeded() bool {
	for _, cond := range d.object.Status.Conditions {
		if cond.Type == appsv1.DeploymentProgressing &&
			cond.Reason == "ProgressDeadlineExceeded" {
			return true
		}
	}
	return false
}
func IsOlderReplicaActive() Predicate {
	return func(d *Deploy) bool {
		return d.IsOlderReplicaActive()
	}
}
func (d *Deploy) IsOlderReplicaActive() bool {
	return d.object.Spec.Replicas != nil &&
		d.object.Status.UpdatedReplicas < *d.object.Spec.Replicas
}