/
strategy.go
115 lines (100 loc) · 4.42 KB
/
strategy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package drain
import (
"context"
"time"
corev1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/go-logr/logr"
upgradev1alpha1 "github.com/openshift/managed-upgrade-operator/api/v1alpha1"
"github.com/openshift/managed-upgrade-operator/pkg/pod"
)
// NodeDrainStrategyBuilder enables implementation for a NodeDrainStrategyBuilder
//
//go:generate mockgen -destination=mocks/nodeDrainStrategyBuilder.go -package=mocks github.com/openshift/managed-upgrade-operator/pkg/drain NodeDrainStrategyBuilder
type NodeDrainStrategyBuilder interface {
NewNodeDrainStrategy(c client.Client, logger logr.Logger, uc *upgradev1alpha1.UpgradeConfig, cfg *NodeDrain) (NodeDrainStrategy, error)
}
// NodeDrainStrategy enables implementation for a NodeDrainStrategy
//
//go:generate mockgen -destination=mocks/nodeDrainStrategy.go -package=mocks github.com/openshift/managed-upgrade-operator/pkg/drain NodeDrainStrategy
type NodeDrainStrategy interface {
Execute(*corev1.Node, logr.Logger) ([]*DrainStrategyResult, error)
HasFailed(*corev1.Node, logr.Logger) (bool, error)
}
// DrainStrategy enables implementation for a DrainStrategy
//
//go:generate mockgen -destination=./drainStrategyMock.go -package=drain -self_package=github.com/openshift/managed-upgrade-operator/pkg/drain github.com/openshift/managed-upgrade-operator/pkg/drain DrainStrategy
type DrainStrategy interface {
Execute(*corev1.Node, logr.Logger) (*DrainStrategyResult, error)
IsValid(*corev1.Node, logr.Logger) (bool, error)
}
// TimedDrainStrategy enables implementation for a TimedDrainStrategy
//
//go:generate mockgen -destination=./timedDrainStrategyMock.go -package=drain -self_package=github.com/openshift/managed-upgrade-operator/pkg/drain github.com/openshift/managed-upgrade-operator/pkg/drain TimedDrainStrategy
type TimedDrainStrategy interface {
GetWaitDuration() time.Duration
GetName() string
GetDescription() string
GetStrategy() DrainStrategy
}
// NewBuilder returns a drainStrategyBuilder
func NewBuilder() NodeDrainStrategyBuilder {
return &drainStrategyBuilder{}
}
type drainStrategyBuilder struct{}
func newTimedStrategy(name string, description string, waitDuration time.Duration, strategy DrainStrategy) TimedDrainStrategy {
return &timedStrategy{
name: name,
description: description,
waitDuration: waitDuration,
strategy: strategy,
}
}
// NewNodeDrainStrategy returns a NodeDrainStrategy
func (dsb *drainStrategyBuilder) NewNodeDrainStrategy(c client.Client, logger logr.Logger, uc *upgradev1alpha1.UpgradeConfig, cfg *NodeDrain) (NodeDrainStrategy, error) {
pdbList := &policyv1.PodDisruptionBudgetList{}
err := c.List(context.TODO(), pdbList)
if err != nil {
if apierrors.IsNotFound(err) {
logger.Info("unable to list PodDisruptionBudgets/v1")
} else {
return nil, err
}
}
defaultOsdPodPredicates := []pod.PodPredicate{isNotDaemonSet}
isNotPdbPod := isNotPdbPod(pdbList)
isPdbPod := isPdbPod(pdbList)
isAllowedNamespace := isAllowedNamespace(cfg.IgnoredNamespacePatterns)
defaultDuration := cfg.GetTimeOutDuration()
pdbDuration := uc.GetPDBDrainTimeoutDuration() + cfg.GetExpectedDrainDuration()
ts := []TimedDrainStrategy{
newTimedStrategy(defaultPodDeleteName, "Default pod deletion", defaultDuration, &podDeletionStrategy{
client: c,
filters: append(defaultOsdPodPredicates, isNotPdbPod, isAllowedNamespace),
}),
newTimedStrategy(defaultPodFinalizerRemovalName, "Default pod finalizer removal", defaultDuration, &removeFinalizersStrategy{
client: c,
filters: append(defaultOsdPodPredicates, isNotPdbPod, isAllowedNamespace),
}),
newTimedStrategy(stuckTerminatingPodName, "Pod stuck terminating removal", defaultDuration, &stuckTerminatingStrategy{
client: c,
filters: append(defaultOsdPodPredicates, isNotPdbPod, isAllowedNamespace),
}),
newTimedStrategy(pdbPodDeleteName, "PDB pod deletion", pdbDuration, &podDeletionStrategy{
client: c,
filters: append(defaultOsdPodPredicates, isPdbPod, isAllowedNamespace),
}),
newTimedStrategy(pdbPodFinalizerRemovalName, "PDB Pod finalizer removal", pdbDuration, &removeFinalizersStrategy{
client: c,
filters: append(defaultOsdPodPredicates, isPdbPod, isAllowedNamespace),
}),
}
return NewNodeDrainStrategy(c, cfg, ts)
}
// DrainStrategyResult holds fields illustrating a drain strategies result
type DrainStrategyResult struct {
Message string
HasExecuted bool
}