-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
[Ingest Manager] Do not await setupIngestManager
in plugin start
#68631
Changes from all commits
1d570a5
8193418
6393d81
9b4af9c
9b66d22
f43f654
bde0cb9
f1c5902
d4ff7b1
b4b0691
c1edd6a
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 |
---|---|---|
|
@@ -28,7 +28,7 @@ export type IngestManagerSetup = void; | |
*/ | ||
export interface IngestManagerStart { | ||
registerDatasource: typeof registerDatasource; | ||
success: boolean; | ||
success?: boolean; | ||
error?: { | ||
message: string; | ||
}; | ||
|
@@ -81,8 +81,8 @@ export class IngestManagerPlugin | |
try { | ||
const permissionsResponse = await core.http.get(appRoutesService.getCheckPermissionsPath()); | ||
if (permissionsResponse.success) { | ||
const { isInitialized: success } = await core.http.post(setupRouteService.getSetupPath()); | ||
return { success, registerDatasource }; | ||
core.http.post(setupRouteService.getSetupPath()); | ||
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. Make the POST to setup to kick off the side-effects, but don't hold up kibana |
||
return { registerDatasource }; | ||
} else { | ||
throw new Error(permissionsResponse.error); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,8 @@ import { | |
removeInstallation, | ||
} from '../../services/epm/packages'; | ||
|
||
import { appContextService } from '../../services'; | ||
|
||
export const getCategoriesHandler: RequestHandler = async (context, request, response) => { | ||
try { | ||
const res = await getCategories(); | ||
|
@@ -125,6 +127,20 @@ export const installPackageHandler: RequestHandler<TypeOf< | |
const { pkgkey } = request.params; | ||
const savedObjectsClient = context.core.savedObjects.client; | ||
const callCluster = context.core.elasticsearch.legacy.client.callAsCurrentUser; | ||
|
||
if (appContextService.getIsInitialized()?.status === 'not_started') { | ||
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. An example of an option for a handler or service. It can check the initialization status and decide how to proceed. It could do any combination of return nothing, return an error, log the issue, |
||
return response.customError({ | ||
statusCode: 503, | ||
body: 'Ingest Manager is not initialized', | ||
}); | ||
} | ||
|
||
if (appContextService.getIsInitialized()?.status === 'error') { | ||
return response.customError({ | ||
statusCode: 500, | ||
body: 'There was an error setting up Ingest Manager', | ||
}); | ||
} | ||
const res = await installPackage({ | ||
savedObjectsClient, | ||
pkgkey, | ||
|
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -78,6 +78,7 @@ export const ingestManagerSetupHandler: RequestHandler = async (context, request | |||
const logger = appContextService.getLogger(); | ||||
try { | ||||
await setupIngestManager(soClient, callCluster); | ||||
|
||||
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.
Suggested change
|
||||
return response.ok({ | ||||
body: { isInitialized: true }, | ||||
}); | ||||
|
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -12,6 +12,10 @@ import { IngestManagerConfigType } from '../../common'; | |||||||||
import { IngestManagerAppContext } from '../plugin'; | ||||||||||
import { CloudSetup } from '../../../cloud/server'; | ||||||||||
|
||||||||||
interface InitializationState { | ||||||||||
status: 'not_started' | 'success' | 'error'; | ||||||||||
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. Just an example. Could expand to include |
||||||||||
error?: Error; | ||||||||||
} | ||||||||||
class AppContextService { | ||||||||||
private encryptedSavedObjects: EncryptedSavedObjectsClient | undefined; | ||||||||||
private security: SecurityPluginSetup | undefined; | ||||||||||
|
@@ -23,6 +27,7 @@ class AppContextService { | |||||||||
private cloud?: CloudSetup; | ||||||||||
private logger: Logger | undefined; | ||||||||||
private httpSetup?: HttpServiceSetup; | ||||||||||
private initializationState?: InitializationState; | ||||||||||
|
||||||||||
public async start(appContext: IngestManagerAppContext) { | ||||||||||
this.encryptedSavedObjects = appContext.encryptedSavedObjects?.getClient(); | ||||||||||
|
@@ -33,6 +38,7 @@ class AppContextService { | |||||||||
this.logger = appContext.logger; | ||||||||||
this.kibanaVersion = appContext.kibanaVersion; | ||||||||||
this.httpSetup = appContext.httpSetup; | ||||||||||
this.initializationState = { status: 'not_started' }; | ||||||||||
|
||||||||||
if (appContext.config$) { | ||||||||||
this.config$ = appContext.config$; | ||||||||||
|
@@ -84,6 +90,14 @@ class AppContextService { | |||||||||
return this.savedObjects; | ||||||||||
} | ||||||||||
|
||||||||||
public getIsInitialized() { | ||||||||||
return this.initializationState; | ||||||||||
} | ||||||||||
|
||||||||||
public setIsInitialized(vals: InitializationState) { | ||||||||||
this.initializationState = vals; | ||||||||||
Comment on lines
+97
to
+98
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.
Suggested change
|
||||||||||
} | ||||||||||
|
||||||||||
public getIsProductionMode() { | ||||||||||
return this.isProductionMode; | ||||||||||
} | ||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,67 +34,74 @@ export async function setupIngestManager( | |
soClient: SavedObjectsClientContract, | ||
callCluster: CallESAsCurrentUser | ||
) { | ||
const [installedPackages, defaultOutput, config] = await Promise.all([ | ||
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. This is just moving the function body inside a try/catch |
||
// packages installed by default | ||
ensureInstalledDefaultPackages(soClient, callCluster), | ||
outputService.ensureDefaultOutput(soClient), | ||
agentConfigService.ensureDefaultAgentConfig(soClient), | ||
ensureDefaultIndices(callCluster), | ||
settingsService.getSettings(soClient).catch((e: any) => { | ||
if (e.isBoom && e.output.statusCode === 404) { | ||
const http = appContextService.getHttpSetup(); | ||
const serverInfo = http.getServerInfo(); | ||
const basePath = http.basePath; | ||
|
||
const cloud = appContextService.getCloud(); | ||
const cloudId = cloud?.isCloudEnabled && cloud.cloudId; | ||
const cloudUrl = cloudId && decodeCloudId(cloudId)?.kibanaUrl; | ||
const flagsUrl = appContextService.getConfig()?.fleet?.kibana?.host; | ||
const defaultUrl = url.format({ | ||
protocol: serverInfo.protocol, | ||
hostname: serverInfo.host, | ||
port: serverInfo.port, | ||
pathname: basePath.serverBasePath, | ||
}); | ||
|
||
return settingsService.saveSettings(soClient, { | ||
agent_auto_upgrade: true, | ||
package_auto_upgrade: true, | ||
kibana_url: cloudUrl || flagsUrl || defaultUrl, | ||
}); | ||
} | ||
|
||
return Promise.reject(e); | ||
}), | ||
]); | ||
|
||
// ensure default packages are added to the default conifg | ||
const configWithDatasource = await agentConfigService.get(soClient, config.id, true); | ||
if (!configWithDatasource) { | ||
throw new Error('Config not found'); | ||
} | ||
if ( | ||
configWithDatasource.datasources.length && | ||
typeof configWithDatasource.datasources[0] === 'string' | ||
) { | ||
throw new Error('Config not found'); | ||
} | ||
for (const installedPackage of installedPackages) { | ||
const packageShouldBeInstalled = DEFAULT_AGENT_CONFIGS_PACKAGES.some( | ||
(packageName) => installedPackage.name === packageName | ||
); | ||
if (!packageShouldBeInstalled) { | ||
continue; | ||
try { | ||
const [installedPackages, defaultOutput, config] = await Promise.all([ | ||
// packages installed by default | ||
ensureInstalledDefaultPackages(soClient, callCluster), | ||
outputService.ensureDefaultOutput(soClient), | ||
agentConfigService.ensureDefaultAgentConfig(soClient), | ||
ensureDefaultIndices(callCluster), | ||
settingsService.getSettings(soClient).catch((e: any) => { | ||
if (e.isBoom && e.output.statusCode === 404) { | ||
const http = appContextService.getHttpSetup(); | ||
const serverInfo = http.getServerInfo(); | ||
const basePath = http.basePath; | ||
|
||
const cloud = appContextService.getCloud(); | ||
const cloudId = cloud?.isCloudEnabled && cloud.cloudId; | ||
const cloudUrl = cloudId && decodeCloudId(cloudId)?.kibanaUrl; | ||
const flagsUrl = appContextService.getConfig()?.fleet?.kibana?.host; | ||
const defaultUrl = url.format({ | ||
protocol: serverInfo.protocol, | ||
hostname: serverInfo.host, | ||
port: serverInfo.port, | ||
pathname: basePath.serverBasePath, | ||
}); | ||
|
||
return settingsService.saveSettings(soClient, { | ||
agent_auto_upgrade: true, | ||
package_auto_upgrade: true, | ||
kibana_url: cloudUrl || flagsUrl || defaultUrl, | ||
}); | ||
} | ||
|
||
return Promise.reject(e); | ||
}), | ||
]); | ||
|
||
// ensure default packages are added to the default conifg | ||
const configWithDatasource = await agentConfigService.get(soClient, config.id, true); | ||
if (!configWithDatasource) { | ||
throw new Error('Config not found'); | ||
} | ||
if ( | ||
configWithDatasource.datasources.length && | ||
typeof configWithDatasource.datasources[0] === 'string' | ||
) { | ||
throw new Error('Config not found'); | ||
} | ||
for (const installedPackage of installedPackages) { | ||
const packageShouldBeInstalled = DEFAULT_AGENT_CONFIGS_PACKAGES.some( | ||
(packageName) => installedPackage.name === packageName | ||
); | ||
if (!packageShouldBeInstalled) { | ||
continue; | ||
} | ||
|
||
const isInstalled = configWithDatasource.datasources.some((d: Datasource | string) => { | ||
return typeof d !== 'string' && d.package?.name === installedPackage.name; | ||
}); | ||
const isInstalled = configWithDatasource.datasources.some((d: Datasource | string) => { | ||
return typeof d !== 'string' && d.package?.name === installedPackage.name; | ||
}); | ||
|
||
if (!isInstalled) { | ||
await addPackageToConfig(soClient, installedPackage, configWithDatasource, defaultOutput); | ||
if (!isInstalled) { | ||
await addPackageToConfig(soClient, installedPackage, configWithDatasource, defaultOutput); | ||
} | ||
} | ||
} catch (e) { | ||
appContextService.setIsInitialized({ status: 'error', error: e }); | ||
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. Something in |
||
} | ||
|
||
appContextService.setIsInitialized({ status: 'success' }); | ||
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. Happy path |
||
return; | ||
} | ||
|
||
export async function setupFleet( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -60,6 +60,7 @@ export class IngestIndexPatternRetriever implements IndexPatternRetriever { | |
try { | ||
const pattern = await this.service.getESIndexPattern( | ||
ctx.core.savedObjects.client, | ||
ctx.core.elasticsearch.legacy.client.callAsCurrentUser, | ||
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. |
||
IngestIndexPatternRetriever.endpointPackageName, | ||
datasetPath | ||
); | ||
|
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.
Is more accurate for what's happening here.
start
will not returnsuccess: true