Skip to content

Commit

Permalink
Merge branch 'main' into implement/v2-test-group-api
Browse files Browse the repository at this point in the history
  • Loading branch information
Spencer authored Apr 26, 2022
2 parents 11778e9 + d371f3a commit 4a3d0b3
Show file tree
Hide file tree
Showing 91 changed files with 2,636 additions and 1,195 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import Path from 'path';

import { run } from '@kbn/dev-utils';
import { REPO_ROOT } from '@kbn/utils';

import { OptimizerConfig } from '../optimizer';
import { parseStats, inAnyEntryChunk } from './parse_stats';

export async function runFindNodeLibsBrowserPolyfillsInEntryBundlesCli() {
run(async ({ log }) => {
const config = OptimizerConfig.create({
includeCoreBundle: true,
repoRoot: REPO_ROOT,
});

const paths = config.bundles.map((b) => Path.resolve(b.outputDir, 'stats.json'));

log.info('analyzing', paths.length, 'stats files');
log.verbose(paths);

const imports = new Set();
for (const path of paths) {
const stats = parseStats(path);

for (const module of stats.modules) {
if (!inAnyEntryChunk(stats, module)) {
continue;
}

// Relying on module name instead of actual imports because these are usual polyfills that assume the global
// Node.js environment when development (i.e.: Buffer doesn't require an import to be used).
if (module.name.includes('node-libs-browser/node_modules/')) {
imports.add(module.name);
}
}
}

log.success('found', imports.size, 'node-libs-browser/* imports in entry bundles');
log.write(
Array.from(imports, (i) => `'${i}',`)
.sort()
.join('\n')
);
});
}
1 change: 1 addition & 0 deletions packages/kbn-optimizer/src/babel_runtime_helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
*/

