ClusterTrustBundle projection: e2e test
This commit is contained in:
		
							
								
								
									
										169
									
								
								test/e2e/auth/projected_clustertrustbundle.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								test/e2e/auth/projected_clustertrustbundle.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,169 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2023 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 auth
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"crypto/ed25519"
 | 
				
			||||||
 | 
						"crypto/rand"
 | 
				
			||||||
 | 
						"crypto/x509"
 | 
				
			||||||
 | 
						"crypto/x509/pkix"
 | 
				
			||||||
 | 
						"encoding/pem"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"math/big"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"regexp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1"
 | 
				
			||||||
 | 
						v1 "k8s.io/api/core/v1"
 | 
				
			||||||
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
 | 
						"k8s.io/apimachinery/pkg/util/uuid"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/test/e2e/feature"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/test/e2e/framework"
 | 
				
			||||||
 | 
						e2epodoutput "k8s.io/kubernetes/test/e2e/framework/pod/output"
 | 
				
			||||||
 | 
						imageutils "k8s.io/kubernetes/test/utils/image"
 | 
				
			||||||
 | 
						admissionapi "k8s.io/pod-security-admission/api"
 | 
				
			||||||
 | 
						"k8s.io/utils/ptr"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/onsi/ginkgo/v2"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var _ = SIGDescribe(feature.ClusterTrustBundle, feature.ClusterTrustBundleProjection, func() {
 | 
				
			||||||
 | 
						f := framework.NewDefaultFramework("projected-clustertrustbundle")
 | 
				
			||||||
 | 
						f.NamespacePodSecurityLevel = admissionapi.LevelBaseline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						goodCert1 := mustMakeCertificate(&x509.Certificate{
 | 
				
			||||||
 | 
							SerialNumber: big.NewInt(0),
 | 
				
			||||||
 | 
							Subject: pkix.Name{
 | 
				
			||||||
 | 
								CommonName: "root1",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							IsCA:                  true,
 | 
				
			||||||
 | 
							BasicConstraintsValid: true,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						goodCert1Block := string(mustMakePEMBlock("CERTIFICATE", nil, goodCert1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ginkgo.It("should be able to mount a single ClusterTrustBundle by name", func(ctx context.Context) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ctb1 := &certificatesv1alpha1.ClusterTrustBundle{
 | 
				
			||||||
 | 
								ObjectMeta: metav1.ObjectMeta{
 | 
				
			||||||
 | 
									Name: "ctb1",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
 | 
				
			||||||
 | 
									TrustBundle: goodCert1Block,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if _, err := f.ClientSet.CertificatesV1alpha1().ClusterTrustBundles().Create(ctx, ctb1, metav1.CreateOptions{}); err != nil {
 | 
				
			||||||
 | 
								framework.Failf("Error while creating ClusterTrustBundle: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							pod := &v1.Pod{
 | 
				
			||||||
 | 
								ObjectMeta: metav1.ObjectMeta{
 | 
				
			||||||
 | 
									Name: "pod-projected-ctb-" + string(uuid.NewUUID()),
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Spec: v1.PodSpec{
 | 
				
			||||||
 | 
									RestartPolicy: v1.RestartPolicyNever,
 | 
				
			||||||
 | 
									Containers: []v1.Container{
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											Name:  "projected-ctb-volume-test",
 | 
				
			||||||
 | 
											Image: imageutils.GetE2EImage(imageutils.Agnhost),
 | 
				
			||||||
 | 
											Args: []string{
 | 
				
			||||||
 | 
												"mounttest",
 | 
				
			||||||
 | 
												"--file_content=/var/run/ctbtest/trust-anchors.pem",
 | 
				
			||||||
 | 
												"--file_mode=/var/run/ctbtest/trust-anchors.pem",
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
											VolumeMounts: []v1.VolumeMount{
 | 
				
			||||||
 | 
												{
 | 
				
			||||||
 | 
													Name:      "ctb-volume",
 | 
				
			||||||
 | 
													MountPath: "/var/run/ctbtest",
 | 
				
			||||||
 | 
												},
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									Volumes: []v1.Volume{
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											Name: "ctb-volume",
 | 
				
			||||||
 | 
											VolumeSource: v1.VolumeSource{
 | 
				
			||||||
 | 
												Projected: &v1.ProjectedVolumeSource{
 | 
				
			||||||
 | 
													Sources: []v1.VolumeProjection{
 | 
				
			||||||
 | 
														{
 | 
				
			||||||
 | 
															ClusterTrustBundle: &v1.ClusterTrustBundleProjection{
 | 
				
			||||||
 | 
																Name: ptr.To("ctb1"),
 | 
				
			||||||
 | 
																Path: "trust-anchors.pem",
 | 
				
			||||||
 | 
															},
 | 
				
			||||||
 | 
														},
 | 
				
			||||||
 | 
													},
 | 
				
			||||||
 | 
												},
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fileModeRegexp := getFileModeRegex("/var/run/ctbtest/trust-anchors.pem", nil)
 | 
				
			||||||
 | 
							expectedOutput := []string{
 | 
				
			||||||
 | 
								regexp.QuoteMeta(goodCert1Block),
 | 
				
			||||||
 | 
								fileModeRegexp,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							e2epodoutput.TestContainerOutputRegexp(ctx, f, "project cluster trust bundle", pod, 0, expectedOutput)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func mustMakeCertificate(template *x509.Certificate) []byte {
 | 
				
			||||||
 | 
						pub, priv, err := ed25519.GenerateKey(rand.Reader)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							framework.Failf("Error while generating key: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cert, err := x509.CreateCertificate(rand.Reader, template, template, pub, priv)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							framework.Failf("Error while making certificate: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return cert
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func mustMakePEMBlock(blockType string, headers map[string]string, data []byte) string {
 | 
				
			||||||
 | 
						return string(pem.EncodeToMemory(&pem.Block{
 | 
				
			||||||
 | 
							Type:    blockType,
 | 
				
			||||||
 | 
							Headers: headers,
 | 
				
			||||||
 | 
							Bytes:   data,
 | 
				
			||||||
 | 
						}))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// getFileModeRegex returns a file mode related regex which should be matched by the mounttest pods' output.
 | 
				
			||||||
 | 
					// If the given mask is nil, then the regex will contain the default OS file modes, which are 0644 for Linux and 0775 for Windows.
 | 
				
			||||||
 | 
					func getFileModeRegex(filePath string, mask *int32) string {
 | 
				
			||||||
 | 
						var (
 | 
				
			||||||
 | 
							linuxMask   int32
 | 
				
			||||||
 | 
							windowsMask int32
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						if mask == nil {
 | 
				
			||||||
 | 
							linuxMask = int32(0644)
 | 
				
			||||||
 | 
							windowsMask = int32(0775)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							linuxMask = *mask
 | 
				
			||||||
 | 
							windowsMask = *mask
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						linuxOutput := fmt.Sprintf("mode of file \"%s\": %v", filePath, os.FileMode(linuxMask))
 | 
				
			||||||
 | 
						windowsOutput := fmt.Sprintf("mode of Windows file \"%v\": %s", filePath, os.FileMode(windowsMask))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return fmt.Sprintf("(%s|%s)", linuxOutput, windowsOutput)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -38,6 +38,8 @@ var (
 | 
				
			|||||||
	ClusterSizeAutoscalingGpu               = framework.WithFeature(framework.ValidFeatures.Add("ClusterSizeAutoscalingGpu"))
 | 
						ClusterSizeAutoscalingGpu               = framework.WithFeature(framework.ValidFeatures.Add("ClusterSizeAutoscalingGpu"))
 | 
				
			||||||
	ClusterSizeAutoscalingScaleDown         = framework.WithFeature(framework.ValidFeatures.Add("ClusterSizeAutoscalingScaleDown"))
 | 
						ClusterSizeAutoscalingScaleDown         = framework.WithFeature(framework.ValidFeatures.Add("ClusterSizeAutoscalingScaleDown"))
 | 
				
			||||||
	ClusterSizeAutoscalingScaleUp           = framework.WithFeature(framework.ValidFeatures.Add("ClusterSizeAutoscalingScaleUp"))
 | 
						ClusterSizeAutoscalingScaleUp           = framework.WithFeature(framework.ValidFeatures.Add("ClusterSizeAutoscalingScaleUp"))
 | 
				
			||||||
 | 
						ClusterTrustBundle                      = framework.WithFeature(framework.ValidFeatures.Add("ClusterTrustBundle"))
 | 
				
			||||||
 | 
						ClusterTrustBundleProjection            = framework.WithFeature(framework.ValidFeatures.Add("ClusterTrustBundleProjection"))
 | 
				
			||||||
	ClusterUpgrade                          = framework.WithFeature(framework.ValidFeatures.Add("ClusterUpgrade"))
 | 
						ClusterUpgrade                          = framework.WithFeature(framework.ValidFeatures.Add("ClusterUpgrade"))
 | 
				
			||||||
	ComprehensiveNamespaceDraining          = framework.WithFeature(framework.ValidFeatures.Add("ComprehensiveNamespaceDraining"))
 | 
						ComprehensiveNamespaceDraining          = framework.WithFeature(framework.ValidFeatures.Add("ComprehensiveNamespaceDraining"))
 | 
				
			||||||
	CPUManager                              = framework.WithFeature(framework.ValidFeatures.Add("CPUManager"))
 | 
						CPUManager                              = framework.WithFeature(framework.ValidFeatures.Add("CPUManager"))
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user