-
Notifications
You must be signed in to change notification settings - Fork 8.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Fleet][EPM] Add TS type for package-spec. Clarify EPR relationship with spec #84946
Changes from all commits
4e10aaa
b36871e
53fc1ca
6c6f863
216f898
09cce23
efc73f9
5f2c4a5
aa6502f
7fa6a05
3f39ec4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ import { | |
requiredPackages, | ||
} from '../../constants'; | ||
import { ValueOf } from '../../types'; | ||
import { PackageSpecManifest, PackageSpecScreenshot } from './package_spec'; | ||
|
||
export type InstallationStatus = typeof installationStatuses; | ||
|
||
|
@@ -67,63 +68,63 @@ export enum ElasticsearchAssetType { | |
|
||
export type DataType = typeof dataTypes; | ||
|
||
export type RegistryRelease = 'ga' | 'beta' | 'experimental'; | ||
export type InstallablePackage = RegistryPackage | ArchivePackage; | ||
|
||
// Fields common to packages that come from direct upload and the registry | ||
export interface InstallablePackage { | ||
name: string; | ||
title?: string; | ||
version: string; | ||
release?: RegistryRelease; | ||
readme?: string; | ||
description: string; | ||
type: string; | ||
categories: string[]; | ||
screenshots?: RegistryImage[]; | ||
icons?: RegistryImage[]; | ||
assets?: string[]; | ||
internal?: boolean; | ||
format_version: string; | ||
data_streams?: RegistryDataStream[]; | ||
policy_templates?: RegistryPolicyTemplate[]; | ||
} | ||
export type ArchivePackage = PackageSpecManifest & | ||
// should an uploaded package be able to specify `internal`? | ||
Pick<RegistryPackage, 'readme' | 'assets' | 'data_streams' | 'internal'>; | ||
|
||
// Uploaded package archives don't have extra fields | ||
// Linter complaint disabled because this extra type is meant for better code readability | ||
// eslint-disable-next-line @typescript-eslint/no-empty-interface | ||
export interface ArchivePackage extends InstallablePackage {} | ||
export type RegistryPackage = PackageSpecManifest & | ||
Partial<RegistryOverridesToOptional> & | ||
RegistryAdditionalProperties & | ||
RegistryOverridePropertyValue; | ||
|
||
// Registry packages do have extra fields. | ||
// cf. type Package struct at https://github.com/elastic/package-registry/blob/master/util/package.go | ||
export interface RegistryPackage extends InstallablePackage { | ||
requirement: RequirementsByServiceName; | ||
type RegistryOverridesToOptional = Pick<PackageSpecManifest, 'title' | 'release'>; | ||
|
||
// our current types have `download`, & `path` as required but they're are optional (have `omitempty`) according to | ||
// https://github.com/elastic/package-registry/blob/master/util/package.go#L57 | ||
// & https://github.com/elastic/package-registry/blob/master/util/package.go#L80-L81 | ||
// However, they are always present in every registry response I checked. Chose to keep types unchanged for now | ||
// and confirm with Registry if they are really optional. Can update types and ~4 places in code later if neccessary | ||
interface RegistryAdditionalProperties { | ||
assets?: string[]; | ||
download: string; | ||
path: string; | ||
readme?: string; | ||
internal?: boolean; // Registry addition[0] and EPM uses it[1] [0]: https://github.com/elastic/package-registry/blob/dd7b021893aa8d66a5a5fde963d8ff2792a9b8fa/util/package.go#L63 [1] | ||
data_streams?: RegistryDataStream[]; // Registry addition [0] [0]: https://github.com/elastic/package-registry/blob/dd7b021893aa8d66a5a5fde963d8ff2792a9b8fa/util/package.go#L65 | ||
} | ||
interface RegistryOverridePropertyValue { | ||
icons?: RegistryImage[]; | ||
screenshots?: RegistryImage[]; | ||
} | ||
|
||
export type RegistryRelease = PackageSpecManifest['release']; | ||
export interface RegistryImage { | ||
src: string; | ||
path: string; | ||
title?: string; | ||
size?: string; | ||
type?: string; | ||
} | ||
|
||
export interface RegistryPolicyTemplate { | ||
name: string; | ||
title: string; | ||
description: string; | ||
inputs: RegistryInput[]; | ||
inputs?: RegistryInput[]; | ||
multiple?: boolean; | ||
} | ||
|
||
export interface RegistryInput { | ||
type: string; | ||
title: string; | ||
description?: string; | ||
vars?: RegistryVarsEntry[]; | ||
description: string; | ||
template_path?: string; | ||
condition?: string; | ||
vars?: RegistryVarsEntry[]; | ||
} | ||
|
||
export interface RegistryStream { | ||
input: string; | ||
title: string; | ||
|
@@ -152,15 +153,15 @@ export type RegistrySearchResult = Pick< | |
| 'release' | ||
| 'description' | ||
| 'type' | ||
| 'icons' | ||
| 'internal' | ||
| 'download' | ||
| 'path' | ||
| 'icons' | ||
| 'internal' | ||
| 'data_streams' | ||
| 'policy_templates' | ||
>; | ||
|
||
export type ScreenshotItem = RegistryImage; | ||
export type ScreenshotItem = RegistryImage | PackageSpecScreenshot; | ||
|
||
// from /categories | ||
// https://github.com/elastic/package-registry/blob/master/docs/api/categories.json | ||
|
@@ -172,7 +173,7 @@ export interface CategorySummaryItem { | |
count: number; | ||
} | ||
|
||
export type RequirementsByServiceName = Record<ServiceName, ServiceRequirements>; | ||
export type RequirementsByServiceName = PackageSpecManifest['conditions']; | ||
export interface AssetParts { | ||
pkgkey: string; | ||
dataset?: string; | ||
|
@@ -241,31 +242,24 @@ export interface RegistryVarsEntry { | |
|
||
// some properties are optional in Registry responses but required in EPM | ||
// internal until we need them | ||
interface PackageAdditions { | ||
export interface EpmPackageAdditions { | ||
title: string; | ||
latestVersion: string; | ||
assets: AssetsGroupedByServiceByType; | ||
removable?: boolean; | ||
} | ||
|
||
type Merge<FirstType, SecondType> = Omit<FirstType, Extract<keyof FirstType, keyof SecondType>> & | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From https://github.com/sindresorhus/type-fest/#utilities. Can move elsewhere later if needed. |
||
SecondType; | ||
|
||
// Managers public HTTP response types | ||
export type PackageList = PackageListItem[]; | ||
|
||
export type PackageListItem = Installable<RegistrySearchResult>; | ||
export type PackagesGroupedByStatus = Record<ValueOf<InstallationStatus>, PackageList>; | ||
export type PackageInfo = | ||
| Installable< | ||
// remove the properties we'll be altering/replacing from the base type | ||
Omit<RegistryPackage, keyof PackageAdditions> & | ||
// now add our replacement definitions | ||
PackageAdditions | ||
> | ||
| Installable< | ||
// remove the properties we'll be altering/replacing from the base type | ||
Omit<ArchivePackage, keyof PackageAdditions> & | ||
// now add our replacement definitions | ||
PackageAdditions | ||
>; | ||
| Installable<Merge<RegistryPackage, EpmPackageAdditions>> | ||
| Installable<Merge<ArchivePackage, EpmPackageAdditions>>; | ||
|
||
export interface Installation extends SavedObjectAttributes { | ||
installed_kibana: KibanaAssetReference[]; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { RegistryPolicyTemplate } from './epm'; | ||
|
||
// Based on https://github.com/elastic/package-spec/blob/master/versions/1/manifest.spec.yml#L8 | ||
export interface PackageSpecManifest { | ||
jfsiii marked this conversation as resolved.
Show resolved
Hide resolved
|
||
format_version: string; | ||
name: string; | ||
title: string; | ||
description: string; | ||
version: string; | ||
license?: 'basic'; | ||
type?: 'integration'; | ||
release: 'experimental' | 'beta' | 'ga'; | ||
categories?: Array<PackageSpecCategory | undefined>; | ||
conditions?: PackageSpecConditions; | ||
icons?: PackageSpecIcon[]; | ||
screenshots?: PackageSpecScreenshot[]; | ||
policy_templates?: RegistryPolicyTemplate[]; | ||
owner: { github: string }; | ||
} | ||
|
||
export type PackageSpecCategory = | ||
| 'aws' | ||
| 'azure' | ||
| 'cloud' | ||
| 'config_management' | ||
| 'containers' | ||
| 'crm' | ||
| 'custom' | ||
| 'datastore' | ||
| 'elastic_stack' | ||
| 'google_cloud' | ||
| 'kubernetes' | ||
| 'languages' | ||
| 'message_queue' | ||
| 'monitoring' | ||
| 'network' | ||
| 'notification' | ||
| 'os_system' | ||
| 'productivity' | ||
| 'security' | ||
| 'support' | ||
| 'ticketing' | ||
| 'version_control' | ||
| 'web'; | ||
|
||
export type PackageSpecConditions = Record< | ||
'kibana', | ||
{ | ||
version: string; | ||
} | ||
>; | ||
|
||
export interface PackageSpecIcon { | ||
src: string; | ||
title?: string; | ||
size?: string; | ||
type?: string; | ||
} | ||
|
||
export interface PackageSpecScreenshot { | ||
src: string; | ||
title: string; | ||
size?: string; | ||
type?: string; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ import { | |
AssetReference, | ||
CategorySummaryList, | ||
Installable, | ||
RegistryPackage, | ||
RegistrySearchResult, | ||
PackageInfo, | ||
} from '../models/epm'; | ||
|
||
|
@@ -30,14 +30,7 @@ export interface GetPackagesRequest { | |
} | ||
|
||
export interface GetPackagesResponse { | ||
response: Array< | ||
Installable< | ||
Pick< | ||
RegistryPackage, | ||
'name' | 'title' | 'version' | 'description' | 'type' | 'icons' | 'download' | 'path' | ||
> | ||
> | ||
>; | ||
response: Array<Installable<RegistrySearchResult>>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reference existing type instead of duplicating the definition |
||
} | ||
|
||
export interface GetLimitedPackagesResponse { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,8 +29,7 @@ export const AssetTitleMap: Record<AssetType, string> = { | |
map: 'Map', | ||
}; | ||
|
||
export const ServiceTitleMap: Record<ServiceName, string> = { | ||
elasticsearch: 'Elasticsearch', | ||
export const ServiceTitleMap: Record<Extract<ServiceName, 'kibana'>, string> = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Package spec (currently) limits values to |
||
kibana: 'Kibana', | ||
}; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ | |
import { useStartServices } from '../../../hooks/use_core'; | ||
import { PLUGIN_ID } from '../../../constants'; | ||
import { epmRouteService } from '../../../services'; | ||
import { RegistryImage } from '../../../../../../common'; | ||
import { PackageSpecIcon, PackageSpecScreenshot, RegistryImage } from '../../../../../../common'; | ||
|
||
const removeRelativePath = (relativePath: string): string => | ||
new URL(relativePath, 'http://example.com').pathname; | ||
|
@@ -15,12 +15,19 @@ export function useLinks() { | |
const { http } = useStartServices(); | ||
return { | ||
toAssets: (path: string) => http.basePath.prepend(`/plugins/${PLUGIN_ID}/assets/${path}`), | ||
toPackageImage: (img: RegistryImage, pkgName: string, pkgVersion: string): string => | ||
img.src | ||
? http.basePath.prepend( | ||
epmRouteService.getFilePath(`/package/${pkgName}/${pkgVersion}${img.src}`) | ||
) | ||
: http.basePath.prepend(epmRouteService.getFilePath(img.path)), | ||
toPackageImage: ( | ||
img: PackageSpecIcon | PackageSpecScreenshot | RegistryImage, | ||
pkgName: string, | ||
pkgVersion: string | ||
): string | undefined => { | ||
const sourcePath = img.src | ||
? `/package/${pkgName}/${pkgVersion}${img.src}` | ||
: 'path' in img && img.path; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
if (sourcePath) { | ||
const filePath = epmRouteService.getFilePath(sourcePath); | ||
return http.basePath.prepend(filePath); | ||
} | ||
}, | ||
toRelativeImage: ({ | ||
path, | ||
packageName, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not strictly required for this change. Only because I was in here and it's still type safe but w/one less import