Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
99eadcc1
Unverified
Commit
99eadcc1
authored
Jul 21, 2021
by
David Nuzik
Committed by
GitHub
Jul 21, 2021
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3692 from galal-hussein/fix_multiple_bootstrap_keys_119
[Release-1.19] Fix multiple bootstrap keys found
parents
fc408211
970cb0cf
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
76 additions
and
24 deletions
+76
-24
storage.go
pkg/cluster/storage.go
+76
-24
No files found.
pkg/cluster/storage.go
View file @
99eadcc1
...
@@ -7,6 +7,7 @@ import (
...
@@ -7,6 +7,7 @@ import (
"io/ioutil"
"io/ioutil"
"os"
"os"
"path/filepath"
"path/filepath"
"strings"
"github.com/k3s-io/kine/pkg/client"
"github.com/k3s-io/kine/pkg/client"
"github.com/rancher/k3s/pkg/bootstrap"
"github.com/rancher/k3s/pkg/bootstrap"
...
@@ -45,14 +46,14 @@ func (c *Cluster) save(ctx context.Context) error {
...
@@ -45,14 +46,14 @@ func (c *Cluster) save(ctx context.Context) error {
return
err
return
err
}
}
_
,
_
,
err
=
c
.
getBootstrapKeyFromStorage
(
ctx
,
storageClient
,
normalizedT
oken
)
_
,
err
=
c
.
getBootstrapKeyFromStorage
(
ctx
,
storageClient
,
normalizedToken
,
t
oken
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
if
err
:=
storageClient
.
Create
(
ctx
,
storageKey
(
normalizedToken
),
data
);
err
!=
nil
{
if
err
:=
storageClient
.
Create
(
ctx
,
storageKey
(
normalizedToken
),
data
);
err
!=
nil
{
if
err
.
Error
()
==
"key exists"
{
if
err
.
Error
()
==
"key exists"
{
logrus
.
Warnln
(
"bootstrap key
exists; please follow documentation on updating a node after snapshot restore
"
)
logrus
.
Warnln
(
"bootstrap key
already exists
"
)
return
nil
return
nil
}
}
return
err
return
err
...
@@ -92,16 +93,14 @@ func (c *Cluster) storageBootstrap(ctx context.Context) error {
...
@@ -92,16 +93,14 @@ func (c *Cluster) storageBootstrap(ctx context.Context) error {
return
err
return
err
}
}
value
,
e
mptyKey
,
err
:=
c
.
getBootstrapKeyFromStorage
(
ctx
,
storageClient
,
normalizedT
oken
)
value
,
e
rr
:=
c
.
getBootstrapKeyFromStorage
(
ctx
,
storageClient
,
normalizedToken
,
t
oken
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
if
value
==
nil
{
if
value
==
nil
{
return
nil
return
nil
}
}
if
emptyKey
{
normalizedToken
=
""
}
data
,
err
:=
decrypt
(
normalizedToken
,
value
.
Data
)
data
,
err
:=
decrypt
(
normalizedToken
,
value
.
Data
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
...
@@ -114,36 +113,38 @@ func (c *Cluster) storageBootstrap(ctx context.Context) error {
...
@@ -114,36 +113,38 @@ func (c *Cluster) storageBootstrap(ctx context.Context) error {
// hashed with empty string and will check for any key that is hashed by different token than the one
// hashed with empty string and will check for any key that is hashed by different token than the one
// passed to it, it will return error if it finds a key that is hashed with different token and will return
// passed to it, it will return error if it finds a key that is hashed with different token and will return
// value if it finds the key hashed by passed token or empty string
// value if it finds the key hashed by passed token or empty string
func
(
c
*
Cluster
)
getBootstrapKeyFromStorage
(
ctx
context
.
Context
,
storageClient
client
.
Client
,
token
string
)
(
*
client
.
Value
,
bool
,
error
)
{
func
(
c
*
Cluster
)
getBootstrapKeyFromStorage
(
ctx
context
.
Context
,
storageClient
client
.
Client
,
normalizedToken
,
oldToken
string
)
(
*
client
.
Value
,
error
)
{
emptyStringKey
:=
storageKey
(
""
)
emptyStringKey
:=
storageKey
(
""
)
tokenKey
:=
storageKey
(
token
)
tokenKey
:=
storageKey
(
normalizedToken
)
bootstrapList
,
err
:=
storageClient
.
List
(
ctx
,
"/bootstrap"
,
0
)
bootstrapList
,
err
:=
storageClient
.
List
(
ctx
,
"/bootstrap"
,
0
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
false
,
err
return
nil
,
err
}
}
if
len
(
bootstrapList
)
==
0
{
if
len
(
bootstrapList
)
==
0
{
c
.
saveBootstrap
=
true
c
.
saveBootstrap
=
true
return
nil
,
false
,
nil
return
nil
,
nil
}
}
if
len
(
bootstrapList
)
>
1
{
if
len
(
bootstrapList
)
>
1
{
return
nil
,
false
,
errors
.
New
(
"found more than on
e bootstrap keys in storage"
)
logrus
.
Warn
(
"found multipl
e bootstrap keys in storage"
)
}
}
bootstrapKV
:=
bootstrapList
[
0
]
// check for empty string key and for old token format with k10 prefix
// checking for empty string bootstrap key
if
err
:=
c
.
migrateOldTokens
(
ctx
,
bootstrapList
,
storageClient
,
emptyStringKey
,
tokenKey
,
normalizedToken
,
oldToken
);
err
!=
nil
{
switch
string
(
bootstrapKV
.
Key
)
{
return
nil
,
err
case
emptyStringKey
:
}
logrus
.
Warn
(
"bootstrap data already found and encrypted with empty string, deleting empty key"
)
c
.
saveBootstrap
=
true
// getting the list of bootstrap again after migrating the empty key
if
err
:=
storageClient
.
Delete
(
ctx
,
emptyStringKey
,
bootstrapKV
.
Modified
);
err
!=
nil
{
bootstrapList
,
err
=
storageClient
.
List
(
ctx
,
"/bootstrap"
,
0
)
return
nil
,
false
,
err
if
err
!=
nil
{
return
nil
,
err
}
for
_
,
bootstrapKV
:=
range
bootstrapList
{
// ensure bootstrap is stored in the current token's key
if
string
(
bootstrapKV
.
Key
)
==
tokenKey
{
return
&
bootstrapKV
,
nil
}
}
return
&
bootstrapKV
,
true
,
nil
case
tokenKey
:
return
&
bootstrapKV
,
false
,
nil
}
}
return
nil
,
false
,
errors
.
New
(
"bootstrap data already found and encrypted with different token"
)
return
nil
,
errors
.
New
(
"bootstrap data already found and encrypted with different token"
)
}
}
// readTokenFromFile will attempt to get the token from <data-dir>/token if it the file not found
// readTokenFromFile will attempt to get the token from <data-dir>/token if it the file not found
...
@@ -175,3 +176,54 @@ func normalizeToken(token string) (string, error) {
...
@@ -175,3 +176,54 @@ func normalizeToken(token string) (string, error) {
}
}
return
password
,
nil
return
password
,
nil
}
}
// migrateOldTokens will list all keys that has prefix /bootstrap and will check for key that is
// hashed with empty string and keys that is hashed with old token format before normalizing
// then migrate those and resave only with the normalized token
func
(
c
*
Cluster
)
migrateOldTokens
(
ctx
context
.
Context
,
bootstrapList
[]
client
.
Value
,
storageClient
client
.
Client
,
emptyStringKey
,
tokenKey
,
token
,
oldToken
string
)
error
{
oldTokenKey
:=
storageKey
(
oldToken
)
for
_
,
bootstrapKV
:=
range
bootstrapList
{
// checking for empty string bootstrap key
if
string
(
bootstrapKV
.
Key
)
==
emptyStringKey
{
logrus
.
Warn
(
"bootstrap data encrypted with empty string, deleting and resaving with token"
)
if
err
:=
doMigrateToken
(
ctx
,
storageClient
,
bootstrapKV
,
""
,
emptyStringKey
,
token
,
tokenKey
);
err
!=
nil
{
return
err
}
}
else
if
string
(
bootstrapKV
.
Key
)
==
oldTokenKey
&&
oldTokenKey
!=
tokenKey
{
logrus
.
Warn
(
"bootstrap data encrypted with old token format string, deleting and resaving with token"
)
if
err
:=
doMigrateToken
(
ctx
,
storageClient
,
bootstrapKV
,
oldToken
,
oldTokenKey
,
token
,
tokenKey
);
err
!=
nil
{
return
err
}
}
}
return
nil
}
func
doMigrateToken
(
ctx
context
.
Context
,
storageClient
client
.
Client
,
keyValue
client
.
Value
,
oldToken
,
oldTokenKey
,
newToken
,
newTokenKey
string
)
error
{
// make sure that the process is non-destructive by decrypting/re-encrypting/storing the data before deleting the old key
data
,
err
:=
decrypt
(
oldToken
,
keyValue
.
Data
)
if
err
!=
nil
{
return
err
}
encryptedData
,
err
:=
encrypt
(
newToken
,
data
)
if
err
!=
nil
{
return
err
}
// saving the new encrypted data with the right token key
if
err
:=
storageClient
.
Create
(
ctx
,
newTokenKey
,
encryptedData
);
err
!=
nil
{
if
err
.
Error
()
==
"key exists"
{
logrus
.
Warn
(
"bootstrap key exists"
)
}
else
if
strings
.
Contains
(
err
.
Error
(),
"not supported for learner"
)
{
logrus
.
Debug
(
"skipping bootstrap data save on learner"
)
return
nil
}
else
{
return
err
}
}
logrus
.
Infof
(
"created bootstrap key %s"
,
newTokenKey
)
// deleting the old key
if
err
:=
storageClient
.
Delete
(
ctx
,
oldTokenKey
,
keyValue
.
Modified
);
err
!=
nil
{
logrus
.
Warnf
(
"failed to delete old bootstrap key %s"
,
oldTokenKey
)
}
return
nil
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment