From 99067f2a40668fff45491a5a407ded1ff9393756 Mon Sep 17 00:00:00 2001 From: Forrest Marshall Date: Mon, 14 Feb 2022 10:52:58 -0800 Subject: [PATCH] improve ca cmp --- lib/services/local/trust.go | 40 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/lib/services/local/trust.go b/lib/services/local/trust.go index 5985999dfd82d..a9de1e88d782b 100644 --- a/lib/services/local/trust.go +++ b/lib/services/local/trust.go @@ -16,12 +16,10 @@ package local import ( "context" - "fmt" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/backend" "github.com/gravitational/teleport/lib/services" - log "github.com/sirupsen/logrus" "github.com/gravitational/trace" ) @@ -93,42 +91,42 @@ func (s *CA) UpsertCertAuthority(ca types.CertAuthority) error { return nil } -const compareAndSwapFixExample = "tctl get %s/%s/%s --with-secrets > ca.yaml && tctl create -f ca.yaml && rm ca.yaml" - // CompareAndSwapCertAuthority updates the cert authority value -// if the existing value matches existing parameter, returns nil if succeeds, +// if the existing value matches expected parameter, returns nil if succeeds, // trace.CompareFailed otherwise. -func (s *CA) CompareAndSwapCertAuthority(new, existing types.CertAuthority) error { +func (s *CA) CompareAndSwapCertAuthority(new, expected types.CertAuthority) error { if err := services.ValidateCertAuthority(new); err != nil { return trace.Wrap(err) } - newValue, err := services.MarshalCertAuthority(new) + + key := backend.Key(authoritiesPrefix, string(new.GetType()), new.GetName()) + + actualItem, err := s.Get(context.TODO(), key) if err != nil { return trace.Wrap(err) } - newItem := backend.Item{ - Key: backend.Key(authoritiesPrefix, string(new.GetType()), new.GetName()), - Value: newValue, - Expires: new.Expiry(), + actual, err := services.UnmarshalCertAuthority(actualItem.Value) + if err != nil { + return trace.Wrap(err) + } + + if !services.CertAuthoritiesEquivalent(actual, expected) { + return trace.CompareFailed("cluster %v settings have been updated, try again", new.GetName()) } - existingValue, err := services.MarshalCertAuthority(existing) + newValue, err := services.MarshalCertAuthority(new) if err != nil { return trace.Wrap(err) } - existingItem := backend.Item{ - Key: backend.Key(authoritiesPrefix, string(existing.GetType()), existing.GetName()), - Value: existingValue, - Expires: existing.Expiry(), + newItem := backend.Item{ + Key: key, + Value: newValue, + Expires: new.Expiry(), } - _, err = s.CompareAndSwap(context.TODO(), existingItem, newItem) + _, err = s.CompareAndSwap(context.TODO(), *actualItem, newItem) if err != nil { if trace.IsCompareFailed(err) { - if len(existing.GetMetadata().Labels) >= 2 { - exampleCmd := fmt.Sprintf(compareAndSwapFixExample, existing.GetKind(), existing.GetSubKind(), existing.GetName()) - log.Warnf("comparison failed on certificate authority with multiple labels; if this occurs consistently, try re-saving the resource: %s", exampleCmd) - } return trace.CompareFailed("cluster %v settings have been updated, try again", new.GetName()) } return trace.Wrap(err)