refactor certificate controller

This commit is contained in:
Mike Danese
2017-05-08 14:44:45 -07:00
parent 8e98f1dfec
commit f04ce3cfba
20 changed files with 341 additions and 351 deletions

View File

@@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package certificates implements an abstract controller that is useful for
// building controllers that manage CSRs
package certificates
import (
@@ -37,33 +39,22 @@ import (
"github.com/golang/glog"
)
// err returned from these interfaces should indicate utter failure that
// should be retried. "Buisness logic" errors should be indicated by adding
// a condition to the CSRs status, not by returning an error.
type AutoApprover interface {
AutoApprove(csr *certificates.CertificateSigningRequest) (*certificates.CertificateSigningRequest, error)
}
type Signer interface {
Sign(csr *certificates.CertificateSigningRequest) (*certificates.CertificateSigningRequest, error)
}
type CertificateController struct {
kubeClient clientset.Interface
csrLister certificateslisters.CertificateSigningRequestLister
csrsSynced cache.InformerSynced
syncHandler func(csrKey string) error
approver AutoApprover
signer Signer
handler func(*certificates.CertificateSigningRequest) error
queue workqueue.RateLimitingInterface
}
func NewCertificateController(kubeClient clientset.Interface, csrInformer certificatesinformers.CertificateSigningRequestInformer, signer Signer, approver AutoApprover) (*CertificateController, error) {
func NewCertificateController(
kubeClient clientset.Interface,
csrInformer certificatesinformers.CertificateSigningRequestInformer,
handler func(*certificates.CertificateSigningRequest) error,
) (*CertificateController, error) {
// Send events to the apiserver
eventBroadcaster := record.NewBroadcaster()
eventBroadcaster.StartLogging(glog.Infof)
@@ -72,8 +63,7 @@ func NewCertificateController(kubeClient clientset.Interface, csrInformer certif
cc := &CertificateController{
kubeClient: kubeClient,
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "certificate"),
signer: signer,
approver: approver,
handler: handler,
}
// Manage the addition/update of certificate requests
@@ -108,7 +98,7 @@ func NewCertificateController(kubeClient clientset.Interface, csrInformer certif
})
cc.csrLister = csrInformer.Lister()
cc.csrsSynced = csrInformer.Informer().HasSynced
cc.syncHandler = cc.maybeSignCertificate
cc.handler = handler
return cc, nil
}
@@ -145,15 +135,15 @@ func (cc *CertificateController) processNextWorkItem() bool {
}
defer cc.queue.Done(cKey)
err := cc.syncHandler(cKey.(string))
if err == nil {
cc.queue.Forget(cKey)
if err := cc.syncFunc(cKey.(string)); err != nil {
cc.queue.AddRateLimited(cKey)
utilruntime.HandleError(fmt.Errorf("Sync %v failed with : %v", cKey, err))
return true
}
cc.queue.AddRateLimited(cKey)
utilruntime.HandleError(fmt.Errorf("Sync %v failed with : %v", cKey, err))
cc.queue.Forget(cKey)
return true
}
func (cc *CertificateController) enqueueCertificateRequest(obj interface{}) {
@@ -169,7 +159,7 @@ func (cc *CertificateController) enqueueCertificateRequest(obj interface{}) {
// been approved and meets policy expectations, generate an X509 cert using the
// cluster CA assets. If successful it will update the CSR approve subresource
// with the signed certificate.
func (cc *CertificateController) maybeSignCertificate(key string) error {
func (cc *CertificateController) syncFunc(key string) error {
startTime := time.Now()
defer func() {
glog.V(4).Infof("Finished syncing certificate request %q (%v)", key, time.Now().Sub(startTime))
@@ -195,32 +185,5 @@ func (cc *CertificateController) maybeSignCertificate(key string) error {
}
csr = copy.(*certificates.CertificateSigningRequest)
if cc.approver != nil {
csr, err = cc.approver.AutoApprove(csr)
if err != nil {
return fmt.Errorf("error auto approving csr: %v", err)
}
_, err = cc.kubeClient.Certificates().CertificateSigningRequests().UpdateApproval(csr)
if err != nil {
return fmt.Errorf("error updating approval for csr: %v", err)
}
}
// At this point, the controller needs to:
// 1. Check the approval conditions
// 2. Generate a signed certificate
// 3. Update the Status subresource
if cc.signer != nil && IsCertificateRequestApproved(csr) {
csr, err := cc.signer.Sign(csr)
if err != nil {
return fmt.Errorf("error auto signing csr: %v", err)
}
_, err = cc.kubeClient.Certificates().CertificateSigningRequests().UpdateStatus(csr)
if err != nil {
return fmt.Errorf("error updating signature for csr: %v", err)
}
}
return nil
return cc.handler(csr)
}