diff --git a/ci/env.defaults b/ci/env.defaults index d597f3fb..16181e47 100644 --- a/ci/env.defaults +++ b/ci/env.defaults @@ -26,8 +26,8 @@ DPF_HELM_REPO_URL=${DPF_HELM_REPO_URL:-oci://ghcr.io/killianmuldoon/doca-platfor OVN_CHART_URL=${OVN_CHART_URL:-oci://ghcr.io/mellanox/charts} OVN_TEMPLATE_CHART_URL=${OVN_TEMPLATE_CHART_URL:-oci://ghcr.io/mellanox/charts} OVN_CHART_VERSION=${OVN_CHART_VERSION:-v25.7.1-79ed186} -OVN_KUBERNETES_UTILS_IMAGE_REPO=${OVN_KUBERNETES_UTILS_IMAGE_REPO:-ghcr.io/mellanox/ovn-kubernetes-dpf-utils} -OVN_KUBERNETES_UTILS_IMAGE_TAG=${OVN_KUBERNETES_UTILS_IMAGE_TAG:-v25.7.1-79ed186} +OVN_KUBERNETES_UTILS_IMAGE_REPO=${OVN_KUBERNETES_UTILS_IMAGE_REPO:-} +OVN_KUBERNETES_UTILS_IMAGE_TAG=${OVN_KUBERNETES_UTILS_IMAGE_TAG:-} SRIOV_DP_RESOURCE_PREFIX=${SRIOV_DP_RESOURCE_PREFIX:-openshift.io} SRIOV_DP_CONFIG_NAME=${SRIOV_DP_CONFIG_NAME:-bf3-p0-vfs} INJECTOR_RESOURCE_NAME=${INJECTOR_RESOURCE_NAME:-${SRIOV_DP_RESOURCE_PREFIX}/${SRIOV_DP_CONFIG_NAME}} diff --git a/manifests/identity-cm.yaml b/manifests/identity-cm.yaml deleted file mode 100644 index 5eaf0cf0..00000000 --- a/manifests/identity-cm.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: network-node-identity - namespace: openshift-network-operator -data: - enabled: "false" diff --git a/manifests/cluster-installation/identity-cm.yaml b/manifests/post-installation/identity-cm.yaml similarity index 100% rename from manifests/cluster-installation/identity-cm.yaml rename to manifests/post-installation/identity-cm.yaml diff --git a/manifests/post-installation/ovn-configuration.yaml b/manifests/post-installation/ovn-configuration.yaml index ce4eed1d..8d75122d 100644 --- a/manifests/post-installation/ovn-configuration.yaml +++ b/manifests/post-installation/ovn-configuration.yaml @@ -9,13 +9,15 @@ spec: helmChart: values: global: - enableOvnKubeIdentity: false + enableOvnKubeIdentity: imagePullSecretName: "dpf-pull-secret" ovnDaemonsetVersion: "" k8sAPIServer: https://:6443 podNetwork: 10.128.0.0/14/23 serviceNetwork: 172.30.0.0/16 mtu: + dpuHealthCheck: + renewInterval: 0 dpuManifests: ovnMultiNetworkEnable: "false" kubernetesSecretName: "ovn-dpu" diff --git a/manifests/post-installation/ovn-credentials-identity.yaml b/manifests/post-installation/ovn-credentials-identity.yaml new file mode 100644 index 00000000..a09aae90 --- /dev/null +++ b/manifests/post-installation/ovn-credentials-identity.yaml @@ -0,0 +1,66 @@ +# DPU node identity RBAC (source: openshift/cluster-network-operator#2927) +--- +# Grant lease permissions via the system:ovn-nodes group +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: openshift-ovn-kubernetes-node-dpu-service-identity-limited + namespace: openshift-ovn-kubernetes +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: openshift-ovn-kubernetes-node-limited +subjects: +- kind: Group + name: system:ovn-nodes + apiGroup: rbac.authorization.k8s.io +--- +# Allow the DPU service account to impersonate node users and groups +# so it can act on behalf of the DPU host node. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: openshift-ovn-kubernetes-node-dpu-host-impersonator +rules: +- apiGroups: [""] + resources: + - users + verbs: + - impersonate +- apiGroups: [""] + resources: + - groups + verbs: + - impersonate + resourceNames: + - system:nodes + - system:authenticated +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: openshift-ovn-kubernetes-node-dpu-host-impersonator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openshift-ovn-kubernetes-node-dpu-host-impersonator +subjects: +- kind: ServiceAccount + name: ovn-kubernetes-node-dpu-service + namespace: openshift-ovn-kubernetes +--- +# Bind DPU SA directly to the cluster-scoped node ClusterRole so it has +# read access to networkpolicies, nodes, pods, services, etc. without +# requiring impersonation for every request. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: ovn-kubernetes-node-limited-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openshift-ovn-kubernetes-node-limited +subjects: +- kind: ServiceAccount + name: ovn-kubernetes-node-dpu-service + namespace: openshift-ovn-kubernetes diff --git a/manifests/post-installation/ovn-credentials-legacy.yaml b/manifests/post-installation/ovn-credentials-legacy.yaml new file mode 100644 index 00000000..9e713bcb --- /dev/null +++ b/manifests/post-installation/ovn-credentials-legacy.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: ovn-kubernetes-node-limited-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openshift-ovn-kubernetes-node-limited +subjects: +- kind: ServiceAccount + name: ovn-kubernetes-node-dpu-service + namespace: openshift-ovn-kubernetes diff --git a/manifests/post-installation/ovn-credentials.yaml b/manifests/post-installation/ovn-credentials.yaml index a0f37460..de4a2436 100644 --- a/manifests/post-installation/ovn-credentials.yaml +++ b/manifests/post-installation/ovn-credentials.yaml @@ -16,17 +16,3 @@ spec: metadata: labels: dpu.nvidia.com/image-pull-secret: "" - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: ovn-kubernetes-node-limited-binding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: openshift-ovn-kubernetes-node-limited -subjects: -- kind: ServiceAccount - name: ovn-kubernetes-node-dpu-service - namespace: openshift-ovn-kubernetes diff --git a/scripts/post-install.sh b/scripts/post-install.sh index 6dfe75e4..6e34e66e 100755 --- a/scripts/post-install.sh +++ b/scripts/post-install.sh @@ -35,6 +35,9 @@ SPECIAL_FILES=( "dpuflavor.yaml" "ovn-template.yaml" "ovn-configuration.yaml" + "ovn-credentials-identity.yaml" + "ovn-credentials-legacy.yaml" + "identity-cm.yaml" "hbn-template.yaml" "hbn-configuration.yaml" "dts-template.yaml" @@ -119,7 +122,12 @@ function update_hbn_ovn_manifests() { ovn_daemonset_version="1.2.0" fi - log "INFO" "ovn-configuration will be set with MTU:$ovn_mtu ovnDaemonsetVersion:$ovn_daemonset_version" + local enable_ovn_kube_identity="false" + if ocp_version_gte "${OPENSHIFT_VERSION}" "4.22" && dpf_version_gte "${DPF_VERSION}" "26.4"; then + enable_ovn_kube_identity="true" + fi + + log "INFO" "ovn-configuration will be set with MTU:$ovn_mtu ovnDaemonsetVersion:$ovn_daemonset_version enableOvnKubeIdentity:$enable_ovn_kube_identity" update_file_multi_replace \ "${POST_INSTALL_DIR}/ovn-configuration.yaml" \ "${GENERATED_POST_INSTALL_DIR}/ovn-configuration.yaml" \ @@ -127,7 +135,8 @@ function update_hbn_ovn_manifests() { "" "${HOST_CLUSTER_API}" \ "" "${DPU_HOST_CIDR}" \ "" "${ovn_mtu}" \ - "" "${ovn_daemonset_version}" + "" "${ovn_daemonset_version}" \ + "" "${enable_ovn_kube_identity}" fi # Update hbn-configuration.yaml @@ -140,6 +149,25 @@ function update_hbn_ovn_manifests() { log [INFO] "HBN OVN manifests updated successfully" } +# Select the correct OVN credentials manifest based on OCP/DPF version. +# OCP >= 4.22 and DPF >= 26.4 use node-identity RBAC (impersonation + group subject). +# Older versions use the legacy ServiceAccount-based ClusterRoleBinding. +function update_ovn_credentials() { + local rbac_file + if ocp_version_gte "${OPENSHIFT_VERSION}" "4.22" && dpf_version_gte "${DPF_VERSION}" "26.4"; then + log "INFO" "OCP ${OPENSHIFT_VERSION} >= 4.22 and DPF ${DPF_VERSION} >= 26.4: using node-identity RBAC" + rbac_file="ovn-credentials-identity.yaml" + else + log "INFO" "Using legacy OVN credentials RBAC (OCP ${OPENSHIFT_VERSION}, DPF ${DPF_VERSION})" + rbac_file="ovn-credentials-legacy.yaml" + cp "${POST_INSTALL_DIR}/identity-cm.yaml" "${GENERATED_POST_INSTALL_DIR}/identity-cm.yaml" + log "INFO" "Node identity disabled via identity-cm.yaml" + fi + + cp "${POST_INSTALL_DIR}/${rbac_file}" "${GENERATED_POST_INSTALL_DIR}/${rbac_file}" + log "INFO" "OVN credentials RBAC ready: ${rbac_file}" +} + # Function to update VF configuration function update_vf_configuration() { log [INFO] "Updating VF configuration in manifests..." @@ -250,6 +278,7 @@ function prepare_post_installation() { # Update manifests with custom values update_bfb_manifest update_hbn_ovn_manifests + update_ovn_credentials update_vf_configuration update_service_templates update_dpu_service_nad diff --git a/scripts/utils.sh b/scripts/utils.sh index eda8513c..f4da2f50 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -425,6 +425,25 @@ ocp_version_gte() { return 1 } +# Compare two DPF version strings (major.minor only, YY.M format). +# Returns 0 (true) if $1 >= $2, 1 (false) otherwise. +# Usage: dpf_version_gte "26.4.0-47183a84" "26.4" && echo "yes" +dpf_version_gte() { + local ver="$1" threshold="$2" + local ver_major ver_minor thr_major thr_minor + ver_major="${ver%%.*}" + ver_minor="${ver#*.}"; ver_minor="${ver_minor%%.*}" + thr_major="${threshold%%.*}" + thr_minor="${threshold#*.}"; thr_minor="${thr_minor%%.*}" + + if (( ver_major > thr_major )); then + return 0 + elif (( ver_major == thr_major && ver_minor >= thr_minor )); then + return 0 + fi + return 1 +} + function ensure_ssh_key_in_home() { if [ ! -f "${SSH_KEY}" ]; then log "ERROR" "SSH public key file not found: ${SSH_KEY}. Set SSH_KEY in .env and place your .pub key there."