This repository has been archived by the owner on Nov 30, 2023. It is now read-only.
/
create_cordon_old_vmss_transition.go
95 lines (75 loc) · 3.94 KB
/
create_cordon_old_vmss_transition.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
package instance
import (
"context"
"fmt"
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute"
"github.com/giantswarm/microerror"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/giantswarm/azure-operator/service/controller/controllercontext"
"github.com/giantswarm/azure-operator/service/controller/internal/state"
"github.com/giantswarm/azure-operator/service/controller/key"
)
func (r *Resource) cordonOldVMSSTransition(ctx context.Context, obj interface{}, currentState state.State) (state.State, error) {
cr, err := key.ToCustomResource(obj)
if err != nil {
return "", microerror.Mask(err)
}
cc, err := controllercontext.FromContext(ctx)
if err != nil {
return "", microerror.Mask(err)
}
if cc.Client.TenantCluster.K8s == nil {
r.logger.LogCtx(ctx, "level", "debug", "message", "tenant cluster client not available yet") // nolint: errcheck
return currentState, nil
}
// If the legacy VMSS still exists with at least one replica, we want to cordon its replicas.
r.logger.LogCtx(ctx, "level", "debug", "message", fmt.Sprintf("Checking if the legacy VMSS %s is still present", key.LegacyWorkerVMSSName(cr))) // nolint: errcheck
vmss, err := r.getScaleSet(ctx, key.ResourceGroupName(cr), key.LegacyWorkerVMSSName(cr))
if err != nil {
return "", microerror.Mask(err)
}
r.logger.LogCtx(ctx, "level", "debug", "message", fmt.Sprintf("The legacy VMSS %s is still present", key.LegacyWorkerVMSSName(cr))) // nolint: errcheck
// The legacy VMSS was found, check the scaling.
legacyVmssHasInstancesRunning := *vmss.Sku.Capacity > 0
if legacyVmssHasInstancesRunning {
// The legacy VMSS has still instances running, cordon all of them.
r.logger.LogCtx(ctx, "level", "debug", "message", fmt.Sprintf("The legacy VMSS %s has %d instances: cordoning those", key.LegacyWorkerVMSSName(cr), *vmss.Sku.Capacity)) // nolint: errcheck
} else {
r.logger.LogCtx(ctx, "level", "debug", "message", fmt.Sprintf("The legacy VMSS %s has 0 instances", key.LegacyWorkerVMSSName(cr))) // nolint: errcheck
}
r.logger.LogCtx(ctx, "level", "debug", "message", "finding all worker VMSS instances") // nolint: errcheck
var allWorkerInstances []compute.VirtualMachineScaleSetVM
{
allWorkerInstances, err = r.allInstances(ctx, cr, key.LegacyWorkerVMSSName)
if IsScaleSetNotFound(err) {
r.logger.LogCtx(ctx, "level", "debug", "message", fmt.Sprintf("did not find the scale set '%s'", key.LegacyWorkerVMSSName(cr))) // nolint: errcheck
return currentState, nil
} else if err != nil {
return "", microerror.Mask(err)
}
}
r.logger.LogCtx(ctx, "level", "debug", "message", fmt.Sprintf("found %d worker VMSS instances", len(allWorkerInstances))) // nolint: errcheck
r.logger.LogCtx(ctx, "level", "debug", "message", "finding all tenant cluster nodes") // nolint: errcheck
var nodes []corev1.Node
{
nodeList, err := cc.Client.TenantCluster.K8s.CoreV1().Nodes().List(metav1.ListOptions{})
if err != nil {
return "", microerror.Mask(err)
}
nodes = nodeList.Items
}
oldNodes, _ := sortNodesByTenantVMState(nodes, allWorkerInstances, cr, key.LegacyWorkerInstanceName)
r.logger.LogCtx(ctx, "level", "debug", "message", fmt.Sprintf("found %d nodes in the legacy VMSS", len(oldNodes))) // nolint: errcheck
r.logger.LogCtx(ctx, "level", "debug", "message", "ensuring old nodes are cordoned") // nolint: errcheck
oldNodesCordoned, err := r.ensureNodesCordoned(ctx, oldNodes)
if err != nil {
return "", microerror.Mask(err)
}
if oldNodesCordoned < len(oldNodes) {
r.logger.LogCtx(ctx, "level", "debug", "message", fmt.Sprintf("not all old nodes are still cordoned; %d pending", len(oldNodes)-oldNodesCordoned)) // nolint: errcheck
return currentState, nil
}
r.logger.LogCtx(ctx, "level", "debug", "message", fmt.Sprintf("ensured all old nodes (%d) are cordoned", oldNodesCordoned)) // nolint: errcheck
return WaitForWorkersToBecomeReady, nil
}