export * from './find_babel_runtime_helpers_in_entry_bundles';
export * from './find_node_libs_browser_polyfills_in_entry_bundles';
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const partialObject = <P extends Props>(props: P) => {
export type Module = TypeOf<typeof moduleSchema>;
const moduleSchema = partialObject({
identifier: schema.string(),
name: schema.string(),
chunks: schema.arrayOf(schema.oneOf([schema.string(), schema.number()])),
reasons: schema.arrayOf(
partialObject({
Expand Down
4 changes: 4 additions & 0 deletions packages/kbn-ui-shared-deps-npm/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ module.exports = (_, argv) => {
'regenerator-runtime/runtime',
'whatwg-fetch',
'symbol-observable',
// Parts of node-libs-browser that are used in many places across Kibana
'buffer',
'punycode',
'util',

/**
* babel runtime helpers referenced from entry chunks
Expand Down
10 changes: 10 additions & 0 deletions scripts/find_node_libs_browser_polyfills_in_use.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

require('../src/setup_node_env/no_transpilation');
require('@kbn/optimizer').runFindNodeLibsBrowserPolyfillsInEntryBundlesCli();
15 changes: 15 additions & 0 deletions test/functional/page_objects/home_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,21 @@ export class HomePageObject extends FtrService {
await this.find.clickByLinkText('Map');
}

async launchSampleLogs(id: string) {
await this.launchSampleDataSet(id);
await this.find.clickByLinkText('Logs');
}

async launchSampleGraph(id: string) {
await this.launchSampleDataSet(id);
await this.find.clickByLinkText('Graph');
}

async launchSampleML(id: string) {
await this.launchSampleDataSet(id);
await this.find.clickByLinkText('ML jobs');
}

async launchSampleDataSet(id: string) {
await this.addSampleDataSet(id);
await this.common.closeToastIfExists();
Expand Down
4 changes: 2 additions & 2 deletions x-pack/plugins/fleet/.storybook/context/cloud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export const getCloud = ({ isCloudEnabled }: { isCloudEnabled: boolean }) => {
const cloud: CloudSetup = {
isCloudEnabled,
baseUrl: 'https://base.url',
cloudId: 'cloud-id',
cloudId: isCloudEnabled ? 'cloud-id' : undefined,
cname: 'found.io',
deploymentUrl: 'https://deployment.url',
deploymentUrl: isCloudEnabled ? 'https://deployment.url' : undefined,
organizationUrl: 'https://organization.url',
profileUrl: 'https://profile.url',
snapshotsUrl: 'https://snapshots.url',
Expand Down
56 changes: 53 additions & 3 deletions x-pack/plugins/fleet/.storybook/context/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ export const getHttp = (basepath = BASE_PATH) => {
serverBasePath: basepath,
},
get: (async (path: string, options: HttpFetchOptions) => {
action('get')(path, options);
action('get')(path, JSON.stringify(options));
// TODO: all of this needs revision, as it's far too clunky... but it works for now,
// with the few paths we're supporting.
if (path === '/api/fleet/agents/setup') {
if (!isReady) {
isReady = true;
return { isReady: false, missing_requirements: ['api_keys', 'fleet_server'] };
}
return { isInitialized: true, nonFatalErrors: [] };
return { isReady: true, isInitialized: true, nonFatalErrors: [], missing_requirements: [] };
}

if (path === '/api/fleet/epm/categories') {
Expand Down Expand Up @@ -79,9 +79,59 @@ export const getHttp = (basepath = BASE_PATH) => {
return { success: true };
}

action(path)('KP: UNSUPPORTED ROUTE');
if (path.match('/api/fleet/agent_policies')) {
return { items: [] };
}

if (path.match('/api/fleet/settings')) {
return { item: { fleet_server_hosts: [] } };
}

if (path.match('/api/fleet/outputs')) {
return {
items: [{ name: 'Default Output', is_default: true, hosts: ['https://test.es:9200'] }],
};
}

action(path)(`UNSUPPORTED ROUTE: GET ${path}`);
return {};
}) as HttpHandler,
post: (async (path: string, options: HttpFetchOptions) => {
action('post')(path, JSON.stringify(options));

if (path.match('/api/fleet/settings')) {
return { items: [] };
}

if (path.match('/api/fleet/service_tokens')) {
return {
name: 'test-token',
value: 'test-token-value',
};
}

if (path.match('/api/fleet/agent_policies')) {
return {
item: {
id: 'test-policy',
name: 'Test Policy',
namespace: 'default',
description: 'Test Policy',
monitoring_enabled: ['metrics'],
data_output_id: 'test-output',
monitoring_output_id: 'test-output',
status: 'active',
packagePolicies: ['test-package-policy'],
updated_on: new Date(),
updated_by: 'elastic',
revision: 0,
agents: 0,
},
};
}

action(path)(`UNSUPPORTED ROUTE: POST ${path}`);
}) as HttpHandler,
} as unknown as HttpStart;

return http;
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/fleet/.storybook/context/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const StorybookContext: React.FC<{ storyContext?: StoryContext }> = ({
chrome: getChrome(),
cloud: {
...getCloud({ isCloudEnabled }),
CloudContextProvider: () => <></>,
CloudContextProvider: ({ children }) => <>{children}</>,
},
customIntegrations: {
ContextProvider: getStorybookContextProvider(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,20 @@ describe('Edit settings', () => {

it('should update Fleet server hosts', () => {
cy.getBySel('editHostsBtn').click();
cy.get('[placeholder="Specify host URL"').type('http://localhost:8220');
cy.get('[placeholder="Specify host URL"').type('https://localhost:8220');

cy.intercept('/api/fleet/settings', {
item: { id: 'fleet-default-settings', fleet_server_hosts: ['http://localhost:8220'] },
item: { id: 'fleet-default-settings', fleet_server_hosts: ['https://localhost:8220'] },
});
cy.intercept('PUT', '/api/fleet/settings', {
fleet_server_hosts: ['http://localhost:8220'],
fleet_server_hosts: ['https://localhost:8220'],
}).as('updateSettings');

cy.getBySel('saveApplySettingsBtn').click();
cy.getBySel(CONFIRM_MODAL_BTN).click();

cy.wait('@updateSettings').then((interception) => {
expect(interception.request.body.fleet_server_hosts[0]).to.equal('http://localhost:8220');
expect(interception.request.body.fleet_server_hosts[0]).to.equal('https://localhost:8220');
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,15 @@ describe('Fleet startup', () => {
});

it('should create Fleet Server policy', () => {
cy.getBySel('fleetServerFlyoutTab-advanced').click();
cy.getBySel('createFleetServerPolicyBtn').click();

// verify policy is created and has fleet server and system package
verifyPolicy('Fleet Server policy 1', ['Fleet Server', 'System']);

navigateToTab(AGENTS_TAB);
cy.getBySel('fleetServerFlyoutTab-advanced').click();

// verify create button changed to dropdown
cy.getBySel('agentPolicyDropdown');

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { EuiSteps } from '@elastic/eui';
import React from 'react';

import { useAdvancedForm } from './hooks';

import {
getAddFleetServerHostStep,
getSelectAgentPolicyStep,
getGenerateServiceTokenStep,
getSetDeploymentModeStep,
getInstallFleetServerStep,
getConfirmFleetServerConnectionStep,
} from './steps';

export const AdvancedTab: React.FunctionComponent = () => {
const {
eligibleFleetServerPolicies,
refreshEligibleFleetServerPolicies,
fleetServerPolicyId,
setFleetServerPolicyId,
isFleetServerReady,
serviceToken,
isLoadingServiceToken,
generateServiceToken,
fleetServerHostForm,
deploymentMode,
setDeploymentMode,
} = useAdvancedForm();

const steps = [
getSelectAgentPolicyStep({
policyId: fleetServerPolicyId,
setPolicyId: setFleetServerPolicyId,
eligibleFleetServerPolicies,
refreshEligibleFleetServerPolicies,
}),
getSetDeploymentModeStep({
deploymentMode,
setDeploymentMode,
disabled: !Boolean(fleetServerPolicyId),
}),
getAddFleetServerHostStep({ fleetServerHostForm, disabled: !Boolean(fleetServerPolicyId) }),
getGenerateServiceTokenStep({
serviceToken,
generateServiceToken,
isLoadingServiceToken,
disabled: !Boolean(fleetServerHostForm.isFleetServerHostSubmitted),
}),
getInstallFleetServerStep({
isFleetServerReady,
serviceToken,
fleetServerHost: fleetServerHostForm.fleetServerHost,
fleetServerPolicyId,
disabled: !Boolean(serviceToken),
}),
getConfirmFleetServerConnectionStep({ isFleetServerReady, disabled: !Boolean(serviceToken) }),
];

return <EuiSteps steps={steps} className="eui-textLeft" />;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { useState } from 'react';
import type { EuiComboBoxOptionOption } from '@elastic/eui';
import { EuiComboBox, EuiText } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';

interface Props {
fleetServerHost: string | undefined;
fleetServerHostSettings: string[];
isDisabled: boolean;
isInvalid: boolean;
onFleetServerHostChange: (host: string) => void;
}

export const FleetServerHostComboBox: React.FunctionComponent<Props> = ({
fleetServerHost,
fleetServerHostSettings,
isDisabled = false,
isInvalid = false,
onFleetServerHostChange,
}) => {
// Track options that are created inline
const [createdOptions, setCreatedOptions] = useState<string[]>([]);

const options = [...createdOptions, ...fleetServerHostSettings].map((option) => ({
label: option,
value: option,
}));

const handleChange = (selectedOptions: Array<EuiComboBoxOptionOption<string>>) => {
const host = selectedOptions[0].value ?? '';
onFleetServerHostChange(host);
};

const handleCreateOption = (option: string) => {
setCreatedOptions([...createdOptions, option]);
onFleetServerHostChange(option);
};

return (
<EuiComboBox<string>
fullWidth
isClearable={false}
singleSelection={{ asPlainText: true }}
placeholder="https://fleet-server-host.com:8220"
options={options}
customOptionText={i18n.translate(
'xpack.fleet.fleetServerSetup.addFleetServerHostCustomOptionText',
{
defaultMessage: 'Add {searchValuePlaceholder} as a new Fleet Server host',
values: { searchValuePlaceholder: '{searchValue}' },
}
)}
selectedOptions={fleetServerHost ? [{ label: fleetServerHost, value: fleetServerHost }] : []}
prepend={
<EuiText>
<FormattedMessage
id="xpack.fleet.fleetServerSetup.addFleetServerHostInputLabel"
defaultMessage="Fleet Server host"
/>
</EuiText>
}
noSuggestions={fleetServerHostSettings.length === 0}
data-test-subj="fleetServerHostInput"
isDisabled={isDisabled}
isInvalid={isInvalid}
onChange={handleChange}
onCreateOption={handleCreateOption}
/>
);
};
Loading

0 comments on commit 4a3d0b3

Please sign in to comment.