diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/BUILD b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/BUILD index 2ce980fa757..6e91c751e16 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/BUILD +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/BUILD @@ -11,6 +11,7 @@ load( go_test( name = "go_default_test", srcs = [ + "controller_ref_test.go", "duration_test.go", "group_version_test.go", "helpers_test.go", @@ -25,12 +26,14 @@ go_test( "//vendor/github.com/ghodss/yaml:go_default_library", "//vendor/github.com/ugorji/go/codec:go_default_library", "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", ], ) go_library( name = "go_default_library", srcs = [ + "controller_ref.go", "conversion.go", "doc.go", "duration.go", diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/controller_ref.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/controller_ref.go new file mode 100644 index 00000000000..042cd5b9c55 --- /dev/null +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/controller_ref.go @@ -0,0 +1,54 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// IsControlledBy checks if the object has a controllerRef set to the given owner +func IsControlledBy(obj Object, owner Object) bool { + ref := GetControllerOf(obj) + if ref == nil { + return false + } + return ref.UID == owner.GetUID() +} + +// GetControllerOf returns a pointer to a copy of the controllerRef if controllee has a controller +func GetControllerOf(controllee Object) *OwnerReference { + for _, ref := range controllee.GetOwnerReferences() { + if ref.Controller != nil && *ref.Controller { + return &ref + } + } + return nil +} + +// NewControllerRef creates an OwnerReference pointing to the given owner. +func NewControllerRef(owner Object, gvk schema.GroupVersionKind) *OwnerReference { + blockOwnerDeletion := true + isController := true + return &OwnerReference{ + APIVersion: gvk.GroupVersion().String(), + Kind: gvk.Kind, + Name: owner.GetName(), + UID: owner.GetUID(), + BlockOwnerDeletion: &blockOwnerDeletion, + Controller: &isController, + } +} diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/controller_ref_test.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/controller_ref_test.go new file mode 100644 index 00000000000..add764a331f --- /dev/null +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/controller_ref_test.go @@ -0,0 +1,133 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "testing" + + "k8s.io/apimachinery/pkg/runtime/schema" +) + +type metaObj struct { + ObjectMeta + TypeMeta +} + +func TestNewControllerRef(t *testing.T) { + gvk := schema.GroupVersionKind{ + Group: "group", + Version: "v1", + Kind: "Kind", + } + obj1 := &metaObj{ + ObjectMeta: ObjectMeta{ + Name: "name", + UID: "uid1", + }, + } + controllerRef := NewControllerRef(obj1, gvk) + if controllerRef.UID != obj1.UID { + t.Errorf("Incorrect UID: %s", controllerRef.UID) + } + if controllerRef.Controller == nil || *controllerRef.Controller != true { + t.Error("Controller must be set to true") + } + if controllerRef.BlockOwnerDeletion == nil || *controllerRef.BlockOwnerDeletion != true { + t.Error("BlockOwnerDeletion must be set to true") + } + if controllerRef.APIVersion == "" || + controllerRef.Kind == "" || + controllerRef.Name == "" { + t.Errorf("All controllerRef fields must be set: %v", controllerRef) + } +} + +func TestGetControllerOf(t *testing.T) { + gvk := schema.GroupVersionKind{ + Group: "group", + Version: "v1", + Kind: "Kind", + } + obj1 := &metaObj{ + ObjectMeta: ObjectMeta{ + UID: "uid1", + Name: "name1", + }, + } + controllerRef := NewControllerRef(obj1, gvk) + var falseRef = false + obj2 := &metaObj{ + ObjectMeta: ObjectMeta{ + UID: "uid2", + Name: "name1", + OwnerReferences: []OwnerReference{ + { + Name: "owner1", + Controller: &falseRef, + }, + *controllerRef, + { + Name: "owner2", + Controller: &falseRef, + }, + }, + }, + } + + if GetControllerOf(obj1) != nil { + t.Error("GetControllerOf must return null") + } + c := GetControllerOf(obj2) + if c.Name != controllerRef.Name || c.UID != controllerRef.UID { + t.Errorf("Incorrect result of GetControllerOf: %v", c) + } +} + +func TestIsControlledBy(t *testing.T) { + gvk := schema.GroupVersionKind{ + Group: "group", + Version: "v1", + Kind: "Kind", + } + obj1 := &metaObj{ + ObjectMeta: ObjectMeta{ + UID: "uid1", + }, + } + obj2 := &metaObj{ + ObjectMeta: ObjectMeta{ + UID: "uid2", + OwnerReferences: []OwnerReference{ + *NewControllerRef(obj1, gvk), + }, + }, + } + obj3 := &metaObj{ + ObjectMeta: ObjectMeta{ + UID: "uid3", + OwnerReferences: []OwnerReference{ + *NewControllerRef(obj2, gvk), + }, + }, + } + if !IsControlledBy(obj2, obj1) || !IsControlledBy(obj3, obj2) { + t.Error("Incorrect IsControlledBy result: false") + } + if IsControlledBy(obj3, obj1) { + t.Error("Incorrect IsControlledBy result: true") + } +}