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;