mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 10:18:13 +00:00 
			
		
		
		
	Merge pull request #129670 from cslink/fix-ephemeral-container-secrets
Fix ephemeral container secret references
This commit is contained in:
		| @@ -94,7 +94,10 @@ func (g *graphPopulator) updatePod(oldObj, obj interface{}) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if oldPod, ok := oldObj.(*corev1.Pod); ok && oldPod != nil { | 	if oldPod, ok := oldObj.(*corev1.Pod); ok && oldPod != nil { | ||||||
|  | 		// Ephemeral containers can add new secret or config map references to the pod. | ||||||
|  | 		hasNewEphemeralContainers := len(pod.Spec.EphemeralContainers) > len(oldPod.Spec.EphemeralContainers) | ||||||
| 		if (pod.Spec.NodeName == oldPod.Spec.NodeName) && (pod.UID == oldPod.UID) && | 		if (pod.Spec.NodeName == oldPod.Spec.NodeName) && (pod.UID == oldPod.UID) && | ||||||
|  | 			!hasNewEphemeralContainers && | ||||||
| 			resourceclaim.PodStatusEqual(oldPod.Status.ResourceClaimStatuses, pod.Status.ResourceClaimStatuses) { | 			resourceclaim.PodStatusEqual(oldPod.Status.ResourceClaimStatuses, pod.Status.ResourceClaimStatuses) { | ||||||
| 			// Node and uid are unchanged, all object references in the pod spec are immutable respectively unmodified (claim statuses). | 			// Node and uid are unchanged, all object references in the pod spec are immutable respectively unmodified (claim statuses). | ||||||
| 			klog.V(5).Infof("updatePod %s/%s, node unchanged", pod.Namespace, pod.Name) | 			klog.V(5).Infof("updatePod %s/%s, node unchanged", pod.Namespace, pod.Name) | ||||||
|   | |||||||
| @@ -856,6 +856,118 @@ func TestNodeAuthorizerSharedResources(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func TestNodeAuthorizerAddEphemeralContainers(t *testing.T) { | ||||||
|  | 	g := NewGraph() | ||||||
|  | 	g.destinationEdgeThreshold = 1 | ||||||
|  | 	identifier := nodeidentifier.NewDefaultNodeIdentifier() | ||||||
|  | 	authz := NewAuthorizer(g, identifier, bootstrappolicy.NodeRules()) | ||||||
|  |  | ||||||
|  | 	node1 := &user.DefaultInfo{Name: "system:node:node1", Groups: []string{"system:nodes"}} | ||||||
|  | 	pod := &corev1.Pod{ | ||||||
|  | 		ObjectMeta: metav1.ObjectMeta{Name: "pod1-node1", Namespace: "ns1"}, | ||||||
|  | 		Spec: corev1.PodSpec{ | ||||||
|  | 			NodeName: "node1", | ||||||
|  | 			Volumes: []corev1.Volume{ | ||||||
|  | 				{VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "node1-only"}}}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ecNewSecret := corev1.EphemeralContainer{ | ||||||
|  | 		TargetContainerName: "targetContainerName", | ||||||
|  | 		EphemeralContainerCommon: corev1.EphemeralContainerCommon{ | ||||||
|  | 			Image:   "imageURL", | ||||||
|  | 			Name:    "eph", | ||||||
|  | 			Command: []string{"command"}, | ||||||
|  | 			EnvFrom: []corev1.EnvFromSource{ | ||||||
|  | 				{ | ||||||
|  | 					SecretRef: &corev1.SecretEnvSource{ | ||||||
|  | 						LocalObjectReference: corev1.LocalObjectReference{ | ||||||
|  | 							Name: "new-secret", | ||||||
|  | 						}, | ||||||
|  | 						Optional: nil, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			SecurityContext: &corev1.SecurityContext{ | ||||||
|  | 				Privileged: &[]bool{true}[0], | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ecNewConfigMap := corev1.EphemeralContainer{ | ||||||
|  | 		TargetContainerName: "targetContainerName", | ||||||
|  | 		EphemeralContainerCommon: corev1.EphemeralContainerCommon{ | ||||||
|  | 			Image:   "imageURL", | ||||||
|  | 			Name:    "eph", | ||||||
|  | 			Command: []string{"command"}, | ||||||
|  | 			EnvFrom: []corev1.EnvFromSource{ | ||||||
|  | 				{ | ||||||
|  | 					ConfigMapRef: &corev1.ConfigMapEnvSource{ | ||||||
|  | 						LocalObjectReference: corev1.LocalObjectReference{ | ||||||
|  | 							Name: "new-config-map", | ||||||
|  | 						}, | ||||||
|  | 						Optional: nil, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			SecurityContext: &corev1.SecurityContext{ | ||||||
|  | 				Privileged: &[]bool{true}[0], | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	p := &graphPopulator{} | ||||||
|  | 	p.graph = g | ||||||
|  | 	p.addPod(pod) | ||||||
|  |  | ||||||
|  | 	testcases := []struct { | ||||||
|  | 		User      user.Info | ||||||
|  | 		Secret    string | ||||||
|  | 		ConfigMap string | ||||||
|  | 		Decision  authorizer.Decision | ||||||
|  | 		EphCont   *corev1.EphemeralContainer | ||||||
|  | 	}{ | ||||||
|  | 		{User: node1, Decision: authorizer.DecisionAllow, Secret: "node1-only"}, | ||||||
|  | 		{User: node1, Decision: authorizer.DecisionNoOpinion, Secret: "new-secret"}, | ||||||
|  | 		{User: node1, Decision: authorizer.DecisionAllow, Secret: "new-secret", EphCont: &ecNewSecret}, | ||||||
|  | 		{User: node1, Decision: authorizer.DecisionNoOpinion, ConfigMap: "new-config-map"}, | ||||||
|  | 		{User: node1, Decision: authorizer.DecisionAllow, ConfigMap: "new-config-map", EphCont: &ecNewConfigMap}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for i, tc := range testcases { | ||||||
|  | 		var ( | ||||||
|  | 			decision authorizer.Decision | ||||||
|  | 			err      error | ||||||
|  | 		) | ||||||
|  | 		if tc.EphCont != nil { | ||||||
|  | 			newPod := &corev1.Pod{} | ||||||
|  | 			pod.DeepCopyInto(newPod) | ||||||
|  | 			newPod.Spec.EphemeralContainers = append(newPod.Spec.EphemeralContainers, *tc.EphCont) | ||||||
|  | 			p.updatePod(pod, newPod) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if len(tc.Secret) > 0 { | ||||||
|  | 			decision, _, err = authz.Authorize(context.Background(), authorizer.AttributesRecord{User: tc.User, ResourceRequest: true, Verb: "get", Resource: "secrets", Namespace: "ns1", Name: tc.Secret}) | ||||||
|  | 			if err != nil { | ||||||
|  | 				t.Errorf("%d: unexpected error: %v", i, err) | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 		} else if len(tc.ConfigMap) > 0 { | ||||||
|  | 			decision, _, err = authz.Authorize(context.Background(), authorizer.AttributesRecord{User: tc.User, ResourceRequest: true, Verb: "get", Resource: "configmaps", Namespace: "ns1", Name: tc.ConfigMap}) | ||||||
|  | 			if err != nil { | ||||||
|  | 				t.Errorf("%d: unexpected error: %v", i, err) | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			t.Fatalf("test case must include a request for a Secret") | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if decision != tc.Decision { | ||||||
|  | 			t.Errorf("%d: expected %v, got %v", i, tc.Decision, decision) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| type sampleDataOpts struct { | type sampleDataOpts struct { | ||||||
| 	nodes       int | 	nodes       int | ||||||
| 	namespaces  int | 	namespaces  int | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Kubernetes Prow Robot
					Kubernetes Prow Robot