Skip to content

Commit 3f6485a

Browse files
authored
✨ fakeclient: Add support for ServiceAccount Token subresource (kubernetes-sigs#2969)
* fake: Add ServiceAccount Token subresource * go fmt * add tests * go fmt * correct wrong type test
1 parent 4381fa0 commit 3f6485a

File tree

2 files changed

+53
-3
lines changed

2 files changed

+53
-3
lines changed

pkg/client/fake/client.go

+17-3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
// Using v4 to match upstream
3333
jsonpatch "gopkg.in/evanphx/json-patch.v4"
3434
appsv1 "k8s.io/api/apps/v1"
35+
authenticationv1 "k8s.io/api/authentication/v1"
3536
autoscalingv1 "k8s.io/api/autoscaling/v1"
3637
corev1 "k8s.io/api/core/v1"
3738
policyv1 "k8s.io/api/policy/v1"
@@ -1128,7 +1129,7 @@ func (sw *fakeSubResourceClient) Get(ctx context.Context, obj, subResource clien
11281129
}
11291130
scale, isScale := subResource.(*autoscalingv1.Scale)
11301131
if !isScale {
1131-
return apierrors.NewBadRequest(fmt.Sprintf("expected Scale, got %t", subResource))
1132+
return apierrors.NewBadRequest(fmt.Sprintf("expected Scale, got %T", subResource))
11321133
}
11331134
scaleOut, err := extractScale(obj)
11341135
if err != nil {
@@ -1149,13 +1150,26 @@ func (sw *fakeSubResourceClient) Create(ctx context.Context, obj client.Object,
11491150
_, isEviction = subResource.(*policyv1.Eviction)
11501151
}
11511152
if !isEviction {
1152-
return apierrors.NewBadRequest(fmt.Sprintf("got invalid type %t, expected Eviction", subResource))
1153+
return apierrors.NewBadRequest(fmt.Sprintf("got invalid type %T, expected Eviction", subResource))
11531154
}
11541155
if _, isPod := obj.(*corev1.Pod); !isPod {
11551156
return apierrors.NewNotFound(schema.GroupResource{}, "")
11561157
}
11571158

11581159
return sw.client.Delete(ctx, obj)
1160+
case "token":
1161+
tokenRequest, isTokenRequest := subResource.(*authenticationv1.TokenRequest)
1162+
if !isTokenRequest {
1163+
return apierrors.NewBadRequest(fmt.Sprintf("got invalid type %T, expected TokenRequest", subResource))
1164+
}
1165+
if _, isServiceAccount := obj.(*corev1.ServiceAccount); !isServiceAccount {
1166+
return apierrors.NewNotFound(schema.GroupResource{}, "")
1167+
}
1168+
1169+
tokenRequest.Status.Token = "fake-token"
1170+
tokenRequest.Status.ExpirationTimestamp = metav1.Date(6041, 1, 1, 0, 0, 0, 0, time.UTC)
1171+
1172+
return sw.client.Get(ctx, client.ObjectKeyFromObject(obj), obj)
11591173
default:
11601174
return fmt.Errorf("fakeSubResourceWriter does not support create for %s", sw.subResource)
11611175
}
@@ -1176,7 +1190,7 @@ func (sw *fakeSubResourceClient) Update(ctx context.Context, obj client.Object,
11761190

11771191
scale, isScale := updateOptions.SubResourceBody.(*autoscalingv1.Scale)
11781192
if !isScale {
1179-
return apierrors.NewBadRequest(fmt.Sprintf("expected Scale, got %t", updateOptions.SubResourceBody))
1193+
return apierrors.NewBadRequest(fmt.Sprintf("expected Scale, got %T", updateOptions.SubResourceBody))
11801194
}
11811195
if err := applyScale(obj, scale); err != nil {
11821196
return err

pkg/client/fake/client_test.go

+36
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
. "github.com/onsi/ginkgo/v2"
2828
. "github.com/onsi/gomega"
2929
appsv1 "k8s.io/api/apps/v1"
30+
authenticationv1 "k8s.io/api/authentication/v1"
3031
autoscalingv1 "k8s.io/api/autoscaling/v1"
3132
coordinationv1 "k8s.io/api/coordination/v1"
3233
corev1 "k8s.io/api/core/v1"
@@ -1959,6 +1960,41 @@ var _ = Describe("Fake client", func() {
19591960
Expect(apierrors.IsBadRequest(err)).To(BeTrue())
19601961
})
19611962

1963+
It("should create a ServiceAccount token through the token subresource", func() {
1964+
sa := &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
1965+
cl := NewClientBuilder().WithObjects(sa).Build()
1966+
1967+
tokenRequest := &authenticationv1.TokenRequest{}
1968+
err := cl.SubResource("token").Create(context.Background(), sa, tokenRequest)
1969+
Expect(err).NotTo(HaveOccurred())
1970+
1971+
Expect(tokenRequest.Status.Token).NotTo(Equal(""))
1972+
Expect(tokenRequest.Status.ExpirationTimestamp).NotTo(Equal(metav1.Time{}))
1973+
})
1974+
1975+
It("should return not found when creating a token for a ServiceAccount that doesn't exist", func() {
1976+
sa := &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
1977+
cl := NewClientBuilder().Build()
1978+
1979+
err := cl.SubResource("token").Create(context.Background(), sa, &authenticationv1.TokenRequest{})
1980+
Expect(err).To(HaveOccurred())
1981+
Expect(apierrors.IsNotFound(err)).To(BeTrue())
1982+
})
1983+
1984+
It("should error when creating a token with the wrong subresource type", func() {
1985+
cl := NewClientBuilder().Build()
1986+
err := cl.SubResource("token").Create(context.Background(), &corev1.ServiceAccount{}, &corev1.Namespace{})
1987+
Expect(err).To(HaveOccurred())
1988+
Expect(apierrors.IsBadRequest(err)).To(BeTrue())
1989+
})
1990+
1991+
It("should error when creating a token with the wrong type", func() {
1992+
cl := NewClientBuilder().Build()
1993+
err := cl.SubResource("token").Create(context.Background(), &corev1.Secret{}, &authenticationv1.TokenRequest{})
1994+
Expect(err).To(HaveOccurred())
1995+
Expect(apierrors.IsNotFound(err)).To(BeTrue())
1996+
})
1997+
19621998
It("should leave typemeta empty on typed get", func() {
19631999
cl := NewClientBuilder().WithObjects(&corev1.Pod{ObjectMeta: metav1.ObjectMeta{
19642000
Namespace: "default",

0 commit comments

Comments
 (0)