k8s.io/kubernetes@v1.29.3/test/e2e/upgrades/node/secrets.go (about)

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package node
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  
    23  	v1 "k8s.io/api/core/v1"
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  	"k8s.io/apimachinery/pkg/util/uuid"
    26  	"k8s.io/kubernetes/test/e2e/framework"
    27  	e2eoutput "k8s.io/kubernetes/test/e2e/framework/pod/output"
    28  	"k8s.io/kubernetes/test/e2e/upgrades"
    29  	imageutils "k8s.io/kubernetes/test/utils/image"
    30  
    31  	"github.com/onsi/ginkgo/v2"
    32  )
    33  
    34  // SecretUpgradeTest test that a secret is available before and after
    35  // a cluster upgrade.
    36  type SecretUpgradeTest struct {
    37  	secret *v1.Secret
    38  }
    39  
    40  // Name returns the tracking name of the test.
    41  func (SecretUpgradeTest) Name() string { return "[sig-storage] [sig-api-machinery] secret-upgrade" }
    42  
    43  // Setup creates a secret and then verifies that a pod can consume it.
    44  func (t *SecretUpgradeTest) Setup(ctx context.Context, f *framework.Framework) {
    45  	secretName := "upgrade-secret"
    46  
    47  	ns := f.Namespace
    48  
    49  	t.secret = &v1.Secret{
    50  		ObjectMeta: metav1.ObjectMeta{
    51  			Namespace: ns.Name,
    52  			Name:      secretName,
    53  		},
    54  		Data: map[string][]byte{
    55  			"data": []byte("keep it secret"),
    56  		},
    57  	}
    58  
    59  	ginkgo.By("Creating a secret")
    60  	var err error
    61  	if t.secret, err = f.ClientSet.CoreV1().Secrets(ns.Name).Create(ctx, t.secret, metav1.CreateOptions{}); err != nil {
    62  		framework.Failf("unable to create test secret %s: %v", t.secret.Name, err)
    63  	}
    64  
    65  	ginkgo.By("Making sure the secret is consumable")
    66  	t.testPod(ctx, f)
    67  }
    68  
    69  // Test waits for the upgrade to complete, and then verifies that a
    70  // pod can still consume the secret.
    71  func (t *SecretUpgradeTest) Test(ctx context.Context, f *framework.Framework, done <-chan struct{}, upgrade upgrades.UpgradeType) {
    72  	<-done
    73  	ginkgo.By("Consuming the secret after upgrade")
    74  	t.testPod(ctx, f)
    75  }
    76  
    77  // Teardown cleans up any remaining resources.
    78  func (t *SecretUpgradeTest) Teardown(ctx context.Context, f *framework.Framework) {
    79  	// rely on the namespace deletion to clean up everything
    80  }
    81  
    82  // testPod creates a pod that consumes a secret and prints it out. The
    83  // output is then verified.
    84  func (t *SecretUpgradeTest) testPod(ctx context.Context, f *framework.Framework) {
    85  	volumeName := "secret-volume"
    86  	volumeMountPath := "/etc/secret-volume"
    87  
    88  	pod := &v1.Pod{
    89  		ObjectMeta: metav1.ObjectMeta{
    90  			Name:      "pod-secrets-" + string(uuid.NewUUID()),
    91  			Namespace: t.secret.ObjectMeta.Namespace,
    92  		},
    93  		Spec: v1.PodSpec{
    94  			Volumes: []v1.Volume{
    95  				{
    96  					Name: volumeName,
    97  					VolumeSource: v1.VolumeSource{
    98  						Secret: &v1.SecretVolumeSource{
    99  							SecretName: t.secret.ObjectMeta.Name,
   100  						},
   101  					},
   102  				},
   103  			},
   104  			Containers: []v1.Container{
   105  				{
   106  					Name:  "secret-volume-test",
   107  					Image: imageutils.GetE2EImage(imageutils.Agnhost),
   108  					Args: []string{
   109  						"mounttest",
   110  						fmt.Sprintf("--file_content=%s/data", volumeMountPath),
   111  						fmt.Sprintf("--file_mode=%s/data", volumeMountPath),
   112  					},
   113  					VolumeMounts: []v1.VolumeMount{
   114  						{
   115  							Name:      volumeName,
   116  							MountPath: volumeMountPath,
   117  						},
   118  					},
   119  				},
   120  				{
   121  					Name:    "secret-env-test",
   122  					Image:   imageutils.GetE2EImage(imageutils.BusyBox),
   123  					Command: []string{"sh", "-c", "env"},
   124  					Env: []v1.EnvVar{
   125  						{
   126  							Name: "SECRET_DATA",
   127  							ValueFrom: &v1.EnvVarSource{
   128  								SecretKeyRef: &v1.SecretKeySelector{
   129  									LocalObjectReference: v1.LocalObjectReference{
   130  										Name: t.secret.ObjectMeta.Name,
   131  									},
   132  									Key: "data",
   133  								},
   134  							},
   135  						},
   136  					},
   137  				},
   138  			},
   139  			RestartPolicy: v1.RestartPolicyNever,
   140  		},
   141  	}
   142  
   143  	expectedOutput := []string{
   144  		"content of file \"/etc/secret-volume/data\": keep it secret",
   145  		"mode of file \"/etc/secret-volume/data\": -rw-r--r--",
   146  	}
   147  
   148  	e2eoutput.TestContainerOutput(ctx, f, "volume consume secrets", pod, 0, expectedOutput)
   149  
   150  	expectedOutput = []string{"SECRET_DATA=keep it secret"}
   151  	e2eoutput.TestContainerOutput(ctx, f, "env consume secrets", pod, 1, expectedOutput)
   152  }