@@ -19,10 +19,12 @@ package uploadconfig
19
19
import (
20
20
"fmt"
21
21
22
- "k8s.io/api/core/v1"
22
+ "github.com/pkg/errors"
23
+ v1 "k8s.io/api/core/v1"
23
24
rbac "k8s.io/api/rbac/v1"
24
25
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25
26
clientset "k8s.io/client-go/kubernetes"
27
+ "k8s.io/klog"
26
28
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
27
29
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
28
30
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
@@ -37,6 +39,69 @@ const (
37
39
NodesKubeadmConfigClusterRoleName = "kubeadm:nodes-kubeadm-config"
38
40
)
39
41
42
+ // ResetClusterStatusForNode removes the APIEndpoint of a given control-plane node
43
+ // from the ClusterStatus and updates the kubeadm ConfigMap
44
+ func ResetClusterStatusForNode (nodeName string , client clientset.Interface ) error {
45
+ fmt .Printf ("[reset] Removing info for node %q from the ConfigMap %q in the %q Namespace\n " ,
46
+ nodeName , kubeadmconstants .KubeadmConfigConfigMap , metav1 .NamespaceSystem )
47
+
48
+ // Get the kubeadm ConfigMap
49
+ configMap , err := client .CoreV1 ().ConfigMaps (metav1 .NamespaceSystem ).Get (kubeadmconstants .KubeadmConfigConfigMap , metav1.GetOptions {})
50
+ if err != nil {
51
+ return errors .Wrap (err , "failed to get config map" )
52
+ }
53
+
54
+ // Handle missing ClusterConfiguration in the ConfigMap. Should only happen if someone manually
55
+ // interacted with the ConfigMap.
56
+ clusterConfigurationYaml , ok := configMap .Data [kubeadmconstants .ClusterConfigurationConfigMapKey ]
57
+ if ! ok {
58
+ return errors .Errorf ("cannot find key %q in ConfigMap %q in the %q Namespace" ,
59
+ kubeadmconstants .ClusterConfigurationConfigMapKey , kubeadmconstants .KubeadmConfigConfigMap , metav1 .NamespaceSystem )
60
+ }
61
+
62
+ // Obtain the existing ClusterStatus object
63
+ clusterStatus , err := configutil .UnmarshalClusterStatus (configMap .Data )
64
+ if err != nil {
65
+ return err
66
+ }
67
+
68
+ // Handle a nil APIEndpoints map. Should only happen if someone manually
69
+ // interacted with the ConfigMap.
70
+ if clusterStatus .APIEndpoints == nil {
71
+ return errors .Errorf ("APIEndpoints from ConfigMap %q in the %q Namespace is nil" ,
72
+ kubeadmconstants .KubeadmConfigConfigMap , metav1 .NamespaceSystem )
73
+ }
74
+
75
+ // Check for existence of the nodeName key in the list of APIEndpoints.
76
+ // Return early if it's missing.
77
+ apiEndpoint , ok := clusterStatus .APIEndpoints [nodeName ]
78
+ if ! ok {
79
+ klog .Warningf ("No APIEndpoint registered for node %q" , nodeName )
80
+ return nil
81
+ }
82
+
83
+ klog .V (2 ).Infof ("Removing APIEndpoint %#v for node %q" , apiEndpoint , nodeName )
84
+ delete (clusterStatus .APIEndpoints , nodeName )
85
+
86
+ // Marshal the ClusterStatus back into YAML
87
+ clusterStatusYaml , err := configutil .MarshalKubeadmConfigObject (clusterStatus )
88
+ if err != nil {
89
+ return err
90
+ }
91
+
92
+ // Update the ClusterStatus in the ConfigMap
93
+ return apiclient .CreateOrUpdateConfigMap (client , & v1.ConfigMap {
94
+ ObjectMeta : metav1.ObjectMeta {
95
+ Name : kubeadmconstants .KubeadmConfigConfigMap ,
96
+ Namespace : metav1 .NamespaceSystem ,
97
+ },
98
+ Data : map [string ]string {
99
+ kubeadmconstants .ClusterConfigurationConfigMapKey : clusterConfigurationYaml ,
100
+ kubeadmconstants .ClusterStatusConfigMapKey : string (clusterStatusYaml ),
101
+ },
102
+ })
103
+ }
104
+
40
105
// UploadConfiguration saves the InitConfiguration used for later reference (when upgrading for instance)
41
106
func UploadConfiguration (cfg * kubeadmapi.InitConfiguration , client clientset.Interface ) error {
42
107
fmt .Printf ("[upload-config] storing the configuration used in ConfigMap %q in the %q Namespace\n " , kubeadmconstants .KubeadmConfigConfigMap , metav1 .NamespaceSystem )
0 commit comments