Skip to content

Commit

Permalink
migrate serviceaccount controllers to new initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
mfojtik committed May 23, 2017
1 parent ca00b44 commit c8ea7e1
Show file tree
Hide file tree
Showing 9 changed files with 375 additions and 139 deletions.
24 changes: 24 additions & 0 deletions pkg/cmd/server/bootstrappolicy/controller_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ var (
controllerRoles = []rbac.ClusterRole{}
// controllerRoleBindings is a slice of roles used for controllers
controllerRoleBindings = []rbac.ClusterRoleBinding{}

// TODO: Import this from upstream once this will get stable package location.
ReadWrite = []string{"get", "list", "watch", "create", "update", "patch", "delete", "deletecollection"}
Read = []string{"get", "list", "watch"}
)

func addControllerRole(role rbac.ClusterRole) {
Expand Down Expand Up @@ -103,6 +107,26 @@ func init() {
eventsRule(),
},
})

// serviceaccount-controller
addControllerRole(rbac.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + InfraServiceAccountControllerServiceAccountName},
Rules: []rbac.PolicyRule{
rbac.NewRule(ReadWrite...).Groups(kapiGroup).Resources("serviceaccounts").RuleOrDie(),
eventsRule(),
},
})

// serviceaccount-pull-secrets-controller
addControllerRole(rbac.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + InfraServiceAccountPullSecretsControllerServiceAccountName},
Rules: []rbac.PolicyRule{
rbac.NewRule(ReadWrite...).Groups(kapiGroup).Resources("serviceaccounts").RuleOrDie(),
rbac.NewRule(ReadWrite...).Groups(kapiGroup).Resources("secrets").RuleOrDie(),
rbac.NewRule(Read...).Groups(kapiGroup).Resources("services").RuleOrDie(),
eventsRule(),
},
})
}

// ControllerRoles returns the cluster roles used by controllers
Expand Down
17 changes: 10 additions & 7 deletions pkg/cmd/server/bootstrappolicy/infra_sa_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@ import (
)

