@@ -17,21 +17,27 @@ limitations under the License.
17
17
package etcd
18
18
19
19
import (
20
+ "errors"
20
21
"fmt"
22
+ "net"
23
+ "net/url"
21
24
22
25
"github.com/k0sproject/k0s/pkg/config"
23
26
"github.com/k0sproject/k0s/pkg/etcd"
24
27
28
+ "github.com/asaskevich/govalidator"
25
29
"github.com/sirupsen/logrus"
26
30
"github.com/spf13/cobra"
31
+ "github.com/spf13/pflag"
27
32
)
28
33
29
34
func etcdLeaveCmd () * cobra.Command {
30
- var etcdPeerAddress string
35
+ var peerAddressArg string
31
36
32
37
cmd := & cobra.Command {
33
38
Use : "leave" ,
34
- Short : "Sign off a given etc node from etcd cluster" ,
39
+ Short : "Leave the etcd cluster, or remove a specific peer" ,
40
+ Args : cobra .NoArgs , // accept peer address via flag, not via arg
35
41
RunE : func (cmd * cobra.Command , args []string ) error {
36
42
opts , err := config .GetCmdOpts (cmd )
37
43
if err != nil {
@@ -42,14 +48,17 @@ func etcdLeaveCmd() *cobra.Command {
42
48
return err
43
49
}
44
50
ctx := cmd .Context ()
45
- if etcdPeerAddress == "" {
46
- etcdPeerAddress = nodeConfig .Spec .Storage .Etcd .PeerAddress
47
- }
48
- if etcdPeerAddress == "" {
49
- return fmt .Errorf ("can't leave etcd cluster: peer address is empty, check the config file or use cli argument" )
51
+
52
+ peerAddress := nodeConfig .Spec .Storage .Etcd .PeerAddress
53
+ if peerAddressArg == "" {
54
+ if peerAddress == "" {
55
+ return fmt .Errorf ("can't leave etcd cluster: this node doesn't have an etcd peer address, check the k0s configuration or use --peer-address" )
56
+ }
57
+ } else {
58
+ peerAddress = peerAddressArg
50
59
}
51
60
52
- peerURL := fmt . Sprintf ( "https://%s:2380 " , etcdPeerAddress )
61
+ peerURL := ( & url. URL { Scheme : "https" , Host : net . JoinHostPort ( peerAddress , "2380" )}). String ( )
53
62
etcdClient , err := etcd .NewClient (opts .K0sVars .CertRootDir , opts .K0sVars .EtcdCertDir , nodeConfig .Spec .Storage .Etcd )
54
63
if err != nil {
55
64
return fmt .Errorf ("can't connect to the etcd: %w" , err )
@@ -64,19 +73,38 @@ func etcdLeaveCmd() *cobra.Command {
64
73
if err := etcdClient .DeleteMember (ctx , peerID ); err != nil {
65
74
logrus .
66
75
WithField ("peerURL" , peerURL ).
67
- WithField ("peerID" , peerID ).
76
+ WithField ("peerID" , fmt . Sprintf ( "%x" , peerID ) ).
68
77
Errorf ("Failed to delete node from cluster" )
69
78
return err
70
79
}
71
80
72
81
logrus .
73
- WithField ("peerID" , peerID ).
82
+ WithField ("peerID" , fmt . Sprintf ( "%x" , peerID ) ).
74
83
Info ("Successfully deleted" )
75
84
return nil
76
85
},
77
86
}
78
87
79
- cmd .Flags ().StringVar (& etcdPeerAddress , "peer-address" , "" , "etcd peer address" )
88
+ cmd .Flags ().AddFlag (& pflag.Flag {
89
+ Name : "peer-address" ,
90
+ Usage : "etcd peer address to remove (default <this node's peer address>)" ,
91
+ Value : (* ipOrDNSName )(& peerAddressArg ),
92
+ })
93
+
80
94
cmd .PersistentFlags ().AddFlagSet (config .GetPersistentFlagSet ())
81
95
return cmd
82
96
}
97
+
98
+ type ipOrDNSName string
99
+
100
+ func (i * ipOrDNSName ) Type () string { return "ip-or-dns-name" }
101
+ func (i * ipOrDNSName ) String () string { return string (* i ) }
102
+
103
+ func (i * ipOrDNSName ) Set (value string ) error {
104
+ if ! govalidator .IsIP (value ) && ! govalidator .IsDNSName (value ) {
105
+ return errors .New ("neither an IP address nor a DNS name" )
106
+ }
107
+
108
+ * i = ipOrDNSName (value )
109
+ return nil
110
+ }
0 commit comments