diff --git a/.changelog/3210.txt b/.changelog/3210.txt new file mode 100644 index 0000000000..e0ae60679d --- /dev/null +++ b/.changelog/3210.txt @@ -0,0 +1,3 @@ +```release-note:bug +control-plane: Only delete ACL tokens matched Pod UID in Service Registration metadata +``` \ No newline at end of file diff --git a/control-plane/connect-inject/constants/constants.go b/control-plane/connect-inject/constants/constants.go index 673a64eabc..75f9eaaad6 100644 --- a/control-plane/connect-inject/constants/constants.go +++ b/control-plane/connect-inject/constants/constants.go @@ -16,6 +16,9 @@ const ( // MetaKeyPodName is the meta key name for Kubernetes pod name used for the Consul services. MetaKeyPodName = "pod-name" + // MetaKeyPodUID is the meta key name for Kubernetes pod uid used for the Consul services. + MetaKeyPodUID = "pod-uid" + // DefaultGracefulPort is the default port that consul-dataplane uses for graceful shutdown. DefaultGracefulPort = 20600 diff --git a/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go b/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go index 9603b6bd3d..fa11e07987 100644 --- a/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go +++ b/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go @@ -407,6 +407,7 @@ func (r *Controller) createServiceRegistrations(pod corev1.Pod, serviceEndpoints metaKeyKubeServiceName: serviceEndpoints.Name, constants.MetaKeyKubeNS: serviceEndpoints.Namespace, metaKeyManagedBy: constants.ManagedByValue, + constants.MetaKeyPodUID: string(pod.UID), metaKeySyntheticNode: "true", } for k, v := range pod.Annotations { @@ -654,6 +655,7 @@ func (r *Controller) createGatewayRegistrations(pod corev1.Pod, serviceEndpoints constants.MetaKeyKubeNS: serviceEndpoints.Namespace, metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: string(pod.UID), } service := &api.AgentService{ @@ -933,7 +935,7 @@ func (r *Controller) deregisterService(apiClient *api.Client, k8sSvcName, k8sSvc if r.AuthMethod != "" && serviceDeregistered { r.Log.Info("reconciling ACL tokens for service", "svc", svc.Service) - err := r.deleteACLTokensForServiceInstance(apiClient, svc, k8sSvcNamespace, svc.Meta[constants.MetaKeyPodName]) + err := r.deleteACLTokensForServiceInstance(apiClient, svc, k8sSvcNamespace, svc.Meta[constants.MetaKeyPodName], svc.Meta[constants.MetaKeyPodUID]) if err != nil { r.Log.Error(err, "failed to reconcile ACL tokens for service", "svc", svc.Service) errs = multierror.Append(errs, err) @@ -948,8 +950,8 @@ func (r *Controller) deregisterService(apiClient *api.Client, k8sSvcName, k8sSvc // deleteACLTokensForServiceInstance finds the ACL tokens that belongs to the service instance and deletes it from Consul. // It will only check for ACL tokens that have been created with the auth method this controller -// has been configured with and will only delete tokens for the provided podName. -func (r *Controller) deleteACLTokensForServiceInstance(apiClient *api.Client, svc *api.AgentService, k8sNS, podName string) error { +// has been configured with and will only delete tokens for the provided podName and podUID. +func (r *Controller) deleteACLTokensForServiceInstance(apiClient *api.Client, svc *api.AgentService, k8sNS, podName, podUID string) error { // Skip if podName is empty. if podName == "" { return nil @@ -985,8 +987,11 @@ func (r *Controller) deleteACLTokensForServiceInstance(apiClient *api.Client, sv tokenPodName := strings.TrimPrefix(tokenMeta[tokenMetaPodNameKey], k8sNS+"/") + // backward compability logic on token with no podUID in metadata + podUIDMatched := tokenMeta[constants.MetaKeyPodUID] == podUID || tokenMeta[constants.MetaKeyPodUID] == "" + // If we can't find token's pod, delete it. - if tokenPodName == podName { + if tokenPodName == podName && podUIDMatched { r.Log.Info("deleting ACL token for pod", "name", podName) if _, err := apiClient.ACL().TokenDelete(token.AccessorID, &api.WriteOptions{Namespace: svc.Namespace}); err != nil { return fmt.Errorf("failed to delete token from Consul: %s", err) diff --git a/control-plane/connect-inject/controllers/endpoints/endpoints_controller_ent_test.go b/control-plane/connect-inject/controllers/endpoints/endpoints_controller_ent_test.go index a7118ed6d8..1520b3efbb 100644 --- a/control-plane/connect-inject/controllers/endpoints/endpoints_controller_ent_test.go +++ b/control-plane/connect-inject/controllers/endpoints/endpoints_controller_ent_test.go @@ -125,7 +125,7 @@ func TestReconcileCreateEndpointWithNamespaces(t *testing.T) { ServiceID: "pod1-service-created", ServiceName: "service-created", ServiceAddress: "1.2.3.4", - ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: testCase.SourceKubeNS, metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: testCase.SourceKubeNS, metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, Namespace: testCase.ExpConsulNS, }, @@ -133,7 +133,7 @@ func TestReconcileCreateEndpointWithNamespaces(t *testing.T) { ServiceID: "pod2-service-created", ServiceName: "service-created", ServiceAddress: "2.2.3.4", - ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod2", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: testCase.SourceKubeNS, metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod2", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: testCase.SourceKubeNS, metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, Namespace: testCase.ExpConsulNS, }, @@ -148,7 +148,7 @@ func TestReconcileCreateEndpointWithNamespaces(t *testing.T) { DestinationServiceName: "service-created", DestinationServiceID: "pod1-service-created", }, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: testCase.SourceKubeNS, metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: testCase.SourceKubeNS, metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, Namespace: testCase.ExpConsulNS, }, @@ -161,7 +161,7 @@ func TestReconcileCreateEndpointWithNamespaces(t *testing.T) { DestinationServiceName: "service-created", DestinationServiceID: "pod2-service-created", }, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod2", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: testCase.SourceKubeNS, metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod2", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: testCase.SourceKubeNS, metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, Namespace: testCase.ExpConsulNS, }, @@ -396,7 +396,7 @@ func TestReconcileCreateGatewayWithNamespaces(t *testing.T) { ServiceID: "mesh-gateway", ServiceName: "mesh-gateway", ServiceAddress: "3.3.3.3", - ServiceMeta: map[string]string{constants.MetaKeyPodName: "mesh-gateway", metaKeyKubeServiceName: "gateway", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "mesh-gateway", metaKeyKubeServiceName: "gateway", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, ServicePort: 8443, ServiceTaggedAddresses: map[string]api.ServiceAddress{ @@ -415,7 +415,7 @@ func TestReconcileCreateGatewayWithNamespaces(t *testing.T) { ServiceID: "terminating-gateway", ServiceName: "terminating-gateway", ServiceAddress: "4.4.4.4", - ServiceMeta: map[string]string{constants.MetaKeyPodName: "terminating-gateway", metaKeyKubeServiceName: "gateway", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "terminating-gateway", metaKeyKubeServiceName: "gateway", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, ServicePort: 8443, Namespace: testCase.ConsulNS, @@ -424,7 +424,7 @@ func TestReconcileCreateGatewayWithNamespaces(t *testing.T) { ServiceID: "ingress-gateway", ServiceName: "ingress-gateway", ServiceAddress: "5.5.5.5", - ServiceMeta: map[string]string{constants.MetaKeyPodName: "ingress-gateway", metaKeyKubeServiceName: "gateway", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "ingress-gateway", metaKeyKubeServiceName: "gateway", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, ServicePort: 21000, ServiceTaggedAddresses: map[string]api.ServiceAddress{ @@ -1315,6 +1315,7 @@ func TestReconcileUpdateEndpointWithNamespaces(t *testing.T) { constants.MetaKeyPodName: "pod1", constants.MetaKeyKubeNS: ts.SourceKubeNS, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, Namespace: ts.ExpConsulNS, }, @@ -1341,6 +1342,7 @@ func TestReconcileUpdateEndpointWithNamespaces(t *testing.T) { constants.MetaKeyPodName: "pod1", constants.MetaKeyKubeNS: ts.SourceKubeNS, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, Namespace: ts.ExpConsulNS, }, @@ -1407,6 +1409,7 @@ func TestReconcileUpdateEndpointWithNamespaces(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, constants.MetaKeyPodName: "pod1", metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, Namespace: ts.ExpConsulNS, }, @@ -1433,6 +1436,7 @@ func TestReconcileUpdateEndpointWithNamespaces(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, constants.MetaKeyPodName: "pod1", metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, Namespace: ts.ExpConsulNS, }, @@ -1454,6 +1458,7 @@ func TestReconcileUpdateEndpointWithNamespaces(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, constants.MetaKeyPodName: "pod2", metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, Namespace: ts.ExpConsulNS, }, @@ -1480,6 +1485,7 @@ func TestReconcileUpdateEndpointWithNamespaces(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, constants.MetaKeyPodName: "pod2", metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, Namespace: ts.ExpConsulNS, }, diff --git a/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go b/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go index 8f430ccd63..6565ecca84 100644 --- a/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go +++ b/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go @@ -767,6 +767,7 @@ func TestReconcileCreateEndpoint_MultiportService(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{}, }, @@ -781,6 +782,7 @@ func TestReconcileCreateEndpoint_MultiportService(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{}, }, @@ -810,6 +812,7 @@ func TestReconcileCreateEndpoint_MultiportService(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{}, }, @@ -830,6 +833,7 @@ func TestReconcileCreateEndpoint_MultiportService(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{}, }, @@ -1062,7 +1066,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { ServiceName: "service-created", ServiceAddress: "1.2.3.4", ServicePort: 0, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, ServiceProxy: &api.AgentServiceConnectProxyConfig{}, NodeMeta: map[string]string{ @@ -1084,7 +1088,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { LocalServicePort: 0, Config: map[string]any{"envoy_telemetry_collector_bind_socket_dir": string("/consul/connect-inject")}, }, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, NodeMeta: map[string]string{ "synthetic-node": "true", @@ -1156,7 +1160,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { ServiceName: "mesh-gateway", ServiceAddress: "1.2.3.4", ServicePort: 8443, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "mesh-gateway", metaKeyKubeServiceName: "mesh-gateway", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "mesh-gateway", metaKeyKubeServiceName: "mesh-gateway", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, ServiceTaggedAddresses: map[string]api.ServiceAddress{ "lan": { @@ -1229,7 +1233,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { ServiceName: "mesh-gateway", ServiceAddress: "1.2.3.4", ServicePort: 8443, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "mesh-gateway", metaKeyKubeServiceName: "mesh-gateway", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "mesh-gateway", metaKeyKubeServiceName: "mesh-gateway", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, ServiceTaggedAddresses: map[string]api.ServiceAddress{ "lan": { @@ -1303,7 +1307,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { ServiceName: "mesh-gateway", ServiceAddress: "1.2.3.4", ServicePort: 8443, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "mesh-gateway", metaKeyKubeServiceName: "mesh-gateway", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "mesh-gateway", metaKeyKubeServiceName: "mesh-gateway", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, ServiceTaggedAddresses: map[string]api.ServiceAddress{ "lan": { @@ -1378,6 +1382,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{}, ServiceProxy: &api.AgentServiceConnectProxyConfig{ @@ -1441,6 +1446,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{}, ServiceProxy: &api.AgentServiceConnectProxyConfig{ @@ -1526,6 +1532,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{}, ServiceTaggedAddresses: map[string]api.ServiceAddress{ @@ -1627,6 +1634,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{}, ServiceTaggedAddresses: map[string]api.ServiceAddress{ @@ -1708,7 +1716,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { ServiceName: "service-created", ServiceAddress: "1.2.3.4", ServicePort: 0, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, ServiceProxy: &api.AgentServiceConnectProxyConfig{}, }, @@ -1717,7 +1725,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { ServiceName: "service-created", ServiceAddress: "2.2.3.4", ServicePort: 0, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod2", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod2", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, ServiceProxy: &api.AgentServiceConnectProxyConfig{}, }, @@ -1735,7 +1743,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { LocalServicePort: 0, Config: map[string]any{"envoy_telemetry_collector_bind_socket_dir": string("/consul/connect-inject")}, }, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, }, { @@ -1750,7 +1758,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { LocalServicePort: 0, Config: map[string]any{"envoy_telemetry_collector_bind_socket_dir": string("/consul/connect-inject")}, }, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod2", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod2", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, }, }, @@ -1849,7 +1857,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { ServiceName: "service-created", ServiceAddress: "1.2.3.4", ServicePort: 0, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, ServiceProxy: &api.AgentServiceConnectProxyConfig{}, }, @@ -1858,7 +1866,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { ServiceName: "service-created", ServiceAddress: "2.2.3.4", ServicePort: 0, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod2", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod2", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, ServiceProxy: &api.AgentServiceConnectProxyConfig{}, }, @@ -1876,7 +1884,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { LocalServicePort: 0, Config: map[string]any{"envoy_telemetry_collector_bind_socket_dir": string("/consul/connect-inject")}, }, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, }, { @@ -1891,7 +1899,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { LocalServicePort: 0, Config: map[string]any{"envoy_telemetry_collector_bind_socket_dir": string("/consul/connect-inject")}, }, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod2", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod2", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, }, }, @@ -1978,6 +1986,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{"abc,123", "pod1"}, ServiceProxy: &api.AgentServiceConnectProxyConfig{}, @@ -2015,6 +2024,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{"abc,123", "pod1"}, }, @@ -2088,7 +2098,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { ServiceName: "service-created", ServiceAddress: "1.2.3.4", ServicePort: 0, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, ServiceProxy: &api.AgentServiceConnectProxyConfig{}, }, @@ -2106,7 +2116,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { LocalServicePort: 0, Config: map[string]any{"envoy_telemetry_collector_bind_socket_dir": string("/consul/connect-inject")}, }, - ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true"}, + ServiceMeta: map[string]string{constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-created", constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodUID: ""}, ServiceTags: []string{}, }, }, @@ -2532,6 +2542,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyKubeServiceName: "service-updated", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, }, }, @@ -2553,6 +2564,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyKubeServiceName: "service-updated", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, Proxy: &api.AgentServiceConnectProxyConfig{ DestinationServiceName: "service-updated", @@ -2620,6 +2632,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { constants.MetaKeyKubeNS: "default", constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-updated", + constants.MetaKeyPodUID: "", }, }, }, @@ -2645,6 +2658,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { constants.MetaKeyKubeNS: "default", constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-updated", + constants.MetaKeyPodUID: "", }, }, }, @@ -3223,6 +3237,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyKubeServiceName: "service-updated", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, }, }, @@ -3244,6 +3259,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyKubeServiceName: "service-updated", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, Proxy: &api.AgentServiceConnectProxyConfig{ DestinationServiceName: "service-updated", @@ -3262,6 +3278,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod2", + constants.MetaKeyPodUID: "", }, }, }, @@ -3275,6 +3292,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod2", + constants.MetaKeyPodUID: "", }, }, }, @@ -3325,6 +3343,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "", }, }, }, @@ -3350,6 +3369,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "", }, }, }, @@ -3370,6 +3390,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod2", + constants.MetaKeyPodUID: "", }, }, }, @@ -3395,6 +3416,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod2", + constants.MetaKeyPodUID: "", }, }, }, @@ -3410,6 +3432,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "", }, }, }, @@ -3424,6 +3447,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "", }, }, }, @@ -3476,6 +3500,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "", }, }, }, @@ -3501,6 +3526,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "", }, }, }, @@ -3860,6 +3886,7 @@ func TestReconcileDeleteEndpoint(t *testing.T) { cases := []struct { name string consulSvcName string + consulPodUid string expectServicesToBeDeleted bool initialConsulSvcs []*api.AgentService enableACLs bool @@ -3945,6 +3972,7 @@ func TestReconcileDeleteEndpoint(t *testing.T) { { name: "When ACLs are enabled, the token should be deleted", consulSvcName: "service-deleted", + consulPodUid: "123", expectServicesToBeDeleted: true, initialConsulSvcs: []*api.AgentService{ { @@ -3958,6 +3986,7 @@ func TestReconcileDeleteEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "123", }, }, { @@ -3976,6 +4005,7 @@ func TestReconcileDeleteEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "123", }, }, }, @@ -4015,6 +4045,7 @@ func TestReconcileDeleteEndpoint(t *testing.T) { { name: "When ACLs are enabled, the mesh-gateway token should be deleted", consulSvcName: "service-deleted", + consulPodUid: "124", expectServicesToBeDeleted: true, initialConsulSvcs: []*api.AgentService{ { @@ -4029,6 +4060,7 @@ func TestReconcileDeleteEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "mesh-gateway", + constants.MetaKeyPodUID: "124", }, TaggedAddresses: map[string]api.ServiceAddress{ "lan": { @@ -4078,6 +4110,7 @@ func TestReconcileDeleteEndpoint(t *testing.T) { { name: "When ACLs are enabled, the ingress-gateway token should be deleted", consulSvcName: "service-deleted", + consulPodUid: "125", expectServicesToBeDeleted: true, initialConsulSvcs: []*api.AgentService{ { @@ -4092,6 +4125,7 @@ func TestReconcileDeleteEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "ingress-gateway", + constants.MetaKeyPodUID: "125", }, TaggedAddresses: map[string]api.ServiceAddress{ "lan": { @@ -4131,6 +4165,7 @@ func TestReconcileDeleteEndpoint(t *testing.T) { { name: "When ACLs are enabled, the terminating-gateway token should be deleted", consulSvcName: "service-deleted", + consulPodUid: "126", expectServicesToBeDeleted: true, initialConsulSvcs: []*api.AgentService{ { @@ -4145,6 +4180,7 @@ func TestReconcileDeleteEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "terminating-gateway", + constants.MetaKeyPodUID: "126", }, }, }, @@ -4191,8 +4227,9 @@ func TestReconcileDeleteEndpoint(t *testing.T) { AuthMethod: test.AuthMethod, BearerToken: test.ServiceAccountJWTToken, Meta: map[string]string{ - "pod": fmt.Sprintf("%s/%s", svc.Meta[constants.MetaKeyKubeNS], svc.Meta[constants.MetaKeyPodName]), - "component": tt.consulSvcName, + "pod": fmt.Sprintf("%s/%s", svc.Meta[constants.MetaKeyKubeNS], svc.Meta[constants.MetaKeyPodName]), + "component": tt.consulSvcName, + constants.MetaKeyPodUID: tt.consulPodUid, }, }, nil) require.NoError(t, err) @@ -4339,6 +4376,7 @@ func TestReconcileIgnoresServiceIgnoreLabel(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "", }, }, } @@ -5946,12 +5984,12 @@ func TestGetTokenMetaFromDescription(t *testing.T) { expectedTokenMeta map[string]string }{ "no description prefix": { - description: `{"pod":"default/pod"}`, - expectedTokenMeta: map[string]string{"pod": "default/pod"}, + description: `{"pod":"default/pod","pod-uid": "123"}`, + expectedTokenMeta: map[string]string{"pod": "default/pod", "pod-uid": "123"}, }, "consul's default description prefix": { - description: `token created via login: {"pod":"default/pod"}`, - expectedTokenMeta: map[string]string{"pod": "default/pod"}, + description: `token created via login: {"pod":"default/pod","pod-uid": "123"}`, + expectedTokenMeta: map[string]string{"pod": "default/pod", "pod-uid": "123"}, }, } diff --git a/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go b/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go index c1fae3eff9..aa22af5fb3 100644 --- a/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go +++ b/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go @@ -108,6 +108,12 @@ func (w *MeshWebhook) consulDataplaneSidecar(namespace corev1.Namespace, pod cor FieldRef: &corev1.ObjectFieldSelector{FieldPath: "metadata.namespace"}, }, }, + { + Name: "POD_UID", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{FieldPath: "metadata.uid"}, + }, + }, { Name: "DP_CREDENTIAL_LOGIN_META", Value: "pod=$(POD_NAMESPACE)/$(POD_NAME)", @@ -118,6 +124,10 @@ func (w *MeshWebhook) consulDataplaneSidecar(namespace corev1.Namespace, pod cor Name: "DP_CREDENTIAL_LOGIN_META1", Value: "pod=$(POD_NAMESPACE)/$(POD_NAME)", }, + { + Name: "DP_CREDENTIAL_LOGIN_META2", + Value: "pod-uid=$(POD_UID)", + }, }, VolumeMounts: []corev1.VolumeMount{ { diff --git a/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go b/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go index e6ce27bab1..2fc44df270 100644 --- a/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go +++ b/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go @@ -216,17 +216,20 @@ func TestHandlerConsulDataplaneSidecar(t *testing.T) { } require.Equal(t, expectedProbe, container.ReadinessProbe) require.Nil(t, container.StartupProbe) - require.Len(t, container.Env, 7) + require.Len(t, container.Env, 9) require.Equal(t, container.Env[0].Name, "TMPDIR") require.Equal(t, container.Env[0].Value, "/consul/connect-inject") require.Equal(t, container.Env[2].Name, "DP_SERVICE_NODE_NAME") require.Equal(t, container.Env[2].Value, "$(NODE_NAME)-virtual") require.Equal(t, container.Env[3].Name, "POD_NAME") require.Equal(t, container.Env[4].Name, "POD_NAMESPACE") - require.Equal(t, container.Env[5].Name, "DP_CREDENTIAL_LOGIN_META") - require.Equal(t, container.Env[5].Value, "pod=$(POD_NAMESPACE)/$(POD_NAME)") - require.Equal(t, container.Env[6].Name, "DP_CREDENTIAL_LOGIN_META1") + require.Equal(t, container.Env[5].Name, "POD_UID") + require.Equal(t, container.Env[6].Name, "DP_CREDENTIAL_LOGIN_META") require.Equal(t, container.Env[6].Value, "pod=$(POD_NAMESPACE)/$(POD_NAME)") + require.Equal(t, container.Env[7].Name, "DP_CREDENTIAL_LOGIN_META1") + require.Equal(t, container.Env[7].Value, "pod=$(POD_NAMESPACE)/$(POD_NAME)") + require.Equal(t, container.Env[8].Name, "DP_CREDENTIAL_LOGIN_META2") + require.Equal(t, container.Env[8].Value, "pod-uid=$(POD_UID)") }) } }