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 1908217: server-side apply e2e: fix oauthclientauthorization race with KCM #25780

Merged
Merged
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
25 changes: 25 additions & 0 deletions test/extended/apiserver/apply.go
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"strings"
"time"

g "github.com/onsi/ginkgo"
o "github.com/onsi/gomega"
Expand All @@ -14,9 +15,11 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
discocache "k8s.io/client-go/discovery/cached"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/restmapper"
"k8s.io/kubernetes/test/e2e/framework"

Expand Down Expand Up @@ -74,6 +77,12 @@ var _ = g.Describe("[sig-api-machinery][Feature:ServerSideApply] Server-Side App
}
resourceClient, unstructuredObj, namespace := createResource(oc, mapper, prerequisite.GvrData, prerequisite.Stub, testNamespace)
testNamespace = namespace

// we need to wait for the tokens to appear at the SA otherwise creation
// of the oauthclientauthorization object fails
if gvr.Resource == "oauthclientauthorizations" && prerequisite.GvrData.Resource == "serviceaccounts" {
waitForSATokens(oc.AdminKubeClient().CoreV1().ServiceAccounts(testNamespace), unstructuredObj.Object)
}
defer deleteResource(resourceClient, unstructuredObj.GetName())
}

Expand Down Expand Up @@ -172,3 +181,19 @@ func createResource(

return resourceClient, &unstructuredObj, testNamespace
}

// waitForSATokens waits for the kube-controller-manager to populate the SA from the unstructured object
// to be populated with a secret defining its tokens
func waitForSATokens(saClient corev1client.ServiceAccountInterface, unstructuredObj map[string]interface{}) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

odd interface. Would be simpler with just the name as string, and the string extracted at the call site.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function is very specific to this test case, I merely extracted the necessary steps not to pollute the code above.

name, _, err := unstructured.NestedString(unstructuredObj, "metadata", "name")
o.Expect(err).NotTo(o.HaveOccurred())
err = wait.PollImmediate(time.Second, 15*time.Second, func() (bool, error) {
sa, err := saClient.Get(context.Background(), name, metav1.GetOptions{})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't there a variant of PollImmediate with context?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't find one in k8s.io/apimachinery/pkg/util/wait/wait.go

if err != nil {
framework.Logf("unexpected error retrieving SA %q: %v", name, err)
return false, nil
}
return len(sa.Secrets) > 0, nil
})
o.Expect(err).NotTo(o.HaveOccurred())
}