From c7b37767ba6bac532b4435cd836e6499b7a44ed6 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Sat, 31 Mar 2018 00:05:06 -0400 Subject: [PATCH] Make certificate approve/deny no-op if CSR is already approved Approval for CSRs is only needed once. If the CSR is already approved or denied we can skip updating it. Add a `--force` flag that allows the existing behavior for when a user has a specific need to update the CSR. This is backwards compatible with the intended use of the conditions, although it's possible some users are depending on the status being updated. It makes bulk approval as an admin much faster for scripting. --- pkg/kubectl/cmd/certificates.go | 38 ++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/pkg/kubectl/cmd/certificates.go b/pkg/kubectl/cmd/certificates.go index f3f335c3ef3..cecef58e509 100644 --- a/pkg/kubectl/cmd/certificates.go +++ b/pkg/kubectl/cmd/certificates.go @@ -87,17 +87,18 @@ func NewCmdCertificateApprove(f cmdutil.Factory, out io.Writer) *cobra.Command { Run: func(cmd *cobra.Command, args []string) { cmdutil.CheckErr(options.Complete(cmd, args)) cmdutil.CheckErr(options.Validate()) - cmdutil.CheckErr(options.RunCertificateApprove(f, out)) + cmdutil.CheckErr(options.RunCertificateApprove(f, out, cmdutil.GetFlagBool(cmd, "force"))) }, } + cmd.Flags().Bool("force", false, "Update the CSR even if it is already approved.") cmdutil.AddOutputFlagsForMutation(cmd) cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, "identifying the resource to update") return cmd } -func (options *CertificateOptions) RunCertificateApprove(f cmdutil.Factory, out io.Writer) error { - return options.modifyCertificateCondition(f, out, func(csr *certificates.CertificateSigningRequest) (*certificates.CertificateSigningRequest, string) { +func (options *CertificateOptions) RunCertificateApprove(f cmdutil.Factory, out io.Writer, force bool) error { + return options.modifyCertificateCondition(f, out, force, func(csr *certificates.CertificateSigningRequest) (*certificates.CertificateSigningRequest, bool, string) { var alreadyApproved bool for _, c := range csr.Status.Conditions { if c.Type == certificates.CertificateApproved { @@ -105,7 +106,7 @@ func (options *CertificateOptions) RunCertificateApprove(f cmdutil.Factory, out } } if alreadyApproved { - return csr, "approved" + return csr, true, "approved" } csr.Status.Conditions = append(csr.Status.Conditions, certificates.CertificateSigningRequestCondition{ Type: certificates.CertificateApproved, @@ -113,7 +114,7 @@ func (options *CertificateOptions) RunCertificateApprove(f cmdutil.Factory, out Message: "This CSR was approved by kubectl certificate approve.", LastUpdateTime: metav1.Now(), }) - return csr, "approved" + return csr, false, "approved" }) } @@ -133,17 +134,18 @@ func NewCmdCertificateDeny(f cmdutil.Factory, out io.Writer) *cobra.Command { Run: func(cmd *cobra.Command, args []string) { cmdutil.CheckErr(options.Complete(cmd, args)) cmdutil.CheckErr(options.Validate()) - cmdutil.CheckErr(options.RunCertificateDeny(f, out)) + cmdutil.CheckErr(options.RunCertificateDeny(f, out, cmdutil.GetFlagBool(cmd, "force"))) }, } + cmd.Flags().Bool("force", false, "Update the CSR even if it is already denied.") cmdutil.AddOutputFlagsForMutation(cmd) cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, "identifying the resource to update") return cmd } -func (options *CertificateOptions) RunCertificateDeny(f cmdutil.Factory, out io.Writer) error { - return options.modifyCertificateCondition(f, out, func(csr *certificates.CertificateSigningRequest) (*certificates.CertificateSigningRequest, string) { +func (options *CertificateOptions) RunCertificateDeny(f cmdutil.Factory, out io.Writer, force bool) error { + return options.modifyCertificateCondition(f, out, force, func(csr *certificates.CertificateSigningRequest) (*certificates.CertificateSigningRequest, bool, string) { var alreadyDenied bool for _, c := range csr.Status.Conditions { if c.Type == certificates.CertificateDenied { @@ -151,7 +153,7 @@ func (options *CertificateOptions) RunCertificateDeny(f cmdutil.Factory, out io. } } if alreadyDenied { - return csr, "denied" + return csr, true, "denied" } csr.Status.Conditions = append(csr.Status.Conditions, certificates.CertificateSigningRequestCondition{ Type: certificates.CertificateDenied, @@ -159,11 +161,11 @@ func (options *CertificateOptions) RunCertificateDeny(f cmdutil.Factory, out io. Message: "This CSR was approved by kubectl certificate deny.", LastUpdateTime: metav1.Now(), }) - return csr, "denied" + return csr, false, "denied" }) } -func (options *CertificateOptions) modifyCertificateCondition(f cmdutil.Factory, out io.Writer, modify func(csr *certificates.CertificateSigningRequest) (*certificates.CertificateSigningRequest, string)) error { +func (options *CertificateOptions) modifyCertificateCondition(f cmdutil.Factory, out io.Writer, force bool, modify func(csr *certificates.CertificateSigningRequest) (*certificates.CertificateSigningRequest, bool, string)) error { var found int c, err := f.ClientSet() if err != nil { @@ -183,12 +185,14 @@ func (options *CertificateOptions) modifyCertificateCondition(f cmdutil.Factory, return err } csr := info.Object.(*certificates.CertificateSigningRequest) - csr, verb := modify(csr) - csr, err = c.Certificates(). - CertificateSigningRequests(). - UpdateApproval(csr) - if err != nil { - return err + csr, hasCondition, verb := modify(csr) + if !hasCondition || force { + csr, err = c.Certificates(). + CertificateSigningRequests(). + UpdateApproval(csr) + if err != nil { + return err + } } found++ cmdutil.PrintSuccess(options.outputStyle == "name", out, info.Object, false, verb)