diff --git a/package-lock.json b/package-lock.json index 96559fedb..805c1bd43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12375,7 +12375,7 @@ "url": "https://github.com/sponsors/gpbl" }, "peerDependencies": { - "react": ">=16.8.0" + "react": "*" } }, "node_modules/react-dom": { diff --git a/src/Assets/IconV2/ic-bg-cloud-vms.svg b/src/Assets/IconV2/ic-bg-cloud-vms.svg new file mode 100644 index 000000000..e9275a938 --- /dev/null +++ b/src/Assets/IconV2/ic-bg-cloud-vms.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/Assets/IconV2/ic-bg-healthy-vms.svg b/src/Assets/IconV2/ic-bg-healthy-vms.svg new file mode 100644 index 000000000..3ec40bbd3 --- /dev/null +++ b/src/Assets/IconV2/ic-bg-healthy-vms.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/Assets/IconV2/ic-bg-running-vms.svg b/src/Assets/IconV2/ic-bg-running-vms.svg new file mode 100644 index 000000000..6e5c7278f --- /dev/null +++ b/src/Assets/IconV2/ic-bg-running-vms.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/Assets/IconV2/ic-bg-tenants.svg b/src/Assets/IconV2/ic-bg-tenants.svg new file mode 100644 index 000000000..e16b5fb6c --- /dev/null +++ b/src/Assets/IconV2/ic-bg-tenants.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/Common/Constants.ts b/src/Common/Constants.ts index 8cc7c1118..4691b8140 100644 --- a/src/Common/Constants.ts +++ b/src/Common/Constants.ts @@ -48,6 +48,7 @@ export const PATTERNS = { ALPHANUMERIC_WITH_SPECIAL_CHAR_AND_SLASH: /^[A-Za-z0-9._/-]+$/, // allow alphanumeric,(.) ,(-),(_),(/) EMAIL: /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/, } + /** @deprecated */ export const URLS = { APP_CI_DETAILS: 'ci-details', @@ -397,6 +398,7 @@ export const DATE_TIME_FORMATS = { DD_MMM_YYYY_HH_MM: 'DD MMM YYYY, hh:mm', DD_MMM_YYYY: 'DD MMM YYYY', 'DD/MM/YYYY': 'DD/MM/YYYY', + FULL_DATE_WITH_TIME: 'DD-MM-YYYY hh:mm:ss', DD_MMM: 'DD MMM', TWENTY_FOUR_HOUR_FORMAT_HOUR: 'HH', ABBREVIATED_MONTH: 'MMM', diff --git a/src/Pages-Devtron-2.0/Navigation/types.ts b/src/Pages-Devtron-2.0/Navigation/types.ts index d07a81318..fab926ade 100644 --- a/src/Pages-Devtron-2.0/Navigation/types.ts +++ b/src/Pages-Devtron-2.0/Navigation/types.ts @@ -14,6 +14,7 @@ export type NavigationItemID = | 'infrastructure-management-chart-store' | 'infrastructure-management-resource-browser' | 'infrastructure-management-resource-watcher' + | 'infrastructure-management-observability' | 'infrastructure-management-catalog-framework' | 'software-release-management-overview' | 'software-release-management-release-hub' diff --git a/src/Pages-Devtron-2.0/Shared/Routes/routes.ts b/src/Pages-Devtron-2.0/Shared/Routes/routes.ts index 68735bbd7..ed6fc0880 100644 --- a/src/Pages-Devtron-2.0/Shared/Routes/routes.ts +++ b/src/Pages-Devtron-2.0/Shared/Routes/routes.ts @@ -317,6 +317,21 @@ export const BASE_ROUTES = { CONTROLLER_DETAILS: 'controller/details/:controllerId', CUSTOMIZE_COLUMNS: 'customize-columns', }, + OBSERVABILITY: { + ROOT: 'observability', + OVERVIEW: 'overview', + TENANTS: { + ROOT: 'tenants', + TENANT_DETAILS: { + ROOT: ':tenantName', + OVERVIEW: 'overview', + VMS: { + ROOT: 'vms', + VM_DETAILS: ':vmName', + }, + }, + }, + }, } as const const APPLICATION_MANAGEMENT_ROOT = `/${BASE_ROUTES.APPLICATION_MANAGEMENT.ROOT}` as const @@ -705,4 +720,20 @@ export const ROUTER_URLS = { ABOUT: `${STACK_MANAGER_ROOT}/${BASE_ROUTES.STACK_MANAGER.ABOUT}`, ABOUT_RELEASES: `${STACK_MANAGER_ROOT}/${BASE_ROUTES.STACK_MANAGER.ABOUT_RELEASES}`, }, + + OBSERVABILITY: { + ROOT: `/${BASE_ROUTES.OBSERVABILITY.ROOT}`, + OVERVIEW: `/${BASE_ROUTES.OBSERVABILITY.ROOT}/${BASE_ROUTES.OBSERVABILITY.OVERVIEW}`, + TENANTS: { + ROOT: `/${BASE_ROUTES.OBSERVABILITY.ROOT}/${BASE_ROUTES.OBSERVABILITY.TENANTS.ROOT}`, + TENANT_DETAILS: { + ROOT: `/${BASE_ROUTES.OBSERVABILITY.ROOT}/${BASE_ROUTES.OBSERVABILITY.TENANTS.ROOT}/${BASE_ROUTES.OBSERVABILITY.TENANTS.TENANT_DETAILS.ROOT}`, + OVERVIEW: `/${BASE_ROUTES.OBSERVABILITY.ROOT}/${BASE_ROUTES.OBSERVABILITY.TENANTS.ROOT}/${BASE_ROUTES.OBSERVABILITY.TENANTS.TENANT_DETAILS.ROOT}/${BASE_ROUTES.OBSERVABILITY.TENANTS.TENANT_DETAILS.OVERVIEW}`, + VMS: { + ROOT: `/${BASE_ROUTES.OBSERVABILITY.ROOT}/${BASE_ROUTES.OBSERVABILITY.TENANTS.ROOT}/${BASE_ROUTES.OBSERVABILITY.TENANTS.TENANT_DETAILS.ROOT}/${BASE_ROUTES.OBSERVABILITY.TENANTS.TENANT_DETAILS.VMS.ROOT}`, + VM_DETAILS: `/${BASE_ROUTES.OBSERVABILITY.ROOT}/${BASE_ROUTES.OBSERVABILITY.TENANTS.ROOT}/${BASE_ROUTES.OBSERVABILITY.TENANTS.TENANT_DETAILS.ROOT}/${BASE_ROUTES.OBSERVABILITY.TENANTS.TENANT_DETAILS.VMS.ROOT}/${BASE_ROUTES.OBSERVABILITY.TENANTS.TENANT_DETAILS.VMS.VM_DETAILS}`, + }, + }, + }, + }, } as const diff --git a/src/Shared/Components/DatePicker/utils.tsx b/src/Shared/Components/DatePicker/utils.tsx index 33166f8bb..91e8d35fe 100644 --- a/src/Shared/Components/DatePicker/utils.tsx +++ b/src/Shared/Components/DatePicker/utils.tsx @@ -14,6 +14,8 @@ * limitations under the License. */ +import { prefixZeroIfSingleDigit } from '@Common/Helper' + import { SelectPickerOptionType } from '../SelectPicker' import { MONTHLY_DATES_CONFIG, TIME_OPTIONS_CONFIG } from './constants' @@ -112,3 +114,22 @@ export const getDefaultDateFromTimeToLive = (timeToLive: string, isTomorrow?: bo nextDate.setHours(hours, minutes, 0) return nextDate } + +// Need to send either the relative time like: now-5m or the timestamp to grafana +// Assuming format is 'DD-MM-YYYY hh:mm:ss' +export const getTimestampFromDateIfAvailable = (dateString: string): string => { + try { + const [day, month, yearAndTime] = dateString.split('-') + const [year, time] = yearAndTime.split(' ') + const updatedTime = time + .split(':') + .map((item) => (['0', '00'].includes(item) ? '00' : prefixZeroIfSingleDigit(Number(item)))) + .join(':') + const formattedDate = `${year}-${prefixZeroIfSingleDigit(Number(month))}-${prefixZeroIfSingleDigit(Number(day))}T${updatedTime}` + const parsedDate = new Date(formattedDate).getTime() + + return Number.isNaN(parsedDate) ? dateString : parsedDate.toString() + } catch { + return dateString + } +} diff --git a/src/Shared/Components/Icon/Icon.tsx b/src/Shared/Components/Icon/Icon.tsx index 8ddb97356..86b80816c 100644 --- a/src/Shared/Components/Icon/Icon.tsx +++ b/src/Shared/Components/Icon/Icon.tsx @@ -36,19 +36,23 @@ import ICBell from '@IconsV2/ic-bell.svg?react' import ICBgBackupSchedule from '@IconsV2/ic-bg-backup-schedule.svg?react' import ICBgBackups from '@IconsV2/ic-bg-backups.svg?react' import ICBgBuild from '@IconsV2/ic-bg-build.svg?react' +import ICBgCloudVms from '@IconsV2/ic-bg-cloud-vms.svg?react' import ICBgCluster from '@IconsV2/ic-bg-cluster.svg?react' import ICBgCpu from '@IconsV2/ic-bg-cpu.svg?react' import ICBgDeploy from '@IconsV2/ic-bg-deploy.svg?react' import ICBgDockerScanner from '@IconsV2/ic-bg-docker-scanner.svg?react' import ICBgEnvironment from '@IconsV2/ic-bg-environment.svg?react' +import ICBgHealthyVms from '@IconsV2/ic-bg-healthy-vms.svg?react' import ICBgMemory from '@IconsV2/ic-bg-memory.svg?react' import ICBgPauseSchedule from '@IconsV2/ic-bg-pause-schedule.svg?react' import ICBgProductionPipelines from '@IconsV2/ic-bg-production-pipelines.svg?react' import ICBgProject from '@IconsV2/ic-bg-project.svg?react' import ICBgRansomwareVulnerableCluster from '@IconsV2/ic-bg-ransomware-vulnerable-cluster.svg?react' import ICBgRestore from '@IconsV2/ic-bg-restore.svg?react' +import ICBgRunningVms from '@IconsV2/ic-bg-running-vms.svg?react' import ICBgScan from '@IconsV2/ic-bg-scan.svg?react' import ICBgStorageLocations from '@IconsV2/ic-bg-storage-locations.svg?react' +import ICBgTenants from '@IconsV2/ic-bg-tenants.svg?react' import ICBgWebhook from '@IconsV2/ic-bg-webhook.svg?react' import ICBharatpe from '@IconsV2/ic-bharatpe.svg?react' import ICBinoculars from '@IconsV2/ic-binoculars.svg?react' @@ -380,19 +384,23 @@ export const iconMap = { 'ic-bg-backup-schedule': ICBgBackupSchedule, 'ic-bg-backups': ICBgBackups, 'ic-bg-build': ICBgBuild, + 'ic-bg-cloud-vms': ICBgCloudVms, 'ic-bg-cluster': ICBgCluster, 'ic-bg-cpu': ICBgCpu, 'ic-bg-deploy': ICBgDeploy, 'ic-bg-docker-scanner': ICBgDockerScanner, 'ic-bg-environment': ICBgEnvironment, + 'ic-bg-healthy-vms': ICBgHealthyVms, 'ic-bg-memory': ICBgMemory, 'ic-bg-pause-schedule': ICBgPauseSchedule, 'ic-bg-production-pipelines': ICBgProductionPipelines, 'ic-bg-project': ICBgProject, 'ic-bg-ransomware-vulnerable-cluster': ICBgRansomwareVulnerableCluster, 'ic-bg-restore': ICBgRestore, + 'ic-bg-running-vms': ICBgRunningVms, 'ic-bg-scan': ICBgScan, 'ic-bg-storage-locations': ICBgStorageLocations, + 'ic-bg-tenants': ICBgTenants, 'ic-bg-webhook': ICBgWebhook, 'ic-bharatpe': ICBharatpe, 'ic-binoculars': ICBinoculars, diff --git a/src/Shared/types.ts b/src/Shared/types.ts index 2d4f96fcd..77fe01dcf 100644 --- a/src/Shared/types.ts +++ b/src/Shared/types.ts @@ -18,8 +18,8 @@ import { ReactNode } from 'react' import { ParsedCountry } from 'react-international-phone' import { Dayjs } from 'dayjs' -import { APIOptions, ApprovalConfigDataType, Strategy } from '@Common/Types' -import { OverrideMergeStrategyType, ReleaseMode } from '@Pages/index' +import { ActionTypes, APIOptions, ApprovalConfigDataType, Strategy } from '@Common/Types' +import { OverrideMergeStrategyType, ReleaseMode, UserStatus } from '@Pages/index' import { CommonNodeAttr, @@ -963,6 +963,7 @@ export enum EntityTypes { GIT = 'git', CLUSTER = 'cluster', NOTIFICATION = 'notification', + OBSERVABILITY = 'observe', } export interface CustomRoles { @@ -1558,6 +1559,14 @@ export interface PipelineDeploymentStrategy { error: ServerError } +export interface ObservabilityPermissionFilter { + entityName: OptionType[] + action: ActionTypes.VIEW | ActionTypes.ADMIN + tenant: OptionType + entityNameError?: boolean + status: UserStatus + timeToLive: string +} export enum RemoteConnectionType { Direct = 'DIRECT', Proxy = 'PROXY',