Use v2 types with agg discovery

This commit is contained in:
Jefftree
2024-01-19 16:13:47 -05:00
parent 301e804c3f
commit 462dd326c2
30 changed files with 2664 additions and 333 deletions

View File

@@ -28,7 +28,7 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
apidiscoveryv2beta1 "k8s.io/api/apidiscovery/v2beta1"
apidiscoveryv2 "k8s.io/api/apidiscovery/v2"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextensions "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
"k8s.io/apimachinery/pkg/api/meta"
@@ -79,14 +79,14 @@ var (
codecs = runtimeserializer.NewCodecFactory(scheme)
serialize runtime.NegotiatedSerializer
basicTestGroup = apidiscoveryv2beta1.APIGroupDiscovery{
basicTestGroup = apidiscoveryv2.APIGroupDiscovery{
ObjectMeta: metav1.ObjectMeta{
Name: "stable.example.com",
},
Versions: []apidiscoveryv2beta1.APIVersionDiscovery{
Versions: []apidiscoveryv2.APIVersionDiscovery{
{
Version: "v1",
Resources: []apidiscoveryv2beta1.APIResourceDiscovery{
Resources: []apidiscoveryv2.APIResourceDiscovery{
{
Resource: "jobs",
Verbs: []string{"create", "list", "watch", "delete"},
@@ -94,19 +94,19 @@ var (
Categories: []string{"all"},
},
},
Freshness: apidiscoveryv2beta1.DiscoveryFreshnessCurrent,
Freshness: apidiscoveryv2.DiscoveryFreshnessCurrent,
},
},
}
basicTestGroupWithFixup = apidiscoveryv2beta1.APIGroupDiscovery{
basicTestGroupWithFixup = apidiscoveryv2.APIGroupDiscovery{
ObjectMeta: metav1.ObjectMeta{
Name: "stable.example.com",
},
Versions: []apidiscoveryv2beta1.APIVersionDiscovery{
Versions: []apidiscoveryv2.APIVersionDiscovery{
{
Version: "v1",
Resources: []apidiscoveryv2beta1.APIResourceDiscovery{
Resources: []apidiscoveryv2.APIResourceDiscovery{
{
Resource: "jobs",
Verbs: []string{"create", "list", "watch", "delete"},
@@ -116,19 +116,19 @@ var (
ResponseKind: &metav1.GroupVersionKind{},
},
},
Freshness: apidiscoveryv2beta1.DiscoveryFreshnessCurrent,
Freshness: apidiscoveryv2.DiscoveryFreshnessCurrent,
},
},
}
basicTestGroupStale = apidiscoveryv2beta1.APIGroupDiscovery{
basicTestGroupStale = apidiscoveryv2.APIGroupDiscovery{
ObjectMeta: metav1.ObjectMeta{
Name: "stable.example.com",
},
Versions: []apidiscoveryv2beta1.APIVersionDiscovery{
Versions: []apidiscoveryv2.APIVersionDiscovery{
{
Version: "v1",
Freshness: apidiscoveryv2beta1.DiscoveryFreshnessStale,
Freshness: apidiscoveryv2.DiscoveryFreshnessStale,
},
},
}
@@ -193,7 +193,7 @@ func TestReadinessAggregatedAPIServiceDiscovery(t *testing.T) {
// Create a resource manager whichs serves our GroupVersion
resourceManager := discoveryendpoint.NewResourceManager("apis")
resourceManager.SetGroups([]apidiscoveryv2beta1.APIGroupDiscovery{basicTestGroup})
resourceManager.SetGroups([]apidiscoveryv2.APIGroupDiscovery{basicTestGroup})
apiServiceWaitCh := make(chan struct{})
@@ -290,7 +290,7 @@ func TestAggregatedAPIServiceDiscovery(t *testing.T) {
// Create a resource manager whichs serves our GroupVersion
resourceManager := discoveryendpoint.NewResourceManager("apis")
resourceManager.SetGroups([]apidiscoveryv2beta1.APIGroupDiscovery{basicTestGroup})
resourceManager.SetGroups([]apidiscoveryv2.APIGroupDiscovery{basicTestGroup})
// Install our ResourceManager as an Aggregated APIService to the
// test server
@@ -371,7 +371,7 @@ func runTestCases(t *testing.T, cases []testCase) {
})
require.NoError(t, err, "v1 discovery must reset between tests: "+diff)
err = WaitForResultWithCondition(ctx, client, func(result apidiscoveryv2beta1.APIGroupDiscoveryList) bool {
err = WaitForResultWithCondition(ctx, client, func(result apidiscoveryv2.APIGroupDiscoveryList) bool {
diff = cmp.Diff(originalV2, result)
return reflect.DeepEqual(result, originalV2)
})
@@ -393,6 +393,7 @@ func TestCRD(t *testing.T) {
applyCRD(makeCRDSpec(stableGroup, "Foo", false, []string{"v1", "v1alpha1", "v1beta1", "v2"})),
waitForGroupVersionsV1([]metav1.GroupVersion{stableV1, stableV1alpha1, stableV1beta1, stableV2}),
waitForGroupVersionsV2([]metav1.GroupVersion{stableV1, stableV1alpha1, stableV1beta1, stableV2}),
waitForGroupVersionsV2Beta1([]metav1.GroupVersion{stableV1, stableV1alpha1, stableV1beta1, stableV2}),
},
},
{
@@ -402,6 +403,7 @@ func TestCRD(t *testing.T) {
applyCRD(makeCRDSpec(stableGroup, "Foo", false, []string{"v1", "v1alpha1", "v1beta1", "v2"})),
waitForGroupVersionsV1([]metav1.GroupVersion{stableV1, stableV1alpha1, stableV1beta1, stableV2}),
waitForGroupVersionsV2([]metav1.GroupVersion{stableV1, stableV1alpha1, stableV1beta1, stableV2}),
waitForGroupVersionsV2Beta1([]metav1.GroupVersion{stableV1, stableV1alpha1, stableV1beta1, stableV2}),
deleteObject{
GroupVersionResource: metav1.GroupVersionResource(apiextensionsv1.SchemeGroupVersion.WithResource("customresourcedefinitions")),
Name: "foos.stable.example.com",
@@ -469,6 +471,7 @@ func TestCRD(t *testing.T) {
// Wait for GV to appear in both discovery documents
waitForGroupVersionsV1([]metav1.GroupVersion{stableV2, stableV1alpha1}),
waitForGroupVersionsV2([]metav1.GroupVersion{stableV2, stableV1alpha1}),
waitForGroupVersionsV2Beta1([]metav1.GroupVersion{stableV2, stableV1alpha1}),
applyAPIService(
apiregistrationv1.APIServiceSpec{
@@ -487,11 +490,13 @@ func TestCRD(t *testing.T) {
// We should now have stable v1 available
waitForGroupVersionsV1([]metav1.GroupVersion{stableV1}),
waitForGroupVersionsV2([]metav1.GroupVersion{stableV1}),
waitForGroupVersionsV2Beta1([]metav1.GroupVersion{stableV1}),
// The CRD group-versions not served by the aggregated
// apiservice should still be availablee
waitForGroupVersionsV1([]metav1.GroupVersion{stableV2, stableV1alpha1}),
waitForGroupVersionsV2([]metav1.GroupVersion{stableV2, stableV1alpha1}),
waitForGroupVersionsV2Beta1([]metav1.GroupVersion{stableV2, stableV1alpha1}),
// Remove API service. Show we have switched to CRD
deleteObject{
@@ -502,9 +507,11 @@ func TestCRD(t *testing.T) {
// Show that we still have stable v1 since it is in the CRD
waitForGroupVersionsV1([]metav1.GroupVersion{stableV2, stableV1alpha1}),
waitForGroupVersionsV2([]metav1.GroupVersion{stableV2, stableV1alpha1}),
waitForGroupVersionsV2Beta1([]metav1.GroupVersion{stableV2, stableV1alpha1}),
waitForAbsentGroupVersionsV1([]metav1.GroupVersion{stableV1}),
waitForAbsentGroupVersionsV2([]metav1.GroupVersion{stableV1}),
waitForAbsentGroupVersionsV2Beta1([]metav1.GroupVersion{stableV1}),
},
},
{
@@ -635,9 +642,9 @@ func TestFreshness(t *testing.T) {
}
switch entry.Freshness {
case apidiscoveryv2beta1.DiscoveryFreshnessCurrent:
case apidiscoveryv2.DiscoveryFreshnessCurrent:
// Skip
case apidiscoveryv2beta1.DiscoveryFreshnessStale:
case apidiscoveryv2.DiscoveryFreshnessStale:
staleGVs = append(staleGVs, targetGv)
default:
return fmt.Errorf("unrecognized freshness '%v' on gv '%v'", entry.Freshness, targetGv)
@@ -704,7 +711,7 @@ func TestFreshness(t *testing.T) {
// Shows a group for which multiple APIServices specify a GroupPriorityMinimum,
// it is sorted the same in both versions of discovery
func TestGroupPriorty(t *testing.T) {
func TestGroupPriority(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AggregatedDiscoveryEndpoint, true)()
makeApiServiceSpec := func(gv metav1.GroupVersion, groupPriorityMin, versionPriority int) apiregistrationv1.APIServiceSpec {

View File

@@ -36,6 +36,7 @@ import (
"k8s.io/client-go/kubernetes"
aggregator "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
apidiscoveryv2 "k8s.io/api/apidiscovery/v2"
apidiscoveryv2beta1 "k8s.io/api/apidiscovery/v2beta1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -43,7 +44,8 @@ import (
)
const acceptV1JSON = "application/json"
const acceptV2JSON = "application/json;g=apidiscovery.k8s.io;v=v2beta1;as=APIGroupDiscoveryList"
const acceptV2Beta1JSON = "application/json;g=apidiscovery.k8s.io;v=v2beta1;as=APIGroupDiscoveryList"
const acceptV2JSON = "application/json;g=apidiscovery.k8s.io;v=v2;as=APIGroupDiscoveryList"
const maxTimeout = 10 * time.Second
@@ -93,9 +95,15 @@ type waitForAbsentGroupVersionsV1 []metav1.GroupVersion
// Wait for groupversions to appear in v2 discovery
type waitForGroupVersionsV2 []metav1.GroupVersion
// Wait for groupversions to appear in v2beta1 discovery
type waitForGroupVersionsV2Beta1 []metav1.GroupVersion
// Wait for groupversions to disappear from v2 discovery
type waitForAbsentGroupVersionsV2 []metav1.GroupVersion
// Wait for groupversions to disappear from v2beta1 discovery
type waitForAbsentGroupVersionsV2Beta1 []metav1.GroupVersion
type waitForStaleGroupVersionsV2 []metav1.GroupVersion
type waitForFreshGroupVersionsV2 []metav1.GroupVersion
@@ -144,10 +152,11 @@ func (a applyAPIService) Cleanup(ctx context.Context, client testClient) error {
return err
}
err = wait.PollWithContext(
err = wait.PollUntilContextTimeout(
ctx,
250*time.Millisecond,
maxTimeout,
true,
func(ctx context.Context) (done bool, err error) {
_, err = client.ApiregistrationV1().APIServices().Get(ctx, name, metav1.GetOptions{})
if err == nil {
@@ -212,10 +221,11 @@ func (a applyCRD) Cleanup(ctx context.Context, client testClient) error {
return err
}
err = wait.PollWithContext(
err = wait.PollUntilContextTimeout(
ctx,
250*time.Millisecond,
maxTimeout,
true,
func(ctx context.Context) (done bool, err error) {
_, err = client.ApiextensionsV1().CustomResourceDefinitions().Get(ctx, name, metav1.GetOptions{})
if err == nil {
@@ -248,9 +258,9 @@ func (d deleteObject) Do(ctx context.Context, client testClient) error {
}
func (w waitForStaleGroupVersionsV2) Do(ctx context.Context, client testClient) error {
err := WaitForResultWithCondition(ctx, client, func(result apidiscoveryv2beta1.APIGroupDiscoveryList) bool {
err := WaitForResultWithCondition(ctx, client, func(result apidiscoveryv2.APIGroupDiscoveryList) bool {
for _, gv := range w {
if info := FindGroupVersionV2(result, gv); info == nil || info.Freshness != apidiscoveryv2beta1.DiscoveryFreshnessStale {
if info := FindGroupVersionV2(result, gv); info == nil || info.Freshness != apidiscoveryv2.DiscoveryFreshnessStale {
return false
}
}
@@ -265,9 +275,9 @@ func (w waitForStaleGroupVersionsV2) Do(ctx context.Context, client testClient)
}
func (w waitForFreshGroupVersionsV2) Do(ctx context.Context, client testClient) error {
err := WaitForResultWithCondition(ctx, client, func(result apidiscoveryv2beta1.APIGroupDiscoveryList) bool {
err := WaitForResultWithCondition(ctx, client, func(result apidiscoveryv2.APIGroupDiscoveryList) bool {
for _, gv := range w {
if info := FindGroupVersionV2(result, gv); info == nil || info.Freshness != apidiscoveryv2beta1.DiscoveryFreshnessCurrent {
if info := FindGroupVersionV2(result, gv); info == nil || info.Freshness != apidiscoveryv2.DiscoveryFreshnessCurrent {
return false
}
}
@@ -282,7 +292,7 @@ func (w waitForFreshGroupVersionsV2) Do(ctx context.Context, client testClient)
}
func (w waitForGroupVersionsV2) Do(ctx context.Context, client testClient) error {
err := WaitForResultWithCondition(ctx, client, func(result apidiscoveryv2beta1.APIGroupDiscoveryList) bool {
err := WaitForResultWithCondition(ctx, client, func(result apidiscoveryv2.APIGroupDiscoveryList) bool {
for _, gv := range w {
if FindGroupVersionV2(result, gv) == nil {
return false
@@ -298,8 +308,25 @@ func (w waitForGroupVersionsV2) Do(ctx context.Context, client testClient) error
return nil
}
func (w waitForGroupVersionsV2Beta1) Do(ctx context.Context, client testClient) error {
err := WaitForV2Beta1ResultWithCondition(ctx, client, func(result apidiscoveryv2beta1.APIGroupDiscoveryList) bool {
for _, gv := range w {
if FindGroupVersionV2Beta1(result, gv) == nil {
return false
}
}
return true
})
if err != nil {
return fmt.Errorf("waiting for groupversions v2 (%v): %w", w, err)
}
return nil
}
func (w waitForAbsentGroupVersionsV2) Do(ctx context.Context, client testClient) error {
err := WaitForResultWithCondition(ctx, client, func(result apidiscoveryv2beta1.APIGroupDiscoveryList) bool {
err := WaitForResultWithCondition(ctx, client, func(result apidiscoveryv2.APIGroupDiscoveryList) bool {
for _, gv := range w {
if FindGroupVersionV2(result, gv) != nil {
return false
@@ -315,6 +342,23 @@ func (w waitForAbsentGroupVersionsV2) Do(ctx context.Context, client testClient)
return nil
}
func (w waitForAbsentGroupVersionsV2Beta1) Do(ctx context.Context, client testClient) error {
err := WaitForV2Beta1ResultWithCondition(ctx, client, func(result apidiscoveryv2beta1.APIGroupDiscoveryList) bool {
for _, gv := range w {
if FindGroupVersionV2Beta1(result, gv) != nil {
return false
}
}
return true
})
if err != nil {
return fmt.Errorf("waiting for absent groupversions v2 (%v): %w", w, err)
}
return nil
}
func (w waitForGroupVersionsV1) Do(ctx context.Context, client testClient) error {
err := WaitForV1GroupsWithCondition(ctx, client, func(result metav1.APIGroupList) bool {
for _, gv := range w {
@@ -429,7 +473,7 @@ func (w waitForResourcesAbsentV1) Do(ctx context.Context, client testClient) err
}
func (w waitForResourcesV2) Do(ctx context.Context, client testClient) error {
err := WaitForResultWithCondition(ctx, client, func(result apidiscoveryv2beta1.APIGroupDiscoveryList) bool {
err := WaitForResultWithCondition(ctx, client, func(result apidiscoveryv2.APIGroupDiscoveryList) bool {
for _, gvr := range w {
if info := FindGroupVersionV2(result, metav1.GroupVersion{Group: gvr.Group, Version: gvr.Version}); info == nil {
return false
@@ -458,7 +502,7 @@ func (w waitForResourcesV2) Do(ctx context.Context, client testClient) error {
}
func (w waitForResourcesAbsentV2) Do(ctx context.Context, client testClient) error {
err := WaitForResultWithCondition(ctx, client, func(result apidiscoveryv2beta1.APIGroupDiscoveryList) bool {
err := WaitForResultWithCondition(ctx, client, func(result apidiscoveryv2.APIGroupDiscoveryList) bool {
for _, gvr := range w {
if info := FindGroupVersionV2(result, metav1.GroupVersion{Group: gvr.Group, Version: gvr.Version}); info == nil {
return false
@@ -484,7 +528,7 @@ func (i inlineAction) Do(ctx context.Context, client testClient) error {
return i(ctx, client)
}
func FetchV2Discovery(ctx context.Context, client testClient) (apidiscoveryv2beta1.APIGroupDiscoveryList, error) {
func FetchV2Discovery(ctx context.Context, client testClient) (apidiscoveryv2.APIGroupDiscoveryList, error) {
result, err := client.
Discovery().
RESTClient().
@@ -494,6 +538,29 @@ func FetchV2Discovery(ctx context.Context, client testClient) (apidiscoveryv2bet
Do(ctx).
Raw()
if err != nil {
return apidiscoveryv2.APIGroupDiscoveryList{}, fmt.Errorf("failed to fetch v2 discovery: %w", err)
}
groupList := apidiscoveryv2.APIGroupDiscoveryList{}
err = json.Unmarshal(result, &groupList)
if err != nil {
return apidiscoveryv2.APIGroupDiscoveryList{}, fmt.Errorf("failed to parse v2 discovery: %w", err)
}
return groupList, nil
}
func FetchV2Beta1Discovery(ctx context.Context, client testClient) (apidiscoveryv2beta1.APIGroupDiscoveryList, error) {
result, err := client.
Discovery().
RESTClient().
Get().
AbsPath("/apis").
SetHeader("Accept", acceptV2Beta1JSON).
Do(ctx).
Raw()
if err != nil {
return apidiscoveryv2beta1.APIGroupDiscoveryList{}, fmt.Errorf("failed to fetch v2 discovery: %w", err)
}
@@ -562,7 +629,7 @@ func FetchV1DiscoveryResource(ctx context.Context, client testClient, gv metav1.
}
func WaitForGroupsAbsent(ctx context.Context, client testClient, groups ...string) error {
return WaitForResultWithCondition(ctx, client, func(groupList apidiscoveryv2beta1.APIGroupDiscoveryList) bool {
return WaitForResultWithCondition(ctx, client, func(groupList apidiscoveryv2.APIGroupDiscoveryList) bool {
for _, searchGroup := range groups {
for _, docGroup := range groupList.Items {
if docGroup.Name == searchGroup {
@@ -598,8 +665,8 @@ func WaitForRootPaths(t *testing.T, ctx context.Context, client testClient, requ
})
}
func WaitForGroups(ctx context.Context, client testClient, groups ...apidiscoveryv2beta1.APIGroupDiscovery) error {
return WaitForResultWithCondition(ctx, client, func(groupList apidiscoveryv2beta1.APIGroupDiscoveryList) bool {
func WaitForGroups(ctx context.Context, client testClient, groups ...apidiscoveryv2.APIGroupDiscovery) error {
return WaitForResultWithCondition(ctx, client, func(groupList apidiscoveryv2.APIGroupDiscoveryList) bool {
for _, searchGroup := range groups {
found := false
for _, docGroup := range groupList.Items {
@@ -616,13 +683,14 @@ func WaitForGroups(ctx context.Context, client testClient, groups ...apidiscover
})
}
func WaitForResultWithCondition(ctx context.Context, client testClient, condition func(result apidiscoveryv2beta1.APIGroupDiscoveryList) bool) error {
func WaitForResultWithCondition(ctx context.Context, client testClient, condition func(result apidiscoveryv2.APIGroupDiscoveryList) bool) error {
// Keep repeatedly fetching document from aggregator.
// Check to see if it contains our service within a reasonable amount of time
return wait.PollWithContext(
return wait.PollUntilContextTimeout(
ctx,
250*time.Millisecond,
maxTimeout,
true,
func(ctx context.Context) (done bool, err error) {
groupList, err := FetchV2Discovery(ctx, client)
if err != nil {
@@ -637,13 +705,36 @@ func WaitForResultWithCondition(ctx context.Context, client testClient, conditio
})
}
func WaitForV2Beta1ResultWithCondition(ctx context.Context, client testClient, condition func(result apidiscoveryv2beta1.APIGroupDiscoveryList) bool) error {
// Keep repeatedly fetching document from aggregator.
// Check to see if it contains our service within a reasonable amount of time
return wait.PollUntilContextTimeout(
ctx,
250*time.Millisecond,
maxTimeout,
true,
func(ctx context.Context) (done bool, err error) {
groupList, err := FetchV2Beta1Discovery(ctx, client)
if err != nil {
return false, err
}
if condition(groupList) {
return true, nil
}
return false, nil
})
}
func WaitForV1GroupsWithCondition(ctx context.Context, client testClient, condition func(result metav1.APIGroupList) bool) error {
// Keep repeatedly fetching document from aggregator.
// Check to see if it contains our service within a reasonable amount of time
return wait.PollWithContext(
return wait.PollUntilContextTimeout(
ctx,
250*time.Millisecond,
maxTimeout,
true,
func(ctx context.Context) (done bool, err error) {
groupList, err := FetchV1DiscoveryGroups(ctx, client)
@@ -662,10 +753,11 @@ func WaitForV1GroupsWithCondition(ctx context.Context, client testClient, condit
func WaitForV1ResourcesWithCondition(ctx context.Context, client testClient, gv metav1.GroupVersion, condition func(result metav1.APIResourceList) bool) error {
// Keep repeatedly fetching document from aggregator.
// Check to see if it contains our service within a reasonable amount of time
return wait.PollWithContext(
return wait.PollUntilContextTimeout(
ctx,
250*time.Millisecond,
maxTimeout,
true,
func(ctx context.Context) (done bool, err error) {
resourceList, err := FetchV1DiscoveryResource(ctx, client, gv)
@@ -697,7 +789,23 @@ func FindGroupVersionV1(discovery metav1.APIGroupList, gv metav1.GroupVersion) b
return false
}
func FindGroupVersionV2(discovery apidiscoveryv2beta1.APIGroupDiscoveryList, gv metav1.GroupVersion) *apidiscoveryv2beta1.APIVersionDiscovery {
func FindGroupVersionV2(discovery apidiscoveryv2.APIGroupDiscoveryList, gv metav1.GroupVersion) *apidiscoveryv2.APIVersionDiscovery {
for _, documentGroup := range discovery.Items {
if documentGroup.Name != gv.Group {
continue
}
for _, documentVersion := range documentGroup.Versions {
if documentVersion.Version == gv.Version {
return &documentVersion
}
}
}
return nil
}
func FindGroupVersionV2Beta1(discovery apidiscoveryv2beta1.APIGroupDiscoveryList, gv metav1.GroupVersion) *apidiscoveryv2beta1.APIVersionDiscovery {
for _, documentGroup := range discovery.Items {
if documentGroup.Name != gv.Group {
continue