forked from kubernetes-sigs/kubebuilder
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
79a06e5
commit 9fd0662
Showing
7 changed files
with
422 additions
and
270 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/* | ||
Copyright 2024 The Kubernetes Authors. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package common | ||
|
||
//nolint:lll | ||
const CertManagerTarget = `#replacements: | ||
# - source: # Add cert-manager annotation to ValidatingWebhookConfiguration, MutatingWebhookConfiguration and CRDs | ||
# kind: Certificate | ||
# group: cert-manager.io | ||
# version: v1 | ||
# name: serving-cert # this name should match the one in certificate.yaml | ||
# fieldPath: .metadata.namespace # namespace of the certificate CR | ||
# targets: | ||
# - select: | ||
# kind: ValidatingWebhookConfiguration | ||
# fieldPaths: | ||
# - .metadata.annotations.[cert-manager.io/inject-ca-from] | ||
# options: | ||
# delimiter: '/' | ||
# index: 0 | ||
# create: true | ||
# - select: | ||
# kind: MutatingWebhookConfiguration | ||
# fieldPaths: | ||
# - .metadata.annotations.[cert-manager.io/inject-ca-from] | ||
# options: | ||
# delimiter: '/' | ||
# index: 0 | ||
# create: true | ||
# - select: | ||
# kind: CustomResourceDefinition | ||
# fieldPaths: | ||
# - .metadata.annotations.[cert-manager.io/inject-ca-from] | ||
# options: | ||
# delimiter: '/' | ||
# index: 0 | ||
# create: true | ||
# - source: | ||
# kind: Certificate | ||
# group: cert-manager.io | ||
# version: v1 | ||
# name: serving-cert # this name should match the one in certificate.yaml | ||
# fieldPath: .metadata.name | ||
# targets: | ||
# - select: | ||
# kind: ValidatingWebhookConfiguration | ||
# fieldPaths: | ||
# - .metadata.annotations.[cert-manager.io/inject-ca-from] | ||
# options: | ||
# delimiter: '/' | ||
# index: 1 | ||
# create: true | ||
# - select: | ||
# kind: MutatingWebhookConfiguration | ||
# fieldPaths: | ||
# - .metadata.annotations.[cert-manager.io/inject-ca-from] | ||
# options: | ||
# delimiter: '/' | ||
# index: 1 | ||
# create: true | ||
# - select: | ||
# kind: CustomResourceDefinition | ||
# fieldPaths: | ||
# - .metadata.annotations.[cert-manager.io/inject-ca-from] | ||
# options: | ||
# delimiter: '/' | ||
# index: 1 | ||
# create: true | ||
# - source: # Add cert-manager annotation to the webhook Service | ||
# kind: Service | ||
# version: v1 | ||
# name: webhook-service | ||
# fieldPath: .metadata.name # namespace of the service | ||
# targets: | ||
# - select: | ||
# kind: Certificate | ||
# group: cert-manager.io | ||
# version: v1 | ||
# fieldPaths: | ||
# - .spec.dnsNames.0 | ||
# - .spec.dnsNames.1 | ||
# options: | ||
# delimiter: '.' | ||
# index: 0 | ||
# create: true | ||
# - source: | ||
# kind: Service | ||
# version: v1 | ||
# name: webhook-service | ||
# fieldPath: .metadata.namespace # namespace of the service | ||
# targets: | ||
# - select: | ||
# kind: Certificate | ||
# group: cert-manager.io | ||
# version: v1 | ||
# fieldPaths: | ||
# - .spec.dnsNames.0 | ||
# - .spec.dnsNames.1 | ||
# options: | ||
# delimiter: '.' | ||
# index: 1 | ||
# create: true` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
/* | ||
Copyright 2024 The Kubernetes Authors. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
package common | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"time" | ||
|
||
"sigs.k8s.io/kubebuilder/v4/test/e2e/utils" | ||
|
||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
const ( | ||
tokenRequestRawString = `{"apiVersion": "authentication.k8s.io/v1", "kind": "TokenRequest"}` | ||
) | ||
|
||
// tokenRequest is a trimmed down version of the authentication.k8s.io/v1/TokenRequest Type | ||
// that we want to use for extracting the token. | ||
type tokenRequest struct { | ||
Status struct { | ||
Token string `json:"token"` | ||
} `json:"status"` | ||
} | ||
|
||
// ServiceAccountToken provides a helper function that can provide you with a service account | ||
// token that you can use to interact with the service. This function leverages the k8s' | ||
// TokenRequest API in raw format in order to make it generic for all version of the k8s that | ||
// is currently being supported in kubebuilder test infra. | ||
// TokenRequest API returns the token in raw JWT format itself. There is no conversion required. | ||
func ServiceAccountToken(kbc *utils.TestContext) (out string, err error) { | ||
secretName := fmt.Sprintf("%s-token-request", kbc.Kubectl.ServiceAccount) | ||
tokenRequestFile := filepath.Join(kbc.Dir, secretName) | ||
err = os.WriteFile(tokenRequestFile, []byte(tokenRequestRawString), os.FileMode(0o755)) | ||
if err != nil { | ||
return out, err | ||
} | ||
var rawJson string | ||
Eventually(func() error { | ||
// Output of this is already a valid JWT token. No need to covert this from base64 to string format | ||
rawJson, err = kbc.Kubectl.Command( | ||
"create", | ||
"--raw", fmt.Sprintf( | ||
"/api/v1/namespaces/%s/serviceaccounts/%s/token", | ||
kbc.Kubectl.Namespace, | ||
kbc.Kubectl.ServiceAccount, | ||
), | ||
"-f", tokenRequestFile, | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
var token tokenRequest | ||
err = json.Unmarshal([]byte(rawJson), &token) | ||
if err != nil { | ||
return err | ||
} | ||
out = token.Status.Token | ||
return nil | ||
}, time.Minute, time.Second).Should(Succeed()) | ||
|
||
return out, err | ||
} | ||
|
||
func EnableMetricsCreateCurlPod(kbc *utils.TestContext) { | ||
_, err := kbc.Kubectl.Command( | ||
"create", "clusterrolebinding", fmt.Sprintf("metrics-%s", kbc.TestSuffix), | ||
fmt.Sprintf("--clusterrole=e2e-%s-metrics-reader", kbc.TestSuffix), | ||
fmt.Sprintf("--serviceaccount=%s:%s", kbc.Kubectl.Namespace, kbc.Kubectl.ServiceAccount)) | ||
ExpectWithOffset(1, err).NotTo(HaveOccurred()) | ||
|
||
token, err := ServiceAccountToken(kbc) | ||
ExpectWithOffset(2, err).NotTo(HaveOccurred()) | ||
ExpectWithOffset(2, token).NotTo(BeEmpty()) | ||
|
||
By("validating that the controller-manager service is available") | ||
_, err = kbc.Kubectl.Get( | ||
true, | ||
"service", fmt.Sprintf("e2e-%s-controller-manager-metrics-service", kbc.TestSuffix), | ||
) | ||
ExpectWithOffset(2, err).NotTo(HaveOccurred(), "Controller-manager service should exist") | ||
|
||
By("ensuring the service endpoint is ready") | ||
eventuallyCheckServiceEndpoint := func() error { | ||
output, err := kbc.Kubectl.Get( | ||
true, | ||
"endpoints", fmt.Sprintf("e2e-%s-controller-manager-metrics-service", kbc.TestSuffix), | ||
"-o", "jsonpath={.subsets[*].addresses[*].ip}", | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
if output == "" { | ||
return fmt.Errorf("no endpoints found") | ||
} | ||
return nil | ||
} | ||
EventuallyWithOffset(2, eventuallyCheckServiceEndpoint, 2*time.Minute, time.Second).Should(Succeed(), | ||
"Service endpoint should be ready") | ||
|
||
By("creating a curl pod to access the metrics endpoint") | ||
cmdOpts := CmdOptsToCreateCurlPod(kbc, token) | ||
_, err = kbc.Kubectl.CommandInNamespace(cmdOpts...) | ||
ExpectWithOffset(2, err).NotTo(HaveOccurred()) | ||
|
||
By("validating that the curl pod is running as expected") | ||
verifyCurlUp := func() error { | ||
status, err := kbc.Kubectl.Get( | ||
true, | ||
"pods", "curl", "-o", "jsonpath={.status.phase}") | ||
ExpectWithOffset(3, err).NotTo(HaveOccurred()) | ||
if status != "Succeeded" { | ||
return fmt.Errorf("curl pod in %s status", status) | ||
} | ||
return nil | ||
} | ||
EventuallyWithOffset(2, verifyCurlUp, 240*time.Second, time.Second).Should(Succeed()) | ||
} | ||
|
||
// GetMetricsOutput return the metrics output from curl pod | ||
func GetMetricsOutput(kbc *utils.TestContext) string { | ||
By("getting logs from curl") | ||
var metricsOutput string | ||
getCurlLogs := func() string { | ||
metricsOutput, err := kbc.Kubectl.Logs("curl") | ||
ExpectWithOffset(3, err).NotTo(HaveOccurred()) | ||
return metricsOutput | ||
} | ||
EventuallyWithOffset(2, getCurlLogs, 10*time.Second, time.Second).Should(ContainSubstring("< HTTP/1.1 200 OK")) | ||
return metricsOutput | ||
} | ||
|
||
// RemoveCurlPod created to collect the metrics | ||
func RemoveCurlPod(kbc *utils.TestContext) { | ||
By("cleaning up the curl pod") | ||
_, err := kbc.Kubectl.Delete(true, "pods/curl") | ||
ExpectWithOffset(3, err).NotTo(HaveOccurred()) | ||
} | ||
|
||
// CmdOptsToCreateCurlPod return the options to create curl Pod | ||
func CmdOptsToCreateCurlPod(kbc *utils.TestContext, token string) []string { | ||
// nolint:lll | ||
cmdOpts := []string{ | ||
"run", "curl", | ||
"--restart=Never", | ||
"--namespace", kbc.Kubectl.Namespace, | ||
"--image=curlimages/curl:7.78.0", | ||
"--", | ||
"/bin/sh", "-c", fmt.Sprintf("curl -v -k -H 'Authorization: Bearer %s' https://e2e-%s-controller-manager-metrics-service.%s.svc.cluster.local:8443/metrics", | ||
token, kbc.TestSuffix, kbc.Kubectl.Namespace), | ||
} | ||
return cmdOpts | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.