mirror of https://github.com/k3s-io/k3s
Merge pull request #11303 from liggitt/token_ca
Add CA data to service account token secrets if missing or differentpull/6/head
commit
b4626a1635
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||||
package serviceaccount
|
package serviceaccount
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -336,22 +337,31 @@ func (e *TokensController) generateTokenIfNeeded(serviceAccount *api.ServiceAcco
|
||||||
secret.Data = map[string][]byte{}
|
secret.Data = map[string][]byte{}
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenData, ok := secret.Data[api.ServiceAccountTokenKey]
|
caData := secret.Data[api.ServiceAccountRootCAKey]
|
||||||
if ok && len(tokenData) > 0 {
|
needsCA := len(e.rootCA) > 0 && bytes.Compare(caData, e.rootCA) != 0
|
||||||
|
|
||||||
|
tokenData := secret.Data[api.ServiceAccountTokenKey]
|
||||||
|
needsToken := len(tokenData) == 0
|
||||||
|
|
||||||
|
if !needsCA && !needsToken {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if e.rootCA != nil && len(e.rootCA) > 0 {
|
|
||||||
|
// Set the CA
|
||||||
|
if needsCA {
|
||||||
secret.Data[api.ServiceAccountRootCAKey] = e.rootCA
|
secret.Data[api.ServiceAccountRootCAKey] = e.rootCA
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the token
|
// Generate the token
|
||||||
token, err := e.token.GenerateToken(*serviceAccount, *secret)
|
if needsToken {
|
||||||
if err != nil {
|
token, err := e.token.GenerateToken(*serviceAccount, *secret)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
secret.Data[api.ServiceAccountTokenKey] = []byte(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the token and annotations
|
// Set annotations
|
||||||
secret.Data[api.ServiceAccountTokenKey] = []byte(token)
|
|
||||||
secret.Annotations[api.ServiceAccountNameKey] = serviceAccount.Name
|
secret.Annotations[api.ServiceAccountNameKey] = serviceAccount.Name
|
||||||
secret.Annotations[api.ServiceAccountUIDKey] = string(serviceAccount.UID)
|
secret.Annotations[api.ServiceAccountUIDKey] = string(serviceAccount.UID)
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,8 @@ func createdTokenSecret() *api.Secret {
|
||||||
},
|
},
|
||||||
Type: api.SecretTypeServiceAccountToken,
|
Type: api.SecretTypeServiceAccountToken,
|
||||||
Data: map[string][]byte{
|
Data: map[string][]byte{
|
||||||
"token": []byte("ABC"),
|
"token": []byte("ABC"),
|
||||||
|
"ca.crt": []byte("CA Data"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +128,8 @@ func serviceAccountTokenSecret() *api.Secret {
|
||||||
},
|
},
|
||||||
Type: api.SecretTypeServiceAccountToken,
|
Type: api.SecretTypeServiceAccountToken,
|
||||||
Data: map[string][]byte{
|
Data: map[string][]byte{
|
||||||
"token": []byte("ABC"),
|
"token": []byte("ABC"),
|
||||||
|
"ca.crt": []byte("CA Data"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,7 +137,21 @@ func serviceAccountTokenSecret() *api.Secret {
|
||||||
// serviceAccountTokenSecretWithoutTokenData returns an existing ServiceAccountToken secret that lacks token data
|
// serviceAccountTokenSecretWithoutTokenData returns an existing ServiceAccountToken secret that lacks token data
|
||||||
func serviceAccountTokenSecretWithoutTokenData() *api.Secret {
|
func serviceAccountTokenSecretWithoutTokenData() *api.Secret {
|
||||||
secret := serviceAccountTokenSecret()
|
secret := serviceAccountTokenSecret()
|
||||||
secret.Data = nil
|
delete(secret.Data, api.ServiceAccountTokenKey)
|
||||||
|
return secret
|
||||||
|
}
|
||||||
|
|
||||||
|
// serviceAccountTokenSecretWithoutCAData returns an existing ServiceAccountToken secret that lacks ca data
|
||||||
|
func serviceAccountTokenSecretWithoutCAData() *api.Secret {
|
||||||
|
secret := serviceAccountTokenSecret()
|
||||||
|
delete(secret.Data, api.ServiceAccountRootCAKey)
|
||||||
|
return secret
|
||||||
|
}
|
||||||
|
|
||||||
|
// serviceAccountTokenSecretWithCAData returns an existing ServiceAccountToken secret with the specified ca data
|
||||||
|
func serviceAccountTokenSecretWithCAData(data []byte) *api.Secret {
|
||||||
|
secret := serviceAccountTokenSecret()
|
||||||
|
secret.Data[api.ServiceAccountRootCAKey] = data
|
||||||
return secret
|
return secret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,6 +337,24 @@ func TestTokenCreation(t *testing.T) {
|
||||||
{Action: "update-secret", Value: serviceAccountTokenSecret()},
|
{Action: "update-secret", Value: serviceAccountTokenSecret()},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"added token secret without ca data": {
|
||||||
|
ClientObjects: []runtime.Object{serviceAccountTokenSecretWithoutCAData()},
|
||||||
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
||||||
|
|
||||||
|
AddedSecret: serviceAccountTokenSecretWithoutCAData(),
|
||||||
|
ExpectedActions: []testclient.FakeAction{
|
||||||
|
{Action: "update-secret", Value: serviceAccountTokenSecret()},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"added token secret with mismatched ca data": {
|
||||||
|
ClientObjects: []runtime.Object{serviceAccountTokenSecretWithCAData([]byte("mismatched"))},
|
||||||
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
||||||
|
|
||||||
|
AddedSecret: serviceAccountTokenSecretWithCAData([]byte("mismatched")),
|
||||||
|
ExpectedActions: []testclient.FakeAction{
|
||||||
|
{Action: "update-secret", Value: serviceAccountTokenSecret()},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
"updated secret without serviceaccount": {
|
"updated secret without serviceaccount": {
|
||||||
ClientObjects: []runtime.Object{serviceAccountTokenSecret()},
|
ClientObjects: []runtime.Object{serviceAccountTokenSecret()},
|
||||||
|
@ -346,6 +380,24 @@ func TestTokenCreation(t *testing.T) {
|
||||||
{Action: "update-secret", Value: serviceAccountTokenSecret()},
|
{Action: "update-secret", Value: serviceAccountTokenSecret()},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"updated token secret without ca data": {
|
||||||
|
ClientObjects: []runtime.Object{serviceAccountTokenSecretWithoutCAData()},
|
||||||
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
||||||
|
|
||||||
|
UpdatedSecret: serviceAccountTokenSecretWithoutCAData(),
|
||||||
|
ExpectedActions: []testclient.FakeAction{
|
||||||
|
{Action: "update-secret", Value: serviceAccountTokenSecret()},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"updated token secret with mismatched ca data": {
|
||||||
|
ClientObjects: []runtime.Object{serviceAccountTokenSecretWithCAData([]byte("mismatched"))},
|
||||||
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
||||||
|
|
||||||
|
UpdatedSecret: serviceAccountTokenSecretWithCAData([]byte("mismatched")),
|
||||||
|
ExpectedActions: []testclient.FakeAction{
|
||||||
|
{Action: "update-secret", Value: serviceAccountTokenSecret()},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
"deleted secret without serviceaccount": {
|
"deleted secret without serviceaccount": {
|
||||||
DeletedSecret: serviceAccountTokenSecret(),
|
DeletedSecret: serviceAccountTokenSecret(),
|
||||||
|
@ -378,7 +430,7 @@ func TestTokenCreation(t *testing.T) {
|
||||||
|
|
||||||
client := testclient.NewSimpleFake(tc.ClientObjects...)
|
client := testclient.NewSimpleFake(tc.ClientObjects...)
|
||||||
|
|
||||||
controller := NewTokensController(client, TokensControllerOptions{TokenGenerator: generator})
|
controller := NewTokensController(client, TokensControllerOptions{TokenGenerator: generator, RootCA: []byte("CA Data")})
|
||||||
|
|
||||||
// Tell the token controller whether its stores have been synced
|
// Tell the token controller whether its stores have been synced
|
||||||
controller.serviceAccountsSynced = func() bool { return !tc.ServiceAccountsSyncPending }
|
controller.serviceAccountsSynced = func() bool { return !tc.ServiceAccountsSyncPending }
|
||||||
|
|
Loading…
Reference in New Issue