From a1ce1cefb57a1201dfa5cc343fada44260e1d85c Mon Sep 17 00:00:00 2001 From: Haoxiang Zhou Date: Mon, 24 Aug 2020 16:35:40 +0200 Subject: [PATCH] Add Events of Issuer and Secret to output Signed-off-by: Haoxiang Zhou --- cmd/ctl/pkg/status/certificate/certificate.go | 32 +++++++++++-- .../status/certificate/certificate_test.go | 41 +++++++++------- cmd/ctl/pkg/status/certificate/types.go | 48 +++++++++++-------- .../ctl/ctl_status_certificate_test.go | 3 ++ 4 files changed, 80 insertions(+), 44 deletions(-) diff --git a/cmd/ctl/pkg/status/certificate/certificate.go b/cmd/ctl/pkg/status/certificate/certificate.go index ded142862..a7df6bd2b 100644 --- a/cmd/ctl/pkg/status/certificate/certificate.go +++ b/cmd/ctl/pkg/status/certificate/certificate.go @@ -68,11 +68,13 @@ type Data struct { Issuer cmapi.GenericIssuer IssuerKind string IssuerError error + IssuerEvents *corev1.EventList Secret *corev1.Secret SecretError error + SecretEvents *corev1.EventList Req *cmapi.CertificateRequest ReqError error - ReqEvent *corev1.EventList + ReqEvents *corev1.EventList Order *cmacme.Order OrderError error Challenges []*cmacme.Challenge @@ -176,11 +178,29 @@ func (o *Options) GetResources(crtName string) (*Data, error) { crtEvents, _ := clientSet.CoreV1().Events(o.Namespace).Search(ctl.Scheme, crtRef) issuer, issuerKind, issuerError := getGenericIssuer(o.CMClient, ctx, crt) + var issuerEvents *corev1.EventList + if issuer != nil { + issuerRef, err := reference.GetReference(ctl.Scheme, issuer) + if err != nil { + return nil, err + } + // Ignore error, since if there was an error, issuerEvents would be nil and handled down the line in DescribeEvents + issuerEvents, _ = clientSet.CoreV1().Events(o.Namespace).Search(ctl.Scheme, issuerRef) + } secret, secretErr := clientSet.CoreV1().Secrets(o.Namespace).Get(ctx, crt.Spec.SecretName, metav1.GetOptions{}) if secretErr != nil { secretErr = fmt.Errorf("error when finding Secret %q: %w\n", crt.Spec.SecretName, secretErr) } + var secretEvents *corev1.EventList + if secret != nil { + secretRef, err := reference.GetReference(ctl.Scheme, secret) + if err != nil { + return nil, err + } + // Ignore error, since if there was an error, secretEvents would be nil and handled down the line in DescribeEvents + secretEvents, _ = clientSet.CoreV1().Events(o.Namespace).Search(ctl.Scheme, secretRef) + } // TODO: What about timing issues? When I query condition it's not ready yet, but then looking for cr it's finished and deleted // Try find the CertificateRequest that is owned by crt and has the correct revision @@ -234,11 +254,13 @@ func (o *Options) GetResources(crtName string) (*Data, error) { Issuer: issuer, IssuerKind: issuerKind, IssuerError: issuerError, + IssuerEvents: issuerEvents, Secret: secret, SecretError: secretErr, + SecretEvents: secretEvents, Req: req, ReqError: reqErr, - ReqEvent: reqEvents, + ReqEvents: reqEvents, Order: order, OrderError: orderErr, Challenges: challenges, @@ -251,9 +273,9 @@ func (o *Options) GetResources(crtName string) (*Data, error) { func StatusFromResources(data *Data) *CertificateStatus { return newCertificateStatusFromCert(data.Certificate). withEvents(data.CrtEvents). - withGenericIssuer(data.Issuer, data.IssuerKind, data.IssuerError). - withSecret(data.Secret, data.SecretError). - withCR(data.Req, data.ReqEvent, data.ReqError). + withGenericIssuer(data.Issuer, data.IssuerKind, data.IssuerEvents, data.IssuerError). + withSecret(data.Secret, data.SecretEvents, data.SecretError). + withCR(data.Req, data.ReqEvents, data.ReqError). withOrder(data.Order, data.OrderError). withChallenges(data.Challenges, data.ChallengeErr) } diff --git a/cmd/ctl/pkg/status/certificate/certificate_test.go b/cmd/ctl/pkg/status/certificate/certificate_test.go index cdb043d37..5c6d62581 100644 --- a/cmd/ctl/pkg/status/certificate/certificate_test.go +++ b/cmd/ctl/pkg/status/certificate/certificate_test.go @@ -250,9 +250,10 @@ MA6koCR/K23HZfML8vT6lcHvQJp9XXaHRIe9NX/M/2f6VpfO7JjKWLou5k5a inputData: &Data{ Certificate: gen.Certificate("test-crt", gen.SetCertificateNamespace(ns)), - Issuer: gen.Issuer("test-issuer"), - IssuerKind: "Issuer", - IssuerError: nil, + Issuer: gen.Issuer("test-issuer"), + IssuerKind: "Issuer", + IssuerError: nil, + IssuerEvents: nil, }, expOutput: &CertificateStatus{ Name: "test-crt", @@ -265,9 +266,10 @@ MA6koCR/K23HZfML8vT6lcHvQJp9XXaHRIe9NX/M/2f6VpfO7JjKWLou5k5a inputData: &Data{ Certificate: gen.Certificate("test-crt", gen.SetCertificateNamespace(ns)), - Issuer: gen.Issuer("test-clusterissuer"), - IssuerKind: "ClusterIssuer", - IssuerError: nil, + Issuer: gen.Issuer("test-clusterissuer"), + IssuerKind: "ClusterIssuer", + IssuerError: nil, + IssuerEvents: nil, }, expOutput: &CertificateStatus{ Name: "test-crt", @@ -283,7 +285,8 @@ MA6koCR/K23HZfML8vT6lcHvQJp9XXaHRIe9NX/M/2f6VpfO7JjKWLou5k5a Secret: gen.Secret("existing-tls-secret", gen.SetSecretNamespace(ns), gen.SetSecretData(map[string][]byte{"tls.crt": tlsCrt})), - SecretError: nil, + SecretError: nil, + SecretEvents: nil, }, expOutput: &CertificateStatus{ Name: "test-crt", @@ -312,8 +315,8 @@ MA6koCR/K23HZfML8vT6lcHvQJp9XXaHRIe9NX/M/2f6VpfO7JjKWLou5k5a Req: gen.CertificateRequest("test-req", gen.SetCertificateRequestNamespace(ns), gen.SetCertificateRequestStatusCondition(cmapi.CertificateRequestCondition{Type: cmapi.CertificateRequestConditionReady, Status: cmmeta.ConditionFalse, Reason: "Pending", Message: "Waiting on certificate issuance from order default/example-order: \"pending\""})), - ReqError: nil, - ReqEvent: nil, + ReqError: nil, + ReqEvents: nil, }, expOutput: &CertificateStatus{ Name: "test-crt", @@ -426,15 +429,17 @@ MA6koCR/K23HZfML8vT6lcHvQJp9XXaHRIe9NX/M/2f6VpfO7JjKWLou5k5a inputData: &Data{ Certificate: gen.Certificate("test-crt", gen.SetCertificateNamespace(ns)), - CrtEvents: nil, - Issuer: gen.Issuer("test-issuer"), - IssuerKind: "", - IssuerError: errors.New("dummy error"), - Secret: gen.Secret("test-secret"), - SecretError: errors.New("dummy error"), - Req: gen.CertificateRequest("test-req"), - ReqError: errors.New("dummy error"), - ReqEvent: nil, + CrtEvents: nil, + Issuer: gen.Issuer("test-issuer"), + IssuerKind: "", + IssuerError: errors.New("dummy error"), + IssuerEvents: nil, + Secret: gen.Secret("test-secret"), + SecretError: errors.New("dummy error"), + SecretEvents: nil, + Req: gen.CertificateRequest("test-req"), + ReqError: errors.New("dummy error"), + ReqEvents: nil, Order: &cmacme.Order{ ObjectMeta: metav1.ObjectMeta{Name: "test-order"}, }, diff --git a/cmd/ctl/pkg/status/certificate/types.go b/cmd/ctl/pkg/status/certificate/types.go index 47d8cf2b4..abe4ff3a0 100644 --- a/cmd/ctl/pkg/status/certificate/types.go +++ b/cmd/ctl/pkg/status/certificate/types.go @@ -75,6 +75,8 @@ type IssuerStatus struct { Kind string // Conditions of Issuer/ClusterIssuer resource Conditions []cmapi.IssuerCondition + // Events of Issuer/ClusterIssuer resource + Events *v1.EventList } type SecretStatus struct { @@ -103,6 +105,8 @@ type SecretStatus struct { AuthorityKeyId []byte // Serial Number of the x509 certificate in the Secret SerialNumber *big.Int + // Events of Secret resource + Events *v1.EventList } type CRStatus struct { @@ -168,7 +172,7 @@ func (status *CertificateStatus) withEvents(events *v1.EventList) *CertificateSt return status } -func (status *CertificateStatus) withGenericIssuer(genericIssuer cmapi.GenericIssuer, issuerKind string, err error) *CertificateStatus { +func (status *CertificateStatus) withGenericIssuer(genericIssuer cmapi.GenericIssuer, issuerKind string, issuerEvents *v1.EventList, err error) *CertificateStatus { if err != nil { status.IssuerStatus = &IssuerStatus{Error: err} return status @@ -178,15 +182,15 @@ func (status *CertificateStatus) withGenericIssuer(genericIssuer cmapi.GenericIs } if issuerKind == "ClusterIssuer" { status.IssuerStatus = &IssuerStatus{Name: genericIssuer.GetName(), Kind: "ClusterIssuer", - Conditions: genericIssuer.GetStatus().Conditions} + Conditions: genericIssuer.GetStatus().Conditions, Events: issuerEvents} return status } status.IssuerStatus = &IssuerStatus{Name: genericIssuer.GetName(), Kind: "Issuer", - Conditions: genericIssuer.GetStatus().Conditions} + Conditions: genericIssuer.GetStatus().Conditions, Events: issuerEvents} return status } -func (status *CertificateStatus) withSecret(secret *v1.Secret, err error) *CertificateStatus { +func (status *CertificateStatus) withSecret(secret *v1.Secret, secretEvents *v1.EventList, err error) *CertificateStatus { if err != nil { status.SecretStatus = &SecretStatus{Error: err} return status @@ -213,7 +217,7 @@ func (status *CertificateStatus) withSecret(secret *v1.Secret, err error) *Certi ExtKeyUsage: x509Cert.ExtKeyUsage, PublicKeyAlgorithm: x509Cert.PublicKeyAlgorithm, SignatureAlgorithm: x509Cert.SignatureAlgorithm, SubjectKeyId: x509Cert.SubjectKeyId, AuthorityKeyId: x509Cert.AuthorityKeyId, - SerialNumber: x509Cert.SerialNumber} + SerialNumber: x509Cert.SerialNumber, Events: secretEvents} return status } @@ -289,13 +293,7 @@ func (status *CertificateStatus) String() string { output += fmt.Sprintf("DNS Names:\n%s", formatStringSlice(status.DNSNames)) - var buf bytes.Buffer - tabWriter := util.NewTabWriter(&buf) - prefixWriter := describe.NewPrefixWriter(tabWriter) - util.DescribeEvents(status.Events, prefixWriter, 0) - tabWriter.Flush() - output += buf.String() - buf.Reset() + output += eventsToString(status.Events, 0) output += status.IssuerStatus.String() output += status.SecretStatus.String() @@ -336,7 +334,9 @@ func (issuerStatus *IssuerStatus) String() string { if conditionMsg == "" { conditionMsg = " No Conditions set\n" } - return fmt.Sprintf(issuerFormat, issuerStatus.Name, issuerStatus.Kind, conditionMsg) + output := fmt.Sprintf(issuerFormat, issuerStatus.Name, issuerStatus.Kind, conditionMsg) + output += eventsToString(issuerStatus.Events, 1) + return output } // String returns the information about the status of a Secret as a string to be printed as output @@ -363,12 +363,14 @@ func (secretStatus *SecretStatus) String() string { if err != nil { extKeyUsageString = err.Error() } - return fmt.Sprintf(secretFormat, secretStatus.Name, strings.Join(secretStatus.IssuerCountry, ", "), + output := fmt.Sprintf(secretFormat, secretStatus.Name, strings.Join(secretStatus.IssuerCountry, ", "), strings.Join(secretStatus.IssuerOrganisation, ", "), secretStatus.IssuerCommonName, keyUsageToString(secretStatus.KeyUsage), extKeyUsageString, secretStatus.PublicKeyAlgorithm, secretStatus.SignatureAlgorithm, hex.EncodeToString(secretStatus.SubjectKeyId), hex.EncodeToString(secretStatus.AuthorityKeyId), hex.EncodeToString(secretStatus.SerialNumber.Bytes())) + output += eventsToString(secretStatus.Events, 1) + return output } var ( @@ -442,13 +444,7 @@ func (crStatus *CRStatus) String() string { infos := fmt.Sprintf(crFormat, crStatus.Name, crStatus.Namespace, conditionMsg) infos = fmt.Sprintf("CertificateRequest:%s", infos) - var buf bytes.Buffer - tabWriter := util.NewTabWriter(&buf) - prefixWriter := describe.NewPrefixWriter(tabWriter) - util.DescribeEvents(crStatus.Events, prefixWriter, 1) - tabWriter.Flush() - infos += buf.String() - buf.Reset() + infos += eventsToString(crStatus.Events, 1) return infos } @@ -501,3 +497,13 @@ func (challengeStatus *ChallengeStatus) String() string { challengeStatus.Name, challengeStatus.Type, challengeStatus.Token, challengeStatus.Key, challengeStatus.State, challengeStatus.Reason, challengeStatus.Processing, challengeStatus.Presented) } + +func eventsToString(events *v1.EventList, baseLevel int) string { + var buf bytes.Buffer + defer buf.Reset() + tabWriter := util.NewTabWriter(&buf) + prefixWriter := describe.NewPrefixWriter(tabWriter) + util.DescribeEvents(events, prefixWriter, baseLevel) + tabWriter.Flush() + return buf.String() +} diff --git a/test/integration/ctl/ctl_status_certificate_test.go b/test/integration/ctl/ctl_status_certificate_test.go index a682b5547..a090f3b27 100644 --- a/test/integration/ctl/ctl_status_certificate_test.go +++ b/test/integration/ctl/ctl_status_certificate_test.go @@ -163,6 +163,7 @@ Issuer: Kind: ClusterIssuer Conditions: No Conditions set + Events: error when finding Secret "example-tls": secrets "example-tls" not found Not Before: Not After: 2020-09-16T09:26:18Z @@ -235,6 +236,7 @@ Issuer: Kind: Issuer Conditions: No Conditions set + Events: Secret: Name: existing-tls-secret Issuer Country: @@ -247,6 +249,7 @@ Secret: Subject Key ID: Authority Key ID: Serial Number: e2f88edc942c148463219da909fd633a + Events: Not Before: Not After: 2020-09-16T09:26:18Z Renewal Time: