Skip to content

Commit

Permalink
k8s: fix a bug in k8s version parsing. Fixes #3870 (#3917)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicks committed Nov 12, 2020
1 parent e9d9800 commit 2d1d321
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 7 deletions.
24 changes: 19 additions & 5 deletions internal/k8s/watch.go
Expand Up @@ -4,9 +4,9 @@ import (
"context"
"fmt"
"net/http"
"strconv"
"time"

"github.com/blang/semver"
"github.com/pkg/errors"
v1 "k8s.io/api/core/v1"
apiErrors "k8s.io/apimachinery/pkg/api/errors"
Expand All @@ -15,6 +15,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/version"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/informers"
"k8s.io/client-go/metadata/metadatainformer"
Expand Down Expand Up @@ -276,6 +277,20 @@ func (kCli K8sClient) WatchServices(ctx context.Context, ns Namespace, ls labels
return ch, nil
}

func supportsPartialMetadata(v *version.Info) bool {
k1dot15, err := semver.ParseTolerant("v1.15.0")
if err != nil {
return false
}
version, err := semver.ParseTolerant(v.GitVersion)
if err != nil {
// If we don't recognize the version number,
// assume this server doesn't support metadata.
return false
}
return version.GTE(k1dot15)
}

func (kCli K8sClient) WatchMeta(ctx context.Context, gvk schema.GroupVersionKind, ns Namespace) (<-chan ObjectMeta, error) {
gvr, err := kCli.gvr(ctx, gvk)
if err != nil {
Expand All @@ -287,11 +302,10 @@ func (kCli K8sClient) WatchMeta(ctx context.Context, gvk schema.GroupVersionKind
return nil, errors.Wrap(err, "WatchMeta")
}

minor, err := strconv.Atoi(version.Minor)
if version.Major == "1" && err == nil && minor <= 14 {
return kCli.watchMeta14Minus(ctx, gvr, ns)
if supportsPartialMetadata(version) {
return kCli.watchMeta15Plus(ctx, gvr, ns)
}
return kCli.watchMeta15Plus(ctx, gvr, ns)
return kCli.watchMeta14Minus(ctx, gvr, ns)
}

// workaround a bug in client-go
Expand Down
36 changes: 34 additions & 2 deletions internal/k8s/watch_test.go
Expand Up @@ -311,7 +311,7 @@ func TestK8sClient_WatchMetaBackfillK8s14(t *testing.T) {
tf := newWatchTestFixture(t)
defer tf.TearDown()

tf.version.Minor = "14"
tf.version.GitVersion = "v1.14.1"

pod1 := fakePod(PodID("abcd"), "efgh")
pod2 := fakePod(PodID("1234"), "hieruyge")
Expand All @@ -323,6 +323,38 @@ func TestK8sClient_WatchMetaBackfillK8s14(t *testing.T) {
tf.assertMeta(expected, ch)
}

type partialMetaTestCase struct {
v string
expected bool
}

func TestSupportsPartialMeta(t *testing.T) {
cases := []partialMetaTestCase{
// minikube
partialMetaTestCase{"v1.19.1", true},
partialMetaTestCase{"v1.15.0", true},
partialMetaTestCase{"v1.14.0", false},

// gke
partialMetaTestCase{"v1.18.10-gke.601", true},
partialMetaTestCase{"v1.15.10-gke.601", true},
partialMetaTestCase{"v1.14.10-gke.601", false},

// microk8s
partialMetaTestCase{"v1.19.3-34+fa32ff1c160058", true},
partialMetaTestCase{"v1.15.3-34+fa32ff1c160058", true},
partialMetaTestCase{"v1.14.3-34+fa32ff1c160058", false},

partialMetaTestCase{"garbage", false},
}
for _, c := range cases {
c := c
t.Run(c.v, func(t *testing.T) {
assert.Equal(t, c.expected, supportsPartialMetadata(&version.Info{GitVersion: c.v}))
})
}
}

type watchTestFixture struct {
t *testing.T
kCli K8sClient
Expand Down Expand Up @@ -384,7 +416,7 @@ func newWatchTestFixture(t *testing.T) *watchTestFixture {
mcs.PrependWatchReactor("*", wr)
ret.metadata = mcs

version := &version.Info{Major: "1", Minor: "19"}
version := &version.Info{Major: "1", Minor: "19", GitVersion: "v1.19.1"}
di := &difake.FakeDiscovery{
Fake: &ktesting.Fake{},
FakedServerVersion: version,
Expand Down

0 comments on commit 2d1d321

Please sign in to comment.