Repository: kiali/kiali

Issue:
[ambient] Update install-istio-via-sail hack script to be able to use Ambient profile
### What do you want to improve?
- Update `install-istio-via-sail` hack script to be able to use Ambient profile if the Ambient argument is sent. 
See https://github.com/istio-ecosystem/sail-operator/blob/main/tests/e2e/ambient/ambient_test.go for an example. 
- Update CI to use also sail 

### What is the current behavior?
Feature not supported

### What is the new behavior?
Include an option (Like, profile? or Ambient?) to be able to use Ambient profile. 

Hints from issue comments:

Solution patch:
diff --git a/.github/workflows/tag-creator.yml b/.github/workflows/tag-bump-version.yml
similarity index 79%
rename from .github/workflows/tag-creator.yml
rename to .github/workflows/tag-bump-version.yml
index 654b66d43..efcfb458c 100644
--- a/.github/workflows/tag-creator.yml
+++ b/.github/workflows/tag-bump-version.yml
@@ -1,10 +1,10 @@
-name: Tag Creator
+name: Tag Bump Version
 
 on:
   workflow_dispatch:
     inputs:
       tag_branch:
-        description: Branch to tag, (Separate branches by commas. Ex v1.65,v1.73)
+        description: Branch to bump version (Separate branches by commas. Ex v1.73,v2.4)
         required: true
         default: v1.73
         type: string
@@ -35,17 +35,19 @@ jobs:
       run: |
         BRANCHES=$(python conversor.py $TAG_BRANCHES)
         echo "branches=$BRANCHES" >> $GITHUB_ENV
-  create_tag:
+
+  bump_version:
     needs: [initialize]
     runs-on: ubuntu-latest
     strategy:
       matrix:
         branch: ${{fromJson(needs.initialize.outputs.branches)}}
     steps:
-    - name: Checkout Backend
+    - name: Checkout branch
       uses: actions/checkout@v4
       with:
         ref: ${{matrix.branch}}
+
     - name: Prepare scripts
       run: |
         cat <<-EOF > bump.py
@@ -68,27 +70,27 @@ jobs:
         print('.'.join(['v' + str(major), str(minor), str(patch)]))
         EOF
 
-    - name: Configure git backend
+    - name: Configure git
       run: |
         git config user.email 'kiali-dev@googlegroups.com'
-
         git config user.name 'kiali-bot'
-    - name: Create Tag in kiali/kiali
-      id: tag_kiali
+
+    - name: Create Bump Version Tag in kiali/kiali
       env:
         BRANCH: ${{matrix.branch}}
       run: |
         RAW_VERSION=$(sed -rn 's/^VERSION \?= (.*)/\1/p' Makefile)
 
-        # Remove any pre release identifier (ie: "-SNAPSHOT")
-        RELEASE_VERSION=${RAW_VERSION%-*}
-        RELEASE_VERSION=$(python bump.py patch $RELEASE_VERSION)
-
-        echo "release_version=$RELEASE_VERSION" >> $GITHUB_ENV
+        RELEASE_VERSION=$(python bump.py patch $RAW_VERSION)
 
+        # Update the version in Kiali repository
         sed -i -r "s/^VERSION \?= (.*)/VERSION \?= $RELEASE_VERSION/" Makefile
         sed -i -r 's/"version": (.*)/"version": "'${RELEASE_VERSION:1}'",/' frontend/package.json
 
+        # Commit the changes
         git add Makefile frontend/package.json
         git commit -m "Bump to version $RELEASE_VERSION"
-        git push origin && git push origin $(git rev-parse HEAD):refs/tags/$RELEASE_VERSION-rc
+        git push origin $(git rev-parse HEAD):refs/heads/$BRANCH
+
+        # Create the bump version tag
+        git push origin $(git rev-parse HEAD):refs/tags/$RELEASE_VERSION-ossm
diff --git a/.github/workflows/tag-release-creator.yml b/.github/workflows/tag-release-creator.yml
new file mode 100644
index 000000000..bdfe82cd7
--- /dev/null
+++ b/.github/workflows/tag-release-creator.yml
@@ -0,0 +1,102 @@
+name: Tag Release Creator
+
+on:
+  workflow_dispatch:
+    inputs:
+      tag_branch:
+        description: Branch to tag (Separate branches by commas. Ex v1.73,v2.4)
+        required: true
+        default: v1.73
+        type: string
+      target_commit:
+        description: Commit hash to tag (if empty, uses HEAD of each branch; if specified, requires single branch)
+        required: false
+        type: string
+
+jobs:
+  initialize:
+    name: Initialize
+    runs-on: ubuntu-latest
+    outputs:
+      branches: ${{ env.branches }}
+    steps:
+    - name: Prepare script to var
+      id: script_convert
+      run: |
+        cat <<-EOF > conversor.py
+        import sys, json
+
+        branch_arg = sys.argv[1]
+        branches = branch_arg.split(',')
+
+        print(json.dumps(branches))
+        EOF
+
+    - name: Set Branch
+      id: branches
+      env:
+        TAG_BRANCHES: ${{ github.event.inputs.tag_branch }}
+      run: |
+        BRANCHES=$(python conversor.py $TAG_BRANCHES)
+        echo "branches=$BRANCHES" >> $GITHUB_ENV
+
+  release_tag:
+    needs: [initialize]
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        branch: ${{fromJson(needs.initialize.outputs.branches)}}
+    steps:
+    - name: Checkout branch
+      uses: actions/checkout@v4
+      with:
+        ref: ${{matrix.branch}}
+        # We need to fetch the full history to check if the commit exists
+        fetch-depth: 0
+
+    - name: Configure git
+      run: |
+        git config user.email 'kiali-dev@googlegroups.com'
+        git config user.name 'kiali-bot'
+
+    - name: Validate target commit
+      run: |
+        # Validate that only single branch is specified when target_commit is provided
+        if [ -n "${{ inputs.target_commit }}" ]; then
+          if [[ "${{ inputs.tag_branch }}" == *","* ]]; then
+            echo "Error: When target_commit is specified, only a single branch is allowed in tag_branch"
+            echo "Provided: ${{ inputs.tag_branch }}"
+            echo "Remove commas and specify only one branch when using a specific commit"
+            exit 1
+          fi
+        fi
+
+        # Set target commit to HEAD if empty
+        if [ -z "${{ inputs.target_commit }}" ]; then
+          TARGET_COMMIT=$(git rev-parse HEAD)
+          echo "No target commit specified, using HEAD: $TARGET_COMMIT"
+        else
+          TARGET_COMMIT="${{ inputs.target_commit }}"
+          echo "Using specified target commit: $TARGET_COMMIT"
+        fi
+
+        # Check if commit exists in the specified branch
+        if ! git merge-base --is-ancestor $TARGET_COMMIT HEAD 2>/dev/null; then
+          echo "Error: Commit $TARGET_COMMIT not found in branch ${{ matrix.branch }}"
+          exit 1
+        fi
+
+        echo "Commit $TARGET_COMMIT is valid and exists in branch ${{ matrix.branch }}"
+        echo "TARGET_COMMIT=$TARGET_COMMIT" >> $GITHUB_ENV
+
+    - name: Create Release Tag in kiali/kiali
+      run: |
+        RELEASE_VERSION=$(sed -rn 's/^VERSION \?= (.*)/\1/p' Makefile)
+
+        echo "Creating release tag $RELEASE_VERSION for commit $TARGET_COMMIT"
+
+        # Create the release tag
+        git push origin $TARGET_COMMIT:refs/tags/$RELEASE_VERSION
+
+        # Delete the bump version tag if it exists
+        git push origin --delete refs/tags/$RELEASE_VERSION-ossm || true
diff --git a/Makefile b/Makefile
index 3847edc4e..bc73426ce 100644
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@ TARGET_ARCHS ?= amd64 arm64 s390x ppc64le
 
 # Identifies the current build.
 # These will be embedded in the app and displayed when it starts.
-VERSION ?= v2.13.0-SNAPSHOT
+VERSION ?= v2.14.0-SNAPSHOT
 COMMIT_HASH ?= $(shell git rev-parse HEAD)
 
 # Version label is used in the OpenShift/K8S resources to identify
diff --git a/business/istio_config.go b/business/istio_config.go
index 1470a2ff2..55fb50652 100644
--- a/business/istio_config.go
+++ b/business/istio_config.go
@@ -18,6 +18,7 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	api_types "k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
+	k8s_inference_v1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
 	k8s_networking_v1 "sigs.k8s.io/gateway-api/apis/v1"
 	k8s_networking_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
 	k8s_networking_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
