diff --git a/control-plane/api-gateway/gatekeeper/init.go b/control-plane/api-gateway/gatekeeper/init.go index 4fec339126..875e15dff3 100644 --- a/control-plane/api-gateway/gatekeeper/init.go +++ b/control-plane/api-gateway/gatekeeper/init.go @@ -192,12 +192,12 @@ func (g Gatekeeper) initContainer(config common.HelmConfig, name, namespace stri // We need to get the userID for the init container. We do not care about what is already defined on the pod // for gateways, as there is no application container that could have taken a UID. - uid, err = ctrlCommon.GetConnectInitUID(*ns, corev1.Pod{}) + uid, err = ctrlCommon.GetConnectInitUID(*ns, corev1.Pod{}, config.ImageDataplane, config.ImageConsulK8S) if err != nil { return corev1.Container{}, err } - gid, err = ctrlCommon.GetConnectInitGroupID(*ns, corev1.Pod{}) + gid, err = ctrlCommon.GetConnectInitGroupID(*ns, corev1.Pod{}, config.ImageDataplane, config.ImageConsulK8S) if err != nil { return corev1.Container{}, err } diff --git a/control-plane/connect-inject/common/openshift.go b/control-plane/connect-inject/common/openshift.go index 406b8e4483..114e82893a 100644 --- a/control-plane/connect-inject/common/openshift.go +++ b/control-plane/connect-inject/common/openshift.go @@ -23,8 +23,11 @@ import ( "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" ) -func GetDataplaneUID(namespace corev1.Namespace, pod corev1.Pod) (int64, error) { - availableUIDs, err := getAvailableIDs(namespace, pod, constants.AnnotationOpenShiftUIDRange) +// GetDataplaneUID returns the UID to use for the Dataplane container in the given namespace. +// The UID is based on the namespace annotation and avoids conflicting with any application container UIDs. +// Containers with dataplaneImage and k8sImage are not considered application containers. +func GetDataplaneUID(namespace corev1.Namespace, pod corev1.Pod, dataplaneImage, k8sImage string) (int64, error) { + availableUIDs, err := getAvailableIDs(namespace, pod, constants.AnnotationOpenShiftUIDRange, dataplaneImage, k8sImage) if err != nil { return 0, err } @@ -36,8 +39,11 @@ func GetDataplaneUID(namespace corev1.Namespace, pod corev1.Pod) (int64, error) return availableUIDs[len(availableUIDs)-2], nil } -func GetDataplaneGroupID(namespace corev1.Namespace, pod corev1.Pod) (int64, error) { - availableUIDs, err := getAvailableIDs(namespace, pod, constants.AnnotationOpenShiftGroups) +// GetDataplaneGroupID returns the group ID to use for the Dataplane container in the given namespace. +// The UID is based on the namespace annotation and avoids conflicting with any application container group IDs. +// Containers with dataplaneImage and k8sImage are not considered application containers. +func GetDataplaneGroupID(namespace corev1.Namespace, pod corev1.Pod, dataplaneImage, k8sImage string) (int64, error) { + availableUIDs, err := getAvailableIDs(namespace, pod, constants.AnnotationOpenShiftGroups, dataplaneImage, k8sImage) if err != nil { return 0, err } @@ -49,8 +55,11 @@ func GetDataplaneGroupID(namespace corev1.Namespace, pod corev1.Pod) (int64, err return availableUIDs[len(availableUIDs)-2], nil } -func GetConnectInitUID(namespace corev1.Namespace, pod corev1.Pod) (int64, error) { - availableUIDs, err := getAvailableIDs(namespace, pod, constants.AnnotationOpenShiftUIDRange) +// GetConnectInitUID returns the UID to use for the connect init container in the given namespace. +// The UID is based on the namespace annotation and avoids conflicting with any application container UIDs. +// Containers with dataplaneImage and k8sImage are not considered application containers. +func GetConnectInitUID(namespace corev1.Namespace, pod corev1.Pod, dataplaneImage, k8sImage string) (int64, error) { + availableUIDs, err := getAvailableIDs(namespace, pod, constants.AnnotationOpenShiftUIDRange, dataplaneImage, k8sImage) if err != nil { return 0, err } @@ -62,8 +71,11 @@ func GetConnectInitUID(namespace corev1.Namespace, pod corev1.Pod) (int64, error return availableUIDs[len(availableUIDs)-1], nil } -func GetConnectInitGroupID(namespace corev1.Namespace, pod corev1.Pod) (int64, error) { - availableUIDs, err := getAvailableIDs(namespace, pod, constants.AnnotationOpenShiftGroups) +// GetConnectInitGroupID returns the group ID to use for the connect init container in the given namespace. +// The group ID is based on the namespace annotation and avoids conflicting with any application container group IDs. +// Containers with dataplaneImage and k8sImage are not considered application containers. +func GetConnectInitGroupID(namespace corev1.Namespace, pod corev1.Pod, dataplaneImage, k8sImage string) (int64, error) { + availableUIDs, err := getAvailableIDs(namespace, pod, constants.AnnotationOpenShiftGroups, dataplaneImage, k8sImage) if err != nil { return 0, err } @@ -75,7 +87,10 @@ func GetConnectInitGroupID(namespace corev1.Namespace, pod corev1.Pod) (int64, e return availableUIDs[len(availableUIDs)-1], nil } -func getAvailableIDs(namespace corev1.Namespace, pod corev1.Pod, annotationName string) ([]int64, error) { +// getAvailableIDs enumerates the entire list of available UIDs in the namespace based on the +// OpenShift annotationName provided. It then removes the UIDs that are already in use by application +// containers. Containers with dataplaneImage and k8sImage are not considered application containers. +func getAvailableIDs(namespace corev1.Namespace, pod corev1.Pod, annotationName, dataplaneImage, k8sImage string) ([]int64, error) { // Collect the list of IDs designated in the Pod for application containers appUIDs := make([]int64, 0) if pod.Spec.SecurityContext != nil { @@ -84,11 +99,7 @@ func getAvailableIDs(namespace corev1.Namespace, pod corev1.Pod, annotationName } } for _, c := range pod.Spec.Containers { - if strings.HasPrefix(c.Name, "consul-dataplane") { - continue - } - - if strings.HasPrefix(c.Name, "consul-connect-inject-init") { + if c.Image == dataplaneImage || c.Image == k8sImage { continue } @@ -119,6 +130,8 @@ func getAvailableIDs(namespace corev1.Namespace, pod corev1.Pod, annotationName return keys, nil } +// getIDsInRange enumerates the entire list of available IDs given the value of the +// OpenShift annotation. This can be the group or user ID range. func getIDsInRange(annotation string) ([]int64, error) { parts := strings.Split(annotation, "/") if len(parts) != 2 { diff --git a/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go b/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go index 3ceacb6025..c30b672093 100644 --- a/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go +++ b/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go @@ -244,11 +244,11 @@ func (w *MeshWebhook) consulDataplaneSidecar(namespace corev1.Namespace, pod cor // Transparent proxy is set in OpenShift. There is an annotation on the namespace that tells us what // the user and group ids should be for the sidecar. var err error - uid, err = common.GetDataplaneUID(namespace, pod) + uid, err = common.GetDataplaneUID(namespace, pod, w.ImageConsulDataplane, w.ImageConsulK8S) if err != nil { return corev1.Container{}, err } - group, err = common.GetDataplaneGroupID(namespace, pod) + group, err = common.GetDataplaneGroupID(namespace, pod, w.ImageConsulDataplane, w.ImageConsulK8S) if err != nil { return corev1.Container{}, err } diff --git a/control-plane/connect-inject/webhook/container_init.go b/control-plane/connect-inject/webhook/container_init.go index c024f33cd1..6ba4ca35a5 100644 --- a/control-plane/connect-inject/webhook/container_init.go +++ b/control-plane/connect-inject/webhook/container_init.go @@ -242,12 +242,12 @@ func (w *MeshWebhook) containerInit(namespace corev1.Namespace, pod corev1.Pod, if w.EnableOpenShift { var err error - uid, err = common.GetConnectInitUID(namespace, pod) + uid, err = common.GetConnectInitUID(namespace, pod, w.ImageConsulDataplane, w.ImageConsulK8S) if err != nil { return corev1.Container{}, err } - group, err = common.GetConnectInitGroupID(namespace, pod) + group, err = common.GetConnectInitGroupID(namespace, pod, w.ImageConsulDataplane, w.ImageConsulK8S) if err != nil { return corev1.Container{}, err } diff --git a/control-plane/connect-inject/webhook/redirect_traffic.go b/control-plane/connect-inject/webhook/redirect_traffic.go index b62c2b614c..c8dc533adb 100644 --- a/control-plane/connect-inject/webhook/redirect_traffic.go +++ b/control-plane/connect-inject/webhook/redirect_traffic.go @@ -36,14 +36,14 @@ func (w *MeshWebhook) iptablesConfigJSON(pod corev1.Pod, ns corev1.Namespace) (s cfg.ExcludeUIDs = append(cfg.ExcludeUIDs, strconv.Itoa(initContainersUserAndGroupID)) } else { // When using OpenShift, the uid and group are saved as an annotation on the namespace - uid, err := common.GetDataplaneUID(ns, pod) + uid, err := common.GetDataplaneUID(ns, pod, w.ImageConsulDataplane, w.ImageConsulK8S) if err != nil { return "", err } cfg.ProxyUserID = strconv.FormatInt(uid, 10) // Exclude the user ID for the init container from traffic redirection. - uid, err = common.GetConnectInitUID(ns, pod) + uid, err = common.GetConnectInitUID(ns, pod, w.ImageConsulDataplane, w.ImageConsulK8S) if err != nil { return "", err }