1
16
17 package auth
18
19 import (
20 "context"
21 "crypto/ed25519"
22 "crypto/rand"
23 "crypto/x509"
24 "crypto/x509/pkix"
25 "encoding/pem"
26 "fmt"
27 "math/big"
28 "os"
29 "regexp"
30
31 certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1"
32 v1 "k8s.io/api/core/v1"
33 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
34 "k8s.io/apimachinery/pkg/util/uuid"
35 "k8s.io/kubernetes/test/e2e/feature"
36 "k8s.io/kubernetes/test/e2e/framework"
37 e2epodoutput "k8s.io/kubernetes/test/e2e/framework/pod/output"
38 imageutils "k8s.io/kubernetes/test/utils/image"
39 admissionapi "k8s.io/pod-security-admission/api"
40 "k8s.io/utils/ptr"
41
42 "github.com/onsi/ginkgo/v2"
43 )
44
45 var _ = SIGDescribe(feature.ClusterTrustBundle, feature.ClusterTrustBundleProjection, func() {
46 f := framework.NewDefaultFramework("projected-clustertrustbundle")
47 f.NamespacePodSecurityLevel = admissionapi.LevelBaseline
48
49 goodCert1 := mustMakeCertificate(&x509.Certificate{
50 SerialNumber: big.NewInt(0),
51 Subject: pkix.Name{
52 CommonName: "root1",
53 },
54 IsCA: true,
55 BasicConstraintsValid: true,
56 })
57
58 goodCert1Block := string(mustMakePEMBlock("CERTIFICATE", nil, goodCert1))
59
60 ginkgo.It("should be able to mount a single ClusterTrustBundle by name", func(ctx context.Context) {
61
62 ctb1 := &certificatesv1alpha1.ClusterTrustBundle{
63 ObjectMeta: metav1.ObjectMeta{
64 Name: "ctb1",
65 },
66 Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
67 TrustBundle: goodCert1Block,
68 },
69 }
70
71 if _, err := f.ClientSet.CertificatesV1alpha1().ClusterTrustBundles().Create(ctx, ctb1, metav1.CreateOptions{}); err != nil {
72 framework.Failf("Error while creating ClusterTrustBundle: %v", err)
73 }
74
75 pod := &v1.Pod{
76 ObjectMeta: metav1.ObjectMeta{
77 Name: "pod-projected-ctb-" + string(uuid.NewUUID()),
78 },
79 Spec: v1.PodSpec{
80 RestartPolicy: v1.RestartPolicyNever,
81 Containers: []v1.Container{
82 {
83 Name: "projected-ctb-volume-test",
84 Image: imageutils.GetE2EImage(imageutils.Agnhost),
85 Args: []string{
86 "mounttest",
87 "--file_content=/var/run/ctbtest/trust-anchors.pem",
88 "--file_mode=/var/run/ctbtest/trust-anchors.pem",
89 },
90 VolumeMounts: []v1.VolumeMount{
91 {
92 Name: "ctb-volume",
93 MountPath: "/var/run/ctbtest",
94 },
95 },
96 },
97 },
98 Volumes: []v1.Volume{
99 {
100 Name: "ctb-volume",
101 VolumeSource: v1.VolumeSource{
102 Projected: &v1.ProjectedVolumeSource{
103 Sources: []v1.VolumeProjection{
104 {
105 ClusterTrustBundle: &v1.ClusterTrustBundleProjection{
106 Name: ptr.To("ctb1"),
107 Path: "trust-anchors.pem",
108 },
109 },
110 },
111 },
112 },
113 },
114 },
115 },
116 }
117
118 fileModeRegexp := getFileModeRegex("/var/run/ctbtest/trust-anchors.pem", nil)
119 expectedOutput := []string{
120 regexp.QuoteMeta(goodCert1Block),
121 fileModeRegexp,
122 }
123
124 e2epodoutput.TestContainerOutputRegexp(ctx, f, "project cluster trust bundle", pod, 0, expectedOutput)
125 })
126 })
127
128 func mustMakeCertificate(template *x509.Certificate) []byte {
129 pub, priv, err := ed25519.GenerateKey(rand.Reader)
130 if err != nil {
131 framework.Failf("Error while generating key: %v", err)
132 }
133
134 cert, err := x509.CreateCertificate(rand.Reader, template, template, pub, priv)
135 if err != nil {
136 framework.Failf("Error while making certificate: %v", err)
137 }
138
139 return cert
140 }
141
142 func mustMakePEMBlock(blockType string, headers map[string]string, data []byte) string {
143 return string(pem.EncodeToMemory(&pem.Block{
144 Type: blockType,
145 Headers: headers,
146 Bytes: data,
147 }))
148 }
149
150
151
152 func getFileModeRegex(filePath string, mask *int32) string {
153 var (
154 linuxMask int32
155 windowsMask int32
156 )
157 if mask == nil {
158 linuxMask = int32(0644)
159 windowsMask = int32(0775)
160 } else {
161 linuxMask = *mask
162 windowsMask = *mask
163 }
164
165 linuxOutput := fmt.Sprintf("mode of file \"%s\": %v", filePath, os.FileMode(linuxMask))
166 windowsOutput := fmt.Sprintf("mode of Windows file \"%v\": %s", filePath, os.FileMode(windowsMask))
167
168 return fmt.Sprintf("(%s|%s)", linuxOutput, windowsOutput)
169 }
170
View as plain text