diff --git a/federation/pkg/federation-controller/util/meta.go b/federation/pkg/federation-controller/util/meta.go index 8ac6eeee94f..ca2c0e61939 100644 --- a/federation/pkg/federation-controller/util/meta.go +++ b/federation/pkg/federation-controller/util/meta.go @@ -20,6 +20,7 @@ import ( "reflect" api_v1 "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/runtime" ) // Copies cluster-independent, user provided data from the given ObjectMeta struct. If in @@ -54,7 +55,7 @@ func DeepCopyObjectMeta(obj api_v1.ObjectMeta) api_v1.ObjectMeta { return copyMeta } -// Checks if cluster-independed, user provided data in two given ObjectMeta are eqaul. If in +// Checks if cluster-independent, user provided data in two given ObjectMeta are equal. If in // the future the ObjectMeta structure is expanded then any field that is not populated // by the api server should be included here. func ObjectMetaEquivalent(a, b api_v1.ObjectMeta) bool { @@ -72,3 +73,13 @@ func ObjectMetaEquivalent(a, b api_v1.ObjectMeta) bool { } return true } + +// Checks if cluster-independent, user provided data in ObjectMeta and Spec in two given top +// level api objects are equivalent. +func ObjectMetaAndSpecEquivalent(a, b runtime.Object) bool { + objectMetaA := reflect.ValueOf(a).Elem().FieldByName("ObjectMeta").Interface().(api_v1.ObjectMeta) + objectMetaB := reflect.ValueOf(b).Elem().FieldByName("ObjectMeta").Interface().(api_v1.ObjectMeta) + specA := reflect.ValueOf(a).Elem().FieldByName("Spec").Interface() + specB := reflect.ValueOf(b).Elem().FieldByName("Spec").Interface() + return ObjectMetaEquivalent(objectMetaA, objectMetaB) && reflect.DeepEqual(specA, specB) +} diff --git a/federation/pkg/federation-controller/util/meta_test.go b/federation/pkg/federation-controller/util/meta_test.go index bf1c67758e5..c5638add590 100644 --- a/federation/pkg/federation-controller/util/meta_test.go +++ b/federation/pkg/federation-controller/util/meta_test.go @@ -65,3 +65,38 @@ func TestObjectMeta(t *testing.T) { assert.True(t, ObjectMetaEquivalent(o5, o6)) assert.True(t, ObjectMetaEquivalent(o3, o5)) } + +func TestObjectMetaAndSpec(t *testing.T) { + s1 := api_v1.Service{ + ObjectMeta: api_v1.ObjectMeta{ + Namespace: "ns1", + Name: "s1", + }, + Spec: api_v1.ServiceSpec{ + ExternalName: "Service1", + }, + } + s1b := s1 + s2 := api_v1.Service{ + ObjectMeta: api_v1.ObjectMeta{ + Namespace: "ns1", + Name: "s2", + }, + Spec: api_v1.ServiceSpec{ + ExternalName: "Service1", + }, + } + s3 := api_v1.Service{ + ObjectMeta: api_v1.ObjectMeta{ + Namespace: "ns1", + Name: "s1", + }, + Spec: api_v1.ServiceSpec{ + ExternalName: "Service2", + }, + } + assert.True(t, ObjectMetaAndSpecEquivalent(&s1, &s1b)) + assert.False(t, ObjectMetaAndSpecEquivalent(&s1, &s2)) + assert.False(t, ObjectMetaAndSpecEquivalent(&s1, &s3)) + assert.False(t, ObjectMetaAndSpecEquivalent(&s2, &s3)) +}