const (
InfraBuildControllerServiceAccountName = "build-controller"
InfraImageTriggerControllerServiceAccountName = "imagetrigger-controller"
ImageTriggerControllerRoleName = "system:imagetrigger-controller"
InfraDeploymentConfigControllerServiceAccountName = "deploymentconfig-controller"
InfraDeploymentTriggerControllerServiceAccountName = "deployment-trigger-controller"
InfraDeployerControllerServiceAccountName = "deployer-controller"
InfraOriginNamespaceServiceAccountName = "origin-namespace-controller"
InfraBuildControllerServiceAccountName = "build-controller"
InfraImageTriggerControllerServiceAccountName = "imagetrigger-controller"
ImageTriggerControllerRoleName = "system:imagetrigger-controller"
InfraDeploymentConfigControllerServiceAccountName = "deploymentconfig-controller"
InfraDeploymentTriggerControllerServiceAccountName = "deployment-trigger-controller"
InfraDeployerControllerServiceAccountName = "deployer-controller"
InfraOriginNamespaceServiceAccountName = "origin-namespace-controller"
InfraServiceAccountControllerServiceAccountName = "serviceaccount-controller"
InfraServiceAccountTokensControllerServiceAccountName = "serviceaccount-tokens-controller"
InfraServiceAccountPullSecretsControllerServiceAccountName = "serviceaccount-pull-secrets-controller"

InfraPersistentVolumeBinderControllerServiceAccountName = "pv-binder-controller"
PersistentVolumeBinderControllerRoleName = "system:pv-binder-controller"
Expand Down
20 changes: 20 additions & 0 deletions pkg/cmd/server/origin/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,26 @@ import (
"github.com/openshift/origin/pkg/cmd/server/origin/controller"
)

func (c *MasterConfig) NewOpenShiftControllerPreInitializers() (map[string]controller.InitFunc, error) {
ret := map[string]controller.InitFunc{}

serviceAccountTokens := controller.ServiceAccountTokensControllerOptions{
ServiceAccountConfig: c.Options.ServiceAccountConfig,
ServiceServingCertConfig: c.Options.ControllerConfig.ServiceServingCert,
}
ret["serviceaccount-tokens"] = serviceAccountTokens.RunController

serviceAccount := controller.ServiceAccountControllerOptions{
ManagedNames: c.Options.ServiceAccountConfig.ManagedNames,
}
ret["serviceaccount"] = serviceAccount.RunController

serviceAccountPullSecrets := controller.ServiceAccountPullSecretsControllerOptions{}
ret["serviceaccount-pull-secrets"] = serviceAccountPullSecrets.RunController

return ret, nil
}

func (c *MasterConfig) NewOpenshiftControllerInitializers() (map[string]controller.InitFunc, error) {
ret := map[string]controller.InitFunc{}

Expand Down
4 changes: 4 additions & 0 deletions pkg/cmd/server/origin/controller/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ type ControllerContext struct {

DeprecatedOpenshiftInformers shared.InformerFactory

// RootClient should only be used for pre-initialization controllers
// (iow. serviceaccount-tokens controller)
RootClientBuilder *controller.SimpleControllerClientBuilder

// Stop is the stop channel
Stop <-chan struct{}
}
Expand Down
129 changes: 129 additions & 0 deletions pkg/cmd/server/origin/controller/serviceaccount.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package controller

import (
"fmt"
"io/ioutil"

"github.com/golang/glog"

"k8s.io/client-go/util/cert"
kapiv1 "k8s.io/kubernetes/pkg/api/v1"
sacontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
"k8s.io/kubernetes/pkg/serviceaccount"

configapi "github.com/openshift/origin/pkg/cmd/server/api"
"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
"github.com/openshift/origin/pkg/cmd/server/crypto"
serviceaccountcontrollers "github.com/openshift/origin/pkg/serviceaccounts/controllers"
)

type ServiceAccountControllerOptions struct {
ManagedNames []string
}

func (c *ServiceAccountControllerOptions) RunController(ctx ControllerContext) (bool, error) {
if len(c.ManagedNames) == 0 {
return true, fmt.Errorf("skipped starting Service Account Manager, no managed names specified")
}

options := sacontroller.DefaultServiceAccountsControllerOptions()
options.ServiceAccounts = []kapiv1.ServiceAccount{}

for _, saName := range c.ManagedNames {
sa := kapiv1.ServiceAccount{}
sa.Name = saName

options.ServiceAccounts = append(options.ServiceAccounts, sa)
}

//REBASE: add new args to NewServiceAccountsController
go sacontroller.NewServiceAccountsController(
ctx.DeprecatedOpenshiftInformers.KubernetesInformers().Core().V1().ServiceAccounts(),
ctx.DeprecatedOpenshiftInformers.KubernetesInformers().Core().V1().Namespaces(),
ctx.ClientBuilder.ClientOrDie(bootstrappolicy.InfraServiceAccountControllerServiceAccountName),
options).Run(1, ctx.Stop)

return true, nil
}

type ServiceAccountTokensControllerOptions struct {
ServiceAccountConfig configapi.ServiceAccountConfig
ServiceServingCertConfig configapi.ServiceServingCert
}

func (c *ServiceAccountTokensControllerOptions) RunController(ctx ControllerContext) (bool, error) {
if len(c.ServiceAccountConfig.PrivateKeyFile) == 0 {
return true, fmt.Errorf("skipped starting Service Account Token Manager, no private key specified")
}

privateKey, err := serviceaccount.ReadPrivateKey(c.ServiceAccountConfig.PrivateKeyFile)
if err != nil {
return true, fmt.Errorf("error reading signing key for Service Account Token Manager: %v", err)
}

rootCA := []byte{}
if len(c.ServiceAccountConfig.MasterCA) > 0 {
rootCA, err = ioutil.ReadFile(c.ServiceAccountConfig.MasterCA)
if err != nil {
glog.Fatalf("error reading master ca file for Service Account Token Manager: %s: %v", c.ServiceAccountConfig.MasterCA, err)
}
if _, err := cert.ParseCertsPEM(rootCA); err != nil {
glog.Fatalf("error parsing master ca file for Service Account Token Manager: %s: %v", c.ServiceAccountConfig.MasterCA, err)
}
}
servingServingCABundle := []byte{}
if c.ServiceServingCertConfig.Signer != nil && len(c.ServiceServingCertConfig.Signer.CertFile) > 0 {
certFile := c.ServiceServingCertConfig.Signer.CertFile
servingServingCA, err := ioutil.ReadFile(certFile)
if err != nil {
return true, fmt.Errorf("error reading ca file for Service Serving Certificate Signer: %s: %v", certFile, err)
}
if _, err := crypto.CertsFromPEM(servingServingCA); err != nil {
return true, fmt.Errorf("error parsing ca file for Service Serving Certificate Signer: %s: %v", certFile, err)
}

// if we have a rootCA bundle add that too. The rootCA will be used when hitting the default master service, since those are signed
// using a different CA by default. The rootCA's key is more closely guarded than ours and if it is compromised, that power could
// be used to change the trusted signers for every pod anyway, so we're already effectively trusting it.
if len(rootCA) > 0 {
servingServingCABundle = append(servingServingCABundle, rootCA...)
servingServingCABundle = append(servingServingCABundle, []byte("\n")...)
}
servingServingCABundle = append(servingServingCABundle, servingServingCA...)
}

go sacontroller.NewTokensController(
ctx.RootClientBuilder.ClientOrDie(bootstrappolicy.InfraServiceAccountTokensControllerServiceAccountName),
sacontroller.TokensControllerOptions{
TokenGenerator: serviceaccount.JWTTokenGenerator(privateKey),
RootCA: rootCA,
ServiceServingCA: servingServingCABundle,
},
).Run(int(ctx.KubeControllerContext.Options.ConcurrentSATokenSyncs), ctx.Stop)

return true, nil
}

type ServiceAccountPullSecretsControllerOptions struct {
}

func (c *ServiceAccountPullSecretsControllerOptions) RunController(ctx ControllerContext) (bool, error) {
kc := ctx.ClientBuilder.KubeInternalClientOrDie(bootstrappolicy.InfraServiceAccountPullSecretsControllerServiceAccountName)

serviceaccountcontrollers.NewDockercfgDeletedController(kc, serviceaccountcontrollers.DockercfgDeletedControllerOptions{}).Run()
serviceaccountcontrollers.NewDockercfgTokenDeletedController(kc, serviceaccountcontrollers.DockercfgTokenDeletedControllerOptions{}).Run()

dockerURLsIntialized := make(chan struct{})
dockercfgController := serviceaccountcontrollers.NewDockercfgController(kc, serviceaccountcontrollers.DockercfgControllerOptions{DockerURLsIntialized: dockerURLsIntialized})
go dockercfgController.Run(5, ctx.Stop)

dockerRegistryControllerOptions := serviceaccountcontrollers.DockerRegistryServiceControllerOptions{
RegistryNamespace: "default",
RegistryServiceName: "docker-registry",
DockercfgController: dockercfgController,
DockerURLsIntialized: dockerURLsIntialized,
}
go serviceaccountcontrollers.NewDockerRegistryServiceController(kc, dockerRegistryControllerOptions).Run(10, ctx.Stop)

return true, nil
}
93 changes: 0 additions & 93 deletions pkg/cmd/server/origin/run_components.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package origin

import (
"fmt"
"io/ioutil"
"net"
"sync"
"time"
Expand All @@ -13,7 +12,6 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
utilwait "k8s.io/apimachinery/pkg/util/wait"
kv1core "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/util/cert"
"k8s.io/client-go/util/flowcontrol"
kctrlmgr "k8s.io/kubernetes/cmd/kube-controller-manager/app"
cmapp "k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
Expand All @@ -25,10 +23,8 @@ import (
kclientsetinternal "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/controller"
kresourcequota "k8s.io/kubernetes/pkg/controller/resourcequota"
sacontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
"k8s.io/kubernetes/pkg/registry/core/service/allocator"
etcdallocator "k8s.io/kubernetes/pkg/registry/core/service/allocator/storage"
"k8s.io/kubernetes/pkg/serviceaccount"

"github.com/openshift/origin/pkg/authorization/controller/authorizationsync"
buildclient "github.com/openshift/origin/pkg/build/client"
Expand Down Expand Up @@ -56,7 +52,6 @@ import (
"github.com/openshift/origin/pkg/security/uidallocator"
"github.com/openshift/origin/pkg/service/controller/ingressip"
servingcertcontroller "github.com/openshift/origin/pkg/service/controller/servingcert"
serviceaccountcontrollers "github.com/openshift/origin/pkg/serviceaccounts/controllers"
templatecontroller "github.com/openshift/origin/pkg/template/controller"
unidlingcontroller "github.com/openshift/origin/pkg/unidling/controller"
)
Expand All @@ -78,94 +73,6 @@ func (c *MasterConfig) RunProjectAuthorizationCache() {
c.ProjectAuthorizationCache.Run(period)
}

// RunServiceAccountsController starts the service account controller
func (c *MasterConfig) RunServiceAccountsController() {
if len(c.Options.ServiceAccountConfig.ManagedNames) == 0 {
glog.Infof("Skipped starting Service Account Manager, no managed names specified")
return
}
options := sacontroller.DefaultServiceAccountsControllerOptions()
options.ServiceAccounts = []kapiv1.ServiceAccount{}

for _, saName := range c.Options.ServiceAccountConfig.ManagedNames {
sa := kapiv1.ServiceAccount{}
sa.Name = saName

options.ServiceAccounts = append(options.ServiceAccounts, sa)
}

//REBASE: add new args to NewServiceAccountsController
go sacontroller.NewServiceAccountsController(c.Informers.KubernetesInformers().Core().V1().ServiceAccounts(), c.Informers.KubernetesInformers().Core().V1().Namespaces(), c.KubeClientsetExternal(), options).Run(1, utilwait.NeverStop)
}

// RunServiceAccountTokensController starts the service account token controller
func (c *MasterConfig) RunServiceAccountTokensController(cm *cmapp.CMServer) {
if len(c.Options.ServiceAccountConfig.PrivateKeyFile) == 0 {
glog.Infof("Skipped starting Service Account Token Manager, no private key specified")
return
}

privateKey, err := serviceaccount.ReadPrivateKey(c.Options.ServiceAccountConfig.PrivateKeyFile)
if err != nil {
glog.Fatalf("Error reading signing key for Service Account Token Manager: %v", err)
}
rootCA := []byte{}
if len(c.Options.ServiceAccountConfig.MasterCA) > 0 {
rootCA, err = ioutil.ReadFile(c.Options.ServiceAccountConfig.MasterCA)
if err != nil {
glog.Fatalf("Error reading master ca file for Service Account Token Manager: %s: %v", c.Options.ServiceAccountConfig.MasterCA, err)
}
if _, err := cert.ParseCertsPEM(rootCA); err != nil {
glog.Fatalf("Error parsing master ca file for Service Account Token Manager: %s: %v", c.Options.ServiceAccountConfig.MasterCA, err)
}
}
servingServingCABundle := []byte{}
if c.Options.ControllerConfig.ServiceServingCert.Signer != nil && len(c.Options.ControllerConfig.ServiceServingCert.Signer.CertFile) > 0 {
servingServingCA, err := ioutil.ReadFile(c.Options.ControllerConfig.ServiceServingCert.Signer.CertFile)
if err != nil {
glog.Fatalf("Error reading ca file for Service Serving Certificate Signer: %s: %v", c.Options.ControllerConfig.ServiceServingCert.Signer.CertFile, err)
}
if _, err := crypto.CertsFromPEM(servingServingCA); err != nil {
glog.Fatalf("Error parsing ca file for Service Serving Certificate Signer: %s: %v", c.Options.ControllerConfig.ServiceServingCert.Signer.CertFile, err)
}

// if we have a rootCA bundle add that too. The rootCA will be used when hitting the default master service, since those are signed
// using a different CA by default. The rootCA's key is more closely guarded than ours and if it is compromised, that power could
// be used to change the trusted signers for every pod anyway, so we're already effectively trusting it.
if len(rootCA) > 0 {
servingServingCABundle = append(servingServingCABundle, rootCA...)
servingServingCABundle = append(servingServingCABundle, []byte("\n")...)
}
servingServingCABundle = append(servingServingCABundle, servingServingCA...)
}

options := sacontroller.TokensControllerOptions{
TokenGenerator: serviceaccount.JWTTokenGenerator(privateKey),
RootCA: rootCA,
ServiceServingCA: servingServingCABundle,
}

go sacontroller.NewTokensController(c.KubeClientsetExternal(), options).Run(int(cm.ConcurrentSATokenSyncs), utilwait.NeverStop)
}

// RunServiceAccountPullSecretsControllers starts the service account pull secret controllers
func (c *MasterConfig) RunServiceAccountPullSecretsControllers() {
serviceaccountcontrollers.NewDockercfgDeletedController(c.KubeClientsetInternal(), serviceaccountcontrollers.DockercfgDeletedControllerOptions{}).Run()
serviceaccountcontrollers.NewDockercfgTokenDeletedController(c.KubeClientsetInternal(), serviceaccountcontrollers.DockercfgTokenDeletedControllerOptions{}).Run()

dockerURLsIntialized := make(chan struct{})
dockercfgController := serviceaccountcontrollers.NewDockercfgController(c.KubeClientsetInternal(), serviceaccountcontrollers.DockercfgControllerOptions{DockerURLsIntialized: dockerURLsIntialized})
go dockercfgController.Run(5, utilwait.NeverStop)

dockerRegistryControllerOptions := serviceaccountcontrollers.DockerRegistryServiceControllerOptions{
RegistryNamespace: "default",
RegistryServiceName: "docker-registry",
DockercfgController: dockercfgController,
DockerURLsIntialized: dockerURLsIntialized,
}
go serviceaccountcontrollers.NewDockerRegistryServiceController(c.KubeClientsetInternal(), dockerRegistryControllerOptions).Run(10, make(chan struct{}))
}

// RunAssetServer starts the asset server for the OpenShift UI.
func (c *MasterConfig) RunAssetServer() {

Expand Down
Loading

0 comments on commit c8ea7e1

Please sign in to comment.