Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug 1831711: Fix incompatible GVK detection for 4.3->4.4 migrations #530

Merged
merged 5 commits into from
May 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 44 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 20 additions & 4 deletions pkg/gvk/gvk.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Compare struct {
// Compare GVKs on both clusters, find incompatible GVKs
// and check each plan source namespace for existence of incompatible GVKs
func (r *Compare) Compare() (map[string][]schema.GroupVersionResource, error) {
srcResourceList, err := collectResources(r.SrcDiscovery)
preferredSrcResourceList, err := collectPreferredResources(r.SrcDiscovery)
if err != nil {
return nil, err
}
Expand All @@ -40,12 +40,12 @@ func (r *Compare) Compare() (map[string][]schema.GroupVersionResource, error) {
return nil, err
}

srcResourceList, err = r.excludeCRDs(srcResourceList)
preferredSrcResourceList, err = r.excludeCRDs(preferredSrcResourceList)
if err != nil {
return nil, err
}

resourcesDiff := compareResources(srcResourceList, dstResourceList)
resourcesDiff := compareResources(preferredSrcResourceList, dstResourceList)
incompatibleGVKs, err := convertToGVRList(resourcesDiff)
if err != nil {
return nil, err
Expand All @@ -54,7 +54,7 @@ func (r *Compare) Compare() (map[string][]schema.GroupVersionResource, error) {
return r.collectIncompatibleMapping(incompatibleGVKs)
}

// CollectResources collects all namespaced scoped apiResources from the cluster
// collectResources collects all namespaced scoped apiResources from the cluster
func collectResources(discovery discovery.DiscoveryInterface) ([]*metav1.APIResourceList, error) {
resources, err := discovery.ServerResources()
if err != nil {
Expand All @@ -71,6 +71,22 @@ func collectResources(discovery discovery.DiscoveryInterface) ([]*metav1.APIReso
return resources, nil
}

// collectPreferredResources collects all preferred namespaced scoped apiResources from the cluster
func collectPreferredResources(discovery discovery.DiscoveryInterface) ([]*metav1.APIResourceList, error) {
resources, err := discovery.ServerPreferredNamespacedResources()
if err != nil {
return nil, err
}

for _, res := range resources {
res.APIResources = excludeSubresources(res.APIResources)
// Some resources appear not to have permissions to list, need to exclude those.
res.APIResources = listAllowed(res.APIResources)
}

return resources, nil
}

// convertToGVRList converts provided apiResourceList to list of GroupVersionResources from the server
func convertToGVRList(resourceList []*metav1.APIResourceList) ([]schema.GroupVersionResource, error) {
GVRs := []schema.GroupVersionResource{}
Expand Down
178 changes: 178 additions & 0 deletions pkg/gvk/gvk_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
package gvk

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/discovery"
"k8s.io/client-go/kubernetes/fake"
"reflect"
"testing"
)

//src 4.3
//{
// "kind": "APIGroup",
// "apiVersion": "v1",
// "name": "apps",
// "versions": [
// {
// "groupVersion": "apps/v1",
// "version": "v1"
// },
// {
// "groupVersion": "apps/v1beta2",
// "version": "v1beta2"
// },
// {
// "groupVersion": "apps/v1beta1",
// "version": "v1beta1"
// }
// ],
// "preferredVersion": {
// "groupVersion": "apps/v1",
// "version": "v1"
// }
//}

//dst 4.4
//{
// "kind": "APIGroup",
// "apiVersion": "v1",
// "name": "apps",
// "versions": [
// {
// "groupVersion": "apps/v1",
// "version": "v1"
// }
// ],
// "preferredVersion": {
// "groupVersion": "apps/v1",
// "version": "v1"
// }
//}
func Test_compareResources(t *testing.T) {
type args struct {
src []*metav1.APIResourceList
dst []*metav1.APIResourceList
}
tests := []struct {
name string
args args
want []*metav1.APIResourceList
}{
{
name: "4.3 -> 4.4",
args: args{
src: []*metav1.APIResourceList{
{
GroupVersion: "apps/v1",
APIResources: []metav1.APIResource{
{
Name: "deployments",
Namespaced: true,
Group: "apps",
Version: "v1beta1",
Kind: "Deployment",
ShortNames: []string{"deploy"},
Verbs: []string{"create", "update", "list", "delete"},
},
},
},
},
dst: []*metav1.APIResourceList{
{
GroupVersion: "apps/v1",
APIResources: []metav1.APIResource{
{
Name: "deployments",
Namespaced: true,
Group: "apps",
Version: "v1",
Kind: "Deployment",
ShortNames: []string{"deploy"},
Verbs: []string{"create", "update", "list", "delete"},
},
},
},
{
GroupVersion: "apps/v1beta1",
APIResources: []metav1.APIResource{
{
Name: "deployments",
Namespaced: true,
Group: "apps",
Version: "v1beta1",
Kind: "Deployment",
ShortNames: []string{"deploy"},
Verbs: []string{"create", "update", "list", "delete"},
},
},
},
{
GroupVersion: "apps/v1beta2",
APIResources: []metav1.APIResource{
{
Name: "deployments",
Namespaced: true,
Group: "apps",
Version: "v1",
Kind: "Deployment",
ShortNames: []string{"deploy"},
Verbs: []string{"create", "update", "list", "delete"},
},
},
},
},
},
want: []*metav1.APIResourceList{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := compareResources(tt.args.src, tt.args.dst); !reflect.DeepEqual(got, tt.want) {
t.Errorf("compareResources() = %v, want %v", got, tt.want)
}
})
}
}

func Test_collectPreferredResources(t *testing.T) {
fakeKubeClient := fake.NewSimpleClientset()
serverGroups, err := fakeKubeClient.Discovery().ServerGroups()
var preferredDeployment metav1.GroupVersionForDiscovery
if err != nil {
t.Fatal(err)
}
for _, group := range serverGroups.Groups {
if group.Kind == "deployments" {
preferredDeployment = group.PreferredVersion
}
}
type args struct {
discovery discovery.DiscoveryInterface
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "client has multiple deployment versions",
args: args{fakeKubeClient.Discovery()},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := collectPreferredResources(tt.args.discovery)
if (err != nil) != tt.wantErr {
t.Errorf("collectResources() error = %v, wantErr %v", err, tt.wantErr)
return
}
for _, resources := range got {
if resources.Kind == "deployments" && resources.GroupVersion != preferredDeployment.GroupVersion {
t.Fail()
}
}
})
}
}
19 changes: 19 additions & 0 deletions vendor/github.com/evanphx/json-patch/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions vendor/github.com/evanphx/json-patch/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.