diff --git a/docs/development/core/server/kibana-plugin-server.httpserverinfo.host.md b/docs/development/core/server/kibana-plugin-server.httpserverinfo.host.md new file mode 100644 index 00000000000000..ee7e1e5b7c9c94 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.httpserverinfo.host.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [HttpServerInfo](./kibana-plugin-server.httpserverinfo.md) > [host](./kibana-plugin-server.httpserverinfo.host.md) + +## HttpServerInfo.host property + +The hostname of the server + +Signature: + +```typescript +host: string; +``` diff --git a/docs/development/core/server/kibana-plugin-server.httpserverinfo.md b/docs/development/core/server/kibana-plugin-server.httpserverinfo.md new file mode 100644 index 00000000000000..6dbdb11ddb66ef --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.httpserverinfo.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [HttpServerInfo](./kibana-plugin-server.httpserverinfo.md) + +## HttpServerInfo interface + + +Signature: + +```typescript +export interface HttpServerInfo +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [host](./kibana-plugin-server.httpserverinfo.host.md) | string | The hostname of the server | +| [name](./kibana-plugin-server.httpserverinfo.name.md) | string | The name of the Kibana server | +| [port](./kibana-plugin-server.httpserverinfo.port.md) | number | The port the server is listening on | +| [protocol](./kibana-plugin-server.httpserverinfo.protocol.md) | 'http' | 'https' | 'socket' | The protocol used by the server | + diff --git a/docs/development/core/server/kibana-plugin-server.httpserverinfo.name.md b/docs/development/core/server/kibana-plugin-server.httpserverinfo.name.md new file mode 100644 index 00000000000000..8d3a45c90a3427 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.httpserverinfo.name.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [HttpServerInfo](./kibana-plugin-server.httpserverinfo.md) > [name](./kibana-plugin-server.httpserverinfo.name.md) + +## HttpServerInfo.name property + +The name of the Kibana server + +Signature: + +```typescript +name: string; +``` diff --git a/docs/development/core/server/kibana-plugin-server.httpserverinfo.port.md b/docs/development/core/server/kibana-plugin-server.httpserverinfo.port.md new file mode 100644 index 00000000000000..5dd5a53830c441 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.httpserverinfo.port.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [HttpServerInfo](./kibana-plugin-server.httpserverinfo.md) > [port](./kibana-plugin-server.httpserverinfo.port.md) + +## HttpServerInfo.port property + +The port the server is listening on + +Signature: + +```typescript +port: number; +``` diff --git a/docs/development/core/server/kibana-plugin-server.httpserverinfo.protocol.md b/docs/development/core/server/kibana-plugin-server.httpserverinfo.protocol.md new file mode 100644 index 00000000000000..08afb5c3f72133 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.httpserverinfo.protocol.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [HttpServerInfo](./kibana-plugin-server.httpserverinfo.md) > [protocol](./kibana-plugin-server.httpserverinfo.protocol.md) + +## HttpServerInfo.protocol property + +The protocol used by the server + +Signature: + +```typescript +protocol: 'http' | 'https' | 'socket'; +``` diff --git a/docs/development/core/server/kibana-plugin-server.httpservicesetup.getserverinfo.md b/docs/development/core/server/kibana-plugin-server.httpservicesetup.getserverinfo.md new file mode 100644 index 00000000000000..4501a7e26f75fa --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.httpservicesetup.getserverinfo.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [HttpServiceSetup](./kibana-plugin-server.httpservicesetup.md) > [getServerInfo](./kibana-plugin-server.httpservicesetup.getserverinfo.md) + +## HttpServiceSetup.getServerInfo property + +Provides common [information](./kibana-plugin-server.httpserverinfo.md) about the running http server. + +Signature: + +```typescript +getServerInfo: () => HttpServerInfo; +``` diff --git a/docs/development/core/server/kibana-plugin-server.httpservicesetup.md b/docs/development/core/server/kibana-plugin-server.httpservicesetup.md index 2a4b0e09977c1c..c2d53ec1eaf52e 100644 --- a/docs/development/core/server/kibana-plugin-server.httpservicesetup.md +++ b/docs/development/core/server/kibana-plugin-server.httpservicesetup.md @@ -86,6 +86,7 @@ async (context, request, response) => { | [createCookieSessionStorageFactory](./kibana-plugin-server.httpservicesetup.createcookiesessionstoragefactory.md) | <T>(cookieOptions: SessionStorageCookieOptions<T>) => Promise<SessionStorageFactory<T>> | Creates cookie based session storage factory [SessionStorageFactory](./kibana-plugin-server.sessionstoragefactory.md) | | [createRouter](./kibana-plugin-server.httpservicesetup.createrouter.md) | () => IRouter | Provides ability to declare a handler function for a particular path and HTTP request method. | | [csp](./kibana-plugin-server.httpservicesetup.csp.md) | ICspConfig | The CSP config used for Kibana. | +| [getServerInfo](./kibana-plugin-server.httpservicesetup.getserverinfo.md) | () => HttpServerInfo | Provides common [information](./kibana-plugin-server.httpserverinfo.md) about the running http server. | | [isTlsEnabled](./kibana-plugin-server.httpservicesetup.istlsenabled.md) | boolean | Flag showing whether a server was configured to use TLS connection. | | [registerAuth](./kibana-plugin-server.httpservicesetup.registerauth.md) | (handler: AuthenticationHandler) => void | To define custom authentication and/or authorization mechanism for incoming requests. | | [registerOnPostAuth](./kibana-plugin-server.httpservicesetup.registeronpostauth.md) | (handler: OnPostAuthHandler) => void | To define custom logic to perform for incoming requests. | diff --git a/docs/development/core/server/kibana-plugin-server.md b/docs/development/core/server/kibana-plugin-server.md index e7b13346525406..a3abeff44c25cb 100644 --- a/docs/development/core/server/kibana-plugin-server.md +++ b/docs/development/core/server/kibana-plugin-server.md @@ -64,6 +64,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ErrorHttpResponseOptions](./kibana-plugin-server.errorhttpresponseoptions.md) | HTTP response parameters | | [FakeRequest](./kibana-plugin-server.fakerequest.md) | Fake request object created manually by Kibana plugins. | | [HttpResponseOptions](./kibana-plugin-server.httpresponseoptions.md) | HTTP response parameters | +| [HttpServerInfo](./kibana-plugin-server.httpserverinfo.md) | | | [HttpServiceSetup](./kibana-plugin-server.httpservicesetup.md) | Kibana HTTP Service provides own abstraction for work with HTTP stack. Plugins don't have direct access to hapi server and its primitives anymore. Moreover, plugins shouldn't rely on the fact that HTTP Service uses one or another library under the hood. This gives the platform flexibility to upgrade or changing our internal HTTP stack without breaking plugins. If the HTTP Service lacks functionality you need, we are happy to discuss and support your needs. | | [HttpServiceStart](./kibana-plugin-server.httpservicestart.md) | | | [IContextContainer](./kibana-plugin-server.icontextcontainer.md) | An object that handles registration of context providers and configuring handlers with context. | diff --git a/src/core/server/http/http_server.test.ts b/src/core/server/http/http_server.test.ts index 60c5bdc44b3110..05ace06fa04e38 100644 --- a/src/core/server/http/http_server.test.ts +++ b/src/core/server/http/http_server.test.ts @@ -62,6 +62,7 @@ beforeAll(() => { beforeEach(() => { config = { + name: 'kibana', host: '127.0.0.1', maxPayload: new ByteSizeValue(1024), port: 10002, @@ -1077,4 +1078,37 @@ describe('setup contract', () => { expect(isTlsEnabled).toBe(false); }); }); + + describe('#getServerInfo', () => { + it('returns correct information', async () => { + let { getServerInfo } = await server.setup(config); + + expect(getServerInfo()).toEqual({ + host: '127.0.0.1', + name: 'kibana', + port: 10002, + protocol: 'http', + }); + + ({ getServerInfo } = await server.setup({ + ...config, + port: 12345, + name: 'custom-name', + host: 'localhost', + })); + + expect(getServerInfo()).toEqual({ + host: 'localhost', + name: 'custom-name', + port: 12345, + protocol: 'http', + }); + }); + + it('returns correct protocol when ssl is enabled', async () => { + const { getServerInfo } = await server.setup(configWithSSL); + + expect(getServerInfo().protocol).toEqual('https'); + }); + }); }); diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts index fdc272041ce354..025ab2bf56ac2d 100644 --- a/src/core/server/http/http_server.ts +++ b/src/core/server/http/http_server.ts @@ -35,7 +35,7 @@ import { import { IsAuthenticated, AuthStateStorage, GetAuthState } from './auth_state_storage'; import { AuthHeadersStorage, GetAuthHeaders } from './auth_headers_storage'; import { BasePath } from './base_path_service'; -import { HttpServiceSetup } from './types'; +import { HttpServiceSetup, HttpServerInfo } from './types'; /** @internal */ export interface HttpServerSetup { @@ -58,6 +58,7 @@ export interface HttpServerSetup { get: GetAuthState; isAuthenticated: IsAuthenticated; }; + getServerInfo: () => HttpServerInfo; } /** @internal */ @@ -122,6 +123,12 @@ export class HttpServer { isAuthenticated: this.authState.isAuthenticated, }, getAuthHeaders: this.authRequestHeaders.get, + getServerInfo: () => ({ + name: config.name, + host: config.host, + port: config.port, + protocol: this.server!.info.protocol, + }), isTlsEnabled: config.ssl.enabled, // Return server instance with the connection options so that we can properly // bridge core and the "legacy" Kibana internally. Once this bridge isn't diff --git a/src/core/server/http/http_service.mock.ts b/src/core/server/http/http_service.mock.ts index 2b2d98d937e859..30032ff5da7968 100644 --- a/src/core/server/http/http_service.mock.ts +++ b/src/core/server/http/http_service.mock.ts @@ -77,12 +77,19 @@ const createSetupContractMock = () => { auth: createAuthMock(), getAuthHeaders: jest.fn(), isTlsEnabled: false, + getServerInfo: jest.fn(), }; setupContract.createCookieSessionStorageFactory.mockResolvedValue( sessionStorageMock.createFactory() ); setupContract.createRouter.mockImplementation(() => mockRouter.create()); setupContract.getAuthHeaders.mockReturnValue({ authorization: 'authorization-header' }); + setupContract.getServerInfo.mockReturnValue({ + host: 'localhost', + name: 'kibana', + port: 80, + protocol: 'http', + }); return setupContract; }; diff --git a/src/core/server/http/types.ts b/src/core/server/http/types.ts index 01b852c26ec934..63278441080556 100644 --- a/src/core/server/http/types.ts +++ b/src/core/server/http/types.ts @@ -252,6 +252,11 @@ export interface HttpServiceSetup { contextName: T, provider: RequestHandlerContextProvider ) => RequestHandlerContextContainer; + + /** + * Provides common {@link HttpServerInfo | information} about the running http server. + */ + getServerInfo: () => HttpServerInfo; } /** @internal */ @@ -273,3 +278,15 @@ export interface HttpServiceStart { /** Indicates if http server is listening on a given port */ isListening: (port: number) => boolean; } + +/** @public */ +export interface HttpServerInfo { + /** The name of the Kibana server */ + name: string; + /** The hostname of the server */ + host: string; + /** The port the server is listening on */ + port: number; + /** The protocol used by the server */ + protocol: 'http' | 'https' | 'socket'; +} diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 91f38c9f2ddbe9..c45acd7f0129a1 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -103,6 +103,7 @@ export { GetAuthState, HttpResponseOptions, HttpResponsePayload, + HttpServerInfo, HttpServiceSetup, HttpServiceStart, ErrorHttpResponseOptions, diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts index d0e0453564f943..f9b18afadc9382 100644 --- a/src/core/server/legacy/legacy_service.ts +++ b/src/core/server/legacy/legacy_service.ts @@ -292,6 +292,7 @@ export class LegacyService implements CoreService { }, csp: setupDeps.core.http.csp, isTlsEnabled: setupDeps.core.http.isTlsEnabled, + getServerInfo: setupDeps.core.http.getServerInfo, }, savedObjects: { setClientFactoryProvider: setupDeps.core.savedObjects.setClientFactoryProvider, diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts index 50ce507520d048..7405638a86ef58 100644 --- a/src/core/server/mocks.ts +++ b/src/core/server/mocks.ts @@ -105,6 +105,7 @@ function createCoreSetupMock() { get: httpService.auth.get, isAuthenticated: httpService.auth.isAuthenticated, }, + getServerInfo: httpService.getServerInfo, }; httpMock.createRouter.mockImplementation(() => httpService.createRouter('')); diff --git a/src/core/server/plugins/plugin_context.ts b/src/core/server/plugins/plugin_context.ts index 30e5209b2fc6a1..77300900e84f33 100644 --- a/src/core/server/plugins/plugin_context.ts +++ b/src/core/server/plugins/plugin_context.ts @@ -164,6 +164,7 @@ export function createPluginSetupContext( auth: { get: deps.http.auth.get, isAuthenticated: deps.http.auth.isAuthenticated }, csp: deps.http.csp, isTlsEnabled: deps.http.isTlsEnabled, + getServerInfo: deps.http.getServerInfo, }, savedObjects: { setClientFactoryProvider: deps.savedObjects.setClientFactoryProvider, diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index e4ea06769007a1..f017eec5c5ec3a 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -736,6 +736,14 @@ export interface HttpResponseOptions { // @public export type HttpResponsePayload = undefined | string | Record | Buffer | Stream; +// @public (undocumented) +export interface HttpServerInfo { + host: string; + name: string; + port: number; + protocol: 'http' | 'https' | 'socket'; +} + // @public export interface HttpServiceSetup { // (undocumented) @@ -747,6 +755,7 @@ export interface HttpServiceSetup { createCookieSessionStorageFactory: (cookieOptions: SessionStorageCookieOptions) => Promise>; createRouter: () => IRouter; csp: ICspConfig; + getServerInfo: () => HttpServerInfo; isTlsEnabled: boolean; registerAuth: (handler: AuthenticationHandler) => void; registerOnPostAuth: (handler: OnPostAuthHandler) => void;