-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Using discovery client to properly check for cluster-scoped resources (…
…#1319) Summary: - [x] proper applying and re-applying of cluster-scoped resources in the apply task - [x] ownership is **NOT** set for cluster-scoped resources to the `Instance` **Note**: the second change has implications, because we would previously set `ownerReference` of **all** resources (even cluster-scoped ones like CRDs) to the `Instance` and though k8s [GC docs](https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/) clearly state that _"Cross-namespace owner references are disallowed by design"_ it would still garbage collect them when the Instance was uninstalled. This is not the case anymore. Operators must utilize the `cleanup` plan to remove cluster-scoped resources. Fixes #1288 #1265 Co-authored-by: Andreas Neumann <aneumann@mesosphere.com>
- Loading branch information
1 parent
2fb38e4
commit ff85649
Showing
17 changed files
with
260 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package resource | ||
|
||
import ( | ||
"fmt" | ||
|
||
"k8s.io/apimachinery/pkg/runtime" | ||
"k8s.io/apimachinery/pkg/runtime/schema" | ||
"k8s.io/client-go/discovery" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
) | ||
|
||
// ObjectKeyFromObject method wraps client.ObjectKeyFromObject method by additionally checking if passed object is | ||
// a cluster-scoped resource (e.g. CustomResourceDefinition, ClusterRole etc.) and removing the namespace from the | ||
// key since cluster-scoped resources are not namespaced. | ||
func ObjectKeyFromObject(r runtime.Object, di discovery.DiscoveryInterface) (client.ObjectKey, error) { | ||
key, err := client.ObjectKeyFromObject(r) | ||
if err != nil { | ||
return client.ObjectKey{}, fmt.Errorf("failed to get an object key from object %v: %v", r.GetObjectKind(), err) | ||
} | ||
|
||
// if the resource is cluster-scoped we need to clear then namespace from the key | ||
isNamespaced, err := IsNamespacedObject(r, di) | ||
if err != nil { | ||
return client.ObjectKey{}, fmt.Errorf("failed to determine if the resource %v is cluster-scoped: %v", r.GetObjectKind(), err) | ||
} | ||
|
||
if !isNamespaced { | ||
key.Namespace = "" | ||
} | ||
return key, nil | ||
} | ||
|
||
func IsNamespacedObject(r runtime.Object, di discovery.DiscoveryInterface) (bool, error) { | ||
gvk := r.GetObjectKind().GroupVersionKind() | ||
return isNamespaced(gvk, di) | ||
} | ||
|
||
// isNamespaced method return true if given runtime.Object is a namespaced (not cluster-scoped) resource. It uses the | ||
// discovery client to fetch all API resources (with Groups and Versions), searches for a resource with the passed GVK | ||
// and returns true if it's namespaced. Method returns an error if passed GVK wasn't found in the discovered resource list. | ||
func isNamespaced(gvk schema.GroupVersionKind, di discovery.DiscoveryInterface) (bool, error) { | ||
// Fetch namespaced API resources | ||
_, apiResources, err := di.ServerGroupsAndResources() | ||
if err != nil { | ||
return false, fmt.Errorf("failed to fetch server groups and resources: %v", err) | ||
} | ||
|
||
for _, rr := range apiResources { | ||
gv, err := schema.ParseGroupVersion(rr.GroupVersion) | ||
if err != nil { | ||
continue | ||
} | ||
for _, r := range rr.APIResources { | ||
if gvk == gv.WithKind(r.Kind) { | ||
return r.Namespaced, nil | ||
} | ||
//log.Printf("[%s], Name: %s: %v", gvk, r.Name, r.Namespaced) | ||
} | ||
} | ||
|
||
return false, fmt.Errorf("a resource with GVK %v seems to be missing in API resource list", gvk) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package resource | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"k8s.io/apimachinery/pkg/runtime/schema" | ||
"k8s.io/client-go/discovery" | ||
|
||
"github.com/kudobuilder/kudo/pkg/test/utils" | ||
) | ||
|
||
func Test_isNamespaced(t *testing.T) { | ||
fdc := utils.FakeDiscoveryClient() | ||
|
||
tests := []struct { | ||
name string | ||
gvk schema.GroupVersionKind | ||
di discovery.DiscoveryInterface | ||
want bool | ||
wantErr bool | ||
}{ | ||
{ | ||
name: "pod", | ||
gvk: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"}, | ||
di: fdc, | ||
want: true, | ||
wantErr: false, | ||
}, | ||
{ | ||
name: "namespace", | ||
gvk: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Namespace"}, | ||
di: fdc, | ||
want: false, | ||
wantErr: false, | ||
}, | ||
{ | ||
name: "customresourcedefinition", | ||
gvk: schema.GroupVersionKind{Group: "apiextensions.k8s.io", Version: "v1beta1", Kind: "CustomResourceDefinition"}, | ||
di: fdc, | ||
want: false, | ||
wantErr: false, | ||
}, | ||
{ | ||
name: "fake", | ||
gvk: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Fake"}, | ||
di: fdc, | ||
want: false, | ||
wantErr: true, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
tt := tt | ||
t.Run(tt.name, func(t *testing.T) { | ||
got, err := isNamespaced(tt.gvk, tt.di) | ||
|
||
assert.True(t, (err != nil) == tt.wantErr) | ||
assert.Equal(t, tt.want, got) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.