diff --git a/.i18nrc.json b/.i18nrc.json index 6527a06b3fb7b..0a3b51bdeb73e 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -42,6 +42,7 @@ "xpack.searchProfiler": "x-pack/plugins/searchprofiler", "xpack.security": "x-pack/plugins/security", "xpack.server": "x-pack/server", + "xpack.snapshotRestore": "x-pack/plugins/snapshot_restore", "xpack.spaces": "x-pack/plugins/spaces", "xpack.upgradeAssistant": "x-pack/plugins/upgrade_assistant", "xpack.uptime": "x-pack/plugins/uptime", diff --git a/src/legacy/ui/public/management/index.d.ts b/src/legacy/ui/public/management/index.d.ts index ed4658f82dea3..b5d927cd90433 100644 --- a/src/legacy/ui/public/management/index.d.ts +++ b/src/legacy/ui/public/management/index.d.ts @@ -28,4 +28,8 @@ declare module 'ui/management' { allowOverride: boolean ): void; export const management: any; // TODO - properly provide types + export const MANAGEMENT_BREADCRUMB: { + text: string; + href: string; + }; } diff --git a/x-pack/index.js b/x-pack/index.js index 3c9f683ed0796..2fd774ee14219 100644 --- a/x-pack/index.js +++ b/x-pack/index.js @@ -37,6 +37,7 @@ import { translations } from './plugins/translations'; import { upgradeAssistant } from './plugins/upgrade_assistant'; import { uptime } from './plugins/uptime'; import { ossTelemetry } from './plugins/oss_telemetry'; +import { snapshotRestore } from './plugins/snapshot_restore'; module.exports = function (kibana) { return [ @@ -73,5 +74,6 @@ module.exports = function (kibana) { upgradeAssistant(kibana), uptime(kibana), ossTelemetry(kibana), + snapshotRestore(kibana), ]; }; diff --git a/x-pack/plugins/snapshot_restore/common/constants.ts b/x-pack/plugins/snapshot_restore/common/constants.ts new file mode 100644 index 0000000000000..2b27fea98ef28 --- /dev/null +++ b/x-pack/plugins/snapshot_restore/common/constants.ts @@ -0,0 +1,19 @@ +/* + * 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 { LICENSE_TYPE_BASIC, LicenseType } from '../../../common/constants'; + +const PLUGIN_NAME = 'Snapshot and Restore'; + +export const PLUGIN = { + ID: 'snapshot_restore', + MINIMUM_LICENSE_REQUIRED: LICENSE_TYPE_BASIC as LicenseType, + getI18nName: (translate: (key: string, config: object) => string): string => { + return translate('xpack.snapshotRestore.appName', { + defaultMessage: PLUGIN_NAME, + }); + }, +}; diff --git a/x-pack/plugins/snapshot_restore/index.ts b/x-pack/plugins/snapshot_restore/index.ts new file mode 100644 index 0000000000000..a3a5c9458e438 --- /dev/null +++ b/x-pack/plugins/snapshot_restore/index.ts @@ -0,0 +1,40 @@ +/* + * 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 { Legacy } from 'kibana'; +import { resolve } from 'path'; +import { PLUGIN } from './common/constants'; +import { Plugin as SnapshotRestorePlugin } from './plugin'; +import { createShim } from './shim'; + +export function snapshotRestore(kibana: any) { + return new kibana.Plugin({ + id: PLUGIN.ID, + configPrefix: 'xpack.snapshot_restore', + publicDir: resolve(__dirname, 'public'), + require: ['kibana', 'elasticsearch', 'xpack_main'], + uiExports: { + styleSheetPaths: resolve(__dirname, 'public/index.scss'), + managementSections: ['plugins/snapshot_restore'], + }, + init(server: Legacy.Server) { + const { core, plugins } = createShim(server, PLUGIN.ID); + const { i18n } = core; + const snapshotRestorePlugin = new SnapshotRestorePlugin(); + + // Start plugin + snapshotRestorePlugin.start(core, plugins); + + // Register license checker + plugins.license.registerLicenseChecker( + server, + PLUGIN.ID, + PLUGIN.getI18nName(i18n.translate), + PLUGIN.MINIMUM_LICENSE_REQUIRED + ); + }, + }); +} diff --git a/x-pack/plugins/snapshot_restore/plugin.ts b/x-pack/plugins/snapshot_restore/plugin.ts new file mode 100644 index 0000000000000..7668eb5cee9dd --- /dev/null +++ b/x-pack/plugins/snapshot_restore/plugin.ts @@ -0,0 +1,16 @@ +/* + * 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 { registerRoutes } from './server/routes/api/register_routes'; +import { Core, Plugins } from './shim'; + +export class Plugin { + public start(core: Core, plugins: Plugins): void { + const router = core.http.createRouter('/api/snapshot_restore/'); + + // Register routes + registerRoutes(router); + } +} diff --git a/x-pack/plugins/snapshot_restore/public/_snapshot_restore.scss b/x-pack/plugins/snapshot_restore/public/_snapshot_restore.scss new file mode 100644 index 0000000000000..3a8e55e66336c --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/_snapshot_restore.scss @@ -0,0 +1 @@ +/* Snapshot and restore plugin styles */ diff --git a/x-pack/plugins/snapshot_restore/public/app/app.tsx b/x-pack/plugins/snapshot_restore/public/app/app.tsx new file mode 100644 index 0000000000000..28c40d15be1d8 --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/app/app.tsx @@ -0,0 +1,28 @@ +/* + * 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 React, { Component } from 'react'; +import { Redirect, Route, Switch } from 'react-router-dom'; + +import { BASE_PATH } from './constants'; +import { AppContext } from './services/app_context'; + +import { SnapshotRestoreHome } from './sections'; + +export class App extends Component { + public static contextType = AppContext; + + public render() { + return ( +
+ + + + +
+ ); + } +} diff --git a/x-pack/plugins/snapshot_restore/public/app/constants/index.ts b/x-pack/plugins/snapshot_restore/public/app/constants/index.ts new file mode 100644 index 0000000000000..23c935b60a4b7 --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/app/constants/index.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export const BASE_PATH = '/management/elasticsearch/snapshot_restore'; diff --git a/x-pack/plugins/snapshot_restore/public/app/index.tsx b/x-pack/plugins/snapshot_restore/public/app/index.tsx new file mode 100644 index 0000000000000..a66d925cb9766 --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/app/index.tsx @@ -0,0 +1,40 @@ +/* + * 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 React from 'react'; +import { render } from 'react-dom'; +import { HashRouter } from 'react-router-dom'; + +import { AppCore, AppPlugins } from '../shim'; +import { App } from './app'; +import { AppContext, AppContextInterface } from './services/app_context'; + +export { BASE_PATH as CLIENT_BASE_PATH } from './constants'; + +export const renderReact = async ( + elem: Element, + core: AppCore, + plugins: AppPlugins +): Promise => { + const { + i18n: { Context: I18nContext }, + } = core; + + const appContext: AppContextInterface = { + core, + plugins, + }; + + render( + + + + + + + , + elem + ); +}; diff --git a/x-pack/plugins/snapshot_restore/public/app/sections/home/home.tsx b/x-pack/plugins/snapshot_restore/public/app/sections/home/home.tsx new file mode 100644 index 0000000000000..452b661a1caa1 --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/app/sections/home/home.tsx @@ -0,0 +1,138 @@ +/* + * 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 React, { PureComponent } from 'react'; +import { Route, RouteComponentProps, Switch } from 'react-router-dom'; + +import { EuiPageBody, EuiPageContent, EuiSpacer, EuiTab, EuiTabs, EuiTitle } from '@elastic/eui'; + +import { BASE_PATH } from '../../constants'; +import { AppContext, AppContextInterface } from '../../services/app_context'; + +import { RepositoryList } from './repository_list'; +import { SnapshotList } from './snapshot_list'; + +type Section = 'repositories' | 'snapshots'; + +interface MatchParams { + section: Section; +} + +interface Props extends RouteComponentProps {} + +interface State { + activeSection: Section; +} + +export class SnapshotRestoreHome extends PureComponent { + public static contextType = AppContext; + + public static getDerivedStateFromProps(nextProps: Props) { + const { + match: { + params: { section }, + }, + } = nextProps; + return { + activeSection: section, + }; + } + public context!: React.ContextType; + + public readonly state: Readonly = { + activeSection: 'repositories' as Section, + }; + + public componentDidMount() { + const { + core: { i18n, chrome }, + plugins: { management }, + } = this.context as AppContextInterface; + + chrome.breadcrumbs.set([ + management.constants.BREADCRUMB, + { + text: i18n.translate('xpack.snapshotRestore.home.BreadcrumbTitle', { + defaultMessage: 'Snapshot and Restore', + }), + href: `#${BASE_PATH}`, + }, + ]); + } + + public onSectionChange = (section: Section): void => { + const { history } = this.props; + history.push(`${BASE_PATH}/${section}`); + }; + + public render() { + const { + core: { + i18n: { FormattedMessage }, + }, + } = this.context as AppContextInterface; + + const tabs = [ + { + id: 'snapshots' as Section, + name: ( + + ), + testSubj: 'srSnapshotsTab', + }, + { + id: 'repositories' as Section, + name: ( + + ), + testSubj: 'srRepositoriesTab', + }, + ]; + + return ( + + + +

+ +

+
+ + + + + {tabs.map(tab => ( + this.onSectionChange(tab.id)} + isSelected={tab.id === this.state.activeSection} + key={tab.id} + data-test-subject={tab.testSubj} + > + {tab.name} + + ))} + + + + + + + + +
+
+ ); + } +} diff --git a/x-pack/plugins/snapshot_restore/public/app/sections/home/index.ts b/x-pack/plugins/snapshot_restore/public/app/sections/home/index.ts new file mode 100644 index 0000000000000..eef70309b49cf --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/app/sections/home/index.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export { SnapshotRestoreHome } from './home'; diff --git a/x-pack/plugins/snapshot_restore/public/app/sections/home/repository_list/index.ts b/x-pack/plugins/snapshot_restore/public/app/sections/home/repository_list/index.ts new file mode 100644 index 0000000000000..63d63db1d81cc --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/app/sections/home/repository_list/index.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export { RepositoryList } from './repository_list'; diff --git a/x-pack/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_list.tsx b/x-pack/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_list.tsx new file mode 100644 index 0000000000000..0d4bdd44d7cb0 --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/app/sections/home/repository_list/repository_list.tsx @@ -0,0 +1,18 @@ +/* + * 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 React, { PureComponent } from 'react'; + +import { AppContext } from '../../../services/app_context'; + +export class RepositoryList extends PureComponent { + public static contextType = AppContext; + public context!: React.ContextType; + + public render() { + return
List of repositories
; + } +} diff --git a/x-pack/plugins/snapshot_restore/public/app/sections/home/snapshot_list/index.ts b/x-pack/plugins/snapshot_restore/public/app/sections/home/snapshot_list/index.ts new file mode 100644 index 0000000000000..f7029f9693e0b --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/app/sections/home/snapshot_list/index.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export { SnapshotList } from './snapshot_list'; diff --git a/x-pack/plugins/snapshot_restore/public/app/sections/home/snapshot_list/snapshot_list.tsx b/x-pack/plugins/snapshot_restore/public/app/sections/home/snapshot_list/snapshot_list.tsx new file mode 100644 index 0000000000000..7281b9599d725 --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/app/sections/home/snapshot_list/snapshot_list.tsx @@ -0,0 +1,18 @@ +/* + * 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 React, { PureComponent } from 'react'; + +import { AppContext } from '../../../services/app_context'; + +export class SnapshotList extends PureComponent { + public static contextType = AppContext; + public context!: React.ContextType; + + public render() { + return
List of snapshots
; + } +} diff --git a/x-pack/plugins/snapshot_restore/public/app/sections/index.ts b/x-pack/plugins/snapshot_restore/public/app/sections/index.ts new file mode 100644 index 0000000000000..fdd85f572aa88 --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/app/sections/index.ts @@ -0,0 +1,9 @@ +/* + * 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. + */ + +export { SnapshotRestoreHome } from './home'; +// export { RepositoryAdd } from './repository_add'; +// export { RepositoryEdit } from './repository_edit'; diff --git a/x-pack/plugins/snapshot_restore/public/app/services/app_context.ts b/x-pack/plugins/snapshot_restore/public/app/services/app_context.ts new file mode 100644 index 0000000000000..7d31c2744ab8b --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/app/services/app_context.ts @@ -0,0 +1,15 @@ +/* + * 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 React from 'react'; +import { AppCore, AppPlugins } from '../../shim'; + +export interface AppContextInterface { + core: AppCore; + plugins: AppPlugins; +} + +export const AppContext = React.createContext(null); diff --git a/x-pack/plugins/snapshot_restore/public/index.html b/x-pack/plugins/snapshot_restore/public/index.html new file mode 100644 index 0000000000000..daa3283b7805d --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/index.html @@ -0,0 +1,3 @@ + +
+
diff --git a/x-pack/plugins/snapshot_restore/public/index.scss b/x-pack/plugins/snapshot_restore/public/index.scss new file mode 100644 index 0000000000000..f3354a4a29630 --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/index.scss @@ -0,0 +1,13 @@ +// Import the EUI global scope so we can use EUI constants +@import 'src/legacy/ui/public/styles/_styling_constants'; + +// Snapshot and restore plugin styles + +// Prefix all styles with "ssr" to avoid conflicts. +// Examples +// ssr +// ssr__legend +// ssr__legend--small +// ssr__legend-isLoading + +@import 'snapshot_restore'; diff --git a/x-pack/plugins/snapshot_restore/public/index.ts b/x-pack/plugins/snapshot_restore/public/index.ts new file mode 100644 index 0000000000000..b23ce6232c2d4 --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/index.ts @@ -0,0 +1,11 @@ +/* + * 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 { Plugin as SnapshotRestorePlugin } from './plugin'; +import { createShim } from './shim'; + +const { core, plugins } = createShim(); +const snapshotRestorePlugin = new SnapshotRestorePlugin(); +snapshotRestorePlugin.start(core, plugins); diff --git a/x-pack/plugins/snapshot_restore/public/plugin.ts b/x-pack/plugins/snapshot_restore/public/plugin.ts new file mode 100644 index 0000000000000..0b6bbc198485d --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/plugin.ts @@ -0,0 +1,88 @@ +/* + * 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 { unmountComponentAtNode } from 'react-dom'; + +import { PLUGIN } from '../common/constants'; +import { CLIENT_BASE_PATH, renderReact } from './app'; +import { AppCore, AppPlugins, Core, Plugins } from './shim'; + +import template from './index.html'; + +const REACT_ROOT_ID = 'snapshotRestoreReactRoot'; + +export class Plugin { + public start(core: Core, plugins: Plugins): void { + const { i18n, routing, http, chrome, notification } = core; + const { management } = plugins; + + // Register management section + const esSection = management.sections.getSection('elasticsearch'); + esSection.register(PLUGIN.ID, { + visible: true, + display: i18n.translate('xpack.snapshotRestore.appName', { + defaultMessage: 'Snapshot and Restore', + }), + order: 7, + url: `#${CLIENT_BASE_PATH}/repositories`, + }); + + const unmountReactApp = (elem: Element | undefined | null): void => { + if (elem) { + unmountComponentAtNode(elem); + } + }; + + // Register react root + routing.registerAngularRoute(`${CLIENT_BASE_PATH}/:section?/:subsection?/:view?/:id`, { + template, + controller: ($scope: any, $route: any, $http: ng.IHttpService, $q: any) => { + let elem: Element | null | undefined; + + // React-router's does not play well with the angular router. It will cause this controller + // to re-execute without the $destroy handler being called. This means that the app will be mounted twice + // creating a memory leak when leaving (only 1 app will be unmounted). + // To avoid this, we unmount the React app each time we enter the controller. + unmountReactApp(elem); + + // NOTE: We depend upon Angular's $http service because it's decorated with interceptors, + // e.g. to check license status per request. + http.setClient($http); + + $scope.$$postDigest(() => { + elem = document.getElementById(REACT_ROOT_ID); + if (elem) { + renderReact( + elem, + { i18n, chrome, notification } as AppCore, + { management } as AppPlugins + ); + } + + // Angular Lifecycle + const appRoute = $route.current; + const stopListeningForLocationChange = $scope.$on('$locationChangeSuccess', () => { + const currentRoute = $route.current; + const isNavigationInApp = currentRoute.$$route.template === appRoute.$$route.template; + + // When we navigate within SR, prevent Angular from re-matching the route and rebuild the app + if (isNavigationInApp) { + $route.current = appRoute; + } else { + // Any clean up when user leaves SR + } + + $scope.$on('$destroy', () => { + if (stopListeningForLocationChange) { + stopListeningForLocationChange(); + } + unmountReactApp(elem); + }); + }); + }); + }, + }); + } +} diff --git a/x-pack/plugins/snapshot_restore/public/shim.ts b/x-pack/plugins/snapshot_restore/public/shim.ts new file mode 100644 index 0000000000000..86de665c39bc9 --- /dev/null +++ b/x-pack/plugins/snapshot_restore/public/shim.ts @@ -0,0 +1,97 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { I18nContext } from 'ui/i18n'; + +import chrome from 'ui/chrome'; +import { management, MANAGEMENT_BREADCRUMB } from 'ui/management'; +import { fatalError } from 'ui/notify'; +import routes from 'ui/routes'; + +import { HashRouter } from 'react-router-dom'; + +export interface AppCore { + i18n: { + [i18nPackage: string]: any; + Context: typeof I18nContext; + FormattedMessage: typeof FormattedMessage; + }; + chrome: typeof chrome; + notification: { + fatalError: typeof fatalError; + }; +} + +export interface AppPlugins { + management: { + sections: typeof management; + constants: { + BREADCRUMB: typeof MANAGEMENT_BREADCRUMB; + }; + }; +} + +export interface Core extends AppCore { + routing: { + registerAngularRoute(path: string, config: object): void; + registerRouter(router: HashRouter): void; + getRouter(): HashRouter | undefined; + }; + http: { + setClient(client: any): void; + getClient(): any; + }; +} + +export interface Plugins extends AppPlugins {} // tslint:disable-line no-empty-interface + +export function createShim(): { core: Core; plugins: Plugins } { + // This is an Angular service, which is why we use this provider pattern + // to access it within our React app. + let httpClient: ng.IHttpService; + + let reactRouter: HashRouter | undefined; + + return { + core: { + i18n: { + ...i18n, + Context: I18nContext, + FormattedMessage, + }, + routing: { + registerAngularRoute: (path: string, config: object): void => { + routes.when(path, config); + }, + registerRouter: (router: HashRouter): void => { + reactRouter = router; + }, + getRouter: (): HashRouter | undefined => { + return reactRouter; + }, + }, + http: { + setClient: (client: any): void => { + httpClient = client; + }, + getClient: (): any => httpClient, + }, + chrome, + notification: { + fatalError, + }, + }, + plugins: { + management: { + sections: management, + constants: { + BREADCRUMB: MANAGEMENT_BREADCRUMB, + }, + }, + }, + }; +} diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/register_routes.ts b/x-pack/plugins/snapshot_restore/server/routes/api/register_routes.ts new file mode 100644 index 0000000000000..f67be9fb1f720 --- /dev/null +++ b/x-pack/plugins/snapshot_restore/server/routes/api/register_routes.ts @@ -0,0 +1,11 @@ +/* + * 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 { Router } from '../../../../../server/lib/create_router'; +import { registerRepositoriesRoutes } from './repositories'; + +export const registerRoutes = (router: Router): void => { + registerRepositoriesRoutes(router); +}; diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/repositories.ts b/x-pack/plugins/snapshot_restore/server/routes/api/repositories.ts new file mode 100644 index 0000000000000..ee1a260ecba4e --- /dev/null +++ b/x-pack/plugins/snapshot_restore/server/routes/api/repositories.ts @@ -0,0 +1,34 @@ +/* + * 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 { Router, RouterRouteHandler } from '../../../../../server/lib/create_router'; + +export function registerRepositoriesRoutes(router: Router) { + router.get('repositories', getAllHandler); + router.get('repositories/{name}', getOneHandler); +} + +const getAllHandler: RouterRouteHandler = async (req, callWithRequest) => { + const repositoriesByName = await callWithRequest('snapshot.getRepository', { + repository: '_all', + }); + const repositories = Object.keys(repositoriesByName).map(name => { + return { + name, + test: repositoriesByName[name], + }; + }); + return repositories; +}; + +const getOneHandler: RouterRouteHandler = async (req, callWithRequest) => { + const { name } = req.params; + const repositoryByName = await callWithRequest('snapshot.getRepository', { repository: name }); + if (repositoryByName[name]) { + return repositoryByName[name]; + } else { + return {}; + } +}; diff --git a/x-pack/plugins/snapshot_restore/shim.ts b/x-pack/plugins/snapshot_restore/shim.ts new file mode 100644 index 0000000000000..186da1a39d3d9 --- /dev/null +++ b/x-pack/plugins/snapshot_restore/shim.ts @@ -0,0 +1,44 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { Legacy } from 'kibana'; +import { createRouter, Router } from '../../server/lib/create_router'; +import { registerLicenseChecker } from '../../server/lib/register_license_checker'; + +export interface Core { + http: { + createRouter(basePath: string): Router; + }; + i18n: { + [i18nPackage: string]: any; + }; +} + +export interface Plugins { + license: { + registerLicenseChecker: typeof registerLicenseChecker; + }; +} + +export function createShim( + server: Legacy.Server, + pluginId: string +): { core: Core; plugins: Plugins } { + return { + core: { + http: { + createRouter: (basePath: string) => createRouter(server, pluginId, basePath), + }, + i18n, + }, + plugins: { + license: { + registerLicenseChecker, + }, + }, + }; +} diff --git a/x-pack/server/lib/create_router/call_with_request_factory/index.d.ts b/x-pack/server/lib/create_router/call_with_request_factory/index.d.ts new file mode 100644 index 0000000000000..fd767ffb89358 --- /dev/null +++ b/x-pack/server/lib/create_router/call_with_request_factory/index.d.ts @@ -0,0 +1,16 @@ +/* + * 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 { Request } from 'hapi'; +import { Legacy } from 'kibana'; +import { CallCluster } from 'src/legacy/core_plugins/elasticsearch'; + +export type CallWithRequest = (...args: any[]) => CallCluster; + +export declare function callWithRequestFactory( + server: Legacy.Server, + request: Request +): CallWithRequest; diff --git a/x-pack/server/lib/create_router/index.d.ts b/x-pack/server/lib/create_router/index.d.ts new file mode 100644 index 0000000000000..d73dd7fcc7ea1 --- /dev/null +++ b/x-pack/server/lib/create_router/index.d.ts @@ -0,0 +1,30 @@ +/* + * 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 { Request, ResponseToolkit } from 'hapi'; +import { Legacy } from 'kibana'; +import { CallWithRequest } from './call_with_request_factory'; + +export type RouterRouteHandler = ( + req: Request, + callWithRequest: ReturnType, + responseToolkit: ResponseToolkit +) => Promise; + +export type RouterRoute = (path: string, handler: RouterRouteHandler) => Router; + +export interface Router { + get: RouterRoute; + post: RouterRoute; + put: RouterRoute; + delete: RouterRoute; + patch: RouterRoute; +} + +export declare function createRouter( + server: Legacy.Server, + pluginId: string, + apiBasePath: string +): Router; diff --git a/x-pack/server/lib/register_license_checker/index.d.ts b/x-pack/server/lib/register_license_checker/index.d.ts new file mode 100644 index 0000000000000..555008921df42 --- /dev/null +++ b/x-pack/server/lib/register_license_checker/index.d.ts @@ -0,0 +1,15 @@ +/* + * 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 { Legacy } from 'kibana'; +import { LicenseType } from '../../../common/constants'; + +export declare function registerLicenseChecker( + server: Legacy.Server, + pluginId: string, + pluginName: string, + minimumLicenseRequired: LicenseType +): void;