Add CA data to service account tokens if missing or different

pull/6/head
Jordan Liggitt 2015-07-15 08:53:21 -04:00
parent fbc85e9838
commit c0bbdeda22
2 changed files with 74 additions and 12 deletions

View File

@ -17,6 +17,7 @@ limitations under the License.
package serviceaccount
import (
"bytes"
"fmt"
"time"
@ -336,22 +337,31 @@ func (e *TokensController) generateTokenIfNeeded(serviceAccount *api.ServiceAcco
secret.Data = map[string][]byte{}
}
tokenData, ok := secret.Data[api.ServiceAccountTokenKey]
if ok && len(tokenData) > 0 {
caData := secret.Data[api.ServiceAccountRootCAKey]
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
}
if e.rootCA != nil && len(e.rootCA) > 0 {
// Set the CA
if needsCA {
secret.Data[api.ServiceAccountRootCAKey] = e.rootCA
}
// Generate the token
token, err := e.token.GenerateToken(*serviceAccount, *secret)
if err != nil {
return err
if needsToken {
token, err := e.token.GenerateToken(*serviceAccount, *secret)
if err != nil {
return err
}
secret.Data[api.ServiceAccountTokenKey] = []byte(token)
}
// Set the token and annotations
secret.Data[api.ServiceAccountTokenKey] = []byte(token)
// Set annotations
secret.Annotations[api.ServiceAccountNameKey] = serviceAccount.Name
secret.Annotations[api.ServiceAccountUIDKey] = string(serviceAccount.UID)

View File

@ -107,7 +107,8 @@ func createdTokenSecret() *api.Secret {
},
Type: api.SecretTypeServiceAccountToken,
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,
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
func serviceAccountTokenSecretWithoutTokenData() *api.Secret {
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
}
@ -321,6 +337,24 @@ func TestTokenCreation(t *testing.T) {
{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": {
ClientObjects: []runtime.Object{serviceAccountTokenSecret()},
@ -346,6 +380,24 @@ func TestTokenCreation(t *testing.T) {
{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": {
DeletedSecret: serviceAccountTokenSecret(),
@ -378,7 +430,7 @@ func TestTokenCreation(t *testing.T) {
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
controller.serviceAccountsSynced = func() bool { return !tc.ServiceAccountsSyncPending }