@@ -47,6 +48,7 @@ type IstioConfigCriteria struct {
 	IncludeK8sGateways            bool
 	IncludeK8sGRPCRoutes          bool
 	IncludeK8sHTTPRoutes          bool
+	IncludeK8sInferencePools      bool
 	IncludeK8sReferenceGrants     bool
 	IncludeK8sTCPRoutes           bool
 	IncludeK8sTLSRoutes           bool
@@ -78,6 +80,8 @@ func (icc IstioConfigCriteria) Include(resource schema.GroupVersionKind) bool {
 		return icc.IncludeK8sGRPCRoutes
 	case kubernetes.K8sHTTPRoutes:
 		return icc.IncludeK8sHTTPRoutes
+	case kubernetes.K8sInferencePools:
+		return icc.IncludeK8sInferencePools
 	case kubernetes.K8sReferenceGrants:
 		return icc.IncludeK8sReferenceGrants
 	case kubernetes.K8sTCPRoutes:
@@ -220,6 +224,7 @@ func (in *IstioConfigService) getIstioConfigList(ctx context.Context, cluster st
 		K8sGateways:        []*k8s_networking_v1.Gateway{},
 		K8sGRPCRoutes:      []*k8s_networking_v1.GRPCRoute{},
 		K8sHTTPRoutes:      []*k8s_networking_v1.HTTPRoute{},
+		K8sInferencePools:  []*k8s_inference_v1alpha2.InferencePool{},
 		K8sReferenceGrants: []*k8s_networking_v1beta1.ReferenceGrant{},
 		K8sTCPRoutes:       []*k8s_networking_v1alpha2.TCPRoute{},
 		K8sTLSRoutes:       []*k8s_networking_v1alpha2.TLSRoute{},
@@ -319,6 +324,17 @@ func (in *IstioConfigService) getIstioConfigList(ctx context.Context, cluster st
 		istioConfigList.K8sHTTPRoutes = ToPtrs(list.Items)
 	}
 
+	if userClient.IsInferenceAPI() && criteria.Include(kubernetes.K8sInferencePools) {
+		list := &k8s_inference_v1alpha2.InferencePoolList{}
+		if err := kubeCache.List(ctx, list, listOpts...); err != nil {
+			return nil, err
+		}
+		istioConfigList.K8sInferencePools = ToPtrs(list.Items)
+		if isWorkloadSelector {
+			istioConfigList.K8sInferencePools = kubernetes.FilterK8sInferencePoolsBySelector(workloadSelector, istioConfigList.K8sInferencePools)
+		}
+	}
+
 	if userClient.IsGatewayAPI() && criteria.Include(kubernetes.K8sReferenceGrants) {
 		list := &k8s_networking_v1beta1.ReferenceGrantList{}
 		if err := kubeCache.List(ctx, list, listOpts...); err != nil {
@@ -477,6 +493,7 @@ func (in *IstioConfigService) GetIstioConfigList(ctx context.Context, cluster st
 		K8sGateways:            kubernetes.FilterByNamespaceNames(istioConfigs.K8sGateways, namespaceNames),
 		K8sGRPCRoutes:          kubernetes.FilterByNamespaceNames(istioConfigs.K8sGRPCRoutes, namespaceNames),
 		K8sHTTPRoutes:          kubernetes.FilterByNamespaceNames(istioConfigs.K8sHTTPRoutes, namespaceNames),
+		K8sInferencePools:      kubernetes.FilterByNamespaceNames(istioConfigs.K8sInferencePools, namespaceNames),
 		K8sReferenceGrants:     kubernetes.FilterByNamespaceNames(istioConfigs.K8sReferenceGrants, namespaceNames),
 		K8sTCPRoutes:           kubernetes.FilterByNamespaceNames(istioConfigs.K8sTCPRoutes, namespaceNames),
 		K8sTLSRoutes:           kubernetes.FilterByNamespaceNames(istioConfigs.K8sTLSRoutes, namespaceNames),
@@ -581,6 +598,13 @@ func (in *IstioConfigService) GetIstioConfigDetails(ctx context.Context, cluster
 			istioConfigDetail.K8sHTTPRoute.APIVersion = kubernetes.K8sHTTPRoutes.GroupVersion().String()
 			istioConfigDetail.Object = istioConfigDetail.K8sHTTPRoute
 		}
+	case kubernetes.K8sInferencePools:
+		istioConfigDetail.K8sInferencePool, err = in.userClients[cluster].InferenceAPI().InferenceV1alpha2().InferencePools(namespace).Get(ctx, object, getOpts)
+		if err == nil {
+			istioConfigDetail.K8sInferencePool.Kind = kubernetes.K8sInferencePools.Kind
+			istioConfigDetail.K8sInferencePool.APIVersion = kubernetes.K8sInferencePools.GroupVersion().String()
+			istioConfigDetail.Object = istioConfigDetail.K8sInferencePool
+		}
 	case kubernetes.K8sReferenceGrants:
 		istioConfigDetail.K8sReferenceGrant, err = in.userClients[cluster].GatewayAPI().GatewayV1beta1().ReferenceGrants(namespace).Get(ctx, object, getOpts)
 		if err == nil {
@@ -721,6 +745,8 @@ func (in *IstioConfigService) DeleteIstioConfigDetail(ctx context.Context, clust
 		err = userClient.GatewayAPI().GatewayV1().GRPCRoutes(namespace).Delete(ctx, name, delOpts)
 	case kubernetes.K8sHTTPRoutes:
 		err = userClient.GatewayAPI().GatewayV1().HTTPRoutes(namespace).Delete(ctx, name, delOpts)
+	case kubernetes.K8sInferencePools:
+		err = userClient.InferenceAPI().InferenceV1alpha2().InferencePools(namespace).Delete(ctx, name, delOpts)
 	case kubernetes.K8sReferenceGrants:
 		err = userClient.GatewayAPI().GatewayV1beta1().ReferenceGrants(namespace).Delete(ctx, name, delOpts)
 	case kubernetes.K8sTCPRoutes:
@@ -855,6 +881,10 @@ func (in *IstioConfigService) UpdateIstioConfigDetail(ctx context.Context, clust
 		istioConfigDetail.K8sHTTPRoute = &k8s_networking_v1.HTTPRoute{}
 		istioConfigDetail.K8sHTTPRoute, err = userClient.GatewayAPI().GatewayV1().HTTPRoutes(namespace).Patch(ctx, name, patchType, bytePatch, patchOpts)
 		istioConfigDetail.Object = istioConfigDetail.K8sHTTPRoute
+	case kubernetes.K8sInferencePools.String():
+		istioConfigDetail.K8sInferencePool = &k8s_inference_v1alpha2.InferencePool{}
+		istioConfigDetail.K8sInferencePool, err = userClient.InferenceAPI().InferenceV1alpha2().InferencePools(namespace).Patch(ctx, name, patchType, bytePatch, patchOpts)
+		istioConfigDetail.Object = istioConfigDetail.K8sInferencePool
 	case kubernetes.K8sReferenceGrants.String():
 		istioConfigDetail.K8sReferenceGrant = &k8s_networking_v1beta1.ReferenceGrant{}
 		fixedPatch := strings.Replace(jsonPatch, "\"group\":null", "\"group\":\"\"", -1)
@@ -989,6 +1019,15 @@ func (in *IstioConfigService) CreateIstioConfigDetail(ctx context.Context, clust
 		istioConfigDetail.K8sHTTPRoute, err = userClient.GatewayAPI().GatewayV1().HTTPRoutes(namespace).Create(ctx, istioConfigDetail.K8sHTTPRoute, createOpts)
 		istioConfigDetail.Object = istioConfigDetail.K8sHTTPRoute
 		name = istioConfigDetail.K8sHTTPRoute.Name
+	case kubernetes.K8sInferencePools.String():
+		istioConfigDetail.K8sInferencePool = &k8s_inference_v1alpha2.InferencePool{}
+		err = json.Unmarshal(body, istioConfigDetail.K8sInferencePool)
+		if err != nil {
+			return istioConfigDetail, api_errors.NewBadRequest(err.Error())
+		}
+		istioConfigDetail.K8sInferencePool, err = userClient.InferenceAPI().InferenceV1alpha2().InferencePools(namespace).Create(ctx, istioConfigDetail.K8sInferencePool, createOpts)
+		istioConfigDetail.Object = istioConfigDetail.K8sInferencePool
+		name = istioConfigDetail.K8sInferencePool.Name
 	case kubernetes.K8sGRPCRoutes.String():
 		istioConfigDetail.K8sGRPCRoute = &k8s_networking_v1.GRPCRoute{}
 		err = json.Unmarshal(body, istioConfigDetail.K8sGRPCRoute)
@@ -1279,6 +1318,7 @@ func ParseIstioConfigCriteria(objects, labelSelector, workloadSelector string) I
 	criteria.IncludeK8sGateways = defaultInclude
 	criteria.IncludeK8sGRPCRoutes = defaultInclude
 	criteria.IncludeK8sHTTPRoutes = defaultInclude
+	criteria.IncludeK8sInferencePools = defaultInclude
 	criteria.IncludeK8sReferenceGrants = defaultInclude
 	criteria.IncludeK8sTCPRoutes = defaultInclude
 	criteria.IncludeK8sTLSRoutes = defaultInclude
@@ -1314,6 +1354,9 @@ func ParseIstioConfigCriteria(objects, labelSelector, workloadSelector string) I
 	if checkType(types, kubernetes.K8sHTTPRoutes.String()) {
 		criteria.IncludeK8sHTTPRoutes = true
 	}
+	if checkType(types, kubernetes.K8sInferencePools.String()) {
+		criteria.IncludeK8sInferencePools = true
+	}
 	if checkType(types, kubernetes.K8sReferenceGrants.String()) {
 		criteria.IncludeK8sReferenceGrants = true
 	}
diff --git a/business/istio_validations.go b/business/istio_validations.go
index 12dbf66c0..4df1f0f3d 100644
--- a/business/istio_validations.go
+++ b/business/istio_validations.go
@@ -295,6 +295,7 @@ func (in *IstioValidationsService) Validate(ctx context.Context, cluster string,
 		IncludeK8sGateways:            true,
 		IncludeK8sGRPCRoutes:          true,
 		IncludeK8sHTTPRoutes:          true,
+		IncludeK8sInferencePools:      true,
 		IncludeK8sReferenceGrants:     true,
 		IncludePeerAuthentications:    true,
 		IncludeRequestAuthentications: true,
@@ -540,6 +541,7 @@ func (in *IstioValidationsService) ValidateIstioObject(ctx context.Context, clus
 		IncludeK8sGateways:            true,
 		IncludeK8sGRPCRoutes:          true,
 		IncludeK8sHTTPRoutes:          true,
+		IncludeK8sInferencePools:      true,
 		IncludeK8sReferenceGrants:     true,
 		IncludePeerAuthentications:    true,
 		IncludeRequestAuthentications: true,
@@ -653,6 +655,9 @@ func (in *IstioValidationsService) ValidateIstioObject(ctx context.Context, clus
 		httpRouteChecker := checkers.K8sHTTPRouteChecker{Conf: conf, Cluster: cluster, K8sHTTPRoutes: istioConfigList.K8sHTTPRoutes, K8sGateways: istioConfigList.K8sGateways, K8sReferenceGrants: istioConfigList.K8sReferenceGrants, Namespaces: namespaces, RegistryServices: registryServices}
 		objectCheckers = []checkers.ObjectChecker{noServiceChecker, httpRouteChecker}
 		referenceChecker = references.K8sHTTPRouteReferences{Conf: conf, K8sHTTPRoutes: istioConfigList.K8sHTTPRoutes, Namespaces: nsNames, K8sReferenceGrants: istioConfigList.K8sReferenceGrants}
+	case kubernetes.K8sInferencePools:
+		// Validation on K8sInferencePools is not expected
+		referenceChecker = references.K8sInferencePoolReferences{Conf: conf, Namespaces: nsNames, K8sInferencePools: istioConfigList.K8sInferencePools, RegistryServices: registryServices, WorkloadsPerNamespace: workloadsPerNamespace}
 	case kubernetes.K8sReferenceGrants:
 		objectCheckers = []checkers.ObjectChecker{
 			checkers.K8sReferenceGrantChecker{Cluster: cluster, K8sReferenceGrants: istioConfigList.K8sReferenceGrants, Namespaces: namespaces},
@@ -788,6 +793,9 @@ func (in *IstioValidationsService) setNamespaceIstioConfig(
 	// All K8sGRPCRoutes
 	namespaceIstioConfigList.K8sGRPCRoutes = append(namespaceIstioConfigList.K8sGRPCRoutes, clusterIstioConfig.K8sGRPCRoutes...)
 
+	// All K8sInferencePools
+	namespaceIstioConfigList.K8sInferencePools = append(namespaceIstioConfigList.K8sInferencePools, clusterIstioConfig.K8sInferencePools...)
+
 	// All K8sReferenceGrants
 	namespaceIstioConfigList.K8sReferenceGrants = append(namespaceIstioConfigList.K8sReferenceGrants, clusterIstioConfig.K8sReferenceGrants...)
 
diff --git a/business/references/k8s_inference_pool_references.go b/business/references/k8s_inference_pool_references.go
new file mode 100644
index 000000000..6d81c5fa0
--- /dev/null
+++ b/business/references/k8s_inference_pool_references.go
@@ -0,0 +1,74 @@
+package references
+
+import (
+	"fmt"
+	"strings"
+
+	k8s_inference_v1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
+
+	"k8s.io/apimachinery/pkg/labels"
+
+	"github.com/kiali/kiali/config"
+	"github.com/kiali/kiali/kubernetes"
+	"github.com/kiali/kiali/models"
+)
+
+type K8sInferencePoolReferences struct {
+	Conf                  *config.Config
+	Namespaces            []string
+	K8sInferencePools     []*k8s_inference_v1alpha2.InferencePool
+	RegistryServices      []*kubernetes.RegistryService
+	WorkloadsPerNamespace map[string]models.Workloads
+}
+
+// References computes and returns all references from the K8sInferencePools.
+func (r K8sInferencePoolReferences) References() models.IstioReferencesMap {
+	result := models.IstioReferencesMap{}
+
+	for _, pool := range r.K8sInferencePools {
+		key := models.IstioReferenceKey{
+			Namespace: pool.Namespace,
+			Name:      pool.Name,
+			ObjectGVK: kubernetes.K8sInferencePools,
+		}
+		references := &models.IstioReferences{}
+		references.ServiceReferences = r.getServiceReferences(pool)
+		references.WorkloadReferences = r.getWorkloadReferences(pool)
+		result.MergeReferencesMap(models.IstioReferencesMap{key: references})
+	}
+
+	return result
+}
+
+// getWorkloadReferences finds all Workloads that are selected by the InferencePool's spec.selector.
+func (r K8sInferencePoolReferences) getWorkloadReferences(pool *k8s_inference_v1alpha2.InferencePool) []models.WorkloadReference {
+	result := make([]models.WorkloadReference, 0)
+
+	poolLabelsS := []string{}
+	poolSelector := pool.Spec.Selector
+	for k, v := range poolSelector {
+		poolLabelsS = append(poolLabelsS, fmt.Sprintf("%s=%s", k, v))
+	}
+	if resourceSelector, err := labels.Parse(strings.Join(poolLabelsS, ",")); err == nil {
+		// InferencePool searches Workloads from own namespace
+		for _, w := range r.WorkloadsPerNamespace[pool.Namespace] {
+			wlLabelSet := labels.Set(w.Labels)
+			if resourceSelector.Matches(wlLabelSet) {
+				result = append(result, models.WorkloadReference{Name: w.Name, Namespace: pool.Namespace})
+			}
+		}
+	}
+
+	return result
+}
+
+// getServiceReferences finds the Service referenced by the InferencePool's spec.extensionRef.
+func (r K8sInferencePoolReferences) getServiceReferences(pool *k8s_inference_v1alpha2.InferencePool) []models.ServiceReference {
+	result := make([]models.ServiceReference, 0)
+
+	fqdn := kubernetes.GetHost(string(pool.Spec.ExtensionRef.Name), pool.Namespace, r.Namespaces, r.Conf)
+	if kubernetes.HasMatchingRegistryService(pool.Namespace, fqdn.String(), r.RegistryServices) {
+		result = append(result, models.ServiceReference{Name: string(pool.Spec.ExtensionRef.Name), Namespace: pool.Namespace})
+	}
+	return result
+}
diff --git a/business/services.go b/business/services.go
index 9e5530403..5890a7cf2 100644
--- a/business/services.go
+++ b/business/services.go
@@ -172,6 +172,7 @@ func (in *SvcService) getServiceListForCluster(ctx context.Context, criteria Ser
 			IncludeK8sGateways:        true,
 			IncludeK8sGRPCRoutes:      true,
 			IncludeK8sHTTPRoutes:      true,
+			IncludeK8sInferencePools:  true,
 			IncludeK8sReferenceGrants: true,
 			IncludeServiceEntries:     true,
 			IncludeVirtualServices:    true,
@@ -269,6 +270,7 @@ func (in *SvcService) buildKubernetesServices(svcs []core_v1.Service, pods []cor
 			svcK8sGRPCRoutes := kubernetes.FilterK8sGRPCRoutesByService(istioConfigList.K8sGRPCRoutes, istioConfigList.K8sReferenceGrants, item.Namespace, item.Name, in.conf)
 			svcK8sHTTPRoutes := kubernetes.FilterK8sHTTPRoutesByService(istioConfigList.K8sHTTPRoutes, istioConfigList.K8sReferenceGrants, item.Namespace, item.Name, in.conf)
 			svcK8sGateways := append(kubernetes.FilterK8sGatewaysByRoutes(istioConfigList.K8sGateways, svcK8sHTTPRoutes, svcK8sGRPCRoutes), kubernetes.FilterK8sGatewaysByLabel(kubernetes.FilterByNamespaceNames(istioConfigList.K8sGateways, []string{item.Namespace}), item.Labels[in.conf.IstioLabels.AmbientWaypointGatewayLabel])...)
+			svcK8sInferencePools := kubernetes.FilterK8sInferencePoolByService(istioConfigList.K8sInferencePools, item.Namespace, item.Name)
 
 			for _, vs := range svcVirtualServices {
 				ref := models.BuildKey(kubernetes.VirtualServices, vs.Name, vs.Namespace, cluster)
@@ -297,6 +299,10 @@ func (in *SvcService) buildKubernetesServices(svcs []core_v1.Service, pods []cor
 				ref := models.BuildKey(kubernetes.K8sHTTPRoutes, route.Name, route.Namespace, cluster)
 				svcReferences = append(svcReferences, &ref)
 			}
+			for _, pool := range svcK8sInferencePools {
+				ref := models.BuildKey(kubernetes.K8sInferencePools, pool.Name, pool.Namespace, cluster)
+				svcReferences = append(svcReferences, &ref)
+			}
 			svcReferences = FilterUniqueIstioReferences(svcReferences)
 			kialiWizard = getVSKialiScenario(svcVirtualServices)
 			if kialiWizard == "" {
@@ -529,6 +535,7 @@ func (in *SvcService) GetServiceDetails(ctx context.Context, cluster, namespace,
 			IncludeK8sGateways:        true,
 			IncludeK8sGRPCRoutes:      true,
 			IncludeK8sHTTPRoutes:      true,
+			IncludeK8sInferencePools:  true,
 			IncludeK8sReferenceGrants: true,
 			IncludeServiceEntries:     true,
 			IncludeVirtualServices:    true,
@@ -629,6 +636,7 @@ func (in *SvcService) GetServiceDetails(ctx context.Context, cluster, namespace,
 	s.DestinationRules = kubernetes.FilterDestinationRulesByService(istioConfigList.DestinationRules, namespace, service, in.conf)
 	s.K8sHTTPRoutes = kubernetes.FilterK8sHTTPRoutesByService(istioConfigList.K8sHTTPRoutes, istioConfigList.K8sReferenceGrants, namespace, service, in.conf)
 	s.K8sGRPCRoutes = kubernetes.FilterK8sGRPCRoutesByService(istioConfigList.K8sGRPCRoutes, istioConfigList.K8sReferenceGrants, namespace, service, in.conf)
+	s.K8sInferencePools = kubernetes.FilterK8sInferencePoolByService(istioConfigList.K8sInferencePools, namespace, service)
 	if s.Service.Type == "External" || s.Service.Type == "Federation" {
 		// On ServiceEntries cases the Service name is the hostname
 		s.ServiceEntries = kubernetes.FilterServiceEntriesByHostname(istioConfigList.ServiceEntries, s.Service.Name)
diff --git a/business/workloads.go b/business/workloads.go
index d9b2361c5..ec361db49 100644
--- a/business/workloads.go
+++ b/business/workloads.go
@@ -267,6 +267,7 @@ func (in *WorkloadService) GetWorkloadList(ctx context.Context, criteria Workloa
 			IncludeEnvoyFilters:           true,
 			IncludeGateways:               true,
 			IncludeK8sGateways:            true,
+			IncludeK8sInferencePools:      true,
 			IncludePeerAuthentications:    true,
 			IncludeRequestAuthentications: true,
 			IncludeSidecars:               true,
@@ -345,6 +346,17 @@ func FilterWorkloadReferences(conf *config.Config, wLabels map[string]string, is
 			wkdReferences = append(wkdReferences, &ref)
 		}
 	}
+	k8sIPFiltered := kubernetes.FilterK8sInferencePoolsBySelector(wSelector, istioConfigList.K8sInferencePools)
+	for _, pool := range k8sIPFiltered {
+		ref := models.BuildKey(kubernetes.K8sInferencePools, pool.Name, pool.Namespace, cluster)
+		exist := false
+		for _, r := range wkdReferences {
+			exist = exist || *r == ref
+		}
+		if !exist {
+			wkdReferences = append(wkdReferences, &ref)
+		}
+	}
 	apFiltered := kubernetes.FilterAuthorizationPoliciesBySelector(wSelector, istioConfigList.AuthorizationPolicies)
 	for _, a := range apFiltered {
 		ref := models.BuildKey(kubernetes.AuthorizationPolicies, a.Name, a.Namespace, cluster)
diff --git a/frontend/cypress/integration/common/hooks.ts b/frontend/cypress/integration/common/hooks.ts
index e58efbaa3..7acfe1e48 100644
--- a/frontend/cypress/integration/common/hooks.ts
+++ b/frontend/cypress/integration/common/hooks.ts
@@ -101,8 +101,20 @@ Before({ tags: '@gateway-api' }, () => {
     if (result.code !== 0) {
       cy.log('Gateway API not found. Enabling it now.');
 
+      cy.exec('kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.3.0" | kubectl apply -f -;')
+        .its('code')
+        .should('eq', 0);
+    }
+  });
+});
+
+Before({ tags: '@gateway-api-ie' }, () => {
+  cy.exec('kubectl get crd inference.networking.x-k8s.io', { failOnNonZeroExit: false }).then(result => {
+    if (result.code !== 0) {
+      cy.log('Gateway API Inference Extension not found. Enabling it now.');
+
       cy.exec(
-        'kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.3.0" | kubectl apply -f -;'
+        'kubectl kustomize "github.com/kubernetes-sigs/gateway-api-inference-extension/config/crd?ref=v0.4.0" | kubectl apply -f -;'
       )
         .its('code')
         .should('eq', 0);
diff --git a/frontend/cypress/integration/common/istio_config.ts b/frontend/cypress/integration/common/istio_config.ts
index 11b549030..b431ce93b 100644
--- a/frontend/cypress/integration/common/istio_config.ts
+++ b/frontend/cypress/integration/common/istio_config.ts
@@ -200,6 +200,27 @@ const minimalK8sReferenceGrant = (name: string, namespace: string, fromNamespace
 }`;
 };
 
+const minimalK8sInferencePool = (name: string, namespace: string, selector: string): string => {
+  return `{
+  "kind": "InferencePool",
+  "apiVersion": "inference.networking.x-k8s.io/v1alpha2",
+  "metadata": {
+    "name": "${name}",
+    "namespace": "${namespace}"
+  },
+  "spec": {
+    "targetPortNumber": 8000,
+    "selector": {
+      "app": "${selector}"
+    },
+    "extensionRef": {
+      "name": "${selector}-epp",
+      "failureMode": "FailClose"
+    }
+  }
+}`;
+};
+
 Given('a {string} AuthorizationPolicy in the {string} namespace', function (name: string, namespace: string) {
   cy.exec(`kubectl delete AuthorizationPolicy ${name} -n ${namespace}`, { failOnNonZeroExit: false });
   cy.exec(`echo '${minimalAuthorizationPolicy(name, namespace)}' | kubectl apply -f -`);
@@ -423,6 +444,13 @@ When(
   }
 );
 
+When(
+  'there is a {string} K8sInferencePool in the {string} namespace with {string} selector',
+  (name: string, ns: string, selector: string) => {
+    cy.exec(`echo '${minimalK8sInferencePool(name, ns, selector)}' | kubectl apply -f  -`);
+  }
+);
+
 When(
   'user adds a {string} listener with {string} host using {string} protocol on port {string} to the {string} K8sGateway in the {string} namespace',
   (listener: string, host: string, protocol: string, port: string, name: string, ns: string) => {
@@ -632,6 +660,7 @@ function waitUntilConfigIsVisible(
   cy.get('[data-test="refresh-button"]').click();
   ensureKialiFinishedLoading();
 
+  const shouldNA = healthStatus.includes('N/A');
   let found = false;
   cy.get('tr')
     .each($row => {
@@ -639,7 +668,16 @@ function waitUntilConfigIsVisible(
       const hasNA = $row[0].innerText.includes('N/A');
 
       if (dataTestAttr !== null) {
-        if (dataTestAttr.value === `VirtualItem_Ns${namespace}_${crdName}_${crdInstanceName}` && !hasNA) {
+        if (shouldNA) {
+          // Check if the row exists and contains healthStatus text (expected to be N/A)
+          cy.get(`[data-test=VirtualItem_Ns${namespace}_${crdName}_${crdInstanceName}]`)
+            .should('be.visible')
+            .then(foundRow => {
+              if (foundRow.text().includes(healthStatus)) {
+                found = true;
+              }
+            });
+        } else if (dataTestAttr.value === `VirtualItem_Ns${namespace}_${crdName}_${crdInstanceName}` && !hasNA) {
           // Check if the health status icon is correct
           cy.get(`[data-test=VirtualItem_Ns${namespace}_${crdName}_${crdInstanceName}] span.pf-v5-c-icon`)
             .should('be.visible')
diff --git a/frontend/cypress/integration/common/mesh.ts b/frontend/cypress/integration/common/mesh.ts
index 621e67e64..7a097fe58 100644
--- a/frontend/cypress/integration/common/mesh.ts
+++ b/frontend/cypress/integration/common/mesh.ts
@@ -53,6 +53,29 @@ When('user selects mesh node with label {string}', (label: string) => {
     });
 });
 
+// For duplicates
+When('user selects mesh node with label {string} and nodeType {string}', (label: string, nodeType: string) => {
+  cy.waitForReact();
+  cy.get('#loading_kiali_spinner').should('not.exist');
+  cy.getReact('MeshPageComponent', { state: { isReady: true } })
+    .should('have.length', 1)
+    .then($graph => {
+      const { state } = $graph[0];
+
+      const controller = state.meshRefs.getController() as Visualization;
+      assert.isTrue(controller.hasGraph());
+
+      const { nodes } = elems(controller);
+      const node = nodes.find(n => {
+        return n.getLabel().toLowerCase() === label.toLowerCase() && n.getData().nodeType === nodeType;
+      });
+      assert.exists(node);
+
+      const setSelectedIds = state.meshRefs.setSelectedIds as (values: string[]) => void;
+      setSelectedIds([node!.getId()]);
+    });
+});
+
 When('user selects tracing mesh node', () => {
   cy.waitForReact();
   cy.get('#loading_kiali_spinner').should('not.exist');
@@ -267,6 +290,16 @@ Then('user sees {string} node side panel', (name: string) => {
     });
 });
 
+Then('user does not see {string} in mesh body', (text: string) => {
+  cy.waitForReact();
+  cy.get('#loading_kiali_spinner').should('not.exist');
+  cy.get('#target-panel-mesh-body')
+    .should('be.visible')
+    .within(() => {
+      cy.contains(text).should('not.exist');
+    });
+});
+
 Then('user sees tracing node side panel', () => {
   cy.waitForReact();
   cy.get('#loading_kiali_spinner').should('not.exist');
diff --git a/frontend/cypress/integration/common/waypoint.ts b/frontend/cypress/integration/common/waypoint.ts
index 77db93b30..c658b8f80 100644
--- a/frontend/cypress/integration/common/waypoint.ts
+++ b/frontend/cypress/integration/common/waypoint.ts
@@ -175,3 +175,8 @@ When('the user validates the Ztunnel tab for the {string} namespace', (namespace
     cy.wrap($cell).contains(namespace);
   });
 });
+
+Then('the user updates the log level to {string}', (level: string) => {
+  cy.get('[data-test=log-actions-dropdown]').should('exist').click();
+  cy.get(`#setLogLevel${level}`).should('exist').click();
+});
diff --git a/frontend/cypress/integration/common/wizard_istio_config.ts b/frontend/cypress/integration/common/wizard_istio_config.ts
index 9b5033916..9ea90be19 100644
--- a/frontend/cypress/integration/common/wizard_istio_config.ts
+++ b/frontend/cypress/integration/common/wizard_istio_config.ts
@@ -26,6 +26,13 @@ When('user deletes k8sgateway named {string} and the resource is no longer avail
   ensureKialiFinishedLoading();
 });
 
+When('user deletes k8sinferencepool named {string} and the resource is no longer available', (name: string) => {
+  cy.exec(`kubectl delete inferencepools.inference.networking.x-k8s.io ${name} -n bookinfo`, {
+    failOnNonZeroExit: false
+  });
+  ensureKialiFinishedLoading();
+});
+
 When('user deletes k8sreferencegrant named {string} and the resource is no longer available', (name: string) => {
   cy.exec(`kubectl delete referencegrants.gateway.networking.k8s.io ${name} -n bookinfo`, { failOnNonZeroExit: false });
   ensureKialiFinishedLoading();
diff --git a/frontend/cypress/integration/featureFiles/istio_config.feature b/frontend/cypress/integration/featureFiles/istio_config.feature
index 6414a5b22..08fc4b470 100644
--- a/frontend/cypress/integration/featureFiles/istio_config.feature
+++ b/frontend/cypress/integration/featureFiles/istio_config.feature
@@ -61,6 +61,16 @@ Feature: Kiali Istio Config page
   Scenario: Ability to create a K8sGateway object
     Then the user can create a "gateway.networking.k8s.io" "v1" "Gateway" K8s Istio object
 
+  @bookinfo-app
+  @gateway-api-ie
+  Scenario: K8s Inference Pool list
+    Given user deletes k8sinferencepool named "foo" and the resource is no longer available
+    When there is a "foo" K8sInferencePool in the "bookinfo" namespace with "details-v1" selector
+    When the user refreshes the page
+    And user selects the "bookinfo" namespace
+    And the user filters by "Type" for "K8sInferencePool"
+    Then the "foo" "K8sInferencePool" of the "bookinfo" namespace should have a "N/A"
+
   @bookinfo-app
   Scenario: Ability to create a PeerAuthentication object
     Then the user can create a "security.istio.io" "v1" "PeerAuthentication" Istio object
diff --git a/frontend/cypress/integration/featureFiles/mesh.feature b/frontend/cypress/integration/featureFiles/mesh.feature
index 6ab6c3b4d..0679c0715 100644
--- a/frontend/cypress/integration/featureFiles/mesh.feature
+++ b/frontend/cypress/integration/featureFiles/mesh.feature
@@ -52,6 +52,7 @@ Feature: Kiali Mesh page
   Scenario: Test istio-system
     When user selects mesh node with label "istio-system"
     Then user sees "istio-system" namespace side panel
+    Then user does not see "dataplane namespaces: 0" in mesh body
 
   @bookinfo-app
   Scenario: User enables gateways
@@ -72,7 +73,7 @@ Feature: Kiali Mesh page
 
   @waypoint-tracing
   Scenario: Test ztunnel
-    When user selects mesh node with label "ztunnel"
+    When user selects mesh node with label "ztunnel" and nodeType "infra"
     Then user sees "ztunnel" node side panel
 
   @skip-ossmc
diff --git a/frontend/cypress/integration/featureFiles/waypoint.feature b/frontend/cypress/integration/featureFiles/waypoint.feature
index da89dc38d..2ba6326e3 100644
--- a/frontend/cypress/integration/featureFiles/waypoint.feature
+++ b/frontend/cypress/integration/featureFiles/waypoint.feature
@@ -53,7 +53,7 @@ Feature: Kiali Waypoint related features
     And validates waypoint Info data for "service"
 
   Scenario: [Workload details - ztunnel] The workload details for a ztunnel are valid
-    Given user is at the details page for the "workload" "istio-system/ztunnel" located in the "" cluster
+    Given user is at the details page for the "workload" "ztunnel/ztunnel" located in the "" cluster
     Then the user cannot see the "missing-sidecar" badge for "ztunnel" workload in "istio-system" namespace
     And the proxy status is "healthy"
     And the user validates the Ztunnel tab for the "bookinfo" namespace
@@ -382,6 +382,11 @@ Feature: Kiali Waypoint related features
     Then user goes to the waypoint "Info" subtab
     And validates waypoint Info data for "service"
 
+  Scenario: [Waypoint details] The waypoint workload log level os updated
+    Given user is at the details page for the "workload" "bookinfo/waypoint" located in the "" cluster
+    When the user goes to the "Logs" tab
+    Then the user updates the log level to "Debug"
+
   @skip-istio-1-23
   Scenario: [Traffic] Sidecar Ambient traffic
     Given user is at the "graph" page
diff --git a/frontend/cypress/integration/featureFiles/workload_logs.feature b/frontend/cypress/integration/featureFiles/workload_logs.feature
index 4cde31bc0..fe276ca49 100644
--- a/frontend/cypress/integration/featureFiles/workload_logs.feature
+++ b/frontend/cypress/integration/featureFiles/workload_logs.feature
@@ -26,7 +26,7 @@ Feature: Workload logs tab
     Given I am on the logs tab of the "custom-logger" workload detail page of the "loggers" namespace
     When I type "GET" on the Show text field
     Then the log pane should only show log lines containing "GET"
-  
+
   @loggers-app
   Scenario: The log pane of the logs tab should hide the lines with the requested text
     Given I am on the logs tab of the "custom-logger" workload detail page of the "loggers" namespace
@@ -38,7 +38,7 @@ Feature: Workload logs tab
     Given I am on the logs tab of the "json-logger" workload detail page of the "loggers" namespace
     When I type "text log format" on the Hide text field
     Then the log pane should only show json log lines
-  
+
   @loggers-app
   Scenario: The json log should contain certain values on the parsed object
     Given I am on the logs tab of the "json-logger" workload detail page of the "loggers" namespace
@@ -84,7 +84,7 @@ Feature: Workload logs tab
     And the "waypoint-ratings" container should be checked
     And the "container-ratings" container should be checked
     And I should see some "ratings-v1" pod selected in the pod selector
-    Then the log pane should show log lines containing "envoy://internal_client_address/"
+    Then the log pane should show log lines containing "ratings.bookinfo.svc.cluster.local"
 
   @bookinfo-app
   @tracing
@@ -92,4 +92,4 @@ Feature: Workload logs tab
   Scenario: The log pane of the logs tab should show spans
     Given I am on the logs tab of the "ratings-v1" workload detail page of the "bookinfo" namespace
     When I enable visualization of spans
-    Then the log pane should show spans
\ No newline at end of file
+    Then the log pane should show spans
diff --git a/frontend/package.json b/frontend/package.json
index 710dd98d2..015401f9d 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@kiali/kiali-ui",
-  "version": "2.13.0",
+  "version": "2.14.0",
   "description": "React UI for [Kiali](https://github.com/kiali/kiali).",
   "keywords": [
     "istio service mesh",
diff --git a/frontend/public/locales/es/translation.json b/frontend/public/locales/es/translation.json
index f215da6fc..e5a7d22a2 100644
--- a/frontend/public/locales/es/translation.json
+++ b/frontend/public/locales/es/translation.json
@@ -24,152 +24,152 @@
   "Abort Percentage": "Porcentaje de Solicitudes Abortadas",
   "Action": "Acción",
   "Actions": "Acciones",
-  "Add a fixed delay before forwarding the request. Format: 1h/1m/1s/1ms. MUST be >=1ms.": "Agrega una demora fija antes de reenviar la solicitud. Formato: 1h/1m/1s/1ms. DEBE ser mayor o igual a 1\u202fms.",
+  "Add a fixed delay before forwarding the request. Format: 1h/1m/1s/1ms. MUST be >=1ms.": "Agrega un retardo fijo antes de reenviar la solicitud. Formato: 1h/1m/1s/1ms. DEBE ser mayor o igual a 1\u202fms.",
   "Add Condition to When List": "Agregar una condición a la sección Cuando",
-  "Add Connection Pool": "Añadir grupo de conexiones",
-  "Add Gateway": "Add Gateway",
-  "Add HTTP Abort": "Add HTTP Abort",
-  "Add HTTP Delay": "Add HTTP Delay",
-  "Add HTTP Retry": "Add HTTP Retry",
-  "Add HTTP Timeout": "Add HTTP Timeout",
-  "Add LoadBalancer": "Add LoadBalancer",
-  "Add Match": "Add Match",
-  "Add new condition key": "Add new condition key",
-  "Add new condition not values": "Add new condition not values",
-  "Add new condition values": "Add new condition values",
-  "Add new operation values": "Add new operation values",
-  "Add new source values": "Add new source values",
-  "Add Operation to To List": "Add Operation to To List",
-  "Add Outlier Detection": "Add Outlier Detection",
-  "Add PeerAuthentication": "Add PeerAuthentication",
-  "Add Route Rule": "Add Route Rule",
-  "Add Rule to Rule List": "Add Rule to Rule List",
-  "Add Source to From List": "Add Source to From List",
-  "Additional Conditions of a Request": "Additional Conditions of a Request",
-  "Additional State": "Additional State",
-  "Address": "Address",
-  "AdvancedOptions": "AdvancedOptions",
-  "Allows all requests to workloads in given namespace(s)": "Allows all requests to workloads in given namespace(s)",
+  "Add Connection Pool": "Agregar grupo de conexiones",
+  "Add Gateway": "Agregar Gateway",
+  "Add HTTP Abort": "Agregar cancelación HTTP",
+  "Add HTTP Delay": "Agregar retardo HTTP",
+  "Add HTTP Retry": "Agregar reintento HTTP",
+  "Add HTTP Timeout": "Agregar tiempo de espera HTTP",
+  "Add LoadBalancer": "Agregar balanceador de carga",
+  "Add Match": "Agregar coincidencia",
+  "Add new condition key": "Agregar nueva clave de condición",
+  "Add new condition not values": "Agregar nuevos valores de condición negativa",
+  "Add new condition values": "Agregar nuevos valores de condición",
+  "Add new operation values": "Agregar nuevos valores de operación",
+  "Add new source values": "Agregar nuevos valores de origen",
+  "Add Operation to To List": "Agregar operación a la lista de destino",
+  "Add Outlier Detection": "Agregar detección de valores atípicos",
+  "Add PeerAuthentication": "Agregar autenticación entre pares",
+  "Add Route Rule": "Agregar regla de enrutamiento",
+  "Add Rule to Rule List": "Agregar regla a la lista de reglas",
+  "Add Source to From List": "Agregar origen a la lista de origen",
+  "Additional Conditions of a Request": "Condiciones adicionales de una solicitud",
+  "Additional State": "Estado adicional",
+  "Address": "Dirección",
+  "AdvancedOptions": "Opciones avanzadas",
+  "Allows all requests to workloads in given namespace(s)": "Permite todas las solicitudes a cargas de trabajo en los espacios de nombres dados",
   "Ambient": "Ambient",
-  "An Istio Config resource needs at least one cluster selected": "An Istio Config resource needs at least one cluster selected",
-  "An Istio Config resource needs at least one namespace selected": "An Istio Config resource needs at least one namespace selected",
-  "and": "and",
-  "Annotations": "Annotations",
-  "API Endpoint: {{apiEndpoint}}": "API Endpoint: {{apiEndpoint}}",
-  "api version: {{apiVersion}}": "api version: {{apiVersion}}",
-  "App": "Applicación",
+  "An Istio Config resource needs at least one cluster selected": "Un recurso de configuración de Istio necesita al menos un clúster seleccionado",
+  "An Istio Config resource needs at least one namespace selected": "Un recurso de configuración de Istio necesita al menos un espacio de nombres seleccionado",
+  "and": "y",
+  "Annotations": "Anotaciones",
+  "API Endpoint: {{apiEndpoint}}": "Endpoint de API: {{apiEndpoint}}",
+  "api version: {{apiVersion}}": "versión de la API: {{apiVersion}}",
+  "App": "Aplicación",
   "Applications": "Aplicaciones",
   "Apps": "Aplicaciones",
-  "Are you sure you want to delete ?": "Are you sure you want to delete ?",
-  "Attempts": "Attempts",
-  "Attribute": "Attribute",
-  "Authorization Policy": "Authorization Policy",
-  "Back": "Back",
-  "Builds an Authorization Policy based on Rules": "Builds an Authorization Policy based on Rules",
-  "CA Certificates": "CA Certificates",
-  "Cancel": "Cancel",
-  "Changes here are not saved to the Kiali CR. If happy with changes, update the Kiali CR using your standard change workflow.": "Changes here are not saved to the Kiali CR. If happy with changes, update the Kiali CR using your standard change workflow.",
-  "Check the usual ports for the tracing service and provide a subset of the tracing configuration based on the tracing services found for external_services.tracing.": "Check the usual ports for the tracing service and provide a subset of the tracing configuration based on the tracing services found for external_services.tracing.",
-  "Choose the traffic rates used to generate the graph. Each supported protocol offers one or more options. Unused protocols can be omitted.": "Choose the traffic rates used to generate the graph. Each supported protocol offers one or more options. Unused protocols can be omitted.",
-  "Circuit Breaker": "Circuit Breaker",
-  "Clear": "Clear",
-  "Click + Drag": "Click + Drag",
-  "click here.": "click here.",
-  "Click kebab menu on a node label to see the contextual menu options for the node.": "Click kebab menu on a node label to see the contextual menu options for the node.",
-  "Click on a node or edge to see its summary and emphasize its end-to-end paths.": "Click on a node or edge to see its summary and emphasize its end-to-end paths.",
-  "Client Certificate": "Client Certificate",
-  "Client Certificate must be non empty": "Client Certificate must be non empty",
-  "Close": "Close",
-  "Close Legend": "Close Legend",
-  "Close Replay": "Close Replay",
+  "Are you sure you want to delete ?": "¿Estás seguro de que deseas eliminar?",
+  "Attempts": "Intentos",
+  "Attribute": "Atributo",
+  "Authorization Policy": "Política de autorización",
+  "Back": "Atrás",
+  "Builds an Authorization Policy based on Rules": "Construye una política de autorización basada en reglas",
+  "CA Certificates": "Certificados CA",
+  "Cancel": "Cancelar",
+  "Changes here are not saved to the Kiali CR. If happy with changes, update the Kiali CR using your standard change workflow.": "Los cambios aquí no se guardan en el CR de Kiali. Si está satisfecho con los cambios, actualice el CR de Kiali usando su flujo de trabajo estándar.",
+  "Check the usual ports for the tracing service and provide a subset of the tracing configuration based on the tracing services found for external_services.tracing.": "Verifique los puertos habituales para el servicio de trazas y proporcione un subconjunto de la configuración de trazas basada en los servicios encontrados para external_services.tracing.",
+  "Choose the traffic rates used to generate the graph. Each supported protocol offers one or more options. Unused protocols can be omitted.": "Elija las tasas de tráfico utilizadas para generar el gráfico. Cada protocolo compatible ofrece una o más opciones. Los protocolos no utilizados pueden omitirse.",
+  "Circuit Breaker": "Interruptor de circuito",
+  "Clear": "Limpiar",
+  "Click + Drag": "Clic + Arrastrar",
+  "click here.": "haz clic aquí.",
+  "Click kebab menu on a node label to see the contextual menu options for the node.": "Haz clic en el menú de tres puntos en la etiqueta de un nodo para ver las opciones del menú contextual para el nodo.",
+  "Click on a node or edge to see its summary and emphasize its end-to-end paths.": "Haz clic en un nodo o conexión para ver su resumen y resaltar sus rutas de extremo a extremo.",
+  "Client Certificate": "Certificado de cliente",
+  "Client Certificate must be non empty": "El certificado de cliente no debe estar vacío",
+  "Close": "Cerrar",
+  "Close Legend": "Cerrar leyenda",
+  "Close Replay": "Cerrar reproducción",
   "Cluster": "Clúster",
-  "Cluster Status": "Cluster Status",
-  "Clusters": "Clusters",
-  "Clusters: {{num}}": "Clusters: {{num}}",
+  "Cluster Status": "Estado del clúster",
+  "Clusters": "Clústeres",
+  "Clusters: {{num}}": "Clústeres: {{num}}",
   "Compact view": "Vista compacta",
-  "Compare with similar traces": "Compare with similar traces",
-  "Concentric": "Concentric",
-  "Condition Builder": "Condition Builder",
-  "Condition Key": "Condition Key",
-  "Condition Key not supported": "Condition Key not supported",
-  "Condition List": "Condition List",
-  "config": "config",
-  "Configuration Discovery": "Configuration Discovery",
-  "Configuration returned valid results": "Configuration returned valid results",
-  "Configuration Tester": "Configuration Tester",
-  "Configuration:": "Configuration:",
-  "Confirm": "Confirm",
-  "Confirm Delete Traffic Routing ?": "Confirm Delete Traffic Routing ?",
-  "Consecutive Errors": "Consecutive Errors",
-  "Contextual Menu": "Contextual Menu",
-  "Contextual menu on nodes": "Contextual menu on nodes",
-  "Control plane": "Control plane",
-  "ControlPlanes: {{num}}": "ControlPlanes: {{num}}",
-  "Copied": "Copied",
-  "Copy": "Copy",
-  "Copy all resources": "Copy all resources",
+  "Compare with similar traces": "Comparar con trazas similares",
+  "Concentric": "Concentrico",
+  "Condition Builder": "Constructor de condiciones",
+  "Condition Key": "Clave de condición",
+  "Condition Key not supported": "Clave de condición no soportada",
+  "Condition List": "Lista de condiciones",
+  "config": "configuración",
+  "Configuration Discovery": "Descubrimiento de configuración",
+  "Configuration returned valid results": "Configuración devolvió resultados válidos",
+  "Configuration Tester": "Prueba de configuración",
+  "Configuration:": "Configuración:",
+  "Confirm": "Confirmar",
+  "Confirm Delete Traffic Routing ?": "¿Confirmar eliminación de enrutamiento de tráfico?",
+  "Consecutive Errors": "Errores consecutivos",
+  "Contextual Menu": "Menú contextual",
+  "Contextual menu on nodes": "Menú contextual en nodos",
+  "Control plane": "Plano de control",
+  "ControlPlanes: {{num}}": "Planos de control: {{num}}",
+  "Copied": "Copiado",
+  "Copy": "Copiar",
+  "Copy all resources": "Copiar todos los recursos",
   "cores": "cores",
-  "Could not create Istio {{type}} objects": "Could not create Istio {{type}} objects",
-  "Could not fetch Permissions.": "Could not fetch Permissions.",
+  "Could not create Istio {{type}} objects": "No se pudieron crear objetos de Istio {{type}}",
+  "Could not fetch Permissions.": "No se pudieron obtener permisos.",
   "CPU": "CPU",
-  "Create": "Create",
-  "Create Gateway": "Create Gateway",
-  "Current duration": "Current duration",
-  "Current refresh interval: {{refreshInterval}}": "Current refresh interval: {{refreshInterval}}",
-  "Current time range": "Current time range",
-  "custom": "custom",
-  "Custom": "Custom",
+  "Create": "Crear",
+  "Create Gateway": "Crear Gateway",
+  "Current duration": "Duración actual",
+  "Current refresh interval: {{refreshInterval}}": "Intervalo de actualización actual: {{refreshInterval}}",
+  "Current time range": "Rango de tiempo actual",
+  "custom": "personalizado",
+  "Custom": "Personalizado",
   "Dagre": "Dagre",
-  "Data Plane": "Data Plane",
-  "dataplane namespaces: {{count}}_one": "dataplane namespaces: {{count}}",
-  "dataplane namespaces: {{count}}_many": "dataplane namespaces: {{count}}",
-  "dataplane namespaces: {{count}}_other": "dataplane namespaces: {{count}}",
-  "Dataplane table": "Dataplane table",
-  "Debug information": "Debug information",
-  "Debug Information": "Debug Information",
-  "Debug information has been copied to your clipboard.": "Debug information has been copied to your clipboard.",
-  "Debug information was copied to your clipboard, but is outdated now. It could be caused by new data received by auto refresh timers.": "Debug information was copied to your clipboard, but is outdated now. It could be caused by new data received by auto refresh timers.",
-  "Degraded": "Degraded",
-  "Delay Percentage": "Delay Percentage",
-  "Delete": "Delete",
-  "Delete Traffic Routing": "Delete Traffic Routing",
-  "Denies all requests to workloads in given namespace(s)": "Denies all requests to workloads in given namespace(s)",
-  "Destination Hosts": "Destination Hosts",
-  "Destination Workload": "Destination Workload",
-  "Details in side panel on nodes": "Details in side panel on nodes",
-  "Direction": "Direction",
-  "Direction type is not valid.": "Direction type is not valid.",
-  "Disable Auto Injection": "Disable Auto Injection",
-  "Disabled": "Disabled",
-  "Discovery": "Discovery",
-  "Display": "Display",
-  "Display envoy config for the selected pod": "Display envoy config for the selected pod",
-  "Display idle nodes": "Display idle nodes",
-  "Display the legend to learn about what the different shapes, colors and backgrounds mean.": "Display the legend to learn about what the different shapes, colors and backgrounds mean.",
-  "Display ztunnel config for the selected pod": "Display ztunnel config for the selected pod",
+  "Data Plane": "Plano de datos",
+  "dataplane namespaces: {{count}}_one": "espacios de nombres de dataplane: {{count}}",
+  "dataplane namespaces: {{count}}_many": "espacios de nombres de dataplane: {{count}}",
+  "dataplane namespaces: {{count}}_other": "espacios de nombres de dataplane: {{count}}",
+  "Dataplane table": "Tabla de Dataplane",
+  "Debug information": "Información de depuración",
+  "Debug Information": "Información de depuración",
+  "Debug information has been copied to your clipboard.": "La información de depuración se ha copiado en su portapapeles.",
+  "Debug information was copied to your clipboard, but is outdated now. It could be caused by new data received by auto refresh timers.": "La información de depuración se copió en su portapapeles, pero está desactualizada. Esto podría deberse a nuevos datos recibidos por los temporizadores de actualización automática.",
+  "Degraded": "Degradado",
+  "Delay Percentage": "Porcentaje de retraso",
+  "Delete": "Eliminar",
+  "Delete Traffic Routing": "Eliminar enrutamiento de tráfico",
+  "Denies all requests to workloads in given namespace(s)": "Deniega todas las solicitudes a cargas de trabajo en los espacios de nombres dados",
+  "Destination Hosts": "Destinos de host",
+  "Destination Workload": "Carga de trabajo de destino",
+  "Details in side panel on nodes": "Detalles en el panel lateral de nodos",
+  "Direction": "Dirección",
+  "Direction type is not valid.": "El tipo de dirección no es válido.",
+  "Disable Auto Injection": "Deshabilitar inyección automática",
+  "Disabled": "Deshabilitado",
+  "Discovery": "Descubrimiento",
+  "Display": "Mostrar",
+  "Display envoy config for the selected pod": "Mostrar configuración de Envoy para el pod seleccionado",
+  "Display idle nodes": "Mostrar nodos inactivos",
+  "Display the legend to learn about what the different shapes, colors and backgrounds mean.": "Mostrar la leyenda para aprender sobre lo que significan las diferentes formas, colores y fondos.",
+  "Display ztunnel config for the selected pod": "Mostrar configuración de ztunnel para el pod seleccionado",
   "Distributed Tracing": "Trazas distribuidas",
-  "Done": "Done",
-  "Download": "Download",
-  "Download all resources in a file": "Download all resources in a file",
-  "Download configuration in a file": "Download configuration in a file",
-  "Drill into node detail graph": "Drill into node detail graph",
-  "Duration": "Duration",
-  "Edges": "Edges",
-  "Edit": "Edit",
-  "Edit and test configuration changes without having to modify the CR.": "Edit and test configuration changes without having to modify the CR.",
-  "Edit Annotations": "Edit Annotations",
-  "Either all namespaces are being filtered or the user has no permission to access namespaces.": "Either all namespaces are being filtered or the user has no permission to access namespaces.",
-  "Empty Graph": "Empty Graph",
-  "Empty Mesh": "Empty Mesh",
-  "Empty value": "Empty value",
-  "Enable Auto Injection": "Enable Auto Injection",
-  "Enabled": "Enabled",
-  "Endpoints": "Endpoints",
-  "Enter a label in the format <label>=<value>. Enter one or multiple labels separated by comma.": "Enter a label in the format <label>=<value>. Enter one or multiple labels separated by comma.",
-  "Error fetching Istio deployment status.": "Error fetching Istio deployment status.",
-  "Error loading graph": "Error loading graph",
-  "Error loading Mesh": "Error loading Mesh",
-  "Evenly distribute traffic": "Evenly distribute traffic",
+  "Done": "Hecho",
+  "Download": "Descargar",
+  "Download all resources in a file": "Descargar todos los recursos en un archivo",
+  "Download configuration in a file": "Descargar configuración en un archivo",
+  "Drill into node detail graph": "Hundirse en el gráfico de detalle del nodo",
+  "Duration": "Duración",
+  "Edges": "Conexiones",
+  "Edit": "Editar",
+  "Edit and test configuration changes without having to modify the CR.": "Editar y probar cambios de configuración sin tener que modificar el CR.",
+  "Edit Annotations": "Editar anotaciones",
+  "Either all namespaces are being filtered or the user has no permission to access namespaces.": "Todos los espacios de nombres están filtrados o el usuario no tiene permiso para acceder a los espacios de nombres.",
+  "Empty Graph": "Gráfico vacío",
+  "Empty Mesh": "Malla vacía",
+  "Empty value": "Valor vacío",
+  "Enable Auto Injection": "Habilitar inyección automática",
+  "Enabled": "Habilitado",
+  "Endpoints": "Puntos finales",
+  "Enter a label in the format <label>=<value>. Enter one or multiple labels separated by comma.": "Ingrese una etiqueta en el formato <etiqueta>=<valor>. Ingrese una o múltiples etiquetas separadas por coma.",
+  "Error fetching Istio deployment status.": "Error al obtener el estado de implementación de Istio.",
+  "Error loading graph": "Error al cargar el gráfico",
+  "Error loading Mesh": "Error al cargar la malla",
+  "Evenly distribute traffic": "Distribuir tráfico de manera uniforme",
   "Every 10s": "Cada 10s",
   "Every 15m": "Cada 15m",
   "Every 15s": "Cada 15s",
@@ -177,352 +177,352 @@
   "Every 30s": "Cada 30s",
   "Every 5m": "Cada 5m",
   "Expand view": "Vista expandida",
-  "Extension": "Extension",
-  "external_services.tracing configuration:": "external_services.tracing configuration:",
-  "Failed Request": "Failed Request",
-  "Failure": "Failure",
-  "Fault Injection": "Fault Injection",
-  "Fault Injection not valid": "Fault Injection not valid",
-  "Filter": "Filter",
+  "Extension": "Extensión",
+  "external_services.tracing configuration:": "configuración de external_services.tracing:",
+  "Failed Request": "Solicitud fallida",
+  "Failure": "Fallo",
+  "Fault Injection": "Inyección de error",
+  "Fault Injection not valid": "Inyección de error no válida",
+  "Filter": "Filtrar",
   "Filter by Application Health": "Filtrar por la salud de la aplicación",
   "Filter by mTLS": "Filtrar por mTLS",
   "Filter by Namespace": "Filtrar por el espacio de nombres",
   "Filter by Namespace Label": "Filtrar por la etiqueta del espacio de nombres",
-  "Find and Hide": "Find and Hide",
-  "Fixed Delay": "Fixed Delay",
-  "For Performance issues troubleshooting, remove sensitive data before posting:": "For Performance issues troubleshooting, remove sensitive data before posting:",
+  "Find and Hide": "Buscar y ocultar",
+  "Fixed Delay": "Retraso fijo",
+  "For Performance issues troubleshooting, remove sensitive data before posting:": "Para solucionar problemas de rendimiento, elimine los datos sensibles antes de publicar:",
   "FQDN": "FQDN",
-  "From": "From",
-  "From List": "From List",
+  "From": "De",
+  "From List": "Lista de origen",
   "Gateway": "Gateway",
-  "Gateway Hosts": "Gateway Hosts",
-  "Gateway hosts should be specified using FQDN format or '*' wildcard.": "Gateway hosts should be specified using FQDN format or '*' wildcard.",
+  "Gateway Hosts": "Hosts de Gateway",
+  "Gateway hosts should be specified using FQDN format or '*' wildcard.": "Los hosts de Gateway deben especificarse usando el formato FQDN o el comodín '*'.",
   "Gateway/Waypoint": "Gateway/Waypoint",
   "Gateways": "Gateways",
   "Gateways: {{num}}": "Gateways: {{num}}",
-  "Graph": "Graph",
-  "Graph Traffic": "Graph Traffic",
-  "Graph Type": "Graph Type",
-  "GraphTour": "GraphTour",
-  "Grid": "Grid",
+  "Graph": "Gráfico",
+  "Graph Traffic": "Gráfico de tráfico",
+  "Graph Type": "Tipo de gráfico",
+  "GraphTour": "Tour del gráfico",
+  "Grid": "Cuadrícula",
   "Health": "Salud",
   "Health for": "Salud de",
-  "Health status": "Health status",
-  "Healthy": "Healthy",
-  "Healthy Request": "Healthy Request",
-  "Help": "Help",
-  "Hide": "Hide",
-  "Highlight or Hide graph elements via typed expressions. Click the dropdown for preset Find or Hide expressions. Click the Find/Hide help icon for details on the expression language.": "Highlight or Hide graph elements via typed expressions. Click the dropdown for preset Find or Hide expressions. Click the Find/Hide help icon for details on the expression language.",
-  "Highlight or Hide mesh elements via typed expressions. Click the dropdown for preset Find or Hide expressions. Click the Find/Hide help icon for details on the expression language.": "Highlight or Hide mesh elements via typed expressions. Click the dropdown for preset Find or Hide expressions. Click the Find/Hide help icon for details on the expression language.",
-  "HTTP Cookie Name must be non empty and TTL must be expressed in in nanoseconds (i.e. 1000, 2000, etc) or seconds (i.e. 10s, 1.5s, etc).": "HTTP Cookie Name must be non empty and TTL must be expressed in in nanoseconds (i.e. 1000, 2000, etc) or seconds (i.e. 10s, 1.5s, etc).",
-  "HTTP Status Code": "HTTP Status Code",
-  "HTTP status code to use to abort the Http request.": "HTTP status code to use to abort the Http request.",
-  "HTTP1 Max Pending Requests": "HTTP1 Max Pending Requests",
-  "Idle": "Idle",
+  "Health status": "Estado de salud",
+  "Healthy": "Saludable",
+  "Healthy Request": "Solicitud saludable",
+  "Help": "Ayuda",
+  "Hide": "Ocultar",
+  "Highlight or Hide graph elements via typed expressions. Click the dropdown for preset Find or Hide expressions. Click the Find/Hide help icon for details on the expression language.": "Resaltar u ocultar elementos del gráfico mediante expresiones tipadas. Haga clic en el menú desplegable para expresiones de búsqueda u ocultación predefinidas. Haga clic en el icono de ayuda de búsqueda/ocultación para obtener detalles sobre el lenguaje de expresión.",
+  "Highlight or Hide mesh elements via typed expressions. Click the dropdown for preset Find or Hide expressions. Click the Find/Hide help icon for details on the expression language.": "Resaltar u ocultar elementos de la malla mediante expresiones tipadas. Haga clic en el menú desplegable para expresiones de búsqueda u ocultación predefinidas. Haga clic en el icono de ayuda de búsqueda/ocultación para obtener detalles sobre el lenguaje de expresión.",
+  "HTTP Cookie Name must be non empty and TTL must be expressed in in nanoseconds (i.e. 1000, 2000, etc) or seconds (i.e. 10s, 1.5s, etc).": "El nombre de la cookie HTTP debe ser no vacío y TTL debe expresarse en nanosegundos (por ejemplo, 1000, 2000, etc.) o segundos (por ejemplo, 10s, 1.5s, etc.).",
+  "HTTP Status Code": "Código de estado HTTP",
+  "HTTP status code to use to abort the Http request.": "Código de estado HTTP a usar para abortar la solicitud HTTP.",
+  "HTTP1 Max Pending Requests": "Máximas solicitudes pendientes de HTTP1",
+  "Idle": "Inactivo",
   "inbound": "entrante",
   "Inbound": "Entrante",
-  "Include mesh gateway": "Include mesh gateway",
+  "Include mesh gateway": "Incluir gateway de malla",
   "Info": "Info",
-  "Infra node": "Infra node",
-  "Istio {{type}} created": "Istio {{type}} created",
-  "Istio Ambient ztunnel detected in the Control plane": "Istio Ambient ztunnel detected in the Control plane",
-  "Istio Component List": "Istio Component List",
+  "Infra node": "Nodo de infraestructura",
+  "Istio {{type}} created": "Istio {{type}} creado",
+  "Istio Ambient ztunnel detected in the Control plane": "Istio Ambient ztunnel detectado en el plano de control",
+  "Istio Component List": "Lista de componentes de Istio",
   "Istio config": "Configuración de Istio",
   "Istio Config": "Configuración de Istio",
-  "Istio control plane": "Istio control plane",
-  "Istio deployment status disabled.": "Istio deployment status disabled.",
-  "Istio revision {{version}}": "Istio revision {{version}}",
+  "Istio control plane": "Plano de control de Istio",
+  "Istio deployment status disabled.": "El estado de implementación de Istio está deshabilitado.",
+  "Istio revision {{version}}": "Revisión de Istio {{version}}",
   "JSON": "JSON",
-  "JSON Log Entry": "JSON Log Entry",
-  "K8s Gateway": "K8s Gateway",
-  "K8s Gateway API is not enabled": "K8s Gateway API is not enabled",
-  "K8s Gateways": "K8s Gateways",
-  "K8s GRPC Routing": "K8s GRPC Routing",
-  "K8s GRPCRoute Hosts": "K8s GRPCRoute Hosts",
-  "K8s HTTP Routing": "K8s HTTP Routing",
-  "K8s HTTPRoute Hosts": "K8s HTTPRoute Hosts",
-  "K8s Reference Grant": "K8s Reference Grant",
-  "Kiali Config": "Kiali Config",
+  "JSON Log Entry": "Entrada de registro JSON",
+  "K8s Gateway": "Gateway K8s",
+  "K8s Gateway API is not enabled": "La API de Gateway K8s no está habilitada",
+  "K8s Gateways": "Gateways K8s",
+  "K8s GRPC Routing": "Enrutamiento GRPC K8s",
+  "K8s GRPCRoute Hosts": "Hosts GRPCRoute K8s",
+  "K8s HTTP Routing": "Enrutamiento HTTP K8s",
+  "K8s HTTPRoute Hosts": "Hosts HTTPRoute K8s",
+  "K8s Reference Grant": "Concesión de referencia K8s",
+  "Kiali Config": "Configuración de Kiali",
   "Kiali home cluster": "Clúster de residencia de Kiali",
-  "Kiali on GitHub": "Kiali on GitHub",
+  "Kiali on GitHub": "Kiali en GitHub",
   "Kiali: {{num}}": "Kiali: {{num}}",
-  "kubernetes version: {{version}}": "kubernetes version: {{version}}",
-  "Labeled by": "Labeled by",
-  "Labels": "Labels",
-  "Last": "Últimos",
-  "Last {{duration}}": "Últimos {{duration}}",
-  "Layout selection": "Layout selection",
-  "Legend": "Legend",
-  "List of enrolled": "List of enrolled",
+  "kubernetes version: {{version}}": "versión de kubernetes: {{version}}",
+  "Labeled by": "Etiquetado por",
+  "Labels": "Etiquetas",
+  "Last": "Último",
+  "Last {{duration}}": "Último {{duration}}",
+  "Layout selection": "Selección de diseño",
+  "Legend": "Leyenda",
+  "List of enrolled": "Lista de inscritos",
   "List view": "Vista de lista",
-  "Loading graph": "Loading graph",
-  "Loading Mesh": "Loading Mesh",
-  "Loading...": "Loading...",
-  "Login to {{cluster}}": "Login to {{cluster}}",
-  "Logout": "Logout",
-  "Logs": "Logs",
+  "Loading graph": "Cargando gráfico",
+  "Loading Mesh": "Cargando malla",
+  "Loading...": "Cargando...",
+  "Login to {{cluster}}": "Iniciar sesión en {{cluster}}",
+  "Logout": "Cerrar sesión",
+  "Logs": "Registros",
   "Manual": "Manual",
-  "Manual refresh required": "Manual refresh required",
-  "Match 'Any request' is defined in a previous rule.": "Match 'Any request' is defined in a previous rule.",
-  "Match any request": "Match any request",
-  "Matching selected": "Matching selected",
-  "Max Connections": "Max Connections",
-  "Maximum number of HTTP1 /TCP connections to a destination host.": "Maximum number of HTTP1 /TCP connections to a destination host.",
-  "Maximum number of pending HTTP requests to a destination.": "Maximum number of pending HTTP requests to a destination.",
+  "Manual refresh required": "Actualización manual requerida",
+  "Match 'Any request' is defined in a previous rule.": "La coincidencia 'Cualquier solicitud' está definida en una regla anterior.",
+  "Match any request": "Coincidir con cualquier solicitud",
+  "Matching selected": "Coincidencia seleccionada",
+  "Max Connections": "Conexiones máximas",
+  "Maximum number of HTTP1 /TCP connections to a destination host.": "Número máximo de conexiones HTTP1 /TCP a un host de destino.",
+  "Maximum number of pending HTTP requests to a destination.": "Número máximo de solicitudes HTTP pendientes a un destino.",
   "mb": "mb",
-  "Mb (Threshold)": "Mb (Threshold)",
+  "Mb (Threshold)": "Mb (Umbral)",
   "Memory": "Memoria",
-  "Menu of options": "Menu of options",
+  "Menu of options": "Menú de opciones",
   "Mesh": "Malla de servicios",
-  "Mesh page": "Mesh page",
-  "mesh settings": "mesh settings",
-  "Mesh: {{name}}": "Mesh: {{name}}",
-  "Metrics": "Metrics",
-  "Min TLS version": "Min TLS version",
-  "Mirror Percentage": "Mirror Percentage",
-  "Mirrored Workload": "Mirrored Workload",
-  "Mirroring": "Mirroring",
-  "Mirrors": "Mirrors",
-  "Missing Sidecar": "Missing Sidecar",
-  "More info at": "More info at",
-  "Mouse wheel": "Mouse wheel",
-  "Move Down": "Move Down",
-  "Move Up": "Move Up",
+  "Mesh page": "Página de malla",
+  "mesh settings": "configuración de malla",
+  "Mesh: {{name}}": "Malla: {{name}}",
+  "Metrics": "Métricas",
+  "Min TLS version": "Versión mínima de TLS",
+  "Mirror Percentage": "Porcentaje de espejo",
+  "Mirrored Workload": "Carga de trabajo espejo",
+  "Mirroring": "Espejo",
+  "Mirrors": "Espejos",
+  "Missing Sidecar": "Sidecar ausente",
+  "More info at": "Más información en",
+  "Mouse wheel": "Rueda del ratón",
+  "Move Down": "Mover hacia abajo",
+  "Move Up": "Mover hacia arriba",
   "mTLS": "mTLS",
-  "mTLS (badge)": "mTLS (badge)",
+  "mTLS (badge)": "mTLS (insignia)",
   "n/a": "n/a",
-  "name": "name",
+  "name": "nombre",
   "Name": "Nombre",
   "Namespace": "Espacio de nombres",
   "Namespace Label": "Etiqueta del espacio de nombres",
   "Namespace: {{namespace}}": "Espacio de nombres: {{namespace}}",
-  "Namespace: {{namespace}} is not found in cluster {{clusterName}}": "Namespace: {{namespace}} is not found in cluster {{clusterName}}",
+  "Namespace: {{namespace}} is not found in cluster {{clusterName}}": "El espacio de nombres {{namespace}} no se encuentra en el clúster {{clusterName}}",
   "Namespaces": "Espacios de nombres",
-  "Next": "Next",
+  "Next": "Siguiente",
   "No {{direction}} traffic": "No hay tráfico {{direction}}",
-  "No Conditions Defined": "No Conditions Defined",
-  "No enrolled services found": "No enrolled services found",
-  "No enrolled workloads found": "No enrolled workloads found",
-  "No graph traffic for the time period.": "No graph traffic for the time period.",
-  "No health information": "No health information",
-  "No labels": "No labels",
-  "No mesh information available.": "No mesh information available.",
-  "No namespace is selected": "No namespace is selected",
-  "No Operations Defined": "No Operations Defined",
-  "No results found": "No results found",
-  "No Route Rules defined": "No Route Rules defined",
-  "No Rules Defined.": "No Rules Defined.",
-  "No Source Matches Defined": "No Source Matches Defined",
-  "No unfiltered namespaces": "No unfiltered namespaces",
-  "No Ztunnel services found": "No Ztunnel services found",
-  "No Ztunnel workloads found": "No Ztunnel workloads found",
-  "Node": "Node",
-  "Node Background": "Node Background",
-  "Node Badges": "Node Badges",
-  "Node Colors": "Node Colors",
-  "Node Shapes": "Node Shapes",
-  "none": "none",
-  "None": "None",
-  "Not found": "Not found",
-  "Not healthy": "Not healthy",
-  "Not Present": "Not Present",
-  "Not ready": "Not ready",
-  "Not Ready": "Not Ready",
-  "Not valid IP": "Not valid IP",
-  "Not Values": "Not Values",
-  "Notification badge": "Notification badge",
-  "now": "now",
-  "Number of errors before a host is ejected from the connection pool.": "Number of errors before a host is ejected from the connection pool.",
-  "Number of retries for a given request.": "Number of retries for a given request.",
-  "Observability: {{num}}": "Observability: {{num}}",
-  "One or more hosts exposed by this gateway. Enter one or multiple hosts separated by comma.": "One or more hosts exposed by this gateway. Enter one or multiple hosts separated by comma.",
-  "One or more labels to select a workload where the AuthorizationPolicy is applied.": "One or more labels to select a workload where the AuthorizationPolicy is applied.",
-  "Operation": "Operation",
-  "Operation Builder": "Operation Builder",
-  "Operation Field": "Operation Field",
-  "Operation List": "Operation List",
-  "Operations of a Request": "Operations of a Request",
-  "or": "or",
+  "No Conditions Defined": "No se definieron condiciones",
+  "No enrolled services found": "No se encontraron servicios inscritos",
+  "No enrolled workloads found": "No se encontraron cargas de trabajo inscritas",
+  "No graph traffic for the time period.": "No hay gráfico de tráfico para el período de tiempo.",
+  "No health information": "No hay información de salud",
+  "No labels": "No hay etiquetas",
+  "No mesh information available.": "No hay información de malla disponible.",
+  "No namespace is selected": "No se ha seleccionado un espacio de nombres",
+  "No Operations Defined": "No se definieron operaciones",
+  "No results found": "No se encontraron resultados",
+  "No Route Rules defined": "No se definieron reglas de enrutamiento",
+  "No Rules Defined.": "No se definieron reglas.",
+  "No Source Matches Defined": "No se definieron coincidencias de origen",
+  "No unfiltered namespaces": "No hay espacios de nombres sin filtrar",
+  "No Ztunnel services found": "No se encontraron servicios de ztunnel",
+  "No Ztunnel workloads found": "No se encontraron cargas de trabajo de ztunnel",
+  "Node": "Nodo",
+  "Node Background": "Fondo del nodo",
+  "Node Badges": "Insignias del nodo",
+  "Node Colors": "Colores del nodo",
+  "Node Shapes": "Formas del nodo",
+  "none": "ninguno",
+  "None": "Ninguno",
+  "Not found": "No encontrado",
+  "Not healthy": "No saludable",
+  "Not Present": "No presente",
+  "Not ready": "No listo",
+  "Not Ready": "No listo",
+  "Not valid IP": "IP no válida",
+  "Not Values": "Valores no",
+  "Notification badge": "Insignia de notificación",
+  "now": "ahora",
+  "Number of errors before a host is ejected from the connection pool.": "Número de errores antes de que un host sea expulsado de la piscina de conexiones.",
+  "Number of retries for a given request.": "Número de reintentos para una solicitud dada.",
+  "Observability: {{num}}": "Observabilidad: {{num}}",
+  "One or more hosts exposed by this gateway. Enter one or multiple hosts separated by comma.": "Uno o más hosts expuestos por este gateway. Ingrese uno o múltiples hosts separados por coma.",
+  "One or more labels to select a workload where the AuthorizationPolicy is applied.": "Una o más etiquetas para seleccionar una carga de trabajo donde se aplica la política de autorización.",
+  "Operation": "Operación",
+  "Operation Builder": "Constructor de operaciones",
+  "Operation Field": "Campo de operación",
+  "Operation List": "Lista de operaciones",
+  "Operations of a Request": "Operaciones de una solicitud",
+  "or": "o",
   "outbound": "saliente",
   "Outbound": "Saliente",
-  "Outbound policy": "Outbound policy",
+  "Outbound policy": "Política de salida",
   "Overview": "Descripción general",
-  "Overview type is not valid.": "Overview type is not valid.",
-  "Pan graph, drag node": "Pan graph, drag node",
-  "Panning": "Panning",
-  "Partially Enabled": "Partially Enabled",
+  "Overview type is not valid.": "El tipo de vista general no es válido.",
+  "Pan graph, drag node": "Panorámica del gráfico, arrastrar nodo",
+  "Panning": "Panorámica",
+  "Partially Enabled": "Habilitado parcialmente",
   "Pause": "Pausa",
-  "Peer Authentication": "Peer Authentication",
-  "Per Try Timeout": "Per Try Timeout",
-  "Percentage of requests on which the delay will be injected.": "Percentage of requests on which the delay will be injected.",
-  "Percentage of requests to be aborted with the error code provided.": "Percentage of requests to be aborted with the error code provided.",
-  "Performance Measurements": "Performance Measurements",
-  "Please include this information when opening a bug:": "Please include this information when opening a bug:",
-  "Pod Name": "Pod Name",
-  "Pod Status": "Pod Status",
-  "Policy": "Policy",
-  "Port": "Port",
-  "Possible configuration(s) found for external_services.tracing": "Possible configuration(s) found for external_services.tracing",
-  "Present": "Present",
-  "Preview": "Preview",
-  "Preview new istio objects": "Preview new istio objects",
-  "Private Key": "Private Key",
-  "Private Key must be non empty": "Private Key must be non empty",
-  "Protocol": "Protocol",
-  "Proxy sync time": "Proxy sync time",
-  "Rediscover": "Rediscover",
-  "Refresh": "Refresh",
-  "Refresh interval": "Refresh interval",
-  "Refresh interval. \"Pause\" refreshes on page change or Refresh button click. \"Manual\" refreshes only on Refresh button click.": "Refresh interval. \"Pause\" refreshes on page change or Refresh button click. \"Manual\" refreshes only on Refresh button click.",
-  "Remove Auto Injection": "Remove Auto Injection",
-  "Remove Rule": "Remove Rule",
-  "Replay": "Replay",
-  "Replay...": "Replay...",
-  "Request Authentication": "Request Authentication",
-  "Request Matching": "Request Matching",
-  "Request Routing": "Request Routing",
-  "Request Timeout": "Request Timeout",
-  "Request Timeout not valid": "Request Timeout not valid",
-  "Request Timeouts": "Request Timeouts",
-  "Reset": "Reset",
-  "Restricted / External": "Restricted / External",
-  "Return to last page": "Return to last page",
-  "revision: {{revision}}": "revision: {{revision}}",
-  "Right click": "Right click",
-  "Right-click or click kebab menu on a node label for links to details, traffic, inbound/outbound metrics and node graph.": "Right-click or click kebab menu on a node label for links to details, traffic, inbound/outbound metrics and node graph.",
-  "Route Rules": "Route Rules",
-  "Route To": "Route To",
-  "Rule List": "Rule List",
-  "Rule order": "Rule order",
-  "Save": "Save",
-  "Secret Name: {{secretName}}": "Secret Name: {{secretName}}",
-  "Select a workload, service or application graph view. An application view can optionally be versioned and relies on app and version labeling. Workload and service graphs provide physical and logical views, respectively.": "Select a workload, service or application graph view. An application view can optionally be versioned and relies on app and version labeling. Workload and service graphs provide physical and logical views, respectively.",
-  "Select edge + side panel": "Select edge + side panel",
-  "Select Gateway": "Select Gateway",
-  "Select how often to refresh the graph and how much historical metric data is used to build the graph, per refresh. For example \"Last 5m\" means use the most recent 5 minutes of request metric data.  To replay a historical time window click the replay icon.  This replaces the current time range controls with the replay toolbar.": "Select how often to refresh the graph and how much historical metric data is used to build the graph, per refresh. For example \"Last 5m\" means use the most recent 5 minutes of request metric data.  To replay a historical time window click the replay icon.  This replaces the current time range controls with the replay toolbar.",
-  "Select how often to refresh the mesh and how much historical metric data is used for metric charts. For example \"Last 5m\" means use the most recent 5 minutes of request metric data.": "Select how often to refresh the mesh and how much historical metric data is used for metric charts. For example \"Last 5m\" means use the most recent 5 minutes of request metric data.",
-  "Select node + side panel": "Select node + side panel",
-  "Select the graph layout for the mesh. Different layouts work best with different meshes. Find the layout that works best. Other buttons here provide zoom and fit-to-screen options.": "Select the graph layout for the mesh. Different layouts work best with different meshes. Find the layout that works best. Other buttons here provide zoom and fit-to-screen options.",
-  "Select the layout for the mesh. Different layouts work best with different meshes. Find the layout that works best. Other buttons here provide zoom and fit-to-screen options.": "Select the layout for the mesh. Different layouts work best with different meshes. Find the layout that works best. Other buttons here provide zoom and fit-to-screen options.",
-  "Select the namespaces you want to see in the graph.": "Select the namespaces you want to see in the graph.",
-  "Select the time range of shown data, and the refresh interval.": "Select the time range of shown data, and the refresh interval.",
-  "Select zoom area": "Select zoom area",
+  "Peer Authentication": "Autenticación entre pares",
+  "Per Try Timeout": "Tiempo de espera por intento",
+  "Percentage of requests on which the delay will be injected.": "Porcentaje de solicitudes en las que se inyectará el retraso.",
+  "Percentage of requests to be aborted with the error code provided.": "Porcentaje de solicitudes a abortar con el código de error proporcionado.",
+  "Performance Measurements": "Medidas de rendimiento",
+  "Please include this information when opening a bug:": "Por favor, incluya esta información cuando abra un error:",
+  "Pod Name": "Nombre del pod",
+  "Pod Status": "Estado del pod",
+  "Policy": "Política",
+  "Port": "Puerto",
+  "Possible configuration(s) found for external_services.tracing": "Se encontraron posibles configuraciones para external_services.tracing",
+  "Present": "Presente",
+  "Preview": "Vista previa",
+  "Preview new istio objects": "Vista previa de objetos de Istio nuevos",
+  "Private Key": "Clave privada",
+  "Private Key must be non empty": "La clave privada no debe estar vacía",
+  "Protocol": "Protocolo",
+  "Proxy sync time": "Tiempo de sincronización del proxy",
+  "Rediscover": "Redescubrir",
+  "Refresh": "Actualizar",
+  "Refresh interval": "Intervalo de actualización",
+  "Refresh interval. \"Pause\" refreshes on page change or Refresh button click. \"Manual\" refreshes only on Refresh button click.": "Intervalo de actualización. \"Pausa\" actualiza al cambiar de página o hacer clic en el botón de actualización. \"Manual\" solo actualiza al hacer clic en el botón de actualización.",
+  "Remove Auto Injection": "Quitar inyección automática",
+  "Remove Rule": "Quitar regla",
+  "Replay": "Reproducir",
+  "Replay...": "Reproducir...",
+  "Request Authentication": "Autenticación de solicitud",
+  "Request Matching": "Coincidencia de solicitud",
+  "Request Routing": "Enrutamiento de solicitud",
+  "Request Timeout": "Tiempo de espera de solicitud",
+  "Request Timeout not valid": "Tiempo de espera de solicitud no válido",
+  "Request Timeouts": "Tiempos de espera de solicitud",
+  "Reset": "Restablecer",
+  "Restricted / External": "Restringido / Externo",
+  "Return to last page": "Volver a la última página",
+  "revision: {{revision}}": "revisión: {{revision}}",
+  "Right click": "Clic derecho",
+  "Right-click or click kebab menu on a node label for links to details, traffic, inbound/outbound metrics and node graph.": "Clic derecho o haga clic en el menú de tres puntos en la etiqueta de un nodo para enlaces a detalles, tráfico, métricas de entrada/salida y gráfico de nodos.",
+  "Route Rules": "Reglas de enrutamiento",
+  "Route To": "Enrutar a",
+  "Rule List": "Lista de reglas",
+  "Rule order": "Orden de reglas",
+  "Save": "Guardar",
+  "Secret Name: {{secretName}}": "Nombre del secreto: {{secretName}}",
+  "Select a workload, service or application graph view. An application view can optionally be versioned and relies on app and version labeling. Workload and service graphs provide physical and logical views, respectively.": "Seleccione una vista de gráfico de carga de trabajo, servicio o aplicación. Una vista de aplicación puede ser opcionalmente versionada y se basa en las etiquetas de aplicación y versión. Los gráficos de carga de trabajo y servicios proporcionan vistas físicas y lógicas, respectivamente.",
+  "Select edge + side panel": "Seleccionar conexiones + panel lateral",
+  "Select Gateway": "Seleccionar Gateway",
+  "Select how often to refresh the graph and how much historical metric data is used to build the graph, per refresh. For example \"Last 5m\" means use the most recent 5 minutes of request metric data.  To replay a historical time window click the replay icon.  This replaces the current time range controls with the replay toolbar.": "Seleccione con qué frecuencia actualizar el gráfico y cuántos datos de métricas históricas se utilizan para construir el gráfico, por actualización. Por ejemplo, \"Últimos 5m\" significa usar los últimos 5 minutos de datos de métricas de solicitud.  Para reproducir una ventana de tiempo histórico, haga clic en el icono de reproducción.  Esto reemplaza los controles de rango de tiempo actuales con la barra de herramientas de reproducción.",
+  "Select how often to refresh the mesh and how much historical metric data is used for metric charts. For example \"Last 5m\" means use the most recent 5 minutes of request metric data.": "Seleccione con qué frecuencia actualizar la malla y cuántos datos de métricas históricas se utilizan para las gráficas de métricas. Por ejemplo, \"Últimos 5m\" significa usar los últimos 5 minutos de datos de métricas de solicitud.",
+  "Select node + side panel": "Seleccionar nodo + panel lateral",
+  "Select the graph layout for the mesh. Different layouts work best with different meshes. Find the layout that works best. Other buttons here provide zoom and fit-to-screen options.": "Seleccione el diseño del gráfico para la malla. Los diferentes diseños funcionan mejor con diferentes mallas. Encuentre el diseño que funcione mejor. Otros botones aquí proporcionan opciones de zoom y ajuste a pantalla.",
+  "Select the layout for the mesh. Different layouts work best with different meshes. Find the layout that works best. Other buttons here provide zoom and fit-to-screen options.": "Seleccione el diseño para la malla. Los diferentes diseños funcionan mejor con diferentes mallas. Encuentre el diseño que funcione mejor. Otros botones aquí proporcionan opciones de zoom y ajuste a pantalla.",
+  "Select the namespaces you want to see in the graph.": "Seleccione los espacios de nombres que desea ver en el gráfico.",
+  "Select the time range of shown data, and the refresh interval.": "Seleccione el rango de tiempo de los datos mostrados y el intervalo de actualización.",
+  "Select zoom area": "Seleccionar área de zoom",
   "Service": "Servicio",
-  "Service Entry": "Service Entry",
-  "Service Name": "Service Name",
-  "Service VIP": "Service VIP",
+  "Service Entry": "Entrada de servicio",
+  "Service Name": "Nombre del servicio",
+  "Service VIP": "VIP del servicio",
   "Services": "Servicios",
-  "Set display options for the mesh.": "Set display options for the mesh.",
-  "Set edge labeling, node badging, and various display options. Response-time edge labeling, security badging, and traffic animation may affect performance. Response-times reflect the 95th percentile.": "Set edge labeling, node badging, and various display options. Response-time edge labeling, security badging, and traffic animation may affect performance. Response-times reflect the 95th percentile.",
-  "Shortcuts": "Shortcuts",
-  "Shortcuts and tips...": "Shortcuts and tips...",
+  "Set display options for the mesh.": "Establecer opciones de visualización para la malla.",
+  "Set edge labeling, node badging, and various display options. Response-time edge labeling, security badging, and traffic animation may affect performance. Response-times reflect the 95th percentile.": "Establezca el etiquetado de conexiones, insignias de nodos y varias opciones de visualización. La etiquetado de tiempo de respuesta, insignias de seguridad y animación de tráfico pueden afectar el rendimiento. Las respuestas de tiempo reflejan el percentil 95.",
+  "Shortcuts": "Atajos",
+  "Shortcuts and tips...": "Atajos y consejos...",
   "Show": "Mostrar",
-  "Side Panel": "Side Panel",
+  "Side Panel": "Panel lateral",
   "Sidecar": "Sidecar",
-  "Single click": "Single click",
-  "Something went wrong": "Something went wrong",
-  "Sorry, there was a problem. Try a refresh or navigate to a different page.": "Sorry, there was a problem. Try a refresh or navigate to a different page.",
-  "Source Builder": "Source Builder",
-  "Source Field": "Source Field",
-  "Source List": "Source List",
-  "Source Matches of a Request": "Source Matches of a Request",
-  "Subset": "Subset",
+  "Single click": "Clic único",
+  "Something went wrong": "Algo salió mal",
+  "Sorry, there was a problem. Try a refresh or navigate to a different page.": "Lo sentimos, hubo un problema. Intente una actualización o navegue a una página diferente.",
+  "Source Builder": "Constructor de origen",
+  "Source Field": "Campo de origen",
+  "Source List": "Lista de origen",
+  "Source Matches of a Request": "Coincidencias de origen de una solicitud",
+  "Subset": "Subconjunto",
   "Switch language": "Cambiar idioma",
   "Switch to {{theme}} Mode": "Cambiar a modo {{theme}}",
-  "System Error": "System Error",
-  "Table": "Table",
-  "Tag: {{tag}}": "Tag: {{tag}}",
-  "TCP Connection": "TCP Connection",
-  "TCP Traffic": "TCP Traffic",
-  "TCP Traffic Shifting": "TCP Traffic Shifting",
-  "Test Configuration": "Test Configuration",
-  "Tester": "Tester",
-  "The control plane must sync each proxy when there is a configuration change. This is the average time spent, per proxy,                  to perform the update. N/A means there was no syncing performed for the configured time period.": "The control plane must sync each proxy when there is a configuration change. This is the average time spent, per proxy,                  to perform the update. N/A means there was no syncing performed for the configured time period.",
-  "The destination hosts to which traffic is being sent. Enter one or multiple hosts separated by comma.": "The destination hosts to which traffic is being sent. Enter one or multiple hosts separated by comma.",
-  "The JSON Log entry has been copied to your clipboard.": "The JSON Log entry has been copied to your clipboard.",
-  "The minimum TLS version for connections among Istio workloads. Defaults to TLSV1_2 if not set. Set by the 'meshConfig.meshMTLS.minProtocolVersion' field.": "The minimum TLS version for connections among Istio workloads. Defaults to TLSV1_2 if not set. Set by the 'meshConfig.meshMTLS.minProtocolVersion' field.",
-  "The refresh interval is set to \"Manual\". To render the graph, select your desired filters and options and then click the Refresh button. Or, if preferred, change the setting to the desired interval.": "The refresh interval is set to \"Manual\". To render the graph, select your desired filters and options and then click the Refresh button. Or, if preferred, change the setting to the desired interval.",
-  "The refresh interval is set to \"Manual\". To render the list, select your desired filters and options and then click the Refresh button. Or, if preferred, change the setting to the desired interval.": "The refresh interval is set to \"Manual\". To render the list, select your desired filters and options and then click the Refresh button. Or, if preferred, change the setting to the desired interval.",
-  "The refresh interval is set to \"Manual\". To render the mesh, select your desired filters and options and then click the Refresh button. Or, if preferred, change the setting to the desired interval.": "The refresh interval is set to \"Manual\". To render the mesh, select your desired filters and options and then click the Refresh button. Or, if preferred, change the setting to the desired interval.",
-  "The refresh interval is set to \"Manual\". To render the overview, select your desired filters and options and then click the Refresh button. Or, if preferred, change the setting to the desired interval.": "The refresh interval is set to \"Manual\". To render the overview, select your desired filters and options and then click the Refresh button. Or, if preferred, change the setting to the desired interval.",
-  "The Side Panel shows details about the currently selected node or edge, otherwise the whole graph.": "The Side Panel shows details about the currently selected node or edge, otherwise the whole graph.",
-  "The Side Panel shows details about the currently selected node or edge, otherwise the whole mesh.": "The Side Panel shows details about the currently selected node or edge, otherwise the whole mesh.",
-  "There are no Workloads with sidecar for this service": "There are no Workloads with sidecar for this service",
-  "There is currently no graph available for the selected namespaces. This usually means the namespaces do not have measurable traffic for the selected time period:": "There is currently no graph available for the selected namespaces. This usually means the namespaces do not have measurable traffic for the selected time period:",
-  "There is currently no mesh information available. This may mean you do not have permission to see any mesh information or have no access to any of the mesh namespaces.": "There is currently no mesh information available. This may mean you do not have permission to see any mesh information or have no access to any of the mesh namespaces.",
-  "There is currently no namespace selected, please select one using the Namespace selector.": "There is currently no namespace selected, please select one using the Namespace selector.",
-  "This chart shows cpu consumption for the {{component}} {{cpuMetricSource}}": "This chart shows cpu consumption for the {{component}} {{cpuMetricSource}}",
-  "This chart shows memory consumption for the {{component}} {{memoryMetricSource}}": "This chart shows memory consumption for the {{component}} {{memoryMetricSource}}",
-  "This rule is not accessible.": "This rule is not accessible.",
-  "This shows the meshConfig.outboundTrafficPolicy.mode setting. It controls the sidecar handling of                 requests to external services (services not defined in Istio’s internal service registry). When                 set to ALLOW_ANY the Istio proxy performs a passthrough to the unknown services. When set to REGISTRY_ONLY                 the Istio proxy blocks requets to hosts without a defined HTTP service or service entry.": "This shows the meshConfig.outboundTrafficPolicy.mode setting. It controls the sidecar handling of                 requests to external services (services not defined in Istio’s internal service registry). When                 set to ALLOW_ANY the Istio proxy performs a passthrough to the unknown services. When set to REGISTRY_ONLY                 the Istio proxy blocks requets to hosts without a defined HTTP service or service entry.",
-  "This type of workload is read-only": "This type of workload is read-only",
-  "This workload is an Istio Ambient waypoint proxy": "This workload is an Istio Ambient waypoint proxy",
-  "Time duration": "Time duration",
-  "Time range": "Time range",
-  "Time Range": "Time Range",
-  "Time Range & Replay": "Time Range & Replay",
-  "Timeout": "Timeout",
-  "Timeout for HTTP requests. Format: 1h/1m/1s/1ms. MUST be >=1ms.": "Timeout for HTTP requests. Format: 1h/1m/1s/1ms. MUST be >=1ms.",
-  "Timeout per retry attempt for a given request. Format: 1h/1m/1s/1ms. MUST be >=1ms.": "Timeout per retry attempt for a given request. Format: 1h/1m/1s/1ms. MUST be >=1ms.",
-  "TLS related settings for connections to the upstream service.": "TLS related settings for connections to the upstream service.",
-  "To": "To",
-  "To List": "To List",
-  "To read the FAQ entry about why your graph may be empty, ": "To read the FAQ entry about why your graph may be empty, ",
+  "System Error": "Error del sistema",
+  "Table": "Tabla",
+  "Tag: {{tag}}": "Etiqueta: {{tag}}",
+  "TCP Connection": "Conexión TCP",
+  "TCP Traffic": "Tráfico TCP",
+  "TCP Traffic Shifting": "Tráfico TCP de cambio",
+  "Test Configuration": "Prueba de configuración",
+  "Tester": "Prueba",
+  "The control plane must sync each proxy when there is a configuration change. This is the average time spent, per proxy,                  to perform the update. N/A means there was no syncing performed for the configured time period.": "El plano de control debe sincronizar cada proxy cuando hay un cambio de configuración. Este es el tiempo promedio, por proxy,                  para realizar la actualización. N/A significa que no se realizó ninguna sincronización para el período de tiempo configurado.",
+  "The destination hosts to which traffic is being sent. Enter one or multiple hosts separated by comma.": "Los hosts de destino a los que se envía el tráfico. Ingrese uno o múltiples hosts separados por coma.",
+  "The JSON Log entry has been copied to your clipboard.": "La entrada de registro JSON se ha copiado en su portapapeles.",
+  "The minimum TLS version for connections among Istio workloads. Defaults to TLSV1_2 if not set. Set by the 'meshConfig.meshMTLS.minProtocolVersion' field.": "La versión mínima de TLS para conexiones entre cargas de trabajo de Istio. Por defecto a TLSV1_2 si no se establece. Establecido por el campo 'meshConfig.meshMTLS.minProtocolVersion'.",
+  "The refresh interval is set to \"Manual\". To render the graph, select your desired filters and options and then click the Refresh button. Or, if preferred, change the setting to the desired interval.": "El intervalo de actualización está configurado en \"Manual\". Para renderizar el gráfico, seleccione sus filtros y opciones deseadas y luego haga clic en el botón de actualización. O, si lo prefiere, cambie la configuración al intervalo deseado.",
+  "The refresh interval is set to \"Manual\". To render the list, select your desired filters and options and then click the Refresh button. Or, if preferred, change the setting to the desired interval.": "El intervalo de actualización está configurado en \"Manual\". Para renderizar la lista, seleccione sus filtros y opciones deseadas y luego haga clic en el botón de actualización. O, si lo prefiere, cambie la configuración al intervalo deseado.",
+  "The refresh interval is set to \"Manual\". To render the mesh, select your desired filters and options and then click the Refresh button. Or, if preferred, change the setting to the desired interval.": "El intervalo de actualización está configurado en \"Manual\". Para renderizar la malla, seleccione sus filtros y opciones deseadas y luego haga clic en el botón de actualización. O, si lo prefiere, cambie la configuración al intervalo deseado.",
+  "The refresh interval is set to \"Manual\". To render the overview, select your desired filters and options and then click the Refresh button. Or, if preferred, change the setting to the desired interval.": "El intervalo de actualización está configurado en \"Manual\". Para renderizar el resumen, seleccione sus filtros y opciones deseadas y luego haga clic en el botón de actualización. O, si lo prefiere, cambie la configuración al intervalo deseado.",
+  "The Side Panel shows details about the currently selected node or edge, otherwise the whole graph.": "El panel lateral muestra los detalles del nodo o conexión actualmente seleccionado, de lo contrario, el gráfico completo.",
+  "The Side Panel shows details about the currently selected node or edge, otherwise the whole mesh.": "El panel lateral muestra los detalles del nodo o conexión actualmente seleccionado, de lo contrario, la malla completa.",
+  "There are no Workloads with sidecar for this service": "No hay cargas de trabajo con sidecar para este servicio",
+  "There is currently no graph available for the selected namespaces. This usually means the namespaces do not have measurable traffic for the selected time period:": "Actualmente no hay gráfico disponible para los espacios de nombres seleccionados. Esto generalmente significa que los espacios de nombres no tienen tráfico medible para el período de tiempo seleccionado:",
+  "There is currently no mesh information available. This may mean you do not have permission to see any mesh information or have no access to any of the mesh namespaces.": "Actualmente no hay información de malla disponible. Esto puede significar que no tiene permiso para ver ninguna información de malla o que no tiene acceso a ningún espacio de nombres de la malla.",
+  "There is currently no namespace selected, please select one using the Namespace selector.": "Actualmente no se ha seleccionado un espacio de nombres, por favor seleccione uno usando el selector de espacio de nombres.",
+  "This chart shows cpu consumption for the {{component}} {{cpuMetricSource}}": "Este gráfico muestra la consumición de CPU para el {{component}} {{cpuMetricSource}}",
+  "This chart shows memory consumption for the {{component}} {{memoryMetricSource}}": "Este gráfico muestra la consumición de memoria para el {{component}} {{memoryMetricSource}}",
+  "This rule is not accessible.": "Esta regla no es accesible.",
+  "This shows the meshConfig.outboundTrafficPolicy.mode setting. It controls the sidecar handling of                 requests to external services (services not defined in Istio’s internal service registry). When                 set to ALLOW_ANY the Istio proxy performs a passthrough to the unknown services. When set to REGISTRY_ONLY                 the Istio proxy blocks requets to hosts without a defined HTTP service or service entry.": "Este muestra el ajuste meshConfig.outboundTrafficPolicy.mode. Controla el manejo del sidecar                 de solicitudes a servicios externos (servicios no definidos en el registro de servicios interno de Istio). Cuando                 se establece en ALLOW_ANY, el proxy de Istio realiza un passthrough a los servicios desconocidos. Cuando se establece en REGISTRY_ONLY                 el proxy de Istio bloquea las solicitudes a hosts sin un servicio HTTP definido o entrada de servicio.",
+  "This type of workload is read-only": "Este tipo de carga de trabajo es de solo lectura",
+  "This workload is an Istio Ambient waypoint proxy": "Esta carga de trabajo es un proxy de waypoint de Istio Ambient",
+  "Time duration": "Duración del tiempo",
+  "Time range": "Rango de tiempo",
+  "Time Range": "Rango de tiempo",
+  "Time Range & Replay": "Rango de tiempo y Reproducción",
+  "Timeout": "Tiempo de espera",
+  "Timeout for HTTP requests. Format: 1h/1m/1s/1ms. MUST be >=1ms.": "Tiempo de espera para solicitudes HTTP. Formato: 1h/1m/1s/1ms. DEBE ser mayor o igual a 1\u202fms.",
+  "Timeout per retry attempt for a given request. Format: 1h/1m/1s/1ms. MUST be >=1ms.": "Tiempo de espera por intento de reintento para una solicitud dada. Formato: 1h/1m/1s/1ms. DEBE ser mayor o igual a 1\u202fms.",
+  "TLS related settings for connections to the upstream service.": "Configuraciones relacionadas con TLS para la conexión al servicio upstream.",
+  "To": "A",
+  "To List": "Lista de destino",
+  "To read the FAQ entry about why your graph may be empty, ": "Para leer la entrada de la FAQ sobre por qué su gráfico puede estar vacío, ",
   "Traffic": "Tráfico",
-  "Traffic Animation": "Traffic Animation",
-  "Traffic Graph": "Tráfico",
-  "Traffic metrics per frame": "Traffic metrics per frame",
-  "Traffic metrics per refresh": "Traffic metrics per refresh",
-  "Traffic Policy": "Traffic Policy",
-  "Traffic routing already exists for this service": "Traffic routing already exists for this service",
-  "Traffic routing doesn't exists for this service": "Traffic routing doesn't exists for this service",
-  "Traffic Shifting": "Traffic Shifting",
-  "Traffic Shifting / TCP Traffic Shifting": "Traffic Shifting / TCP Traffic Shifting",
-  "Traffic Source": "Traffic Source",
-  "Traffic Status": "Traffic Status",
-  "Traffic Status (Last {{duration}})": "Traffic Status (Last {{duration}})",
-  "Traffic Weight": "Traffic Weight",
-  "TTL is expressed in nanoseconds (i.e. 1000, 2000, etc) or seconds (i.e. 10s, 1.5s, etc).": "TTL is expressed in nanoseconds (i.e. 1000, 2000, etc) or seconds (i.e. 10s, 1.5s, etc).",
-  "Unhealthy": "Unhealthy",
-  "unknown": "unknown",
-  "Unreachable": "Unreachable",
-  "Unselected Namespace": "Unselected Namespace",
+  "Traffic Animation": "Animación de tráfico",
+  "Traffic Graph": "Gráfico de tráfico",
+  "Traffic metrics per frame": "Métricas de tráfico por fotograma",
+  "Traffic metrics per refresh": "Métricas de tráfico por actualización",
+  "Traffic Policy": "Política de tráfico",
+  "Traffic routing already exists for this service": "El enrutamiento de tráfico ya existe para este servicio",
+  "Traffic routing doesn't exists for this service": "El enrutamiento de tráfico no existe para este servicio",
+  "Traffic Shifting": "Cambio de tráfico",
+  "Traffic Shifting / TCP Traffic Shifting": "Cambio de tráfico / Tráfico TCP de cambio",
+  "Traffic Source": "Fuente de tráfico",
+  "Traffic Status": "Estado de tráfico",
+  "Traffic Status (Last {{duration}})": "Estado de tráfico (Último {{duration}})",
+  "Traffic Weight": "Peso de tráfico",
+  "TTL is expressed in nanoseconds (i.e. 1000, 2000, etc) or seconds (i.e. 10s, 1.5s, etc).": "TTL se expresa en nanosegundos (por ejemplo, 1000, 2000, etc.) o segundos (por ejemplo, 10s, 1.5s, etc.).",
+  "Unhealthy": "No saludable",
+  "unknown": "desconocido",
+  "Unreachable": "Inalcanzable",
+  "Unselected Namespace": "Espacio de nombres no seleccionado",
   "Update": "Actualizar",
-  "User does not have enough permission for this action.": "User does not have enough permission for this action.",
-  "User does not have permission": "User does not have permission",
-  "User does not have permission on this Workload": "User does not have permission on this Workload",
-  "User does not have permission to create Istio Config on namespace: {{namespace}}": "User does not have permission to create Istio Config on namespace: {{namespace}}",
+  "User does not have enough permission for this action.": "El usuario no tiene permiso suficiente para esta acción.",
+  "User does not have permission": "El usuario no tiene permiso",
+  "User does not have permission on this Workload": "El usuario no tiene permiso en esta carga de trabajo",
+  "User does not have permission to create Istio Config on namespace: {{namespace}}": "El usuario no tiene permiso para crear configuración de Istio en el espacio de nombres: {{namespace}}",
   "Value": "Valor",
-  "Values": "Values",
-  "Values and NotValues cannot be empty": "Values and NotValues cannot be empty",
-  "version: {{version}}": "version: {{version}}",
+  "Values": "Valores",
+  "Values and NotValues cannot be empty": "Los valores y exclusiones no pueden estar vacíos",
+  "version: {{version}}": "versión: {{version}}",
   "Version: {{version}}": "Versión: {{version}}",
-  "View Annotations": "View Annotations",
-  "View in Tracing": "View in Tracing",
-  "View on Graph": "View on Graph",
-  "Virtual Service / Request Routing": "Virtual Service / Request Routing",
-  "VirtualService Host '*' wildcard not allowed on mesh gateway.": "VirtualService Host '*' wildcard not allowed on mesh gateway.",
-  "VirtualService Hosts": "VirtualService Hosts",
-  "Visit the Mesh page": "Ver la malla de servicios",
-  "Warn": "Warn",
+  "View Annotations": "Ver anotaciones",
+  "View in Tracing": "Ver en trazas",
+  "View on Graph": "Ver en gráfico",
+  "Virtual Service / Request Routing": "Servicio virtual / Enrutamiento de solicitud",
+  "VirtualService Host '*' wildcard not allowed on mesh gateway.": "El comodín '*' en VirtualService Host no está permitido en el gateway de malla.",
+  "VirtualService Hosts": "Hosts de VirtualService",
+  "Visit the Mesh page": "Visite la página de malla",
+  "Warn": "Advertencia",
   "Waypoint": "Waypoint",
-  "Waypoint proxy": "Waypoint proxy",
+  "Waypoint proxy": "Proxy de waypoint",
   "Waypoints": "Waypoints",
   "Waypoints: {{num}}": "Waypoints: {{num}}",
-  "Weighted routing": "Weighted routing",
-  "When": "When",
-  "When enabled in an Ambient environment, include waypoints in the mesh topology.": "When enabled in an Ambient environment, include waypoints in the mesh topology.",
-  "When enabled, include gateways in the mesh topology.": "When enabled, include gateways in the mesh topology.",
-  "When List": "When List",
-  "While the health check is simple and checks only for an HTTP 200 response for the URL, this check is more comprehensive and attempts to validate the returned trace data. It will typically use the internal_url to perform the checks. If Kiali is running outside of the cluster, the external_url will be used.": "While the health check is simple and checks only for an HTTP 200 response for the URL, this check is more comprehensive and attempts to validate the returned trace data. It will typically use the internal_url to perform the checks. If Kiali is running outside of the cluster, the external_url will be used.",
+  "Weighted routing": "Enrutamiento ponderado",
+  "When": "Cuando",
+  "When enabled in an Ambient environment, include waypoints in the mesh topology.": "Cuando está habilitado en un entorno Ambient, incluya waypoints en la topología de la malla.",
+  "When enabled, include gateways in the mesh topology.": "Cuando está habilitado, incluya gateways en la topología de la malla.",
+  "When List": "Cuando la lista",
+  "While the health check is simple and checks only for an HTTP 200 response for the URL, this check is more comprehensive and attempts to validate the returned trace data. It will typically use the internal_url to perform the checks. If Kiali is running outside of the cluster, the external_url will be used.": "Mientras que la comprobación de salud es simple y solo verifica una respuesta HTTP 200 para la URL, esta comprobación es más completa e intenta validar los datos de traza devueltos. Típicamente usará la internal_url para realizar las comprobaciones. Si Kiali se ejecuta fuera del clúster, se usará la external_url.",
   "Workload": "Carga de trabajo",
-  "Workload Entry": "Workload Entry",
-  "Workload Selector": "Workload Selector",
+  "Workload Entry": "Entrada de carga de trabajo",
+  "Workload Selector": "Selector de carga de trabajo",
   "Workloads": "Cargas de trabajo",
-  "You are currently displaying \"Idle nodes\". Send requests to the service mesh and click the Refresh button.": "You are currently displaying \"Idle nodes\". Send requests to the service mesh and click the Refresh button.",
-  "You can enable \"Idle Nodes\" to display nodes that have yet to see any request traffic.": "You can enable \"Idle Nodes\" to display nodes that have yet to see any request traffic.",
+  "You are currently displaying \"Idle nodes\". Send requests to the service mesh and click the Refresh button.": "Actualmente está mostrando \"Nodos inactivos\". Envíe solicitudes a la malla de servicios y haga clic en el botón de actualización.",
+  "You can enable \"Idle Nodes\" to display nodes that have yet to see any request traffic.": "Puede habilitar \"Nodos inactivos\" para mostrar nodos que aún no han visto ningún tráfico de solicitud.",
   "Zoom": "Zoom",
-  "Zoom graph": "Zoom graph",
-  "Ztunnel services config": "Ztunnel services config",
-  "Ztunnel workloads config": "Ztunnel workloads config"
+  "Zoom graph": "Zoom del gráfico",
+  "Ztunnel services config": "Configuración de servicios de ztunnel",
+  "Ztunnel workloads config": "Configuración de cargas de trabajo de ztunnel"
 }
diff --git a/frontend/src/components/Pf/PfBadges.tsx b/frontend/src/components/Pf/PfBadges.tsx
index 94ba70992..78d621a81 100644
--- a/frontend/src/components/Pf/PfBadges.tsx
+++ b/frontend/src/components/Pf/PfBadges.tsx
@@ -42,6 +42,7 @@ export const PFBadges: { [key: string]: PFBadgeType } = Object.freeze({
   K8sGateway: { badge: 'G', tt: 'Gateway (K8s)' } as PFBadgeType,
   K8sGRPCRoute: { badge: 'gRPC', tt: 'GRPCRoute (K8s)' } as PFBadgeType,
   K8sHTTPRoute: { badge: 'HTTP', tt: 'HTTPRoute (K8s)' } as PFBadgeType,
+  K8sInferencePool: { badge: 'IP', tt: 'InferencePool (K8s)' } as PFBadgeType,
   K8sReferenceGrant: { badge: 'RG', tt: 'ReferenceGrant (K8s)' } as PFBadgeType,
   K8sTCPRoute: { badge: 'TCP', tt: 'TCPRoute (K8s)' } as PFBadgeType,
   K8sTLSRoute: { badge: 'TLS', tt: 'TLSRoute (K8s)' } as PFBadgeType,
diff --git a/frontend/src/pages/IstioConfigList/FiltersAndSorts.ts b/frontend/src/pages/IstioConfigList/FiltersAndSorts.ts
index 14cc2a051..ec9e242ab 100644
--- a/frontend/src/pages/IstioConfigList/FiltersAndSorts.ts
+++ b/frontend/src/pages/IstioConfigList/FiltersAndSorts.ts
@@ -129,6 +129,10 @@ export const istioTypeFilter: FilterType = {
       id: 'K8sHTTPRoute',
       title: 'K8sHTTPRoute'
     },
+    {
+      id: 'K8sInferencePool',
+      title: 'K8sInferencePool'
+    },
     {
       id: 'K8sReferenceGrant',
       title: 'K8sReferenceGrant'
diff --git a/frontend/src/pages/IstioConfigList/__tests__/IstioConfigListComponent.test.ts b/frontend/src/pages/IstioConfigList/__tests__/IstioConfigListComponent.test.ts
index c3a6ced80..591702b79 100644
--- a/frontend/src/pages/IstioConfigList/__tests__/IstioConfigListComponent.test.ts
+++ b/frontend/src/pages/IstioConfigList/__tests__/IstioConfigListComponent.test.ts
@@ -84,6 +84,7 @@ describe('IstioConfigList#filterByName', () => {
     expect(filtered.resources[getGVKTypeString(gvkType.K8sGateway)].length).toBe(0);
     expect(filtered.resources[getGVKTypeString(gvkType.K8sGRPCRoute)].length).toBe(0);
     expect(filtered.resources[getGVKTypeString(gvkType.K8sHTTPRoute)].length).toBe(0);
+    expect(filtered.resources[getGVKTypeString(gvkType.K8sInferencePool)].length).toBe(0);
     expect(filtered.resources[getGVKTypeString(gvkType.K8sReferenceGrant)].length).toBe(0);
     expect(filtered.resources[getGVKTypeString(gvkType.K8sTCPRoute)].length).toBe(0);
     expect(filtered.resources[getGVKTypeString(gvkType.K8sTLSRoute)].length).toBe(0);
diff --git a/frontend/src/pages/Mesh/target/TargetPanelCommon.tsx b/frontend/src/pages/Mesh/target/TargetPanelCommon.tsx
index 39d4f28d6..0fe73f699 100644
--- a/frontend/src/pages/Mesh/target/TargetPanelCommon.tsx
+++ b/frontend/src/pages/Mesh/target/TargetPanelCommon.tsx
@@ -359,9 +359,8 @@ export const renderInfraSummary = (
     controlPlaneNodes = controlPlaneNodes.filter(
       n => n.getData().cluster === forCluster && (!forNamespace || n.getData().namespace === forNamespace)
     );
-    dataPlaneNodes = dataPlaneNodes.filter(
-      n => n.getData().cluster === forCluster && (!forNamespace || n.getData().namespace === forNamespace)
-    );
+    // 'infraType: dataplane' does not have a value for 'namespace', a filtering by 'revision' is used when displaying
+    dataPlaneNodes = dataPlaneNodes.filter(n => n.getData().cluster === forCluster);
     gatewayNodes = gatewayNodes.filter(
       n => n.getData().cluster === forCluster && (!forNamespace || n.getData().namespace === forNamespace)
     );
@@ -390,7 +389,7 @@ export const renderInfraSummary = (
         {controlPlaneNodes.map(infra => {
           const cpRev = infra.getData().infraData.revision ?? 'default';
           const dataPlaneNode = dataPlaneNodes.find(dpn => {
-            const dpRev = dpn.getData().infraData.revision ?? 'default';
+            const dpRev = dpn.getData().version ?? 'default';
             return cpRev === dpRev;
           });
           const dataPlaneNamespaceCount = dataPlaneNode?.getData().infraData?.length ?? 0;
diff --git a/frontend/src/pages/ServiceDetails/ServiceInfo.tsx b/frontend/src/pages/ServiceDetails/ServiceInfo.tsx
index bcf979397..332ae91c6 100644
--- a/frontend/src/pages/ServiceDetails/ServiceInfo.tsx
+++ b/frontend/src/pages/ServiceDetails/ServiceInfo.tsx
@@ -27,7 +27,8 @@ import {
   k8sHTTPRouteToIstioItems,
   k8sGRPCRouteToIstioItems,
   validationKey,
-  k8sGwToIstioItems
+  k8sGwToIstioItems,
+  k8sInferencePoolToIstioItems
 } from '../../types/IstioConfigList';
 import { canCreate, canUpdate } from '../../types/Permissions';
 import { KialiAppState } from '../../store/Store';
@@ -224,11 +225,17 @@ class ServiceInfoComponent extends React.Component<Props, ServiceInfoState> {
         )
       : [];
 
+    const k8sInferencePoolIstioConfigItems = this.props.serviceDetails?.k8sInferencePools
+      ? k8sInferencePoolToIstioItems(this.props.serviceDetails.k8sInferencePools, this.props.cluster)
+      : [];
+
     const istioConfigItems = seIstioConfigItems.concat(
       gwIstioConfigItems.concat(
         k8sGwIstioConfigItems.concat(
           vsIstioConfigItems.concat(
-            drIstioConfigItems.concat(k8sHTTPRouteIstioConfigItems.concat(k8sGRPCRouteIstioConfigItems))
+            drIstioConfigItems.concat(
+              k8sHTTPRouteIstioConfigItems.concat(k8sGRPCRouteIstioConfigItems.concat(k8sInferencePoolIstioConfigItems))
+            )
           )
         )
       )
diff --git a/frontend/src/pages/WorkloadDetails/WorkloadInfo.tsx b/frontend/src/pages/WorkloadDetails/WorkloadInfo.tsx
index eb5126871..b1a70a532 100644
--- a/frontend/src/pages/WorkloadDetails/WorkloadInfo.tsx
+++ b/frontend/src/pages/WorkloadDetails/WorkloadInfo.tsx
@@ -49,7 +49,8 @@ const workloadIstioResources = [
   getGVKTypeString(gvkType.Sidecar),
   getGVKTypeString(gvkType.RequestAuthentication),
   getGVKTypeString(gvkType.EnvoyFilter),
-  getGVKTypeString(gvkType.WorkloadGroup)
+  getGVKTypeString(gvkType.WorkloadGroup),
+  getGVKTypeString(gvkType.K8sInferencePool)
 ];
 
 export class WorkloadInfo extends React.Component<WorkloadInfoProps, WorkloadInfoState> {
diff --git a/frontend/src/pages/WorkloadDetails/WorkloadPodLogs.tsx b/frontend/src/pages/WorkloadDetails/WorkloadPodLogs.tsx
index 5da019907..49e8b5f29 100644
--- a/frontend/src/pages/WorkloadDetails/WorkloadPodLogs.tsx
+++ b/frontend/src/pages/WorkloadDetails/WorkloadPodLogs.tsx
@@ -843,12 +843,15 @@ export class WorkloadPodLogsComponent extends React.Component<WorkloadPodLogsPro
   };
 
   private getLogsDiv = (): React.ReactNode => {
-    const hasProxyContainer = this.state.containerOptions?.some(opt => opt.isProxy);
-
+    // istio-proxy for waypoint proxies
+    const hasProxyContainer = this.state.containerOptions?.some(opt => {
+      return opt.isProxy || opt.name === 'istio-proxy';
+    });
     const logDropDowns = Object.keys(LogLevel).map(level => {
       return (
         <DropdownItem
           key={`setLogLevel${level}`}
+          id={`setLogLevel${level}`}
           onClick={() => {
             this.setLogLevel(LogLevel[level]);
           }}
@@ -940,6 +943,7 @@ export class WorkloadPodLogsComponent extends React.Component<WorkloadPodLogsPro
                 toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
                   <MenuToggle
                     ref={toggleRef}
+                    data-test="log-actions-dropdown"
                     className={kebabToggleStyle}
                     aria-label="Actions"
                     variant="plain"
diff --git a/frontend/src/services/__mockData__/getServiceDetail.ts b/frontend/src/services/__mockData__/getServiceDetail.ts
index 2d5d5c907..c0456bf0f 100644
--- a/frontend/src/services/__mockData__/getServiceDetail.ts
+++ b/frontend/src/services/__mockData__/getServiceDetail.ts
@@ -89,6 +89,7 @@ export const SERVICE_DETAILS: ServiceDetailsInfo = {
   ],
   k8sHTTPRoutes: [],
   k8sGRPCRoutes: [],
+  k8sInferencePools: [],
   destinationRules: [
     {
       kind: 'DestinationRule',
diff --git a/frontend/src/types/IstioConfigList.ts b/frontend/src/types/IstioConfigList.ts
index 6bd3015bf..aa9580606 100644
--- a/frontend/src/types/IstioConfigList.ts
+++ b/frontend/src/types/IstioConfigList.ts
@@ -11,7 +11,8 @@ import {
   VirtualService,
   IstioObject,
   GroupVersionKind,
-  K8sResource
+  K8sResource,
+  K8sInferencePool
 } from './IstioObjects';
 import { ResourcePermissions } from './Permissions';
 import { getGVKTypeString, getIstioObjectGVK, kindToStringIncludeK8s } from '../utils/IstioConfigUtils';
@@ -67,6 +68,7 @@ export enum gvkType {
   K8sGatewayClass = 'K8sGatewayClass',
   K8sGRPCRoute = 'K8sGRPCRoute',
   K8sHTTPRoute = 'K8sHTTPRoute',
+  K8sInferencePool = 'K8sInferencePool',
   K8sReferenceGrant = 'K8sReferenceGrant',
   K8sTCPRoute = 'K8sTCPRoute',
   K8sTLSRoute = 'K8sTLSRoute',
@@ -103,6 +105,7 @@ export const dicTypeToGVK: { [key in gvkType]: GroupVersionKind } = {
   [gvkType.K8sGatewayClass]: { Group: 'gateway.networking.k8s.io', Version: 'v1', Kind: 'GatewayClass' },
   [gvkType.K8sGRPCRoute]: { Group: 'gateway.networking.k8s.io', Version: 'v1', Kind: 'GRPCRoute' },
   [gvkType.K8sHTTPRoute]: { Group: 'gateway.networking.k8s.io', Version: 'v1', Kind: 'HTTPRoute' },
+  [gvkType.K8sInferencePool]: { Group: 'inference.networking.x-k8s.io', Version: 'v1alpha2', Kind: 'InferencePool' },
   [gvkType.K8sReferenceGrant]: { Group: 'gateway.networking.k8s.io', Version: 'v1beta1', Kind: 'ReferenceGrant' },
   [gvkType.K8sTCPRoute]: { Group: 'gateway.networking.k8s.io', Version: 'v1alpha2', Kind: 'TCPRoute' },
   [gvkType.K8sTLSRoute]: { Group: 'gateway.networking.k8s.io', Version: 'v1alpha2', Kind: 'TLSRoute' },
@@ -527,3 +530,27 @@ export const k8sGRPCRouteToIstioItems = (
 
   return istioItems;
 };
+
+export const k8sInferencePoolToIstioItems = (
+  inferencePools: K8sInferencePool[],
+  cluster?: string
+): IstioConfigItem[] => {
+  const istioItems: IstioConfigItem[] = [];
+
+  inferencePools.forEach(pool => {
+    const item = {
+      cluster: cluster,
+      namespace: pool.metadata.namespace ?? '',
+      kind: pool.kind,
+      apiVersion: pool.apiVersion,
+      name: pool.metadata.name,
+      creationTimestamp: pool.metadata.creationTimestamp,
+      resource: pool,
+      resourceVersion: pool.metadata.resourceVersion
+    };
+
+    istioItems.push(item);
+  });
+
+  return istioItems;
+};
diff --git a/frontend/src/types/IstioObjects.ts b/frontend/src/types/IstioObjects.ts
index f6056d296..6bc8c5b16 100644
--- a/frontend/src/types/IstioObjects.ts
+++ b/frontend/src/types/IstioObjects.ts
@@ -854,6 +854,10 @@ export interface K8sHTTPRoute extends IstioObject {
   spec: K8sHTTPRouteSpec;
 }
 
+export interface K8sInferencePool extends IstioObject {
+  spec: K8sInferencePoolSpec;
+}
+
 export interface K8sReferenceGrant extends IstioObject {
   spec: K8sReferenceGrantSpec;
 }
@@ -898,6 +902,20 @@ export interface K8sHTTPRouteSpec extends K8sCommonRouteSpec {
   rules?: K8sHTTPRouteRule[];
 }
 
+export interface K8sInferencePoolSpec extends K8sCommonRouteSpec {
+  extensionRef?: K8sInferencePoolExtensionRef;
+  selector?: WorkloadSelector;
+  targetPortNumber?: number;
+}
+
+export interface K8sInferencePoolExtensionRef {
+  failureMode: string;
+  group: string;
+  kind: string;
+  name: string;
+  portNumber: number;
+}
+
 export interface K8sReferenceGrantSpec {
   from?: K8sReferenceRule[];
   to?: K8sReferenceRule[];
diff --git a/frontend/src/types/ServiceInfo.ts b/frontend/src/types/ServiceInfo.ts
index 532f978bd..6bc05557d 100644
--- a/frontend/src/types/ServiceInfo.ts
+++ b/frontend/src/types/ServiceInfo.ts
@@ -4,6 +4,7 @@ import {
   getWizardUpdateLabel,
   K8sHTTPRoute,
   K8sGRPCRoute,
+  K8sInferencePool,
   ObjectCheck,
   ObjectValidation,
   ServiceEntry,
@@ -95,6 +96,7 @@ export interface ServiceDetailsInfo {
   istioSidecar: boolean;
   k8sGRPCRoutes: K8sGRPCRoute[];
   k8sHTTPRoutes: K8sHTTPRoute[];
+  k8sInferencePools: K8sInferencePool[];
   namespaceMTLS?: TLSStatus;
   service: Service;
   serviceEntries: ServiceEntry[];
diff --git a/go.mod b/go.mod
index 2c0c1b0ca..24cbb2d44 100644
--- a/go.mod
+++ b/go.mod
@@ -13,40 +13,42 @@ require (
 	github.com/gorilla/mux v1.8.1
 	github.com/mitchellh/mapstructure v1.4.3
 	github.com/nitishm/engarde v0.1.1
-	github.com/onsi/ginkgo/v2 v2.22.0
-	github.com/onsi/gomega v1.36.1
+	github.com/onsi/ginkgo/v2 v2.23.4
+	github.com/onsi/gomega v1.37.0
 	github.com/openshift/api v0.0.0-20240109042830-44756aa36879
 	github.com/openshift/client-go v0.0.0-20240109161853-2425b4b6d3b3
-	github.com/prometheus/client_golang v1.19.1
-	github.com/prometheus/common v0.55.0
+	github.com/prometheus/client_golang v1.22.0
+	github.com/prometheus/common v0.65.0
 	github.com/rs/zerolog v1.34.0
 	github.com/stretchr/testify v1.10.0
 	go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.47.0
-	go.opentelemetry.io/otel v1.34.0
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0
+	go.opentelemetry.io/otel v1.35.0
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0
 	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.22.0
-	go.opentelemetry.io/otel/sdk v1.34.0
-	go.opentelemetry.io/otel/trace v1.34.0
-	go.uber.org/automaxprocs v1.5.3
+	go.opentelemetry.io/otel/sdk v1.35.0
+	go.opentelemetry.io/otel/trace v1.35.0
+	go.uber.org/automaxprocs v1.6.0
 	golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
-	golang.org/x/oauth2 v0.25.0
-	golang.org/x/sync v0.13.0
-	google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422
-	google.golang.org/grpc v1.71.1
+	golang.org/x/oauth2 v0.30.0
+	golang.org/x/sync v0.14.0
+	google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463
+	google.golang.org/grpc v1.73.0
 	google.golang.org/protobuf v1.36.6
 	gopkg.in/yaml.v2 v2.4.0
 	istio.io/api v1.25.0
 	istio.io/client-go v1.25.0
-	k8s.io/api v0.32.3
-	k8s.io/apimachinery v0.32.3
-	k8s.io/client-go v0.32.3
-	sigs.k8s.io/controller-runtime v0.20.4
+	k8s.io/api v0.33.2
+	k8s.io/apimachinery v0.33.2
+	k8s.io/client-go v0.33.2
+	sigs.k8s.io/controller-runtime v0.21.0
 	sigs.k8s.io/gateway-api v1.3.0
+	sigs.k8s.io/gateway-api-inference-extension v0.4.0
 )
 
 require (
 	github.com/beorn7/perks v1.0.1 // indirect
+	github.com/blang/semver/v4 v4.0.0 // indirect
 	github.com/cenkalti/backoff/v4 v4.3.0 // indirect
 	github.com/cespare/xxhash/v2 v2.3.0 // indirect
 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
@@ -55,7 +57,7 @@ require (
 	github.com/felixge/httpsnoop v1.0.4 // indirect
 	github.com/fsnotify/fsnotify v1.7.0 // indirect
 	github.com/fxamacker/cbor/v2 v2.7.0 // indirect
-	github.com/go-logr/logr v1.4.2 // indirect
+	github.com/go-logr/logr v1.4.3 // indirect
 	github.com/go-logr/stdr v1.2.2 // indirect
 	github.com/go-logr/zapr v1.3.0 // indirect
 	github.com/go-openapi/jsonpointer v0.21.0 // indirect
@@ -63,12 +65,11 @@ require (
 	github.com/go-openapi/swag v0.23.0 // indirect
 	github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
 	github.com/google/btree v1.1.3 // indirect
-	github.com/google/gnostic-models v0.6.8 // indirect
-	github.com/google/gofuzz v1.2.0 // indirect
-	github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect
+	github.com/google/gnostic-models v0.6.9 // indirect
+	github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
 	github.com/google/uuid v1.6.0 // indirect
-	github.com/gorilla/websocket v1.5.1 // indirect
-	github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
+	github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/mailru/easyjson v0.7.7 // indirect
@@ -81,7 +82,7 @@ require (
 	github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
-	github.com/prometheus/client_model v0.6.1 // indirect
+	github.com/prometheus/client_model v0.6.2 // indirect
 	github.com/prometheus/procfs v0.15.1 // indirect
 	github.com/rs/xid v1.6.0 // indirect
 	github.com/spf13/pflag v1.0.6 // indirect
@@ -89,27 +90,28 @@ require (
 	github.com/vjeantet/grok v1.0.0 // indirect
 	github.com/x448/float16 v0.8.4 // indirect
 	go.opentelemetry.io/auto/sdk v1.1.0 // indirect
-	go.opentelemetry.io/otel/metric v1.34.0 // indirect
-	go.opentelemetry.io/proto/otlp v1.3.1 // indirect
+	go.opentelemetry.io/otel/metric v1.35.0 // indirect
+	go.opentelemetry.io/proto/otlp v1.4.0 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
 	go.uber.org/zap v1.27.0 // indirect
-	golang.org/x/crypto v0.37.0 // indirect
-	golang.org/x/net v0.39.0 // indirect
-	golang.org/x/sys v0.32.0 // indirect
-	golang.org/x/term v0.31.0 // indirect
-	golang.org/x/text v0.24.0 // indirect
-	golang.org/x/time v0.7.0 // indirect
-	golang.org/x/tools v0.30.0 // indirect
+	golang.org/x/crypto v0.38.0 // indirect
+	golang.org/x/net v0.40.0 // indirect
+	golang.org/x/sys v0.33.0 // indirect
+	golang.org/x/term v0.32.0 // indirect
+	golang.org/x/text v0.25.0 // indirect
+	golang.org/x/time v0.9.0 // indirect
+	golang.org/x/tools v0.31.0 // indirect
 	gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect
 	gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
-	k8s.io/apiextensions-apiserver v0.32.3 // indirect
+	k8s.io/apiextensions-apiserver v0.33.2 // indirect
 	k8s.io/klog/v2 v2.130.1 // indirect
-	k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
-	k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
+	k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
+	k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect
 	sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
+	sigs.k8s.io/randfill v1.0.0 // indirect
 	sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
 	sigs.k8s.io/yaml v1.4.0 // indirect
 )
diff --git a/go.sum b/go.sum
index c4e68f0dc..41fcdfb6b 100644
--- a/go.sum
+++ b/go.sum
@@ -6,6 +6,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
+github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
 github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
 github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
@@ -30,8 +32,8 @@ github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXE
 github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY=
 github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
-github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
+github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
 github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
 github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
@@ -53,24 +55,24 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek
 github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
 github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
 github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
-github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
-github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
+github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
+github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
 github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
 github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
-github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
+github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
+github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
 github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
-github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
-github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
+github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
+github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
 github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
 github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
 github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
@@ -79,10 +81,14 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
+github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
 github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
 github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
 github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
@@ -109,10 +115,10 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J
 github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
 github.com/nitishm/engarde v0.1.1 h1:+hT7EGP64L1wKnIv64xzu94oSR3n+SFqcsDHiGDcTVQ=
 github.com/nitishm/engarde v0.1.1/go.mod h1:nlzhv5c2J4WL9e/Y8sebkZ2PJBY790US8d+Z/vS/qqY=
-github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
-github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
-github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
-github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
+github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
+github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
+github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
+github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
 github.com/openshift/api v0.0.0-20240109042830-44756aa36879 h1:9JfgDtOi0be+p2HsXwIahS8rXlt4MQRj6Vlpmx1DDg8=
 github.com/openshift/api v0.0.0-20240109042830-44756aa36879/go.mod h1:qNtV0315F+f8ld52TLtPvrfivZpdimOzTi3kn9IVbtU=
 github.com/openshift/client-go v0.0.0-20240109161853-2425b4b6d3b3 h1:XQv/z/1tedDGPeplmowftfUUrR3BtglN6Hv5kLzy1CU=
@@ -124,12 +130,12 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
 github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
-github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
-github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
-github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
-github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
-github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
-github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
+github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
+github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
+github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
+github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
+github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
+github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
 github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
 github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
 github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
@@ -158,26 +164,26 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS
 go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
 go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.47.0 h1:yPWywmjyhn5C64Z7OLdIfjnbwOQF/Xz89HNqSVquC2E=
 go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.47.0/go.mod h1:jk2INQzOTr9e27FwMs2JVXXttZc/3bucJX/7l3YVfbw=
-go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
-go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ=
+go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
+go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA=
 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.22.0 h1:FyjCyI9jVEfqhUh2MoSkmolPjfh5fp2hnV0b0irxH4Q=
 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.22.0/go.mod h1:hYwym2nDEeZfG/motx0p7L7J1N1vyzIThemQsb4g2qY=
-go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
-go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
-go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
-go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
-go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
-go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
-go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
-go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
-go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
-go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
-go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
-go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
+go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
+go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
+go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
+go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
+go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
+go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
+go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
+go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
+go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
+go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
+go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
+go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
 go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
 go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
 go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
@@ -189,8 +195,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
-golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
-golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
+golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
+golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -205,17 +211,17 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
-golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
-golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
-golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
-golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
+golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
+golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
+golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
-golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
+golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
+golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -229,45 +235,45 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
-golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
+golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
 golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
-golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
-golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
+golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
+golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
-golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
-golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
-golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
+golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
+golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
+golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
-golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
+golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
+golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
 gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
-google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 h1:GVIKPyP/kLIyVOgOnTwFOrvQaQUzOzGMCxgFUOEmm24=
-google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422/go.mod h1:b6h1vNKhxaSoEI+5jc3PJUCustfli/mRab7295pY7rw=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
-google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI=
-google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
+google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 h1:hE3bRWtU6uceqlh4fhrSnUyjKHMKB9KrTLLG+bc0ddM=
+google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463/go.mod h1:U90ffi8eUL9MwPcrJylN5+Mk2v3vuPDptd5yyNUiRR8=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 h1:e0AIkUUhxyBKh6ssZNrAMeqhA7RKUj42346d1y02i2g=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
+google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
+google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
 google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
 google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -285,28 +291,31 @@ istio.io/api v1.25.0 h1:UVQNFUAz4R06NagA+QpEzLmi4sw+m+UuMgD6sIyXawA=
 istio.io/api v1.25.0/go.mod h1:QFzEXv/IT582T0FHZVp1QoolvE4ws0zz/vVO55blmlE=
 istio.io/client-go v1.25.0 h1:MMG8r1g+o2yEzVwi0AGSdB6EQyLEhYz8YMYQQIw8IZw=
 istio.io/client-go v1.25.0/go.mod h1:Y4qIjNIVCkpZMiq/e3C7tMjOm7aYUbxT6ebtmai1TRY=
-k8s.io/api v0.32.3 h1:Hw7KqxRusq+6QSplE3NYG4MBxZw1BZnq4aP4cJVINls=
-k8s.io/api v0.32.3/go.mod h1:2wEDTXADtm/HA7CCMD8D8bK4yuBUptzaRhYcYEEYA3k=
-k8s.io/apiextensions-apiserver v0.32.3 h1:4D8vy+9GWerlErCwVIbcQjsWunF9SUGNu7O7hiQTyPY=
-k8s.io/apiextensions-apiserver v0.32.3/go.mod h1:8YwcvVRMVzw0r1Stc7XfGAzB/SIVLunqApySV5V7Dss=
-k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U=
-k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
-k8s.io/client-go v0.32.3 h1:RKPVltzopkSgHS7aS98QdscAgtgah/+zmpAogooIqVU=
-k8s.io/client-go v0.32.3/go.mod h1:3v0+3k4IcT9bXTc4V2rt+d2ZPPG700Xy6Oi0Gdl2PaY=
+k8s.io/api v0.33.2 h1:YgwIS5jKfA+BZg//OQhkJNIfie/kmRsO0BmNaVSimvY=
+k8s.io/api v0.33.2/go.mod h1:fhrbphQJSM2cXzCWgqU29xLDuks4mu7ti9vveEnpSXs=
+k8s.io/apiextensions-apiserver v0.33.2 h1:6gnkIbngnaUflR3XwE1mCefN3YS8yTD631JXQhsU6M8=
+k8s.io/apiextensions-apiserver v0.33.2/go.mod h1:IvVanieYsEHJImTKXGP6XCOjTwv2LUMos0YWc9O+QP8=
+k8s.io/apimachinery v0.33.2 h1:IHFVhqg59mb8PJWTLi8m1mAoepkUNYmptHsV+Z1m5jY=
+k8s.io/apimachinery v0.33.2/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
+k8s.io/client-go v0.33.2 h1:z8CIcc0P581x/J1ZYf4CNzRKxRvQAwoAolYPbtQes+E=
+k8s.io/client-go v0.33.2/go.mod h1:9mCgT4wROvL948w6f6ArJNb7yQd7QsvqavDeZHvNmHo=
 k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
 k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
-k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y=
-k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4=
-k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
-k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
-sigs.k8s.io/controller-runtime v0.20.4 h1:X3c+Odnxz+iPTRobG4tp092+CvBU9UK0t/bRf+n0DGU=
-sigs.k8s.io/controller-runtime v0.20.4/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY=
+k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4=
+k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8=
+k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
+k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8=
+sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM=
 sigs.k8s.io/gateway-api v1.3.0 h1:q6okN+/UKDATola4JY7zXzx40WO4VISk7i9DIfOvr9M=
 sigs.k8s.io/gateway-api v1.3.0/go.mod h1:d8NV8nJbaRbEKem+5IuxkL8gJGOZ+FJ+NvOIltV8gDk=
+sigs.k8s.io/gateway-api-inference-extension v0.4.0 h1:JoTYxBCkQStJGpV1rwdAR6oDrxquyLsNMECY1My7Ggk=
+sigs.k8s.io/gateway-api-inference-extension v0.4.0/go.mod h1:44aUo5kUCGHJ1No/MwLofF2sTarkQ4wQYXr9gz92fhw=
 sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
 sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
-sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016 h1:kXv6kKdoEtedwuqMmkqhbkgvYKeycVbC8+iPCP9j5kQ=
 sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
+sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
+sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
 sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
 sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
 sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
diff --git a/hack/istio/install-istio-via-istioctl.sh b/hack/istio/install-istio-via-istioctl.sh
index dd95215a8..0d2b815fc 100755
--- a/hack/istio/install-istio-via-istioctl.sh
+++ b/hack/istio/install-istio-via-istioctl.sh
@@ -29,6 +29,7 @@ ISTIO_EGRESSGATEWAY_ENABLED="true"
 ISTIO_INGRESSGATEWAY_ENABLED="true"
 K8S_GATEWAY_API_ENABLED="false"
 K8S_GATEWAY_API_VERSION=""
+K8S_GATEWAY_API_IE_VERSION=""
 ISTIO_VERSION=""
 MESH_ID=""
 MTLS="true"
@@ -129,6 +130,10 @@ while [[ $# -gt 0 ]]; do
       K8S_GATEWAY_API_VERSION="$2"
       shift;shift
       ;;
+    -gaiev|--k8s-gateway-api-ie-version)
+      K8S_GATEWAY_API_IE_VERSION="$2"
+      shift;shift
+      ;;
     -iv|--istio-version)
       ISTIO_VERSION="$2"
       shift;shift
@@ -576,9 +581,16 @@ else
       echo "Gateway API Version is not specified, taking the latest released version"
       K8S_GATEWAY_API_VERSION=`curl --head --silent "https://github.com/kubernetes-sigs/gateway-api/releases/latest" | grep "location: " | awk '{print $2}' | sed "s/.*tag\///g" | cat -v | sed "s/\^M//g"`
     fi
+    if [ "${K8S_GATEWAY_API_IE_VERSION}" == "" ]; then
+      echo "Gateway API Inference Extension Version is not specified, taking the latest released version"
+      K8S_GATEWAY_API_IE_VERSION=`curl --head --silent "https://github.com/kubernetes-sigs/gateway-api-inference-extension/releases/latest" | grep "location: " | awk '{print $2}' | sed "s/.*tag\///g" | cat -v | sed "s/\^M//g"`
+    fi
     echo "Verifying that Gateway API is installed; if it is not then Gateway API version ${K8S_GATEWAY_API_VERSION} will be installed now."
     $CLIENT_EXE get crd gateways.gateway.networking.k8s.io &> /dev/null || \
       { $CLIENT_EXE kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=${K8S_GATEWAY_API_VERSION}" | $CLIENT_EXE apply -f -; }
+    echo "Verifying that Gateway API Inference Extension is installed; if it is not then Gateway API Inference Extension version ${K8S_GATEWAY_API_IE_VERSION} will be installed now."
+    $CLIENT_EXE get crd inferencepools.inference.networking.x-k8s.io &> /dev/null || \
+      { $CLIENT_EXE kustomize "github.com/kubernetes-sigs/gateway-api-inference-extension/config/crd?ref=${K8S_GATEWAY_API_IE_VERSION}" | $CLIENT_EXE apply -f -; }
   fi
 
   # Do some OpenShift specific things
diff --git a/hack/istio/install-istio-via-sail.sh b/hack/istio/install-istio-via-sail.sh
index 94031b49d..91030b6da 100755
--- a/hack/istio/install-istio-via-sail.sh
+++ b/hack/istio/install-istio-via-sail.sh
@@ -36,6 +36,7 @@ for req in "${requirements[@]}"; do
 done
 
 ADDONS="prometheus grafana jaeger"
+CONFIG_PROFILE=""
 CUSTOM_INSTALL_SETTINGS=""
 PATCH_FILE=""
 WAIT=true
@@ -48,6 +49,10 @@ while [[ $# -gt 0 ]]; do
       ADDONS="$2"
       shift;shift
       ;;
+    -cp|--config-profile)
+      CONFIG_PROFILE="$2"
+      shift;shift
+      ;;
     -pf|--patch-file)
       PATCH_FILE="$2"
       shift;shift
@@ -72,6 +77,8 @@ Valid command line arguments:
        Make sure this value is space-separated. Valid addon names can be found in your Istio
        distribution directory samples/addons and tempo. tempo and jaeger are not allowed at once.
        Default: prometheus grafana jaeger
+  -cp|--config-profile <name>:
+       istio config profile. Just default and ambient are valid values.
   -pf|--patch-file <name=value>:
        filepath to a yaml file of an Istio resource that will overlay the default Istio resource.
        --patch-file /path/to/patch-file.yaml
@@ -111,11 +118,48 @@ echo "Verifying that Gateway API is installed; if it is not then Gateway API ver
 kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
   { kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=${K8S_GATEWAY_API_VERSION}" | kubectl apply -f -; }
 
+K8S_GATEWAY_API_IE_VERSION=$(curl --head --silent "https://github.com/kubernetes-sigs/gateway-api-inference-extension/releases/latest" | grep "location: " | awk '{print $2}' | sed "s/.*tag\///g" | cat -v | sed "s/\^M//g")
+echo "Verifying that Gateway API Inference Extension is installed; if it is not then Gateway API Inference Extension version ${K8S_GATEWAY_API_IE_VERSION} will be installed now."
+kubectl get crd inferencepools.inference.networking.x-k8s.io &> /dev/null || \
+  { kubectl kustomize "github.com/kubernetes-sigs/gateway-api-inference-extension/config/crd?ref=${K8S_GATEWAY_API_IE_VERSION}" | kubectl apply -f -; }
+
 SERVICE="jaeger-collector.istio-system.svc.cluster.local"
 if is_in_array "tempo" "tempo" "${ADDONS}"; then
   SERVICE=otel-collector.istio-system.svc.cluster.local
 fi
 
+if [ "${CONFIG_PROFILE}" == "ambient" ]; then
+cniYAML=$(
+cat <<EOF
+apiVersion: sailoperator.io/v1
+kind: IstioCNI
+metadata:
+  name: default
+spec:
+  values:
+    cni:
+      ambient:
+        dnsCapture: true
+  profile: ambient
+  namespace: istio-cni
+EOF
+)
+
+ztunnelYAML=$(
+cat <<EOF
+apiVersion: sailoperator.io/v1alpha1
+kind: ZTunnel
+metadata:
+  name: default
+spec:
+  profile: ambient
+  namespace: ztunnel
+  values: {}
+EOF
+)
+
+fi
+
 ISTIO_YAML=$(
 cat <<EOF
 apiVersion: sailoperator.io/v1
@@ -139,8 +183,6 @@ spec:
     global:
       meshID: mesh-default
       network: network-default
-      multiCluster:
-        clusterName: cluster-default
       proxy:
         resources:
           requests:
@@ -159,6 +201,17 @@ spec:
 EOF
 )
 
+if [ "${CONFIG_PROFILE}" == "ambient" ]; then
+  ISTIO_YAML=$(echo "$ISTIO_YAML" | yq eval '
+    .spec.profile = "ambient" |
+    .spec.values.pilot.trustedZtunnelNamespace = "ztunnel"
+  ' -)
+else
+  ISTIO_YAML=$(echo "$ISTIO_YAML" | yq eval '
+    .spec.values.global.multiCluster.clusterName = "cluster-default"
+  ' -)
+fi
+
 if [ -n "${PATCH_FILE}" ]; then
   base_yaml=$(mktemp)
   echo "$ISTIO_YAML" > "$base_yaml"
@@ -179,6 +232,16 @@ if [ "${WAIT}" == "true" ]; then
   kubectl wait --for=condition=Ready istios -l kiali.io/testing --timeout=300s
 fi
 
+if [ "${CONFIG_PROFILE}" == "ambient" ]; then
+  echo "Installing CNI for Ambient"
+  kubectl get ns "istio-cni" || kubectl create ns "istio-cni"
+  kubectl apply -f - <<<"$cniYAML"
+
+  echo "Create ztunnel namespace"
+  kubectl get ns "ztunnel" || kubectl create ns "ztunnel"
+  kubectl apply -f - <<<"$ztunnelYAML"
+fi
+
 # Install addons
 for addon in ${ADDONS}; do
   if [ "${addon}" == "tempo" ]; then
diff --git a/hack/istio/multicluster/deploy-kiali.sh b/hack/istio/multicluster/deploy-kiali.sh
index bffa3b47d..4429c465a 100755
--- a/hack/istio/multicluster/deploy-kiali.sh
+++ b/hack/istio/multicluster/deploy-kiali.sh
@@ -136,7 +136,8 @@ deploy_kiali() {
         remote_url_flag="--remote-cluster-url https://$(${CLIENT_EXE} get nodes ${CLUSTER2_NAME}-control-plane --context ${CLUSTER2_CONTEXT} -o jsonpath='{.status.addresses[?(@.type == "InternalIP")].address}'):6443"
       fi
       echo "Preparing remote cluster secret for single Kiali install in multicluster mode."
-      ${SCRIPT_DIR}/kiali-prepare-remote-cluster.sh -c ${CLIENT_EXE} --remote-cluster-name ${CLUSTER2_NAME} -kcc ${CLUSTER1_CONTEXT} -rcc ${CLUSTER2_CONTEXT} ${remote_url_flag} -vo false ${openshift_flags} -rcns ${ISTIO_NAMESPACE}
+
+      ${SCRIPT_DIR}/kiali-prepare-remote-cluster.sh -c ${CLIENT_EXE} --remote-cluster-name ${CLUSTER2_NAME} -kcc ${CLUSTER1_CONTEXT} -rcc ${CLUSTER2_CONTEXT} ${remote_url_flag} -vo false ${openshift_flags} -rcns ${ISTIO_NAMESPACE} -kshc ${KIALI_SERVER_HELM_CHARTS}
     else
       echo "Preparing remote cluster secrets for both Kiali installs."
       local remote_url_flag1=""
diff --git a/hack/istio/multicluster/kiali-prepare-remote-cluster.sh b/hack/istio/multicluster/kiali-prepare-remote-cluster.sh
index 856175876..b3f9a8af2 100755
--- a/hack/istio/multicluster/kiali-prepare-remote-cluster.sh
+++ b/hack/istio/multicluster/kiali-prepare-remote-cluster.sh
@@ -24,6 +24,7 @@ DEFAULT_CLIENT_EXE="kubectl"
 DEFAULT_DELETE="false"
 DEFAULT_DRY_RUN="false"
 DEFAULT_HELM="helm"
+DEFAULT_HELM_CHARTS="kiali-server"
 DEFAULT_KIALI_CLUSTER_CONTEXT="east"
 DEFAULT_KIALI_CLUSTER_NAMESPACE="istio-system"
 DEFAULT_KIALI_VERSION="latest"
@@ -45,6 +46,7 @@ DEFAULT_EXEC_AUTH_JSON=""
 : ${KIALI_CLUSTER_CONTEXT:=${DEFAULT_KIALI_CLUSTER_CONTEXT}}
 : ${KIALI_CLUSTER_NAMESPACE:=${DEFAULT_KIALI_CLUSTER_NAMESPACE}}
 : ${KIALI_RESOURCE_NAME:=${DEFAULT_RESOURCE_NAME}}
+: ${KIALI_SERVER_HELM_CHARTS:=${DEFAULT_HELM_CHARTS}}
 : ${KIALI_VERSION:=${DEFAULT_KIALI_VERSION}}
 : ${PROCESS_KIALI_SECRET:=${DEFAULT_PROCESS_KIALI_SECRET}}
 : ${PROCESS_REMOTE_RESOURCES:=${DEFAULT_PROCESS_REMOTE_RESOURCES}}
@@ -120,7 +122,7 @@ create_resources_in_remote_cluster() {
       --set auth.strategy=anonymous                         \
       --repo https://kiali.org/helm-charts                  \
       kiali-server                                          \
-      kiali-server)"
+      ${KIALI_SERVER_HELM_CHARTS})"
 
   if [ "${DRY_RUN}" == "true" ]; then
     echo "${helm_template_output}"
@@ -382,6 +384,10 @@ while [ $# -gt 0 ]; do
       KIALI_RESOURCE_NAME="$2"
       shift;shift
       ;;
+    -kshc|--kiali-server-helm-charts)
+      KIALI_SERVER_HELM_CHARTS="$2"
+      shift;shift
+      ;;
     -kv|--kiali-version)
       KIALI_VERSION="$2"
       shift;shift
@@ -480,6 +486,8 @@ Valid command line arguments:
                                   Default: "${DEFAULT_KIALI_CLUSTER_NAMESPACE}"
   -krn|--kiali-resource-name: used to name all the resources on the remote cluster.
                               Default: "${DEFAULT_RESOURCE_NAME}"
+  -kshc|--kiali-server-helm-charts <path>: If specified, must be the path to a Kiali server helm charts tarball. If not
+                                           specified, the latest published helm charts is used.
   -kv|--kiali-version: The version of Kiali that is installed. This is used to
                        determine what the role should look like. Pass in
                        "latest" to specify the latest version of Kiali.
@@ -552,6 +560,7 @@ info HELM=${HELM}
 info KIALI_CLUSTER_CONTEXT=${KIALI_CLUSTER_CONTEXT}
 info KIALI_CLUSTER_NAMESPACE=${KIALI_CLUSTER_NAMESPACE}
 info KIALI_RESOURCE_NAME=${KIALI_RESOURCE_NAME}
+info KIALI_SERVER_HELM_CHARTS=${KIALI_SERVER_HELM_CHARTS}
 info KIALI_VERSION=${KIALI_VERSION}
 info REMOTE_CLUSTER_CONTEXT=${REMOTE_CLUSTER_CONTEXT}
 info REMOTE_CLUSTER_NAME=${REMOTE_CLUSTER_NAME}
diff --git a/hack/istio/multicluster/roleBookinfo.yaml b/hack/istio/multicluster/roleBookinfo.yaml
index 94d635bd0..b63c5835d 100644
--- a/hack/istio/multicluster/roleBookinfo.yaml
+++ b/hack/istio/multicluster/roleBookinfo.yaml
@@ -4,91 +4,92 @@ metadata:
   name: kiali-bookinfo
   namespace: bookinfo
 rules:
-  - apiGroups: [""]
-    resources:
-      - configmaps
-      - endpoints
-      - pods/log
-    verbs:
-      - get
-      - list
-      - watch
-  - apiGroups: [""]
-    resources:
-      - namespaces
-      - pods
-      - replicationcontrollers
-      - services
-    verbs:
-      - get
-      - list
-      - watch
-      - patch
-  - apiGroups: [""]
-    resources:
-      - pods/portforward
-    verbs:
-      - create
-      - post
-  - apiGroups: ["extensions", "apps"]
-    resources:
-      - daemonsets
-      - deployments
-      - replicasets
-      - statefulsets
-    verbs:
-      - get
-      - list
-      - watch
-      - patch
-  - apiGroups: ["batch"]
-    resources:
-      - cronjobs
-      - jobs
-    verbs:
-      - get
-      - list
-      - watch
-      - patch
-  - apiGroups:
-      - networking.istio.io
-      - security.istio.io
-      - extensions.istio.io
-      - telemetry.istio.io
-      - gateway.networking.k8s.io
-    resources: ["*"]
-    verbs:
-      - get
-      - list
-      - watch
-      - create
-      - delete
-      - patch
-  - apiGroups: ["apps.openshift.io"]
-    resources:
-      - deploymentconfigs
-    verbs:
-      - get
-      - list
-      - watch
-      - patch
-  - apiGroups: ["project.openshift.io"]
-    resources:
-      - projects
-    verbs:
-      - get
-  - apiGroups: ["route.openshift.io"]
-    resources:
-      - routes
-    verbs:
-      - get
-  - apiGroups: ["authentication.k8s.io"]
-    resources:
-      - tokenreviews
-    verbs:
-      - create
-  - apiGroups: ["oauth.openshift.io"]
-    resources:
-      - oauthclients
-    verbs:
-      - get
\ No newline at end of file
+- apiGroups: [""]
+  resources:
+  - configmaps
+  - endpoints
+  - pods/log
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups: [""]
+  resources:
+  - namespaces
+  - pods
+  - replicationcontrollers
+  - services
+  verbs:
+  - get
+  - list
+  - watch
+  - patch
+- apiGroups: [""]
+  resources:
+  - pods/portforward
+  verbs:
+  - create
+  - post
+- apiGroups: ["extensions", "apps"]
+  resources:
+  - daemonsets
+  - deployments
+  - replicasets
+  - statefulsets
+  verbs:
+  - get
+  - list
+  - watch
+  - patch
+- apiGroups: ["batch"]
+  resources:
+  - cronjobs
+  - jobs
+  verbs:
+  - get
+  - list
+  - watch
+  - patch
+- apiGroups:
+  - networking.istio.io
+  - security.istio.io
+  - extensions.istio.io
+  - telemetry.istio.io
+  - gateway.networking.k8s.io
+  - inference.networking.x-k8s.io
+  resources: ["*"]
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - delete
+  - patch
+- apiGroups: ["apps.openshift.io"]
+  resources:
+  - deploymentconfigs
+  verbs:
+  - get
+  - list
+  - watch
+  - patch
+- apiGroups: ["project.openshift.io"]
+  resources:
+  - projects
+  verbs:
+  - get
+- apiGroups: ["route.openshift.io"]
+  resources:
+  - routes
+  verbs:
+  - get
+- apiGroups: ["authentication.k8s.io"]
+  resources:
+  - tokenreviews
+  verbs:
+  - create
+- apiGroups: ["oauth.openshift.io"]
+  resources:
+  - oauthclients
+  verbs:
+  - get
diff --git a/hack/run-integration-tests.sh b/hack/run-integration-tests.sh
index 5c5528279..4a04dd94c 100755
--- a/hack/run-integration-tests.sh
+++ b/hack/run-integration-tests.sh
@@ -398,11 +398,10 @@ elif [ "${TEST_SUITE}" == "${FRONTEND_AMBIENT}" ]; then
   ensureKialiTracesReady "true"
 
   if [ "${TESTS_ONLY}" == "false" ]; then
-    "${SCRIPT_DIR}"/setup-kind-in-ci.sh --auth-strategy token ${ISTIO_VERSION_ARG} --ambient true ${HELM_CHARTS_DIR_ARG}
+    "${SCRIPT_DIR}"/setup-kind-in-ci.sh --auth-strategy token ${ISTIO_VERSION_ARG} --ambient true --sail true ${HELM_CHARTS_DIR_ARG}
 
-    ISTIO_INGRESS_IP="$(kubectl get svc istio-ingressgateway -n istio-system -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')"
     # Install demo apps
-    "${SCRIPT_DIR}"/istio/install-testing-demos.sh -c "kubectl" -g "${ISTIO_INGRESS_IP}" --ambient true
+    "${SCRIPT_DIR}"/istio/install-testing-demos.sh -c "kubectl" --ambient true --use-gateway-api true
   fi
 
   ensureKialiServerReady
diff --git a/hack/setup-kind-in-ci.sh b/hack/setup-kind-in-ci.sh
index de7abc635..9501f7ed2 100755
--- a/hack/setup-kind-in-ci.sh
+++ b/hack/setup-kind-in-ci.sh
@@ -218,9 +218,16 @@ setup_kind_singlecluster() {
 
   if [ -n "${AMBIENT}" ]; then
       infomsg "Installing Istio with Ambient profile"
-      # -net is giving issues trying to access the services inside the cluster with HTTP code 56
-      # At least with Ambient 1.21
-      "${SCRIPT_DIR}"/istio/install-istio-via-istioctl.sh --reduce-resources true --client-exe-path "$(which kubectl)" -cn "cluster-default" -mid "mesh-default" -gae true ${hub_arg:-} -cp ambient
+      if [ "${SAIL}" == "true" ]; then
+        local image_tag_arg=${ISTIO_TAG:+--set ".spec.values.pilot.tag=\"${ISTIO_TAG}\""}
+        local image_hub_arg=${ISTIO_HUB:+--set ".spec.values.pilot.hub=\"${ISTIO_HUB}\""}
+        local version_arg=${ISTIO_VERSION:+--set ".spec.version=\"v${ISTIO_VERSION}\""}
+        "${ISTIO_INSTALL_SCRIPT}" ${image_tag_arg} ${image_hub_arg} ${version_arg} --config-profile ambient
+      else
+        # -net is giving issues trying to access the services inside the cluster with HTTP code 56
+        # At least with Ambient 1.21
+        "${SCRIPT_DIR}"/istio/install-istio-via-istioctl.sh --reduce-resources true --client-exe-path "$(which kubectl)" -cn "cluster-default" -mid "mesh-default" -gae true ${hub_arg:-} -cp ambient
+      fi
   elif [ "${SAIL}" == "true" ]; then
     install_istio
   else
diff --git a/handlers/dashboards.go b/handlers/dashboards.go
index 7529721af..634e26a3c 100644
--- a/handlers/dashboards.go
+++ b/handlers/dashboards.go
@@ -1,7 +1,6 @@
 package handlers
 
 import (
-	"fmt"
 	"net/http"
 	"net/url"
 	"strings"
@@ -288,12 +287,8 @@ func ZtunnelDashboard(
 			return
 		}
 
-		if namespace != conf.IstioNamespace {
-			RespondWithError(w, http.StatusBadRequest, fmt.Sprintf("namespace [%s] is not the control plane namespace", namespace))
-			return
-		}
-
 		metricsService := business.NewMetricsService(prom, conf)
+
 		ztunnelMetrics, err := metricsService.GetZtunnelMetrics(params)
 		if err != nil {
 			RespondWithError(w, http.StatusServiceUnavailable, err.Error())
diff --git a/handlers/metrics.go b/handlers/metrics.go
index 19a0692cf..bd8f22acc 100644
--- a/handlers/metrics.go
+++ b/handlers/metrics.go
@@ -268,11 +268,6 @@ func ResourceUsageMetrics(conf *config.Config, cache cache.KialiCache, discovery
 			return
 		}
 
-		if namespace != conf.IstioNamespace {
-			RespondWithError(w, http.StatusBadRequest, fmt.Sprintf("namespace [%s] is not the control plane namespace", namespace))
-			return
-		}
-
 		metricsService := business.NewMetricsService(prom, conf)
 		metrics := make(models.MetricsMap)
 
diff --git a/kiali.go b/kiali.go
index a1be7219b..65e50c7cf 100644
--- a/kiali.go
+++ b/kiali.go
@@ -60,6 +60,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/cluster"
 	"sigs.k8s.io/controller-runtime/pkg/manager"
 	metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
+	k8sinferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
 	k8snetworkingv1 "sigs.k8s.io/gateway-api/apis/v1"
 	k8snetworkingv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
 	k8snetworkingv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
@@ -242,6 +243,7 @@ func main() {
 		if _, err := layer.IstioConfig.GetIstioConfigList(ctx, cluster, business.IstioConfigCriteria{
 			IncludeGateways:               true,
 			IncludeK8sGateways:            true,
+			IncludeK8sInferencePools:      true,
 			IncludeK8sGRPCRoutes:          true,
 			IncludeK8sHTTPRoutes:          true,
 			IncludeK8sTCPRoutes:           true,
@@ -410,7 +412,7 @@ func newManager(ctx context.Context, conf *config.Config, logger *zerolog.Logger
 		// Disable metrics server since Kiali has its own metrics server.
 		Cache: ctrlcache.Options{
 			DefaultNamespaces: defaultNamespaces,
-			DefaultWatchErrorHandler: func(r *toolscache.Reflector, err error) {
+			DefaultWatchErrorHandler: func(ctx context.Context, r *toolscache.Reflector, err error) {
 				if apierrors.IsForbidden(err) {
 					log.Infof("A namespace appears to have been deleted or Kiali is forbidden from seeing it [err=%v]. Shutting down cache.", err)
 					// These are all the types that Kiali caches.
@@ -441,6 +443,7 @@ func newManager(ctx context.Context, conf *config.Config, logger *zerolog.Logger
 						&k8snetworkingv1.GatewayClass{},
 						&k8snetworkingv1.HTTPRoute{},
 						&k8snetworkingv1.GRPCRoute{},
+						&k8sinferencev1alpha2.InferencePool{},
 						&k8snetworkingv1beta1.ReferenceGrant{},
 						&k8snetworkingv1alpha2.TCPRoute{},
 						&k8snetworkingv1alpha2.TLSRoute{},
diff --git a/kiali_internal_api.md b/kiali_internal_api.md
index 29b127faf..6a88a5e3d 100644
--- a/kiali_internal_api.md
+++ b/kiali_internal_api.md
@@ -11742,6 +11742,7 @@ Invalid values include:
 | IstioSidecar | boolean| `bool` |  | |  |  |
 | K8sGRPCRoutes | [][GRPCRoute](#g-rpc-route)| `[]*GRPCRoute` |  | |  |  |
 | K8sHTTPRoutes | [][HTTPRoute](#http-route)| `[]*HTTPRoute` |  | |  |  |
+| K8sInferencePools | [][InferencePool](#inference-pool)| `[]*InferencePool` |  | |  |  |
 | K8sReferenceGrants | [][ReferenceGrant](#reference-grant)| `[]*ReferenceGrant` |  | |  |  |
 | ServiceEntries | [][ServiceEntry](#service-entry)| `[]*ServiceEntry` |  | |  |  |
 | SubServices | [][ServiceOverview](#service-overview)| `[]*ServiceOverview` |  | |  |  |
diff --git a/kubernetes/client.go b/kubernetes/client.go
index cb44afc3f..47c6a14bc 100644
--- a/kubernetes/client.go
+++ b/kubernetes/client.go
@@ -16,6 +16,7 @@ import (
 	"k8s.io/client-go/rest"
 	"k8s.io/client-go/tools/clientcmd"
 	ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
+	inferenceapiclient "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned"
 	gatewayapiclient "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned"
 
 	kialiconfig "github.com/kiali/kiali/config"
@@ -51,6 +52,7 @@ type ClientInterface interface {
 	IsOpenShift() bool
 	IsExpGatewayAPI() bool
 	IsGatewayAPI() bool
+	IsInferenceAPI() bool
 	IsIstioAPI() bool
 	// ClusterInfo returns some information about the cluster this client is connected to.
 	// This gets set when the client is first created.
@@ -109,9 +111,12 @@ type K8SClient struct {
 	isExpGatewayAPI *bool
 	// isGatewayAPI private variable will check if K8s Gateway API CRD exists on cluster or not
 	isGatewayAPI *bool
-	gatewayapi   gatewayapiclient.Interface
-	isIstioAPI   *bool
-	clusterInfo  ClusterInfo
+	// isInferenceAPI private variable will check if K8s Gateway API Inference Extension CRD exists on cluster or not
+	isInferenceAPI *bool
+	gatewayapi     gatewayapiclient.Interface
+	inferenceapi   inferenceapiclient.Interface
+	isIstioAPI     *bool
+	clusterInfo    ClusterInfo
 
 	// mutex to acquire if you want to access or modify any field in K8SClient concurrently
 	rwMutex sync.RWMutex
@@ -214,6 +219,11 @@ func newClientFromConfig(config *rest.Config) (*K8SClient, error) {
 		return nil, err
 	}
 
+	client.inferenceapi, err = inferenceapiclient.NewForConfig(config)
+	if err != nil {
+		return nil, err
+	}
+
 	client.osAppsClient, err = osappsclient.NewForConfig(config)
 	if err != nil {
 		return nil, err
@@ -249,6 +259,7 @@ func NewClient(
 	kubeClient kube.Interface,
 	istioClient istio.Interface,
 	gatewayapiClient gatewayapiclient.Interface,
+	inferenceapiClient inferenceapiclient.Interface,
 	osAppsClient osappsclient.Interface,
 	projectClient projectclient.Interface,
 	routeClient routeclient.Interface,
@@ -260,6 +271,7 @@ func NewClient(
 		istioClientset: istioClient,
 		k8s:            kubeClient,
 		gatewayapi:     gatewayapiClient,
+		inferenceapi:   inferenceapiClient,
 		osAppsClient:   osAppsClient,
 		projectClient:  projectClient,
 		routeClient:    routeClient,
diff --git a/kubernetes/filters.go b/kubernetes/filters.go
index f2ff7b0da..66f404ee5 100644
--- a/kubernetes/filters.go
+++ b/kubernetes/filters.go
@@ -14,6 +14,7 @@ import (
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
+	k8s_inference_v1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
 	k8s_networking_v1 "sigs.k8s.io/gateway-api/apis/v1"
 	k8s_networking_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
 
@@ -231,6 +232,24 @@ func FilterK8sGatewaysByLabel(allGws []*k8s_networking_v1.Gateway, gatewayLabel
 	return gateways
 }
 
+func FilterK8sInferencePoolsBySelector(workloadSelector string, inferencePools []*k8s_inference_v1alpha2.InferencePool) []*k8s_inference_v1alpha2.InferencePool {
+	filtered := []*k8s_inference_v1alpha2.InferencePool{}
+	workloadLabels := mapWorkloadSelector(workloadSelector)
+	for _, pool := range inferencePools {
+		wkLabelsS := []string{}
+		poolSelector := pool.Spec.Selector
+		for k, v := range poolSelector {
+			wkLabelsS = append(wkLabelsS, fmt.Sprintf("%s=%s", k, v))
+		}
+		if resourceSelector, err := labels.Parse(strings.Join(wkLabelsS, ",")); err == nil {
+			if resourceSelector.Matches(labels.Set(workloadLabels)) {
+				filtered = append(filtered, pool)
+			}
+		}
+	}
+	return filtered
+}
+
 func FilterPodsByController(controllerName string, controllerGVK schema.GroupVersionKind, allPods []core_v1.Pod) []core_v1.Pod {
 	var pods []core_v1.Pod
 	for _, pod := range allPods {
@@ -594,6 +613,16 @@ func FilterK8sGRPCRoutesByService(allRoutes []*k8s_networking_v1.GRPCRoute, refe
 	return filtered
 }
 
+func FilterK8sInferencePoolByService(allObjects []*k8s_inference_v1alpha2.InferencePool, namespace string, serviceName string) []*k8s_inference_v1alpha2.InferencePool {
+	filtered := []*k8s_inference_v1alpha2.InferencePool{}
+	for _, obj := range allObjects {
+		if string(*obj.Spec.ExtensionRef.Kind) == ServiceType && string(obj.Spec.ExtensionRef.Name) == serviceName && obj.Namespace == namespace {
+			filtered = append(filtered, obj)
+		}
+	}
+	return filtered
+}
+
 func FilterVirtualServiceByRoute(vs *networking_v1.VirtualService, service string, namespace string, conf *config.Config) bool {
 	if vs == nil {
 		return false
diff --git a/kubernetes/istio.go b/kubernetes/istio.go
index 7f4d87f4d..f6f6c7c2e 100644
--- a/kubernetes/istio.go
+++ b/kubernetes/istio.go
@@ -13,6 +13,7 @@ import (
 	istio "istio.io/client-go/pkg/clientset/versioned"
 	appsv1 "k8s.io/api/apps/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	inferenceapiclient "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned"
 	k8s_networking_v1 "sigs.k8s.io/gateway-api/apis/v1"
 	gatewayapiclient "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned"
 
@@ -79,6 +80,9 @@ type IstioClientInterface interface {
 	// GatewayAPI returns the gateway-api kube client.
 	GatewayAPI() gatewayapiclient.Interface
 
+	// InferenceAPI returns the inference-extensions-api kube client.
+	InferenceAPI() inferenceapiclient.Interface
+
 	GetConfigDump(namespace, podName string) (*ConfigDump, error)
 }
 
@@ -95,6 +99,10 @@ func (in *K8SClient) GatewayAPI() gatewayapiclient.Interface {
 	return in.gatewayapi
 }
 
+func (in *K8SClient) InferenceAPI() inferenceapiclient.Interface {
+	return in.inferenceapi
+}
+
 func (in *K8SClient) GetConfigDump(namespace, podName string) (*ConfigDump, error) {
 	// Fetching the Config Dump from the pod's Envoy.
 	// The port 15000 is open on each Envoy Sidecar (managed by Istio) to serve the Envoy Admin  interface.
diff --git a/kubernetes/kubernetes.go b/kubernetes/kubernetes.go
index 358d5d184..f4cf66a1b 100644
--- a/kubernetes/kubernetes.go
+++ b/kubernetes/kubernetes.go
@@ -262,6 +262,22 @@ func (in *K8SClient) IsGatewayAPI() bool {
 	return *in.isGatewayAPI
 }
 
+func (in *K8SClient) IsInferenceAPI() bool {
+	in.rwMutex.Lock()
+	defer in.rwMutex.Unlock()
+	if in.InferenceAPI() == nil {
+		return false
+	}
+	if in.isInferenceAPI == nil {
+		v1alpha2Types := map[string]string{
+			K8sInferencePoolsType: "inferencepools",
+		}
+		isInferenceAPI := checkInferenceAPIs(in, K8sInferenceGroupVersionV1Alpha2.String(), v1alpha2Types)
+		in.isInferenceAPI = &isInferenceAPI
+	}
+	return *in.isInferenceAPI
+}
+
 func (in *K8SClient) IsExpGatewayAPI() bool {
 	in.rwMutex.Lock()
 	defer in.rwMutex.Unlock()
@@ -303,6 +319,28 @@ func checkGatewayAPIs(in *K8SClient, version string, types map[string]string, is
 	return found == len(types)
 }
 
+func checkInferenceAPIs(in *K8SClient, version string, types map[string]string) bool {
+	found := 0
+	res, err := in.k8s.Discovery().ServerResourcesForGroupVersion(version)
+	if err != nil {
+		log.Debugf("K8s Gateway API Inference Extension CRDs are not installed. Required K8s Gateway API Inference Extension version: %s. Gateway API Inference Extension will not be used.", version)
+		return false
+	}
+	for _, r := range res.APIResources {
+		if name, foundKind := types[r.Kind]; foundKind && r.Name == name {
+			found++
+		}
+	}
+	if found > 0 && found < len(types) {
+		keys := make([]string, 0, len(types))
+		for key := range types {
+			keys = append(keys, key)
+		}
+		log.Warningf("Not all required K8s Gateway API Inference Extension CRDs are installed for version: %s, expected: %s", version, strings.Join(keys, ", "))
+	}
+	return found == len(types)
+}
+
 // Is IstioAPI checks whether Istio API is installed or not
 func (in *K8SClient) IsIstioAPI() bool {
 	in.rwMutex.Lock()
diff --git a/kubernetes/scheme.go b/kubernetes/scheme.go
index 44c9ecc67..a9693b4ff 100644
--- a/kubernetes/scheme.go
+++ b/kubernetes/scheme.go
@@ -13,6 +13,7 @@ import (
 	telemetryv1 "istio.io/client-go/pkg/apis/telemetry/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
+	k8sinferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
 	k8snetworkingv1 "sigs.k8s.io/gateway-api/apis/v1"
 	k8snetworkingv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
 	k8snetworkingv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
@@ -32,6 +33,7 @@ func NewScheme() (*runtime.Scheme, error) {
 		k8snetworkingv1.Install,
 		k8snetworkingv1beta1.Install,
 		k8snetworkingv1alpha2.Install,
+		k8sinferencev1alpha2.Install,
 		osappsscheme.AddToScheme,
 		oauthscheme.AddToScheme,
 		projectscheme.AddToScheme,
diff --git a/kubernetes/types.go b/kubernetes/types.go
index 66e2fc20b..13f367497 100644
--- a/kubernetes/types.go
+++ b/kubernetes/types.go
@@ -25,6 +25,7 @@ const (
 	K8sGatewayClassType   = "GatewayClass"
 	K8sGRPCRouteType      = "GRPCRoute"
 	K8sHTTPRouteType      = "HTTPRoute"
+	K8sInferencePoolsType = "InferencePool"
 	K8sReferenceGrantType = "ReferenceGrant"
 	K8sTCPRouteType       = "TCPRoute"
 	K8sTLSRouteType       = "TLSRoute"
@@ -70,6 +71,7 @@ var (
 	K8sGatewayClasses  = K8sNetworkingGroupVersionV1.WithKind(K8sGatewayClassType)
 	K8sGRPCRoutes      = K8sNetworkingGroupVersionV1.WithKind(K8sGRPCRouteType)
 	K8sHTTPRoutes      = K8sNetworkingGroupVersionV1.WithKind(K8sHTTPRouteType)
+	K8sInferencePools  = K8sInferenceGroupVersionV1Alpha2.WithKind(K8sInferencePoolsType)
 	K8sReferenceGrants = K8sNetworkingGroupVersionV1Beta1.WithKind(K8sReferenceGrantType)
 	K8sTCPRoutes       = K8sNetworkingGroupVersionV1Alpha2.WithKind(K8sTCPRouteType)
 	K8sTLSRoutes       = K8sNetworkingGroupVersionV1Alpha2.WithKind(K8sTLSRouteType)
@@ -127,6 +129,11 @@ var (
 		Version: "v1",
 	}
 
+	K8sInferenceGroupVersionV1Alpha2 = schema.GroupVersion{
+		Group:   "inference.networking.x-k8s.io",
+		Version: "v1alpha2",
+	}
+
 	K8sNetworkingGroupVersionV1Alpha2 = schema.GroupVersion{
 		Group:   "gateway.networking.k8s.io",
 		Version: "v1alpha2",
@@ -173,6 +180,7 @@ var (
 		K8sGateways.String():        K8sGateways,
 		K8sGRPCRoutes.String():      K8sGRPCRoutes,
 		K8sHTTPRoutes.String():      K8sHTTPRoutes,
+		K8sInferencePools.String():  K8sInferencePools,
 		K8sReferenceGrants.String(): K8sReferenceGrants,
 		K8sTCPRoutes.String():       K8sTCPRoutes,
 		K8sTLSRoutes.String():       K8sTLSRoutes,
diff --git a/models/istio_config.go b/models/istio_config.go
index 6c6052911..33ad56142 100644
--- a/models/istio_config.go
+++ b/models/istio_config.go
@@ -10,6 +10,7 @@ import (
 	telemetry_v1 "istio.io/client-go/pkg/apis/telemetry/v1"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"sigs.k8s.io/controller-runtime/pkg/client"
+	k8s_inference_v1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
 	k8s_networking_v1 "sigs.k8s.io/gateway-api/apis/v1"
 	k8s_networking_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
 	k8s_networking_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
@@ -35,6 +36,7 @@ type IstioConfigList struct {
 	K8sGateways        []*k8s_networking_v1.Gateway             `json:"-"`
 	K8sGRPCRoutes      []*k8s_networking_v1.GRPCRoute           `json:"-"`
 	K8sHTTPRoutes      []*k8s_networking_v1.HTTPRoute           `json:"-"`
+	K8sInferencePools  []*k8s_inference_v1alpha2.InferencePool  `json:"-"`
 	K8sReferenceGrants []*k8s_networking_v1beta1.ReferenceGrant `json:"-"`
 	K8sTCPRoutes       []*k8s_networking_v1alpha2.TCPRoute      `json:"-"`
 	K8sTLSRoutes       []*k8s_networking_v1alpha2.TLSRoute      `json:"-"`
@@ -64,6 +66,7 @@ func (i IstioConfigList) MarshalJSON() ([]byte, error) {
 	resources[kubernetes.K8sGateways.String()] = i.K8sGateways
 	resources[kubernetes.K8sGRPCRoutes.String()] = i.K8sGRPCRoutes
 	resources[kubernetes.K8sHTTPRoutes.String()] = i.K8sHTTPRoutes
+	resources[kubernetes.K8sInferencePools.String()] = i.K8sInferencePools
 	resources[kubernetes.K8sReferenceGrants.String()] = i.K8sReferenceGrants
 	resources[kubernetes.K8sTCPRoutes.String()] = i.K8sTCPRoutes
 	resources[kubernetes.K8sTLSRoutes.String()] = i.K8sTLSRoutes
@@ -149,6 +152,10 @@ func (i *IstioConfigList) UnmarshalJSON(data []byte) error {
 			if err := json.Unmarshal(rawMessage, &i.K8sHTTPRoutes); err != nil {
 				return err
 			}
+		case kubernetes.K8sInferencePools.String():
+			if err := json.Unmarshal(rawMessage, &i.K8sInferencePools); err != nil {
+				return err
+			}
 		case kubernetes.K8sReferenceGrants.String():
 			if err := json.Unmarshal(rawMessage, &i.K8sReferenceGrants); err != nil {
 				return err
@@ -228,6 +235,9 @@ func (i *IstioConfigList) ConvertToResponse() {
 	if i.K8sHTTPRoutes == nil {
 		i.K8sHTTPRoutes = []*k8s_networking_v1.HTTPRoute{}
 	}
+	if i.K8sInferencePools == nil {
+		i.K8sInferencePools = []*k8s_inference_v1alpha2.InferencePool{}
+	}
 	if i.K8sReferenceGrants == nil {
 		i.K8sReferenceGrants = []*k8s_networking_v1beta1.ReferenceGrant{}
 	}
@@ -275,6 +285,7 @@ type IstioConfigDetails struct {
 	K8sGateway        *k8s_networking_v1.Gateway             `json:"-"`
 	K8sGRPCRoute      *k8s_networking_v1.GRPCRoute           `json:"-"`
 	K8sHTTPRoute      *k8s_networking_v1.HTTPRoute           `json:"-"`
+	K8sInferencePool  *k8s_inference_v1alpha2.InferencePool  `json:"-"`
 	K8sReferenceGrant *k8s_networking_v1beta1.ReferenceGrant `json:"-"`
 	K8sTCPRoute       *k8s_networking_v1alpha2.TCPRoute      `json:"-"`
 	K8sTLSRoute       *k8s_networking_v1alpha2.TLSRoute      `json:"-"`
@@ -324,6 +335,8 @@ func (i IstioConfigDetails) MarshalJSON() ([]byte, error) {
 		resource = i.K8sGRPCRoute
 	} else if i.K8sHTTPRoute != nil {
 		resource = i.K8sHTTPRoute
+	} else if i.K8sInferencePool != nil {
+		resource = i.K8sInferencePool
 	} else if i.K8sReferenceGrant != nil {
 		resource = i.K8sReferenceGrant
 	} else if i.K8sTCPRoute != nil {
@@ -479,6 +492,13 @@ func (icd *IstioConfigDetails) UnmarshalJSON(data []byte) error {
 		}
 		icd.K8sHTTPRoute = &httpRoute
 
+	case kubernetes.K8sInferencePools:
+		var inferencePool k8s_inference_v1alpha2.InferencePool
+		if err := json.Unmarshal(temp.Resource, &inferencePool); err != nil {
+			return err
+		}
+		icd.K8sInferencePool = &inferencePool
+
 	case kubernetes.K8sReferenceGrants:
 		var refGrant k8s_networking_v1beta1.ReferenceGrant
 		if err := json.Unmarshal(temp.Resource, &refGrant); err != nil {
@@ -624,6 +644,9 @@ var IstioConfigHelpMessages = map[string][]IstioConfigHelp{
 	kubernetes.K8sHTTPRoutes.String(): { // TODO
 		{ObjectField: "", Message: "Kubernetes Gateway API Configuration Object. HTTPRoute is for multiplexing HTTP or terminated HTTPS connections."},
 	},
+	kubernetes.K8sInferencePools.String(): { // TODO
+		{ObjectField: "", Message: "Kubernetes Gateway API Inference Extension Configuration Object. InferencePool defines a group of pods dedicated to serving AI models."},
+	},
 	kubernetes.K8sReferenceGrants.String(): {
 		{ObjectField: "spec", Message: "Kubernetes Gateway API Configuration Object. ReferenceGrant is for enabling cross namespace references within Gateway API."},
 		{ObjectField: "spec.from", Message: "Define the group, kind, and namespace of resources that may reference items described in the to list."},
@@ -671,6 +694,7 @@ func (configList IstioConfigList) FilterIstioConfigs(nss []string) *IstioConfigs
 			filtered[ns].K8sGateways = []*k8s_networking_v1.Gateway{}
 			filtered[ns].K8sGRPCRoutes = []*k8s_networking_v1.GRPCRoute{}
 			filtered[ns].K8sHTTPRoutes = []*k8s_networking_v1.HTTPRoute{}
+			filtered[ns].K8sInferencePools = []*k8s_inference_v1alpha2.InferencePool{}
 			filtered[ns].K8sReferenceGrants = []*k8s_networking_v1beta1.ReferenceGrant{}
 			filtered[ns].K8sTCPRoutes = []*k8s_networking_v1alpha2.TCPRoute{}
 			filtered[ns].K8sTLSRoutes = []*k8s_networking_v1alpha2.TLSRoute{}
@@ -721,6 +745,12 @@ func (configList IstioConfigList) FilterIstioConfigs(nss []string) *IstioConfigs
 			}
 		}
 
+		for _, pool := range configList.K8sInferencePools {
+			if pool.Namespace == ns {
+				filtered[ns].K8sInferencePools = append(filtered[ns].K8sInferencePools, pool)
+			}
+		}
+
 		for _, rg := range configList.K8sReferenceGrants {
 			if rg.Namespace == ns {
 				filtered[ns].K8sReferenceGrants = append(filtered[ns].K8sReferenceGrants, rg)
@@ -816,6 +846,7 @@ func (configList IstioConfigList) MergeConfigs(ns IstioConfigList) IstioConfigLi
 	configList.K8sGateways = append(configList.K8sGateways, ns.K8sGateways...)
 	configList.K8sGRPCRoutes = append(configList.K8sGRPCRoutes, ns.K8sGRPCRoutes...)
 	configList.K8sHTTPRoutes = append(configList.K8sHTTPRoutes, ns.K8sHTTPRoutes...)
+	configList.K8sInferencePools = append(configList.K8sInferencePools, ns.K8sInferencePools...)
 	configList.K8sReferenceGrants = append(configList.K8sReferenceGrants, ns.K8sReferenceGrants...)
 	configList.K8sTCPRoutes = append(configList.K8sTCPRoutes, ns.K8sTCPRoutes...)
 	configList.K8sTLSRoutes = append(configList.K8sTLSRoutes, ns.K8sTLSRoutes...)
diff --git a/models/service.go b/models/service.go
index 42db06433..fe3cedf56 100644
--- a/models/service.go
+++ b/models/service.go
@@ -4,6 +4,7 @@ import (
 	networking_v1 "istio.io/client-go/pkg/apis/networking/v1"
 	core_v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/labels"
+	"sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
 	k8s_networking_v1 "sigs.k8s.io/gateway-api/apis/v1"
 	k8s_networking_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
 
@@ -91,6 +92,7 @@ type ServiceDetails struct {
 	IstioSidecar       bool                                     `json:"istioSidecar"`
 	K8sGRPCRoutes      []*k8s_networking_v1.GRPCRoute           `json:"k8sGRPCRoutes"`
 	K8sHTTPRoutes      []*k8s_networking_v1.HTTPRoute           `json:"k8sHTTPRoutes"`
+	K8sInferencePools  []*v1alpha2.InferencePool                `json:"k8sInferencePools"`
 	K8sReferenceGrants []*k8s_networking_v1beta1.ReferenceGrant `json:"k8sReferenceGrants"`
 	Service            Service                                  `json:"service"`
 	ServiceEntries     []*networking_v1.ServiceEntry            `json:"serviceEntries"`



Test patch:
diff --git a/business/references/k8s_inference_pool_references_test.go b/business/references/k8s_inference_pool_references_test.go
new file mode 100644
index 000000000..b68f8c3b8
--- /dev/null
+++ b/business/references/k8s_inference_pool_references_test.go
@@ -0,0 +1,141 @@
+package references
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	k8s_inference_v1alpha2 "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2"
+
+	"github.com/kiali/kiali/config"
+	"github.com/kiali/kiali/kubernetes"
+	"github.com/kiali/kiali/models"
+	"github.com/kiali/kiali/tests/data"
+)
+
+func prepareTestForK8sInferencePool(pool *k8s_inference_v1alpha2.InferencePool, workloads models.Workloads, services []*kubernetes.RegistryService) models.IstioReferences {
+	conf := config.Get()
+	if conf.KubernetesConfig.ClusterName == "" {
+		conf.KubernetesConfig.ClusterName = "Kubernetes"
+	}
+
+	references := K8sInferencePoolReferences{
+		Conf:              conf,
+		Namespaces:        []string{pool.Namespace, "different-ns"},
+		K8sInferencePools: []*k8s_inference_v1alpha2.InferencePool{pool},
+		WorkloadsPerNamespace: map[string]models.Workloads{
+			pool.Namespace: workloads,
+		},
+		RegistryServices: services,
+	}
+	return *references.References()[models.IstioReferenceKey{ObjectGVK: kubernetes.K8sInferencePools, Namespace: pool.Namespace, Name: pool.Name}]
+}
+
+// TestK8sInferencePoolReferences tests that both workload and service references are correctly found.
+func TestK8sInferencePoolReferences(t *testing.T) {
+	assert := assert.New(t)
+	config.Set(config.NewConfig())
+
+	// Setup mocks
+	pool := fakeInferencePool("test-pool", "test-ns", map[k8s_inference_v1alpha2.LabelKey]k8s_inference_v1alpha2.LabelValue{"app": "vllm-llama3-8b-instruct"}, "my-service-epp")
+	workloads := models.Workloads{
+		data.CreateWorkload("workload1", map[string]string{"app": "vllm-llama3-8b-instruct"}),
+		data.CreateWorkload("workload2", map[string]string{"app": "vllm-llama3-8b-instruct-new"}),
+		data.CreateWorkload("other-workload", map[string]string{"app": "other-app"}),
+	}
+	services := data.CreateFakeMultiRegistryServices([]string{"my-service-epp.test-ns.svc.cluster.local", "other-service"}, "test-ns", ".")
+
+	references := prepareTestForK8sInferencePool(pool, workloads, services)
+
+	// Check Workload references
+	assert.Len(references.WorkloadReferences, 1)
+	assert.ElementsMatch([]string{"workload1"}, []string{references.WorkloadReferences[0].Name})
+
+	// Check Service references
+	assert.Len(references.ServiceReferences, 1)
+	assert.Equal("my-service-epp", references.ServiceReferences[0].Name)
+	assert.Equal("test-ns", references.ServiceReferences[0].Namespace)
+}
+
+// TestK8sInferencePoolNoWorkloadReferences tests the case where the selector matches no workloads.
+func TestK8sInferencePoolNoWorkloadReferences(t *testing.T) {
+	assert := assert.New(t)
+	config.Set(config.NewConfig())
+
+	pool := fakeInferencePool("test-pool", "test-ns", map[k8s_inference_v1alpha2.LabelKey]k8s_inference_v1alpha2.LabelValue{"app": "vllm-llama3-8b-instruct"}, "my-service-epp")
+	workloads := models.Workloads{
+		data.CreateWorkload("workload1", map[string]string{"app": "my-app"}),
+	}
+	services := data.CreateFakeMultiRegistryServices([]string{"my-service-epp.test-ns.svc.cluster.local", "other-service"}, "test-ns", ".")
+
+	references := prepareTestForK8sInferencePool(pool, workloads, services)
+
+	// Check Workload references empty
+	assert.Empty(references.WorkloadReferences)
+
+	// Check Service references (1)
+	assert.Len(references.ServiceReferences, 1)
+	assert.Equal("my-service-epp", references.ServiceReferences[0].Name)
+}
+
+// TestK8sInferencePoolNoServiceReference tests the case where the extensionRef points to a non-existent service.
+func TestK8sInferencePoolNoServiceReference(t *testing.T) {
+	assert := assert.New(t)
+	config.Set(config.NewConfig())
+
+	pool := fakeInferencePool("test-pool", "test-ns", map[k8s_inference_v1alpha2.LabelKey]k8s_inference_v1alpha2.LabelValue{"app": "vllm-llama3-8b-instruct"}, "non-existent-service")
+	workloads := models.Workloads{
+		data.CreateWorkload("workload1", map[string]string{"app": "vllm-llama3-8b-instruct"}),
+	}
+	services := data.CreateFakeMultiRegistryServices([]string{"my-service-epp.test-ns.svc.cluster.local", "other-service"}, "test-ns", ".")
+
+	references := prepareTestForK8sInferencePool(pool, workloads, services)
+
+	// Check Workload references (1)
+	assert.Len(references.WorkloadReferences, 1)
+	assert.Equal("workload1", references.WorkloadReferences[0].Name)
+
+	// Check Service references empty
+	assert.Empty(references.ServiceReferences)
+}
+
+// TestK8sInferencePoolNoReferences tests the case where neither selector nor extensionRef match anything.
+func TestK8sInferencePoolNoReferences(t *testing.T) {
+	assert := assert.New(t)
+	config.Set(config.NewConfig())
+
+	// Create a pool with a selector that won't match and a reference to a non-existent service
+	pool := fakeInferencePool("test-pool", "test-ns", map[k8s_inference_v1alpha2.LabelKey]k8s_inference_v1alpha2.LabelValue{"app": "non-existent"}, "non-existent")
+	workloads := models.Workloads{
+		data.CreateWorkload("workload1", map[string]string{"app": "my-app"}),
+	}
+	services := data.CreateFakeMultiRegistryServices([]string{"my-service-epp.test-ns.svc.cluster.local", "other-service"}, "test-ns", ".")
+
+	references := prepareTestForK8sInferencePool(pool, workloads, services)
+
+	// Check both references are empty
+	assert.Empty(references.WorkloadReferences)
+	assert.Empty(references.ServiceReferences)
+}
+
+// fakeInferencePool is a helper to create K8sInferencePool objects for testing.
+func fakeInferencePool(name, namespace string, selector map[k8s_inference_v1alpha2.LabelKey]k8s_inference_v1alpha2.LabelValue, serviceRefName string) *k8s_inference_v1alpha2.InferencePool {
+	kind := k8s_inference_v1alpha2.Kind("Service")
+	return &k8s_inference_v1alpha2.InferencePool{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      name,
+			Namespace: namespace,
+		},
+		Spec: k8s_inference_v1alpha2.InferencePoolSpec{
+			Selector: selector,
+			EndpointPickerConfig: k8s_inference_v1alpha2.EndpointPickerConfig{
+				ExtensionRef: &k8s_inference_v1alpha2.Extension{
+					ExtensionReference: k8s_inference_v1alpha2.ExtensionReference{
+						Name: k8s_inference_v1alpha2.ObjectName(serviceRefName),
+						Kind: &kind,
+					},
+				},
+			},
+		},
+	}
+}
diff --git a/kubernetes/kubetest/fake.go b/kubernetes/kubetest/fake.go
index 325e39561..62a5e9072 100644
--- a/kubernetes/kubetest/fake.go
+++ b/kubernetes/kubetest/fake.go
@@ -24,6 +24,8 @@ import (
 	kubefake "k8s.io/client-go/kubernetes/fake"
 	kubescheme "k8s.io/client-go/kubernetes/scheme"
 	ctrlfake "sigs.k8s.io/controller-runtime/pkg/client/fake"
+	inferenceapifake "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/fake"
+	inferenceapischeme "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/scheme"
 	gatewayapi "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned"
 	gatewayapifake "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned/fake"
 	gatewayapischeme "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned/scheme"
@@ -46,6 +48,11 @@ func isGatewayAPIResource(obj runtime.Object) bool {
 	return err == nil
 }
 
+func isInferenceAPIResource(obj runtime.Object) bool {
+	_, _, err := inferenceapischeme.Scheme.ObjectKinds(obj)
+	return err == nil
+}
+
 func isProjectResource(obj runtime.Object) bool {
 	_, _, err := projectscheme.Scheme.ObjectKinds(obj)
 	return err == nil
@@ -79,15 +86,16 @@ func NewFakeK8sClient(objects ...runtime.Object) *FakeK8sClient {
 	// is wrong. The guessing of the resource name only happens with tracker.Add inside of NewSimpleClientset.
 	// If we create the object after creating the clientset, then the tracker will use the correct resource name.
 	var (
-		kubeObjects       []runtime.Object
-		istioObjects      []runtime.Object
-		gatewayapiObjects []runtime.Object
-		osAppsObjects     []runtime.Object
-		routeObjects      []runtime.Object
-		projectObjects    []runtime.Object
-		userObjects       []runtime.Object
-		oAuthObjects      []runtime.Object
-		istioGateways     []*networking_v1.Gateway
+		kubeObjects         []runtime.Object
+		istioObjects        []runtime.Object
+		gatewayapiObjects   []runtime.Object
+		inferenceapiObjects []runtime.Object
+		osAppsObjects       []runtime.Object
+		routeObjects        []runtime.Object
+		projectObjects      []runtime.Object
+		userObjects         []runtime.Object
+		oAuthObjects        []runtime.Object
+		istioGateways       []*networking_v1.Gateway
 	)
 
 	scheme, err := kialikube.NewScheme()
@@ -110,6 +118,8 @@ func NewFakeK8sClient(objects ...runtime.Object) *FakeK8sClient {
 			}
 		case isGatewayAPIResource(o):
 			gatewayapiObjects = append(gatewayapiObjects, o)
+		case isInferenceAPIResource(o):
+			inferenceapiObjects = append(inferenceapiObjects, o)
 		case isOSAppsResource(o):
 			osAppsObjects = append(osAppsObjects, o)
 		case isRouteResource(o):
@@ -126,6 +136,7 @@ func NewFakeK8sClient(objects ...runtime.Object) *FakeK8sClient {
 	kubeClient := kubefake.NewSimpleClientset(kubeObjects...)
 	istioClient := istiofake.NewSimpleClientset(istioObjects...)
 	gatewayAPIClient := gatewayapifake.NewSimpleClientset(gatewayapiObjects...)
+	inferenceAPIClient := inferenceapifake.NewSimpleClientset(inferenceapiObjects...)
 	osAppsClient := osappsfake.NewSimpleClientset(osAppsObjects...)
 	projectClient := projectfake.NewSimpleClientset(projectObjects...)
 	routeClient := routefake.NewSimpleClientset(routeObjects...)
@@ -140,7 +151,7 @@ func NewFakeK8sClient(objects ...runtime.Object) *FakeK8sClient {
 	}
 
 	return &FakeK8sClient{
-		UserClientInterface: kialikube.NewClient(kubeClient, istioClient, gatewayAPIClient, osAppsClient, projectClient, routeClient, userClient, oAuthClient, ctrlclient),
+		UserClientInterface: kialikube.NewClient(kubeClient, istioClient, gatewayAPIClient, inferenceAPIClient, osAppsClient, projectClient, routeClient, userClient, oAuthClient, ctrlclient),
 		KubeClientset:       kubeClient,
 		IstioClientset:      istioClient,
 		ProjectFake:         projectClient,
@@ -152,9 +163,10 @@ func NewFakeK8sClient(objects ...runtime.Object) *FakeK8sClient {
 
 // FakeK8sClient is an implementation of the kiali Kubernetes client interface used for tests.
 type FakeK8sClient struct {
-	OpenShift         bool
-	GatewayAPIEnabled bool
-	IstioAPIEnabled   bool
+	OpenShift           bool
+	GatewayAPIEnabled   bool
+	InferenceAPIEnabled bool
+	IstioAPIEnabled     bool
 	kialikube.UserClientInterface
 	// Underlying kubernetes clientset.
 	KubeClientset kubernetes.Interface
@@ -173,6 +185,7 @@ type FakeK8sClient struct {
 func (c *FakeK8sClient) IsOpenShift() bool                  { return c.OpenShift }
 func (c *FakeK8sClient) IsExpGatewayAPI() bool              { return c.GatewayAPIEnabled }
 func (c *FakeK8sClient) IsGatewayAPI() bool                 { return c.GatewayAPIEnabled }
+func (c *FakeK8sClient) IsInferenceAPI() bool               { return c.InferenceAPIEnabled }
 func (c *FakeK8sClient) IsIstioAPI() bool                   { return c.IstioAPIEnabled }
 func (c *FakeK8sClient) GetToken() string                   { return c.Token }
 func (c *FakeK8sClient) ClusterInfo() kialikube.ClusterInfo { return c.KubeClusterInfo }
diff --git a/kubernetes/kubetest/mock.go b/kubernetes/kubetest/mock.go
index 201466b0c..7d376a703 100644
--- a/kubernetes/kubetest/mock.go
+++ b/kubernetes/kubetest/mock.go
@@ -16,6 +16,7 @@ import (
 	"k8s.io/apimachinery/pkg/version"
 	"k8s.io/client-go/tools/clientcmd/api"
 	"sigs.k8s.io/controller-runtime/pkg/client"
+	inferenceapifake "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/fake"
 	gatewayapifake "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned/fake"
 
 	"github.com/kiali/kiali/config"
@@ -102,8 +103,9 @@ func (o *K8SClientFactoryMock) GetSAClientsAsUserClientInterfaces() map[string]k
 
 type K8SClientMock struct {
 	mock.Mock
-	istioClientset      *istio_fake.Clientset
-	gatewayapiClientSet *gatewayapifake.Clientset
+	istioClientset        *istio_fake.Clientset
+	gatewayapiClientSet   *gatewayapifake.Clientset
+	inferenceapiClientSet *inferenceapifake.Clientset
 	client.Reader
 }
 
@@ -117,6 +119,7 @@ func NewK8SClientMock() *K8SClientMock {
 	k8s.On("IsOpenShift").Return(true)
 	k8s.On("IsExpGatewayAPI").Return(false)
 	k8s.On("IsGatewayAPI").Return(false)
+	k8s.On("IsInferenceAPI").Return(false)
 	k8s.On("IsIstioAPI").Return(true)
 	k8s.On("GetKialiTokenForHomeCluster").Return("", "")
 	return k8s
@@ -168,6 +171,11 @@ func (o *K8SClientMock) IsGatewayAPI() bool {
 	return args.Get(0).(bool)
 }
 
+func (o *K8SClientMock) IsInferenceAPI() bool {
+	args := o.Called()
+	return args.Get(0).(bool)
+}
+
 func (o *K8SClientMock) IsIstioAPI() bool {
 	args := o.Called()
 	return args.Get(0).(bool)
diff --git a/kubernetes/kubetest/mock_istio.go b/kubernetes/kubetest/mock_istio.go
index f2f50dd0d..a4bf69ac4 100644
--- a/kubernetes/kubetest/mock_istio.go
+++ b/kubernetes/kubetest/mock_istio.go
@@ -8,6 +8,8 @@ import (
 	istio_fake "istio.io/client-go/pkg/clientset/versioned/fake"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
+	inferenceapiclient "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned"
+	inferenceapifake "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/fake"
 	gatewayapiclient "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned"
 	gatewayapifake "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned/fake"
 
@@ -34,6 +36,10 @@ func (o *K8SClientMock) MockGatewayApi(objects ...runtime.Object) {
 	o.gatewayapiClientSet = gatewayapifake.NewSimpleClientset(objects...)
 }
 
+func (o *K8SClientMock) MockInferenceApi(objects ...runtime.Object) {
+	o.inferenceapiClientSet = inferenceapifake.NewSimpleClientset(objects...)
+}
+
 func (o *K8SClientMock) Istio() istio.Interface {
 	return o.istioClientset
 }
@@ -42,6 +48,10 @@ func (o *K8SClientMock) GatewayAPI() gatewayapiclient.Interface {
 	return o.gatewayapiClientSet
 }
 
+func (o *K8SClientMock) InferenceAPI() inferenceapiclient.Interface {
+	return o.inferenceapiClientSet
+}
+
 func (o *K8SClientMock) CanConnectToIstiod() (kubernetes.IstioComponentStatus, error) {
 	args := o.Called()
 	return args.Get(0).(kubernetes.IstioComponentStatus), args.Error(1)
diff --git a/prometheus/prometheustest/mock.go b/prometheus/prometheustest/mock.go
index c7397cdee..6fb191979 100644
--- a/prometheus/prometheustest/mock.go
+++ b/prometheus/prometheustest/mock.go
@@ -52,12 +52,12 @@ func (o *PromAPIMock) Runtimeinfo(ctx context.Context) (prom_v1.RuntimeinfoResul
 	return args.Get(0).(prom_v1.RuntimeinfoResult), nil
 }
 
-func (o *PromAPIMock) LabelNames(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) ([]string, prom_v1.Warnings, error) {
+func (o *PromAPIMock) LabelNames(ctx context.Context, matches []string, startTime time.Time, endTime time.Time, opts ...prom_v1.Option) ([]string, prom_v1.Warnings, error) {
 	args := o.Called(ctx, matches, startTime, endTime)
 	return args.Get(0).([]string), args.Get(1).(prom_v1.Warnings), nil
 }
 
-func (o *PromAPIMock) LabelValues(ctx context.Context, label string, matches []string, startTime time.Time, endTime time.Time) (model.LabelValues, prom_v1.Warnings, error) {
+func (o *PromAPIMock) LabelValues(ctx context.Context, label string, matches []string, startTime time.Time, endTime time.Time, opts ...prom_v1.Option) (model.LabelValues, prom_v1.Warnings, error) {
 	args := o.Called(ctx, label, matches, startTime, endTime)
 	return args.Get(0).(model.LabelValues), nil, nil
 }
@@ -90,7 +90,7 @@ func (o *PromAPIMock) Flags(ctx context.Context) (prom_v1.FlagsResult, error) {
 	return prom_v1.FlagsResult{}, nil
 }
 
-func (o *PromAPIMock) Series(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) ([]model.LabelSet, prom_v1.Warnings, error) {
+func (o *PromAPIMock) Series(ctx context.Context, matches []string, startTime time.Time, endTime time.Time, opts ...prom_v1.Option) ([]model.LabelSet, prom_v1.Warnings, error) {
 	args := o.Called(ctx, matches, startTime, endTime)
 	return args.Get(0).([]model.LabelSet), nil, nil
 }
@@ -110,7 +110,7 @@ func (o *PromAPIMock) TargetsMetadata(ctx context.Context, matchTarget, metric,
 	return args.Get(0).([]prom_v1.MetricMetadata), nil
 }
 
-func (o *PromAPIMock) TSDB(ctx context.Context) (prom_v1.TSDBResult, error) {
+func (o *PromAPIMock) TSDB(ctx context.Context, opts ...prom_v1.Option) (prom_v1.TSDBResult, error) {
 	return prom_v1.TSDBResult{}, nil
 }
 
diff --git a/tests/integration/tests/istio_config_test.go b/tests/integration/tests/istio_config_test.go
index 481d328b4..853a098ef 100644
--- a/tests/integration/tests/istio_config_test.go
+++ b/tests/integration/tests/istio_config_test.go
@@ -92,6 +92,11 @@ func assertConfigs(configList models.IstioConfigList, namespace string, require
 		require.True(gw.Namespace == namespace)
 		require.NotNil(gw.Name)
 	}
+	require.NotNil(configList.K8sInferencePools)
+	for _, ipl := range configList.K8sInferencePools {
+		require.True(ipl.Namespace == namespace)
+		require.NotNil(ipl.Name)
+	}
 	require.NotNil(configList.K8sReferenceGrants)
 	for _, rg := range configList.K8sReferenceGrants {
 		require.True(rg.Namespace == namespace)