consul/internal/resource/equality.go

175 lines
3.6 KiB
Go
Raw Normal View History

// Copyright (c) HashiCorp, Inc.
[COMPLIANCE] License changes (#18443) * Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Updating the license from MPL to Business Source License Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at <Blog URL>, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl. * add missing license headers * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 --------- Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
2023-08-11 13:12:13 +00:00
// SPDX-License-Identifier: BUSL-1.1
package resource
import "github.com/hashicorp/consul/proto-public/pbresource"
// EqualType compares two resource types for equality without reflection.
func EqualType(a, b *pbresource.Type) bool {
if a == b {
return true
}
if a == nil || b == nil {
return false
}
return a.Group == b.Group &&
a.GroupVersion == b.GroupVersion &&
a.Kind == b.Kind
}
// EqualTenancy compares two resource tenancies for equality without reflection.
func EqualTenancy(a, b *pbresource.Tenancy) bool {
if a == b {
return true
}
if a == nil || b == nil {
return false
}
return a.Partition == b.Partition &&
a.Namespace == b.Namespace
}
// TODO(peering/v2) add equality method peer tenancy
// EqualID compares two resource IDs for equality without reflection.
func EqualID(a, b *pbresource.ID) bool {
if a == b {
return true
}
if a == nil || b == nil {
return false
}
return EqualType(a.Type, b.Type) &&
EqualTenancy(a.Tenancy, b.Tenancy) &&
a.Name == b.Name &&
a.Uid == b.Uid
}
// EqualStatus compares two statuses for equality without reflection.
//
// Pass true for compareUpdatedAt to compare the UpdatedAt timestamps, which you
// generally *don't* want when dirty checking the status in a controller.
func EqualStatus(a, b *pbresource.Status, compareUpdatedAt bool) bool {
if a == b {
return true
}
if a == nil || b == nil {
return false
}
if a.ObservedGeneration != b.ObservedGeneration {
return false
}
if compareUpdatedAt && !a.UpdatedAt.AsTime().Equal(b.UpdatedAt.AsTime()) {
return false
}
if len(a.Conditions) != len(b.Conditions) {
return false
}
for i, ac := range a.Conditions {
bc := b.Conditions[i]
if !EqualCondition(ac, bc) {
return false
}
}
return true
}
// EqualCondition compares two conditions for equality without reflection.
func EqualCondition(a, b *pbresource.Condition) bool {
if a == b {
return true
}
if a == nil || b == nil {
return false
}
return a.Type == b.Type &&
a.State == b.State &&
a.Reason == b.Reason &&
a.Message == b.Message &&
EqualReference(a.Resource, b.Resource)
}
// EqualReference compares two references for equality without reflection.
func EqualReference(a, b *pbresource.Reference) bool {
if a == b {
return true
}
if a == nil || b == nil {
return false
}
return EqualType(a.Type, b.Type) &&
EqualTenancy(a.Tenancy, b.Tenancy) &&
a.Name == b.Name &&
a.Section == b.Section
}
// ReferenceOrIDMatch compares two references or IDs to see if they both refer
// to the same thing.
//
// Note that this only compares fields that are common between them as
// represented by the ReferenceOrID interface and notably ignores the section
// field on references and the uid field on ids.
func ReferenceOrIDMatch(ref1, ref2 ReferenceOrID) bool {
if ref1 == nil || ref2 == nil {
return false
}
return EqualType(ref1.GetType(), ref2.GetType()) &&
EqualTenancy(ref1.GetTenancy(), ref2.GetTenancy()) &&
ref1.GetName() == ref2.GetName()
}
// EqualStatusMap compares two status maps for equality without reflection.
func EqualStatusMap(a, b map[string]*pbresource.Status) bool {
if len(a) != len(b) {
return false
}
compared := make(map[string]struct{})
for k, av := range a {
bv, ok := b[k]
if !ok {
return false
}
if !EqualStatus(av, bv, true) {
return false
}
compared[k] = struct{}{}
}
for k, bv := range b {
if _, skip := compared[k]; skip {
continue
}
av, ok := a[k]
if !ok {
return false
}
if !EqualStatus(av, bv, true) {
return false
}
}
return true
}