mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 02:08: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 | ||||
| 	} | ||||
| 	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) && | ||||
| 			!hasNewEphemeralContainers && | ||||
| 			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). | ||||
| 			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 { | ||||
| 	nodes       int | ||||
| 	namespaces  int | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Kubernetes Prow Robot
					Kubernetes Prow Robot