@@ -47,8 +47,66 @@ func IsMetaStoreOnly(store v2store.Store) (bool, error) {
4747 if err != nil {
4848 return false , err
4949 }
50+
51+ // storePermsPrefix is the internal prefix of the storage layer dedicated to storing user data.
52+ // refer to https://github.com/etcd-io/etcd/blob/v3.5.21/server/etcdserver/api/v2auth/auth.go#L40
53+ storePermsPrefix := "/2"
5054 for _ , n := range event .Node .Nodes {
51- if n .Key != storePrefix && n .Nodes .Len () > 0 {
55+ if n .Key == storePrefix {
56+ continue
57+ }
58+
59+ // For auth data, even after we remove all users and roles, the node
60+ // "/2/roles" and "/2/users" are still present in the tree. We need
61+ // to exclude such case. See an example below,
62+ // Refer to https://github.com/etcd-io/etcd/discussions/20231#discussioncomment-13791940
63+ /*
64+ "2": {
65+ "Path": "/2",
66+ "CreatedIndex": 204749,
67+ "ModifiedIndex": 204749,
68+ "ExpireTime": "0001-01-01T00:00:00Z",
69+ "Value": "",
70+ "Children": {
71+ "enabled": {
72+ "Path": "/2/enabled",
73+ "CreatedIndex": 204752,
74+ "ModifiedIndex": 16546016,
75+ "ExpireTime": "0001-01-01T00:00:00Z",
76+ "Value": "false",
77+ "Children": null
78+ },
79+ "roles": {
80+ "Path": "/2/roles",
81+ "CreatedIndex": 204751,
82+ "ModifiedIndex": 204751,
83+ "ExpireTime": "0001-01-01T00:00:00Z",
84+ "Value": "",
85+ "Children": {}
86+ },
87+ "users": {
88+ "Path": "/2/users",
89+ "CreatedIndex": 204750,
90+ "ModifiedIndex": 204750,
91+ "ExpireTime": "0001-01-01T00:00:00Z",
92+ "Value": "",
93+ "Children": {}
94+ }
95+ }
96+ }
97+ */
98+ if n .Key == storePermsPrefix {
99+ if n .Nodes .Len () > 0 {
100+ for _ , child := range n .Nodes {
101+ if child .Nodes .Len () > 0 {
102+ return false , nil
103+ }
104+ }
105+ }
106+ continue
107+ }
108+
109+ if n .Nodes .Len () > 0 {
52110 return false , nil
53111 }
54112 }
0 commit comments