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 07bdaecba8..dd7cb4d243 100644 --- a/control-plane/connect-inject/constants/constants.go +++ b/control-plane/connect-inject/constants/constants.go @@ -49,6 +49,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 ea22628022..fa88daeb31 100644 --- a/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go +++ b/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go @@ -429,6 +429,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 { @@ -679,6 +680,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{ @@ -958,7 +960,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) @@ -973,8 +975,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 @@ -1010,8 +1012,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 44e64acba1..1c55bcd7f3 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 @@ -126,7 +126,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, }, @@ -134,7 +134,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, }, @@ -149,7 +149,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, }, @@ -162,7 +162,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, }, @@ -397,7 +397,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{ @@ -416,7 +416,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, @@ -425,7 +425,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{ @@ -1316,6 +1316,7 @@ func TestReconcileUpdateEndpointWithNamespaces(t *testing.T) { constants.MetaKeyPodName: "pod1", constants.MetaKeyKubeNS: ts.SourceKubeNS, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, Namespace: ts.ExpConsulNS, }, @@ -1342,6 +1343,7 @@ func TestReconcileUpdateEndpointWithNamespaces(t *testing.T) { constants.MetaKeyPodName: "pod1", constants.MetaKeyKubeNS: ts.SourceKubeNS, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, Namespace: ts.ExpConsulNS, }, @@ -1408,6 +1410,7 @@ func TestReconcileUpdateEndpointWithNamespaces(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, constants.MetaKeyPodName: "pod1", metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, Namespace: ts.ExpConsulNS, }, @@ -1434,6 +1437,7 @@ func TestReconcileUpdateEndpointWithNamespaces(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, constants.MetaKeyPodName: "pod1", metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, Namespace: ts.ExpConsulNS, }, @@ -1455,6 +1459,7 @@ func TestReconcileUpdateEndpointWithNamespaces(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, constants.MetaKeyPodName: "pod2", metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, Namespace: ts.ExpConsulNS, }, @@ -1481,6 +1486,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 cb0e6807c1..4c92892367 100644 --- a/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go +++ b/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go @@ -715,6 +715,7 @@ func TestReconcileCreateEndpoint_MultiportService(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{}, }, @@ -729,6 +730,7 @@ func TestReconcileCreateEndpoint_MultiportService(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{}, }, @@ -758,6 +760,7 @@ func TestReconcileCreateEndpoint_MultiportService(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{}, }, @@ -778,6 +781,7 @@ func TestReconcileCreateEndpoint_MultiportService(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{}, }, @@ -1010,7 +1014,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{ @@ -1032,7 +1036,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", @@ -1104,7 +1108,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": { @@ -1177,7 +1181,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": { @@ -1251,7 +1255,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": { @@ -1326,6 +1330,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{}, ServiceProxy: &api.AgentServiceConnectProxyConfig{ @@ -1389,6 +1394,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{}, ServiceProxy: &api.AgentServiceConnectProxyConfig{ @@ -1474,6 +1480,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{}, ServiceTaggedAddresses: map[string]api.ServiceAddress{ @@ -1575,6 +1582,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{}, ServiceTaggedAddresses: map[string]api.ServiceAddress{ @@ -1656,7 +1664,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{}, }, @@ -1665,7 +1673,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{}, }, @@ -1683,7 +1691,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{}, }, { @@ -1698,7 +1706,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{}, }, }, @@ -1797,7 +1805,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{}, }, @@ -1806,7 +1814,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{}, }, @@ -1824,7 +1832,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{}, }, { @@ -1839,7 +1847,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{}, }, }, @@ -1937,6 +1945,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{"abc,123", "pod1"}, ServiceProxy: &api.AgentServiceConnectProxyConfig{}, @@ -1982,6 +1991,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { constants.MetaKeyKubeNS: "default", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, ServiceTags: []string{"abc,123", "pod1"}, }, @@ -2055,7 +2065,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{}, }, @@ -2073,7 +2083,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{}, }, }, @@ -2531,6 +2541,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyKubeServiceName: "service-updated", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, }, }, @@ -2552,6 +2563,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyKubeServiceName: "service-updated", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, Proxy: &api.AgentServiceConnectProxyConfig{ DestinationServiceName: "service-updated", @@ -2619,6 +2631,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { constants.MetaKeyKubeNS: "default", constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-updated", + constants.MetaKeyPodUID: "", }, }, }, @@ -2644,6 +2657,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { constants.MetaKeyKubeNS: "default", constants.MetaKeyPodName: "pod1", metaKeyKubeServiceName: "service-updated", + constants.MetaKeyPodUID: "", }, }, }, @@ -3222,6 +3236,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyKubeServiceName: "service-updated", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, }, }, @@ -3243,6 +3258,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyKubeServiceName: "service-updated", metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", + constants.MetaKeyPodUID: "", }, Proxy: &api.AgentServiceConnectProxyConfig{ DestinationServiceName: "service-updated", @@ -3261,6 +3277,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod2", + constants.MetaKeyPodUID: "", }, }, }, @@ -3274,6 +3291,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod2", + constants.MetaKeyPodUID: "", }, }, }, @@ -3324,6 +3342,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "", }, }, }, @@ -3349,6 +3368,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "", }, }, }, @@ -3369,6 +3389,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod2", + constants.MetaKeyPodUID: "", }, }, }, @@ -3394,6 +3415,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod2", + constants.MetaKeyPodUID: "", }, }, }, @@ -3409,6 +3431,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "", }, }, }, @@ -3423,6 +3446,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "", }, }, }, @@ -3475,6 +3499,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "", }, }, }, @@ -3500,6 +3525,7 @@ func TestReconcileUpdateEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "", }, }, }, @@ -3859,6 +3885,7 @@ func TestReconcileDeleteEndpoint(t *testing.T) { cases := []struct { name string consulSvcName string + consulPodUid string expectServicesToBeDeleted bool initialConsulSvcs []*api.AgentService enableACLs bool @@ -3944,6 +3971,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{ { @@ -3957,6 +3985,7 @@ func TestReconcileDeleteEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "123", }, }, { @@ -3975,6 +4004,7 @@ func TestReconcileDeleteEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "123", }, }, }, @@ -4014,6 +4044,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{ { @@ -4028,6 +4059,7 @@ func TestReconcileDeleteEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "mesh-gateway", + constants.MetaKeyPodUID: "124", }, TaggedAddresses: map[string]api.ServiceAddress{ "lan": { @@ -4077,6 +4109,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{ { @@ -4091,6 +4124,7 @@ func TestReconcileDeleteEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "ingress-gateway", + constants.MetaKeyPodUID: "125", }, TaggedAddresses: map[string]api.ServiceAddress{ "lan": { @@ -4130,6 +4164,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{ { @@ -4144,6 +4179,7 @@ func TestReconcileDeleteEndpoint(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "terminating-gateway", + constants.MetaKeyPodUID: "126", }, }, }, @@ -4190,8 +4226,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) @@ -4338,6 +4375,7 @@ func TestReconcileIgnoresServiceIgnoreLabel(t *testing.T) { metaKeyManagedBy: constants.ManagedByValue, metaKeySyntheticNode: "true", constants.MetaKeyPodName: "pod1", + constants.MetaKeyPodUID: "", }, }, } @@ -5945,12 +5983,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 03f47a8e84..6ff75c76c4 100644 --- a/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go +++ b/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go @@ -112,6 +112,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)", @@ -122,6 +128,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 4261887b12..c105e71b7b 100644 --- a/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go +++ b/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go @@ -221,17 +221,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)") }) } } diff --git a/control-plane/subcommand/flags/consul.go b/control-plane/subcommand/flags/consul.go index cd577790fc..9368b95b3d 100644 --- a/control-plane/subcommand/flags/consul.go +++ b/control-plane/subcommand/flags/consul.go @@ -11,11 +11,10 @@ import ( "strings" "time" + "github.com/hashicorp/consul-k8s/control-plane/consul" "github.com/hashicorp/consul-server-connection-manager/discovery" "github.com/hashicorp/consul/api" "github.com/hashicorp/go-rootcerts" - - "github.com/hashicorp/consul-k8s/control-plane/consul" ) const (