add ca to token controller and all service accounts

pull/6/head
Mike Danese 2015-06-23 15:43:59 -07:00
parent befe545033
commit 56bde3342a
10 changed files with 55 additions and 17 deletions

View File

@ -28,7 +28,13 @@
{% endif -%}
{% endif -%}
{% set params = "--master=127.0.0.1:8080" + " " + cluster_name + " " + cluster_cidr + " " + allocate_node_cidrs + " " + cloud_provider + " " + cloud_config + service_account_key + pillar['log_level'] -%}
{% set root_ca_file = "" -%}
{% if grains['cloud'] is defined and grains.cloud in [ 'aws', 'gce' ] %}
{% set root_ca_file = "--root_ca_file=/srv/kubernetes/ca.crt" -%}
{% endif -%}
{% set params = "--master=127.0.0.1:8080" + " " + cluster_name + " " + cluster_cidr + " " + allocate_node_cidrs + " " + cloud_provider + " " + cloud_config + service_account_key + pillar['log_level'] + " " + root_ca_file -%}
{
"apiVersion": "v1beta3",

View File

@ -23,6 +23,8 @@ limitations under the License.
package app
import (
"fmt"
"io/ioutil"
"net"
"net/http"
"net/http/pprof"
@ -73,6 +75,7 @@ type CMServer struct {
DeletingPodsQps float32
DeletingPodsBurst int
ServiceAccountKeyFile string
RootCAFile string
ClusterName string
ClusterCIDR util.IPNet
@ -156,6 +159,7 @@ func (s *CMServer) AddFlags(fs *pflag.FlagSet) {
fs.BoolVar(&s.AllocateNodeCIDRs, "allocate-node-cidrs", false, "Should CIDRs for Pods be allocated and set on the cloud provider.")
fs.StringVar(&s.Master, "master", s.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig)")
fs.StringVar(&s.Kubeconfig, "kubeconfig", s.Kubeconfig, "Path to kubeconfig file with authorization and master location information.")
fs.StringVar(&s.RootCAFile, "root-ca-file", s.RootCAFile, "If set, this root certificate authority will be included in service account's token secret. This must be a valid PEM-encoded CA bundle.")
}
// Run runs the CMServer. This should never exit.
@ -243,6 +247,20 @@ func (s *CMServer) Run(_ []string) error {
}
pvRecycler.Run()
var rootCA []byte
if s.RootCAFile != "" {
rootCA, err := ioutil.ReadFile(s.RootCAFile)
if err != nil {
return fmt.Errorf("error reading root-ca-file at %s: %v", s.RootCAFile, err)
}
if _, err := util.CertsFromPEM(rootCA); err != nil {
return fmt.Errorf("error parsing root-ca-file at %s: %v", s.RootCAFile, err)
}
} else {
rootCA = kubeconfig.CAData
}
if len(s.ServiceAccountKeyFile) > 0 {
privateKey, err := serviceaccount.ReadPrivateKey(s.ServiceAccountKeyFile)
if err != nil {
@ -250,9 +268,10 @@ func (s *CMServer) Run(_ []string) error {
} else {
serviceaccount.NewTokensController(
kubeClient,
serviceaccount.DefaultTokenControllerOptions(
serviceaccount.JWTTokenGenerator(privateKey),
),
serviceaccount.TokensControllerOptions{
TokenGenerator: serviceaccount.JWTTokenGenerator(privateKey),
RootCA: rootCA,
},
).Run()
}
}

View File

@ -157,9 +157,10 @@ func (s *CMServer) Run(_ []string) error {
} else {
serviceaccount.NewTokensController(
kubeClient,
serviceaccount.DefaultTokenControllerOptions(
serviceaccount.JWTTokenGenerator(privateKey),
),
serviceaccount.TokensControllerOptions{
TokenGenerator: serviceaccount.JWTTokenGenerator(privateKey),
RootCA: kubeconfig.CAData,
},
).Run()
}
}

View File

@ -1998,6 +1998,8 @@ const (
ServiceAccountTokenKey = "token"
// ServiceAccountKubeconfigKey is the key of the optional kubeconfig data for SecretTypeServiceAccountToken secrets
ServiceAccountKubeconfigKey = "kubernetes.kubeconfig"
// ServiceAccountRootCAKey is the key of the optional root certificate authority for SecretTypeServiceAccountToken secrets
ServiceAccountRootCAKey = "ca.crt"
// SecretTypeDockercfg contains a dockercfg file that follows the same format rules as ~/.dockercfg
//

View File

@ -1894,6 +1894,8 @@ const (
ServiceAccountTokenKey = "token"
// ServiceAccountKubeconfigKey is the key of the optional kubeconfig data for SecretTypeServiceAccountToken secrets
ServiceAccountKubeconfigKey = "kubernetes.kubeconfig"
// ServiceAccountRootCAKey is the key of the optional root certificate authority for SecretTypeServiceAccountToken secrets
ServiceAccountRootCAKey = "ca.crt"
// SecretTypeDockercfg contains a dockercfg file that follows the same format rules as ~/.dockercfg
//

View File

@ -1900,6 +1900,8 @@ const (
ServiceAccountTokenKey = "token"
// ServiceAccountKubeconfigKey is the key of the optional kubeconfig data for SecretTypeServiceAccountToken secrets
ServiceAccountKubeconfigKey = "kubernetes.kubeconfig"
// ServiceAccountRootCAKey is the key of the optional root certificate authority for SecretTypeServiceAccountToken secrets
ServiceAccountRootCAKey = "ca.crt"
// SecretTypeDockercfg contains a dockercfg file that follows the same format rules as ~/.dockercfg
//

View File

@ -44,11 +44,8 @@ type TokensControllerOptions struct {
// SecretResync is the time.Duration at which to fully re-list secrets.
// If zero, re-list will be delayed as long as possible
SecretResync time.Duration
}
// DefaultTokenControllerOptions returns
func DefaultTokenControllerOptions(tokenGenerator TokenGenerator) TokensControllerOptions {
return TokensControllerOptions{TokenGenerator: tokenGenerator}
// This CA will be added in the secretes of service accounts
RootCA []byte
}
// NewTokensController returns a new *TokensController.
@ -56,6 +53,7 @@ func NewTokensController(cl client.Interface, options TokensControllerOptions) *
e := &TokensController{
client: cl,
token: options.TokenGenerator,
rootCA: options.RootCA,
}
e.serviceAccounts, e.serviceAccountController = framework.NewIndexerInformer(
@ -110,6 +108,8 @@ type TokensController struct {
client client.Interface
token TokenGenerator
rootCA []byte
serviceAccounts cache.Indexer
secrets cache.Indexer
@ -293,6 +293,9 @@ func (e *TokensController) createSecret(serviceAccount *api.ServiceAccount) erro
return err
}
secret.Data[api.ServiceAccountTokenKey] = []byte(token)
if e.rootCA != nil && len(e.rootCA) > 0 {
secret.Data[api.ServiceAccountRootCAKey] = e.rootCA
}
// Save the secret
if _, err := e.client.Secrets(serviceAccount.Namespace).Create(secret); err != nil {
@ -337,6 +340,9 @@ func (e *TokensController) generateTokenIfNeeded(serviceAccount *api.ServiceAcco
if ok && len(tokenData) > 0 {
return nil
}
if e.rootCA != nil && len(e.rootCA) > 0 {
secret.Data[api.ServiceAccountRootCAKey] = e.rootCA
}
// Generate the token
token, err := e.token.GenerateToken(*serviceAccount, *secret)

View File

@ -378,7 +378,7 @@ func TestTokenCreation(t *testing.T) {
client := testclient.NewSimpleFake(tc.ClientObjects...)
controller := NewTokensController(client, DefaultTokenControllerOptions(generator))
controller := NewTokensController(client, TokensControllerOptions{TokenGenerator: generator})
// Tell the token controller whether its stores have been synced
controller.serviceAccountsSynced = func() bool { return !tc.ServiceAccountsSyncPending }

View File

@ -123,16 +123,16 @@ func certificatesFromFile(file string) ([]*x509.Certificate, error) {
if err != nil {
return nil, err
}
certs, err := certsFromPEM(pemBlock)
certs, err := CertsFromPEM(pemBlock)
if err != nil {
return nil, fmt.Errorf("error reading %s: %s", file, err)
}
return certs, nil
}
// certsFromPEM returns the x509.Certificates contained in the given PEM-encoded byte array
// CertsFromPEM returns the x509.Certificates contained in the given PEM-encoded byte array
// Returns an error if a certificate could not be parsed, or if the data does not contain any certificates
func certsFromPEM(pemCerts []byte) ([]*x509.Certificate, error) {
func CertsFromPEM(pemCerts []byte) ([]*x509.Certificate, error) {
ok := false
certs := []*x509.Certificate{}
for len(pemCerts) > 0 {

View File

@ -422,7 +422,7 @@ func startServiceAccountTestServer(t *testing.T) (*client.Client, client.Config,
})
// Start the service account and service account token controllers
tokenController := serviceaccount.NewTokensController(rootClient, serviceaccount.DefaultTokenControllerOptions(serviceaccount.JWTTokenGenerator(serviceAccountKey)))
tokenController := serviceaccount.NewTokensController(rootClient, serviceaccount.TokensControllerOptions{TokenGenerator: serviceaccount.JWTTokenGenerator(serviceAccountKey)})
tokenController.Run()
serviceAccountController := serviceaccount.NewServiceAccountsController(rootClient, serviceaccount.DefaultServiceAccountsControllerOptions())
serviceAccountController.Run()