2015-04-21 03:25:56 +00:00
|
|
|
/*
|
|
|
|
Copyright 2014 The Kubernetes Authors All rights reserved.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package serviceaccount
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
|
2015-08-05 22:03:47 +00:00
|
|
|
"k8s.io/kubernetes/pkg/api"
|
2016-02-16 22:16:45 +00:00
|
|
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
|
2016-01-29 06:34:08 +00:00
|
|
|
"k8s.io/kubernetes/pkg/client/testing/core"
|
2015-08-05 22:03:47 +00:00
|
|
|
"k8s.io/kubernetes/pkg/runtime"
|
|
|
|
utilrand "k8s.io/kubernetes/pkg/util/rand"
|
2015-04-21 03:25:56 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type testGenerator struct {
|
|
|
|
GeneratedServiceAccounts []api.ServiceAccount
|
|
|
|
GeneratedSecrets []api.Secret
|
|
|
|
Token string
|
|
|
|
Err error
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *testGenerator) GenerateToken(serviceAccount api.ServiceAccount, secret api.Secret) (string, error) {
|
|
|
|
t.GeneratedSecrets = append(t.GeneratedSecrets, secret)
|
|
|
|
t.GeneratedServiceAccounts = append(t.GeneratedServiceAccounts, serviceAccount)
|
|
|
|
return t.Token, t.Err
|
|
|
|
}
|
|
|
|
|
|
|
|
// emptySecretReferences is used by a service account without any secrets
|
|
|
|
func emptySecretReferences() []api.ObjectReference {
|
|
|
|
return []api.ObjectReference{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// missingSecretReferences is used by a service account that references secrets which do no exist
|
|
|
|
func missingSecretReferences() []api.ObjectReference {
|
|
|
|
return []api.ObjectReference{{Name: "missing-secret-1"}}
|
|
|
|
}
|
|
|
|
|
|
|
|
// regularSecretReferences is used by a service account that references secrets which are not ServiceAccountTokens
|
|
|
|
func regularSecretReferences() []api.ObjectReference {
|
|
|
|
return []api.ObjectReference{{Name: "regular-secret-1"}}
|
|
|
|
}
|
|
|
|
|
|
|
|
// tokenSecretReferences is used by a service account that references a ServiceAccountToken secret
|
|
|
|
func tokenSecretReferences() []api.ObjectReference {
|
|
|
|
return []api.ObjectReference{{Name: "token-secret-1"}}
|
|
|
|
}
|
|
|
|
|
|
|
|
// addTokenSecretReference adds a reference to the ServiceAccountToken that will be created
|
|
|
|
func addTokenSecretReference(refs []api.ObjectReference) []api.ObjectReference {
|
|
|
|
return append(refs, api.ObjectReference{Name: "default-token-fplln"})
|
|
|
|
}
|
|
|
|
|
|
|
|
// serviceAccount returns a service account with the given secret refs
|
|
|
|
func serviceAccount(secretRefs []api.ObjectReference) *api.ServiceAccount {
|
|
|
|
return &api.ServiceAccount{
|
|
|
|
ObjectMeta: api.ObjectMeta{
|
|
|
|
Name: "default",
|
|
|
|
UID: "12345",
|
|
|
|
Namespace: "default",
|
|
|
|
ResourceVersion: "1",
|
|
|
|
},
|
|
|
|
Secrets: secretRefs,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-02 05:36:18 +00:00
|
|
|
// updatedServiceAccount returns a service account with the resource version modified
|
|
|
|
func updatedServiceAccount(secretRefs []api.ObjectReference) *api.ServiceAccount {
|
|
|
|
sa := serviceAccount(secretRefs)
|
|
|
|
sa.ResourceVersion = "2"
|
|
|
|
return sa
|
|
|
|
}
|
|
|
|
|
2015-04-21 03:25:56 +00:00
|
|
|
// opaqueSecret returns a persisted non-ServiceAccountToken secret named "regular-secret-1"
|
|
|
|
func opaqueSecret() *api.Secret {
|
|
|
|
return &api.Secret{
|
|
|
|
ObjectMeta: api.ObjectMeta{
|
|
|
|
Name: "regular-secret-1",
|
|
|
|
Namespace: "default",
|
|
|
|
UID: "23456",
|
|
|
|
ResourceVersion: "1",
|
|
|
|
},
|
|
|
|
Type: "Opaque",
|
|
|
|
Data: map[string][]byte{
|
|
|
|
"mykey": []byte("mydata"),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// createdTokenSecret returns the ServiceAccountToken secret posted when creating a new token secret.
|
|
|
|
// Named "default-token-fplln", since that is the first generated name after rand.Seed(1)
|
|
|
|
func createdTokenSecret() *api.Secret {
|
|
|
|
return &api.Secret{
|
|
|
|
ObjectMeta: api.ObjectMeta{
|
|
|
|
Name: "default-token-fplln",
|
|
|
|
Namespace: "default",
|
|
|
|
Annotations: map[string]string{
|
|
|
|
api.ServiceAccountNameKey: "default",
|
|
|
|
api.ServiceAccountUIDKey: "12345",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Type: api.SecretTypeServiceAccountToken,
|
|
|
|
Data: map[string][]byte{
|
2016-02-11 19:46:56 +00:00
|
|
|
"token": []byte("ABC"),
|
|
|
|
"ca.crt": []byte("CA Data"),
|
|
|
|
"namespace": []byte("default"),
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// serviceAccountTokenSecret returns an existing ServiceAccountToken secret named "token-secret-1"
|
|
|
|
func serviceAccountTokenSecret() *api.Secret {
|
|
|
|
return &api.Secret{
|
|
|
|
ObjectMeta: api.ObjectMeta{
|
|
|
|
Name: "token-secret-1",
|
|
|
|
Namespace: "default",
|
|
|
|
UID: "23456",
|
|
|
|
ResourceVersion: "1",
|
|
|
|
Annotations: map[string]string{
|
|
|
|
api.ServiceAccountNameKey: "default",
|
|
|
|
api.ServiceAccountUIDKey: "12345",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Type: api.SecretTypeServiceAccountToken,
|
|
|
|
Data: map[string][]byte{
|
2016-02-11 19:46:56 +00:00
|
|
|
"token": []byte("ABC"),
|
|
|
|
"ca.crt": []byte("CA Data"),
|
|
|
|
"namespace": []byte("default"),
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// serviceAccountTokenSecretWithoutTokenData returns an existing ServiceAccountToken secret that lacks token data
|
|
|
|
func serviceAccountTokenSecretWithoutTokenData() *api.Secret {
|
|
|
|
secret := serviceAccountTokenSecret()
|
2015-07-15 12:53:21 +00:00
|
|
|
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
|
2015-04-21 03:25:56 +00:00
|
|
|
return secret
|
|
|
|
}
|
|
|
|
|
2016-02-11 19:46:56 +00:00
|
|
|
// serviceAccountTokenSecretWithoutNamespaceData returns an existing ServiceAccountToken secret that lacks namespace data
|
|
|
|
func serviceAccountTokenSecretWithoutNamespaceData() *api.Secret {
|
|
|
|
secret := serviceAccountTokenSecret()
|
|
|
|
delete(secret.Data, api.ServiceAccountNamespaceKey)
|
|
|
|
return secret
|
|
|
|
}
|
|
|
|
|
|
|
|
// serviceAccountTokenSecretWithNamespaceData returns an existing ServiceAccountToken secret with the specified namespace data
|
|
|
|
func serviceAccountTokenSecretWithNamespaceData(data []byte) *api.Secret {
|
|
|
|
secret := serviceAccountTokenSecret()
|
|
|
|
secret.Data[api.ServiceAccountNamespaceKey] = data
|
|
|
|
return secret
|
|
|
|
}
|
|
|
|
|
2015-04-21 03:25:56 +00:00
|
|
|
func TestTokenCreation(t *testing.T) {
|
|
|
|
testcases := map[string]struct {
|
|
|
|
ClientObjects []runtime.Object
|
|
|
|
|
2015-06-05 18:21:28 +00:00
|
|
|
SecretsSyncPending bool
|
|
|
|
ServiceAccountsSyncPending bool
|
|
|
|
|
2015-04-21 03:25:56 +00:00
|
|
|
ExistingServiceAccount *api.ServiceAccount
|
|
|
|
ExistingSecrets []*api.Secret
|
|
|
|
|
|
|
|
AddedServiceAccount *api.ServiceAccount
|
|
|
|
UpdatedServiceAccount *api.ServiceAccount
|
|
|
|
DeletedServiceAccount *api.ServiceAccount
|
|
|
|
AddedSecret *api.Secret
|
|
|
|
UpdatedSecret *api.Secret
|
|
|
|
DeletedSecret *api.Secret
|
|
|
|
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions []core.Action
|
2015-04-21 03:25:56 +00:00
|
|
|
}{
|
|
|
|
"new serviceaccount with no secrets": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccount(emptySecretReferences()), createdTokenSecret()},
|
|
|
|
|
|
|
|
AddedServiceAccount: serviceAccount(emptySecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewGetAction("serviceaccounts", api.NamespaceDefault, "default"),
|
|
|
|
core.NewCreateAction("secrets", api.NamespaceDefault, createdTokenSecret()),
|
|
|
|
core.NewUpdateAction("serviceaccounts", api.NamespaceDefault, serviceAccount(addTokenSecretReference(emptySecretReferences()))),
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
},
|
2015-06-05 18:21:28 +00:00
|
|
|
"new serviceaccount with no secrets with unsynced secret store": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccount(emptySecretReferences()), createdTokenSecret()},
|
|
|
|
|
|
|
|
SecretsSyncPending: true,
|
|
|
|
|
|
|
|
AddedServiceAccount: serviceAccount(emptySecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewGetAction("serviceaccounts", api.NamespaceDefault, "default"),
|
|
|
|
core.NewCreateAction("secrets", api.NamespaceDefault, createdTokenSecret()),
|
|
|
|
core.NewUpdateAction("serviceaccounts", api.NamespaceDefault, serviceAccount(addTokenSecretReference(emptySecretReferences()))),
|
2015-06-05 18:21:28 +00:00
|
|
|
},
|
|
|
|
},
|
2015-04-21 03:25:56 +00:00
|
|
|
"new serviceaccount with missing secrets": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccount(missingSecretReferences()), createdTokenSecret()},
|
|
|
|
|
|
|
|
AddedServiceAccount: serviceAccount(missingSecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewGetAction("serviceaccounts", api.NamespaceDefault, "default"),
|
|
|
|
core.NewCreateAction("secrets", api.NamespaceDefault, createdTokenSecret()),
|
|
|
|
core.NewUpdateAction("serviceaccounts", api.NamespaceDefault, serviceAccount(addTokenSecretReference(missingSecretReferences()))),
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
},
|
2015-06-05 18:21:28 +00:00
|
|
|
"new serviceaccount with missing secrets with unsynced secret store": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccount(missingSecretReferences()), createdTokenSecret()},
|
|
|
|
|
|
|
|
SecretsSyncPending: true,
|
|
|
|
|
|
|
|
AddedServiceAccount: serviceAccount(missingSecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{},
|
2015-06-05 18:21:28 +00:00
|
|
|
},
|
2015-04-21 03:25:56 +00:00
|
|
|
"new serviceaccount with non-token secrets": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccount(regularSecretReferences()), createdTokenSecret(), opaqueSecret()},
|
|
|
|
|
|
|
|
AddedServiceAccount: serviceAccount(regularSecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewGetAction("serviceaccounts", api.NamespaceDefault, "default"),
|
|
|
|
core.NewCreateAction("secrets", api.NamespaceDefault, createdTokenSecret()),
|
|
|
|
core.NewUpdateAction("serviceaccounts", api.NamespaceDefault, serviceAccount(addTokenSecretReference(regularSecretReferences()))),
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
"new serviceaccount with token secrets": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccount(tokenSecretReferences()), serviceAccountTokenSecret()},
|
|
|
|
ExistingSecrets: []*api.Secret{serviceAccountTokenSecret()},
|
|
|
|
|
|
|
|
AddedServiceAccount: serviceAccount(tokenSecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{},
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
2015-06-02 05:36:18 +00:00
|
|
|
"new serviceaccount with no secrets with resource conflict": {
|
|
|
|
ClientObjects: []runtime.Object{updatedServiceAccount(emptySecretReferences()), createdTokenSecret()},
|
|
|
|
|
|
|
|
AddedServiceAccount: serviceAccount(emptySecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewGetAction("serviceaccounts", api.NamespaceDefault, "default"),
|
2015-06-02 05:36:18 +00:00
|
|
|
},
|
|
|
|
},
|
2015-04-21 03:25:56 +00:00
|
|
|
|
|
|
|
"updated serviceaccount with no secrets": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccount(emptySecretReferences()), createdTokenSecret()},
|
|
|
|
|
|
|
|
UpdatedServiceAccount: serviceAccount(emptySecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewGetAction("serviceaccounts", api.NamespaceDefault, "default"),
|
|
|
|
core.NewCreateAction("secrets", api.NamespaceDefault, createdTokenSecret()),
|
|
|
|
core.NewUpdateAction("serviceaccounts", api.NamespaceDefault, serviceAccount(addTokenSecretReference(emptySecretReferences()))),
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
},
|
2015-06-05 18:21:28 +00:00
|
|
|
"updated serviceaccount with no secrets with unsynced secret store": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccount(emptySecretReferences()), createdTokenSecret()},
|
|
|
|
|
|
|
|
SecretsSyncPending: true,
|
|
|
|
|
|
|
|
UpdatedServiceAccount: serviceAccount(emptySecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewGetAction("serviceaccounts", api.NamespaceDefault, "default"),
|
|
|
|
core.NewCreateAction("secrets", api.NamespaceDefault, createdTokenSecret()),
|
|
|
|
core.NewUpdateAction("serviceaccounts", api.NamespaceDefault, serviceAccount(addTokenSecretReference(emptySecretReferences()))),
|
2015-06-05 18:21:28 +00:00
|
|
|
},
|
|
|
|
},
|
2015-04-21 03:25:56 +00:00
|
|
|
"updated serviceaccount with missing secrets": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccount(missingSecretReferences()), createdTokenSecret()},
|
|
|
|
|
|
|
|
UpdatedServiceAccount: serviceAccount(missingSecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewGetAction("serviceaccounts", api.NamespaceDefault, "default"),
|
|
|
|
core.NewCreateAction("secrets", api.NamespaceDefault, createdTokenSecret()),
|
|
|
|
core.NewUpdateAction("serviceaccounts", api.NamespaceDefault, serviceAccount(addTokenSecretReference(missingSecretReferences()))),
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
},
|
2015-06-05 18:21:28 +00:00
|
|
|
"updated serviceaccount with missing secrets with unsynced secret store": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccount(missingSecretReferences()), createdTokenSecret()},
|
|
|
|
|
|
|
|
SecretsSyncPending: true,
|
|
|
|
|
|
|
|
UpdatedServiceAccount: serviceAccount(missingSecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{},
|
2015-06-05 18:21:28 +00:00
|
|
|
},
|
2015-04-21 03:25:56 +00:00
|
|
|
"updated serviceaccount with non-token secrets": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccount(regularSecretReferences()), createdTokenSecret(), opaqueSecret()},
|
|
|
|
|
|
|
|
UpdatedServiceAccount: serviceAccount(regularSecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewGetAction("serviceaccounts", api.NamespaceDefault, "default"),
|
|
|
|
core.NewCreateAction("secrets", api.NamespaceDefault, createdTokenSecret()),
|
|
|
|
core.NewUpdateAction("serviceaccounts", api.NamespaceDefault, serviceAccount(addTokenSecretReference(regularSecretReferences()))),
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
"updated serviceaccount with token secrets": {
|
|
|
|
ExistingSecrets: []*api.Secret{serviceAccountTokenSecret()},
|
|
|
|
|
|
|
|
UpdatedServiceAccount: serviceAccount(tokenSecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{},
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
2015-06-02 05:36:18 +00:00
|
|
|
"updated serviceaccount with no secrets with resource conflict": {
|
|
|
|
ClientObjects: []runtime.Object{updatedServiceAccount(emptySecretReferences()), createdTokenSecret()},
|
|
|
|
|
|
|
|
UpdatedServiceAccount: serviceAccount(emptySecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewGetAction("serviceaccounts", api.NamespaceDefault, "default"),
|
2015-06-02 05:36:18 +00:00
|
|
|
},
|
|
|
|
},
|
2015-04-21 03:25:56 +00:00
|
|
|
|
|
|
|
"deleted serviceaccount with no secrets": {
|
|
|
|
DeletedServiceAccount: serviceAccount(emptySecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{},
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
"deleted serviceaccount with missing secrets": {
|
|
|
|
DeletedServiceAccount: serviceAccount(missingSecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{},
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
"deleted serviceaccount with non-token secrets": {
|
|
|
|
ClientObjects: []runtime.Object{opaqueSecret()},
|
|
|
|
|
|
|
|
DeletedServiceAccount: serviceAccount(regularSecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{},
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
"deleted serviceaccount with token secrets": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccountTokenSecret()},
|
|
|
|
ExistingSecrets: []*api.Secret{serviceAccountTokenSecret()},
|
|
|
|
|
|
|
|
DeletedServiceAccount: serviceAccount(tokenSecretReferences()),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewDeleteAction("secrets", api.NamespaceDefault, "token-secret-1"),
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
"added secret without serviceaccount": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccountTokenSecret()},
|
|
|
|
|
|
|
|
AddedSecret: serviceAccountTokenSecret(),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewGetAction("serviceaccounts", api.NamespaceDefault, "default"),
|
|
|
|
core.NewDeleteAction("secrets", api.NamespaceDefault, "token-secret-1"),
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
"added secret with serviceaccount": {
|
|
|
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
|
|
|
|
|
|
|
AddedSecret: serviceAccountTokenSecret(),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{},
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
"added token secret without token data": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccountTokenSecretWithoutTokenData()},
|
|
|
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
|
|
|
|
|
|
|
AddedSecret: serviceAccountTokenSecretWithoutTokenData(),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewUpdateAction("secrets", api.NamespaceDefault, serviceAccountTokenSecret()),
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
},
|
2015-07-15 12:53:21 +00:00
|
|
|
"added token secret without ca data": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccountTokenSecretWithoutCAData()},
|
|
|
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
|
|
|
|
|
|
|
AddedSecret: serviceAccountTokenSecretWithoutCAData(),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewUpdateAction("secrets", api.NamespaceDefault, serviceAccountTokenSecret()),
|
2015-07-15 12:53:21 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
"added token secret with mismatched ca data": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccountTokenSecretWithCAData([]byte("mismatched"))},
|
|
|
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
|
|
|
|
|
|
|
AddedSecret: serviceAccountTokenSecretWithCAData([]byte("mismatched")),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewUpdateAction("secrets", api.NamespaceDefault, serviceAccountTokenSecret()),
|
2015-07-15 12:53:21 +00:00
|
|
|
},
|
|
|
|
},
|
2016-02-11 19:46:56 +00:00
|
|
|
"added token secret without namespace data": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccountTokenSecretWithoutNamespaceData()},
|
|
|
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
|
|
|
|
|
|
|
AddedSecret: serviceAccountTokenSecretWithoutNamespaceData(),
|
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewUpdateAction("secrets", api.NamespaceDefault, serviceAccountTokenSecret()),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"added token secret with custom namespace data": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccountTokenSecretWithNamespaceData([]byte("custom"))},
|
|
|
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
|
|
|
|
|
|
|
AddedSecret: serviceAccountTokenSecretWithNamespaceData([]byte("custom")),
|
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
// no update is performed... the custom namespace is preserved
|
|
|
|
},
|
|
|
|
},
|
2015-04-21 03:25:56 +00:00
|
|
|
|
|
|
|
"updated secret without serviceaccount": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccountTokenSecret()},
|
|
|
|
|
|
|
|
UpdatedSecret: serviceAccountTokenSecret(),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewGetAction("serviceaccounts", api.NamespaceDefault, "default"),
|
|
|
|
core.NewDeleteAction("secrets", api.NamespaceDefault, "token-secret-1"),
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
"updated secret with serviceaccount": {
|
|
|
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
|
|
|
|
|
|
|
UpdatedSecret: serviceAccountTokenSecret(),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{},
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
"updated token secret without token data": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccountTokenSecretWithoutTokenData()},
|
|
|
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
|
|
|
|
|
|
|
UpdatedSecret: serviceAccountTokenSecretWithoutTokenData(),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewUpdateAction("secrets", api.NamespaceDefault, serviceAccountTokenSecret()),
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
},
|
2015-07-15 12:53:21 +00:00
|
|
|
"updated token secret without ca data": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccountTokenSecretWithoutCAData()},
|
|
|
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
|
|
|
|
|
|
|
UpdatedSecret: serviceAccountTokenSecretWithoutCAData(),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewUpdateAction("secrets", api.NamespaceDefault, serviceAccountTokenSecret()),
|
2015-07-15 12:53:21 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
"updated token secret with mismatched ca data": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccountTokenSecretWithCAData([]byte("mismatched"))},
|
|
|
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
|
|
|
|
|
|
|
UpdatedSecret: serviceAccountTokenSecretWithCAData([]byte("mismatched")),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewUpdateAction("secrets", api.NamespaceDefault, serviceAccountTokenSecret()),
|
2015-07-15 12:53:21 +00:00
|
|
|
},
|
|
|
|
},
|
2016-02-11 19:46:56 +00:00
|
|
|
"updated token secret without namespace data": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccountTokenSecretWithoutNamespaceData()},
|
|
|
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
|
|
|
|
|
|
|
UpdatedSecret: serviceAccountTokenSecretWithoutNamespaceData(),
|
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewUpdateAction("secrets", api.NamespaceDefault, serviceAccountTokenSecret()),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"updated token secret with custom namespace data": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccountTokenSecretWithNamespaceData([]byte("custom"))},
|
|
|
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
|
|
|
|
|
|
|
UpdatedSecret: serviceAccountTokenSecretWithNamespaceData([]byte("custom")),
|
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
// no update is performed... the custom namespace is preserved
|
|
|
|
},
|
|
|
|
},
|
2015-04-21 03:25:56 +00:00
|
|
|
|
|
|
|
"deleted secret without serviceaccount": {
|
|
|
|
DeletedSecret: serviceAccountTokenSecret(),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{},
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
"deleted secret with serviceaccount with reference": {
|
|
|
|
ClientObjects: []runtime.Object{serviceAccount(tokenSecretReferences())},
|
|
|
|
ExistingServiceAccount: serviceAccount(tokenSecretReferences()),
|
|
|
|
|
|
|
|
DeletedSecret: serviceAccountTokenSecret(),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{
|
|
|
|
core.NewGetAction("serviceaccounts", api.NamespaceDefault, "default"),
|
|
|
|
core.NewUpdateAction("serviceaccounts", api.NamespaceDefault, serviceAccount(emptySecretReferences())),
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
"deleted secret with serviceaccount without reference": {
|
|
|
|
ExistingServiceAccount: serviceAccount(emptySecretReferences()),
|
|
|
|
|
|
|
|
DeletedSecret: serviceAccountTokenSecret(),
|
2016-01-29 06:34:08 +00:00
|
|
|
ExpectedActions: []core.Action{},
|
2015-04-21 03:25:56 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for k, tc := range testcases {
|
|
|
|
|
|
|
|
// Re-seed to reset name generation
|
2015-07-22 22:01:51 +00:00
|
|
|
utilrand.Seed(1)
|
2015-04-21 03:25:56 +00:00
|
|
|
|
|
|
|
generator := &testGenerator{Token: "ABC"}
|
|
|
|
|
2016-01-29 06:34:08 +00:00
|
|
|
client := fake.NewSimpleClientset(tc.ClientObjects...)
|
2015-04-21 03:25:56 +00:00
|
|
|
|
2015-07-15 12:53:21 +00:00
|
|
|
controller := NewTokensController(client, TokensControllerOptions{TokenGenerator: generator, RootCA: []byte("CA Data")})
|
2015-04-21 03:25:56 +00:00
|
|
|
|
2015-06-05 18:21:28 +00:00
|
|
|
// Tell the token controller whether its stores have been synced
|
|
|
|
controller.serviceAccountsSynced = func() bool { return !tc.ServiceAccountsSyncPending }
|
|
|
|
controller.secretsSynced = func() bool { return !tc.SecretsSyncPending }
|
2015-05-19 09:24:17 +00:00
|
|
|
|
2015-04-21 03:25:56 +00:00
|
|
|
if tc.ExistingServiceAccount != nil {
|
|
|
|
controller.serviceAccounts.Add(tc.ExistingServiceAccount)
|
|
|
|
}
|
|
|
|
for _, s := range tc.ExistingSecrets {
|
|
|
|
controller.secrets.Add(s)
|
|
|
|
}
|
|
|
|
|
|
|
|
if tc.AddedServiceAccount != nil {
|
|
|
|
controller.serviceAccountAdded(tc.AddedServiceAccount)
|
|
|
|
}
|
|
|
|
if tc.UpdatedServiceAccount != nil {
|
|
|
|
controller.serviceAccountUpdated(nil, tc.UpdatedServiceAccount)
|
|
|
|
}
|
|
|
|
if tc.DeletedServiceAccount != nil {
|
|
|
|
controller.serviceAccountDeleted(tc.DeletedServiceAccount)
|
|
|
|
}
|
|
|
|
if tc.AddedSecret != nil {
|
|
|
|
controller.secretAdded(tc.AddedSecret)
|
|
|
|
}
|
|
|
|
if tc.UpdatedSecret != nil {
|
|
|
|
controller.secretUpdated(nil, tc.UpdatedSecret)
|
|
|
|
}
|
|
|
|
if tc.DeletedSecret != nil {
|
|
|
|
controller.secretDeleted(tc.DeletedSecret)
|
|
|
|
}
|
|
|
|
|
2015-07-06 21:37:46 +00:00
|
|
|
actions := client.Actions()
|
|
|
|
for i, action := range actions {
|
2015-04-21 03:25:56 +00:00
|
|
|
if len(tc.ExpectedActions) < i+1 {
|
2015-07-06 21:37:46 +00:00
|
|
|
t.Errorf("%s: %d unexpected actions: %+v", k, len(actions)-len(tc.ExpectedActions), actions[i:])
|
2015-04-21 03:25:56 +00:00
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
expectedAction := tc.ExpectedActions[i]
|
2015-08-03 13:21:11 +00:00
|
|
|
if !reflect.DeepEqual(expectedAction, action) {
|
|
|
|
t.Errorf("%s: Expected\n\t%#v\ngot\n\t%#v", k, expectedAction, action)
|
2015-04-21 03:25:56 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-06 21:37:46 +00:00
|
|
|
if len(tc.ExpectedActions) > len(actions) {
|
|
|
|
t.Errorf("%s: %d additional expected actions:%+v", k, len(tc.ExpectedActions)-len(actions), tc.ExpectedActions[len(actions):])
|
2015-04-21 03:25:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|