diff --git a/console-extensions.json b/console-extensions.json index 3b8fc3bd..15af009c 100644 --- a/console-extensions.json +++ b/console-extensions.json @@ -52,6 +52,9 @@ "component": { "$codeRef": "pipelinesComponent.PipelinesOverviewPage" } + }, + "flags": { + "required": ["PIPELINE_TEKTON_RESULT_INSTALLED"] } }, { diff --git a/locales/en/plugin__pipelines-console-plugin.json b/locales/en/plugin__pipelines-console-plugin.json index d780ba3a..d8cc0759 100644 --- a/locales/en/plugin__pipelines-console-plugin.json +++ b/locales/en/plugin__pipelines-console-plugin.json @@ -11,6 +11,8 @@ "Average duration": "Average duration", "Average Duration": "Average Duration", "Cancelled": "Cancelled", + "ClusterVersion": "ClusterVersion", + "ClusterVersions": "ClusterVersions", "Duration": "Duration", "Failed": "Failed", "Last day": "Last day", diff --git a/src/components/hooks/use-k8sGet-hook.ts b/src/components/hooks/use-k8sGet-hook.ts new file mode 100644 index 00000000..1e7471e5 --- /dev/null +++ b/src/components/hooks/use-k8sGet-hook.ts @@ -0,0 +1,34 @@ +import { + K8sModel, + K8sResourceCommon, + k8sGet, +} from '@openshift-console/dynamic-plugin-sdk'; +import * as React from 'react'; + +export const useK8sGet = ( + kind: K8sModel, + name?: string, + namespace?: string, +): [R, boolean, unknown] => { + const [data, setData] = React.useState(); + const [loaded, setLoaded] = React.useState(false); + const [loadError, setLoadError] = React.useState(); + React.useEffect(() => { + const fetch = async () => { + try { + setLoadError(null); + setLoaded(false); + setData(null); + const resource = await k8sGet({ model: kind, name, ns: namespace }); + setData(resource); + } catch (error) { + setLoadError(error); + } finally { + setLoaded(true); + } + }; + fetch(); + }, [kind, name, namespace]); + + return [data, loaded, loadError]; +}; diff --git a/src/components/pipelines-overview/list-pages/PipelineRunsForPipelinesList.tsx b/src/components/pipelines-overview/list-pages/PipelineRunsForPipelinesList.tsx index ac6240f7..5f777529 100644 --- a/src/components/pipelines-overview/list-pages/PipelineRunsForPipelinesList.tsx +++ b/src/components/pipelines-overview/list-pages/PipelineRunsForPipelinesList.tsx @@ -16,6 +16,9 @@ import { listPageTableColumnClasses as tableColumnClasses, } from '../utils'; import PipelineRunsForPipelinesRow from './PipelineRunsForPipelinesRow'; +import { ClusterVersionModel } from '../../../models'; +import { ClusterVersionKind } from '../../../types'; +import { useK8sGet } from '../../hooks/use-k8sGet-hook'; type PipelineRunsForPipelinesListProps = { summaryData: SummaryProps[]; @@ -23,10 +26,18 @@ type PipelineRunsForPipelinesListProps = { loaded: boolean; }; +export const getClusterVersion = (cv: ClusterVersionKind): string => { + return cv?.status?.history?.[0]?.version || cv?.spec?.desiredUpdate?.version; +}; + const PipelineRunsForPipelinesList: React.FC< PipelineRunsForPipelinesListProps > = ({ summaryData, summaryDataFiltered, loaded }) => { const { t } = useTranslation('plugin__pipelines-console-plugin'); + const [clusterVersionData, clusterVersionLoaded] = + useK8sGet(ClusterVersionModel, 'version'); + const clusterVersion = + clusterVersionLoaded && getClusterVersion(clusterVersionData); const EmptyMsg = () => ( {t('No PipelineRuns found')} @@ -109,6 +120,7 @@ const PipelineRunsForPipelinesList: React.FC< loadError={false} unfilteredData={summaryData} EmptyMsg={EmptyMsg} + rowData={{ clusterVersion }} /> ); }; diff --git a/src/components/pipelines-overview/list-pages/PipelineRunsForPipelinesRow.tsx b/src/components/pipelines-overview/list-pages/PipelineRunsForPipelinesRow.tsx index 69256eb1..6ba2dcab 100644 --- a/src/components/pipelines-overview/list-pages/PipelineRunsForPipelinesRow.tsx +++ b/src/components/pipelines-overview/list-pages/PipelineRunsForPipelinesRow.tsx @@ -12,22 +12,29 @@ import { } from '@openshift-console/dynamic-plugin-sdk'; import { formatTime, formatTimeLastRunTime } from '../dateTime'; import { ALL_NAMESPACES_KEY } from '../../../consts'; -import { PipelineModel } from '../../../models'; +import { PipelineModel, PipelineModelV1Beta1 } from '../../../models'; import { useActiveNamespace } from '../../hooks/useActiveNamespace'; -const pipelineReference = getReferenceForModel(PipelineModel); - -const PipelineRunsForPipelinesRow: React.FC> = ({ - obj, -}) => { +const PipelineRunsForPipelinesRow: React.FC< + RowProps +> = ({ obj, rowData }) => { const [activeNamespace] = useActiveNamespace(); const [namespace, name] = obj.group_value.split('/'); - + const { clusterVersion } = rowData; + const isV1SupportCluster = + clusterVersion.split('.')[0] === '4' && clusterVersion.split('.')[1] > '13'; + const pipelineReference = getReferenceForModel( + isV1SupportCluster ? PipelineModel : PipelineModelV1Beta1, + ); return ( <> diff --git a/src/models.ts b/src/models.ts index c04624c1..d085224c 100644 --- a/src/models.ts +++ b/src/models.ts @@ -21,6 +21,24 @@ export const PipelineModel = { color, }; +export const PipelineModelV1Beta1 = { + apiGroup: 'tekton.dev', + apiVersion: 'v1beta1', + label: 'Pipeline', + // t('Pipeline') + labelKey: 'Pipeline', + // t('Pipelines') + labelPluralKey: 'Pipelines', + plural: 'pipelines', + abbr: 'PL', + namespaced: true, + kind: 'Pipeline', + id: 'pipeline', + labelPlural: 'Pipelines', + crd: true, + color, +}; + export const RepositoryModel = { apiGroup: 'pipelinesascode.tekton.dev', apiVersion: 'v1alpha1', @@ -71,3 +89,20 @@ export const RouteModel: K8sKind = { kind: 'Route', id: 'route', }; + +export const ClusterVersionModel: K8sKind = { + label: 'ClusterVersion', + // t('ClusterVersion') + labelKey: 'ClusterVersion', + labelPlural: 'ClusterVersions', + // t('ClusterVersions') + labelPluralKey: 'ClusterVersions', + apiVersion: 'v1', + apiGroup: 'config.openshift.io', + plural: 'clusterversions', + abbr: 'CV', + namespaced: false, + kind: 'ClusterVersion', + id: 'clusterversion', + crd: true, +}; diff --git a/src/types/openshift.ts b/src/types/openshift.ts index 2e123ac2..c3e48045 100644 --- a/src/types/openshift.ts +++ b/src/types/openshift.ts @@ -10,3 +10,35 @@ export type K8sResourceKind = K8sResourceCommon & { status?: { [key: string]: any }; data?: { [key: string]: any }; }; + +export type UpdateHistory = { + state: 'Completed' | 'Partial'; + startedTime: string; + completionTime: string; + version: string; + image: string; + verified: boolean; +}; + +export type Release = { + version: string; + image: string; + url?: string; + channels?: string[]; +}; +type ClusterVersionStatus = { + desired: Release; + history: UpdateHistory[]; +}; + +type ClusterVersionSpec = { + channel: string; + clusterID: string; + desiredUpdate?: Release; + upstream?: string; +}; + +export type ClusterVersionKind = { + spec: ClusterVersionSpec; + status: ClusterVersionStatus; +} & K8sResourceCommon;