diff --git a/frontend/public/components/utils/volume-type.tsx b/frontend/public/components/utils/volume-type.tsx
index 3cfb01e3ffd..7cc24d391cb 100644
--- a/frontend/public/components/utils/volume-type.tsx
+++ b/frontend/public/components/utils/volume-type.tsx
@@ -1,9 +1,64 @@
-import type { FC } from 'react';
+import type { FC, ReactNode } from 'react';
import * as _ from 'lodash';
+import { useTranslation } from 'react-i18next';
import type { Volume } from '../../module/k8s';
import { getVolumeLocation, getVolumeType } from '../../module/k8s/pods';
import { ResourceLink } from './resource-link';
+const ProjectedVolumeSources: FC<{ volume: Volume; namespace: string }> = ({
+ volume,
+ namespace,
+}) => {
+ const { t } = useTranslation('public');
+ const sources = volume.projected?.sources;
+ if (!Array.isArray(sources) || sources.length === 0) {
+ return t('Projected');
+ }
+
+ const sourceElements: ReactNode[] = [];
+ sources.forEach((source) => {
+ if (source.configMap) {
+ sourceElements.push(
+ ,
+ );
+ } else if (source.secret) {
+ sourceElements.push(
+ ,
+ );
+ } else if (source.serviceAccountToken) {
+ sourceElements.push(
+
+ {t('ServiceAccountToken')}
+ ,
+ );
+ } else if (source.downwardAPI) {
+ sourceElements.push(
+
+ {t('DownwardAPI')}
+ ,
+ );
+ } else if (source.clusterTrustBundle) {
+ sourceElements.push(
+
+ {t('ClusterTrustBundle')}
+ ,
+ );
+ }
+ });
+
+ return sourceElements.length > 0 ? <>{sourceElements}> : t('Projected');
+};
+
export const VolumeType: FC = ({ volume, namespace }) => {
if (volume) {
if (volume.secret) {
@@ -23,6 +78,10 @@ export const VolumeType: FC = ({ volume, namespace }) => {
/>
);
}
+
+ if (volume.projected) {
+ return ;
+ }
}
const type = getVolumeType(volume);
diff --git a/frontend/public/locales/en/public.json b/frontend/public/locales/en/public.json
index e19dcaa4a47..ae8f3f06e33 100644
--- a/frontend/public/locales/en/public.json
+++ b/frontend/public/locales/en/public.json
@@ -371,6 +371,7 @@
"ClusterRoleBinding": "ClusterRoleBinding",
"ClusterRoleBindings": "ClusterRoleBindings",
"ClusterRoles": "ClusterRoles",
+ "ClusterTrustBundle": "ClusterTrustBundle",
"ClusterVersion": "ClusterVersion",
"ClusterVersion details": "ClusterVersion details",
"ClusterVersions": "ClusterVersions",
@@ -482,6 +483,7 @@
"CronJob": "CronJob",
"CronJob details": "CronJob details",
"CronJobs": "CronJobs",
+ "CSI": "CSI",
"CSIDriver": "CSIDriver",
"CSIDrivers": "CSIDrivers",
"Current": "Current",
@@ -579,6 +581,7 @@
"Download command-line tools": "Download command-line tools",
"Download YAML": "Download YAML",
"Downloading...": "Downloading...",
+ "DownwardAPI": "DownwardAPI",
"Drag and drop file with your private SSH key here or browse to upload it.": "Drag and drop file with your private SSH key here or browse to upload it.",
"Drag and drop file with your value here or browse to upload it.": "Drag and drop file with your value here or browse to upload it.",
"Drag and drop YAML or JSON files into the editor, or manually enter files and use <2>---2> to separate each definition.": "Drag and drop YAML or JSON files into the editor, or manually enter files and use <2>---2> to separate each definition.",
@@ -630,6 +633,7 @@
"Environment": "Environment",
"Environment variables": "Environment variables",
"Environment variables set from parent": "Environment variables set from parent",
+ "Ephemeral": "Ephemeral",
"Error": "Error",
"Error connecting to event stream": "Error connecting to event stream",
"Error connecting to event stream: {{ error }}": "Error connecting to event stream: {{ error }}",
@@ -661,6 +665,7 @@
"Explore new features and resources within the developer perspective.": "Explore new features and resources within the developer perspective.",
"Export as CSV": "Export as CSV",
"Exposed ports": "Exposed ports",
+ "Exposes pod and container fields to a running container as files.": "Exposes pod and container fields to a running container as files.",
"Extra scopes": "Extra scopes",
"Failed": "Failed",
"Failed pods": "Failed pods",
@@ -1402,6 +1407,7 @@
"ServiceAccount": "ServiceAccount",
"ServiceAccount details": "ServiceAccount details",
"ServiceAccounts": "ServiceAccounts",
+ "ServiceAccountToken": "ServiceAccountToken",
"ServiceMonitor": "ServiceMonitor",
"ServiceMonitors": "ServiceMonitors",
"Services": "Services",
@@ -1734,6 +1740,8 @@
"Volume": "Volume",
"Volume binding mode": "Volume binding mode",
"Volume mode": "Volume mode",
+ "Volume provided by an external Container Storage Interface driver.": "Volume provided by an external Container Storage Interface driver.",
+ "Volume that is handled by a cluster storage driver and follows the lifecycle of the pod.": "Volume that is handled by a cluster storage driver and follows the lifecycle of the pod.",
"VolumeAttributesClass": "VolumeAttributesClass",
"VolumeAttributesClass \"{{target}}\" is pending application.": "VolumeAttributesClass \"{{target}}\" is pending application.",
"VolumeAttributesClass application pending": "VolumeAttributesClass application pending",
diff --git a/frontend/public/module/k8s/pods.ts b/frontend/public/module/k8s/pods.ts
index 12ae296b9b0..de20b0dedca 100644
--- a/frontend/public/module/k8s/pods.ts
+++ b/frontend/public/module/k8s/pods.ts
@@ -97,6 +97,27 @@ const VolumeSource = {
'public~A projected volume maps several existing volume sources into the same directory.',
),
},
+ downwardAPI: {
+ id: 'downwardAPI',
+ label: i18next.t('public~DownwardAPI'),
+ description: i18next.t(
+ 'public~Exposes pod and container fields to a running container as files.',
+ ),
+ },
+ csi: {
+ id: 'csi',
+ label: i18next.t('public~CSI'),
+ description: i18next.t(
+ 'public~Volume provided by an external Container Storage Interface driver.',
+ ),
+ },
+ ephemeral: {
+ id: 'ephemeral',
+ label: i18next.t('public~Ephemeral'),
+ description: i18next.t(
+ 'public~Volume that is handled by a cluster storage driver and follows the lifecycle of the pod.',
+ ),
+ },
};
export const getVolumeType = (volume: Volume) => {
@@ -138,6 +159,9 @@ export const getVolumeLocation = (volume: Volume) => {
case VolumeSource.emptyDir.id:
case VolumeSource.secret.id:
case VolumeSource.projected.id:
+ case VolumeSource.downwardAPI.id:
+ case VolumeSource.csi.id:
+ case VolumeSource.ephemeral.id:
return null;
// Defaults to space separated sorted keys.
default: