Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into fix-transform-clo…
Browse files Browse the repository at this point in the history
…ne-fields
  • Loading branch information
qn895 committed Oct 1, 2020
2 parents 5e1323b + 5aa3fb5 commit 896f7f3
Show file tree
Hide file tree
Showing 64 changed files with 474 additions and 230 deletions.
12 changes: 12 additions & 0 deletions packages/kbn-config/src/env.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,18 @@ test('pluginSearchPaths contains x-pack/examples plugins path if --run-examples
expect(env.pluginSearchPaths).toContain('/some/home/dir/x-pack/examples');
});

test('pluginSearchPaths does not contain x-pack/examples plugins path if --oss flag is true', () => {
const env = new Env(
'/some/home/dir',
packageInfos,
getEnvOptions({
cliArgs: { runExamples: true, oss: true },
})
);

expect(env.pluginSearchPaths).not.toContain('/some/home/dir/x-pack/examples');
});

test('pluginSearchPaths does not contains examples plugins path if --run-examples flag is false', () => {
const env = new Env(
'/some/home/dir',
Expand Down
5 changes: 3 additions & 2 deletions packages/kbn-config/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,9 @@ export class Env {
resolve(this.homeDir, 'src', 'plugins'),
...(options.cliArgs.oss ? [] : [resolve(this.homeDir, 'x-pack', 'plugins')]),
resolve(this.homeDir, 'plugins'),
...(options.cliArgs.runExamples
? [resolve(this.homeDir, 'examples'), resolve(this.homeDir, 'x-pack', 'examples')]
...(options.cliArgs.runExamples ? [resolve(this.homeDir, 'examples')] : []),
...(options.cliArgs.runExamples && !options.cliArgs.oss
? [resolve(this.homeDir, 'x-pack', 'examples')]
: []),
resolve(this.homeDir, '..', 'kibana-extra'),
];
Expand Down
43 changes: 38 additions & 5 deletions src/dev/code_coverage/docs/team_assignment/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,41 @@
# Team Assignment Ingestion Pipeline
# Code Coverage Team Assignments

Team assignment will occur once per ci run.
Team assignment uses an ingest pipeline.
Team assignment occurs once per ci run.

The coverage user has the coverage admin role.
The "orchestration" entry point is a [Jenkinsfile Scripted Pipeline](https://github.com/elastic/kibana/blob/f73bc48b3bbbb5ad2042c1aa267aea2150b7b742/.ci/Jenkinsfile_coverage#L21)
This Jenkinsfile runs a [shell script](https://github.com/elastic/kibana/blob/master/src/dev/code_coverage/shell_scripts/generate_team_assignments_and_ingest_coverage.sh#L33) that kicks everything off.
The end result is the data is ingested to our [Kibana Stats Cluster](https://kibana-stats.elastic.dev/app/dashboards#/view/58b8db70-62f9-11ea-8312-7f2d69b79843?_g=(filters%3A!()%2CrefreshInterval%3A(pause%3A!t%2Cvalue%3A0)%2Ctime%3A(from%3Anow-7d%2Cto%3Anow)))

This role must have the rights depicted below ![Cluster Rights](./security_privleges.png)
## Team Assignment Parsing (from .github/CODEOWNERS)
We add additional metadata to the CODEOWNERS file.
This metadata allows users to assign teams to paths, in a friendly location.
Example CODEOWNERS Block:
_notice the coverage delimiter `#CC# ...`_
```
/x-pack/test/functional/es_archives/endpoint/ @elastic/endpoint-app-team @elastic/siem
/x-pack/test/plugin_functional/plugins/resolver_test/ @elastic/endpoint-app-team @elastic/siem
/x-pack/test/plugin_functional/test_suites/resolver/ @elastic/endpoint-app-team @elastic/siem
#CC# /x-pack/legacy/plugins/siem/ @elastic/siem
#CC# /x-pack/plugins/siem/ @elastic/siem
#CC# /x-pack/plugins/security_solution/ @elastic/siem
```
The first 3 lines above fill the usual purpose of the CODEOWNERS file and cause PRs modifying files in these paths to require approval by the listed team(s).
They also attribute files in those paths for purpose of code coverage reporting.
The last 3 lines above ONLY attribute files in those paths for purpose of code coverage reporting.

## Team Assignment Data File Creation (Before Ingestion)
We create a data file containing all paths in the repo, with a team assigned.
Example Team Assignments Block:
```
x-pack/plugins/security_solution/common/constants.ts siem
x-pack/plugins/security_solution/common/detection_engine/build_exceptions_query.test.ts siem
x-pack/plugins/security_solution/common/detection_engine/build_exceptions_query.ts siem
...
```

## Team Assignment Data File Usage (During Code Coverage Ingestion)
Subsequently, we use the data file during ingestion.
We search the data file, for any given "coveredFilePath"
- Given the above assignments block, and lets say the "coveredFilePath" during ingestion is
- `x-pack/plugins/security_solution/common/constants.ts`
- The team assignment would be `siem` in our [Kibana Stats Cluster](https://kibana-stats.elastic.dev/app/dashboards#/view/58b8db70-62f9-11ea-8312-7f2d69b79843?_g=(filters%3A!()%2CrefreshInterval%3A(pause%3A!t%2Cvalue%3A0)%2Ctime%3A(from%3Anow-7d%2Cto%3Anow)))
Binary file not shown.
2 changes: 2 additions & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
// Resolve modules in the same way as Node.js. Aka make `require` works the
// same in TypeScript as it does in Node.js.
"moduleResolution": "node",
// "resolveJsonModule" allows for importing, extracting types from and generating .json files.
"resolveJsonModule": true,
// Disallow inconsistently-cased references to the same file.
"forceConsistentCasingInFileNames": true,
// Forbid unused local variables as the rule was deprecated by ts-lint
Expand Down
9 changes: 0 additions & 9 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,6 @@ declare module '*.svg' {
export default content;
}

// allow JSON files to be imported directly without lint errors
// see: https://github.com/palantir/tslint/issues/1264#issuecomment-228433367
// and: https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#arbitrary-expressions-are-forbidden-in-export-assignments-in-ambient-contexts
declare module '*.json' {
const json: any;
// eslint-disable-next-line import/no-default-export
export default json;
}

type MethodKeysOf<T> = {
[K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
}[keyof T];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ describe('ErrorGroupOverview -> List', () => {
<MemoryRouter>
<MockApmPluginContextWrapper>
<MockUrlParamsContextProvider>
{/* @ts-expect-error invalid json props */}
<ErrorGroupList items={props.items} serviceName="opbeans-python" />
</MockUrlParamsContextProvider>
</MockApmPluginContextWrapper>
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,20 @@ import { EuiCallOut, EuiButton } from '@elastic/eui';
import React from 'react';
import { i18n } from '@kbn/i18n';
import { useApmPluginContext } from '../../../../hooks/useApmPluginContext';
import { useMlHref } from '../../../../../../ml/public';

export function LegacyJobsCallout() {
const { core } = useApmPluginContext();
const {
core,
plugins: { ml },
} = useApmPluginContext();
const mlADLink = useMlHref(ml, core.http.basePath.get(), {
page: 'jobs',
pageState: {
jobId: 'high_mean_response_time',
},
});

return (
<EuiCallOut
title={i18n.translate(
Expand All @@ -28,11 +39,7 @@ export function LegacyJobsCallout() {
}
)}
</p>
<EuiButton
href={core.http.basePath.prepend(
'/app/ml#/jobs?mlManagement=(jobId:high_mean_response_time)'
)}
>
<EuiButton href={mlADLink}>
{i18n.translate(
'xpack.apm.settings.anomaly_detection.legacy_jobs.button',
{ defaultMessage: 'Review jobs' }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import mockTransaction from './mockTransaction.json';

describe('DiscoverTransactionLink component', () => {
it('should render with data', () => {
// @ts-expect-error invalid json mock
const transaction: Transaction = mockTransaction;

expect(
Expand All @@ -25,6 +26,7 @@ describe('DiscoverTransactionLink component', () => {

describe('getDiscoverQuery', () => {
it('should return the correct query params object', () => {
// @ts-expect-error invalid json mock
const transaction: Transaction = mockTransaction;
const result = getDiscoverQuery(transaction);
expect(result).toMatchSnapshot();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('MLJobLink', () => {
);

expect(href).toMatchInlineSnapshot(
`"/basepath/app/ml#/timeseriesexplorer?_g=(ml:(jobIds:!(myservicename-mytransactiontype-high_mean_response_time)),refreshInterval:(pause:!t,value:0),time:(from:now/w,to:now-4h))"`
`"/app/ml/timeseriesexplorer?_g=(ml:(jobIds:!(myservicename-mytransactiontype-high_mean_response_time)),refreshInterval:(pause:!t,value:0),time:(from:now%2Fw,to:now-4h))&_a=(mlTimeSeriesExplorer:(),zoom:(from:now%2Fw,to:now-4h))"`
);
});
it('should produce the correct URL with jobId, serviceName, and transactionType', async () => {
Expand All @@ -41,7 +41,27 @@ describe('MLJobLink', () => {
);

expect(href).toMatchInlineSnapshot(
`"/basepath/app/ml#/timeseriesexplorer?_g=(ml:(jobIds:!(myservicename-mytransactiontype-high_mean_response_time)),refreshInterval:(pause:!t,value:0),time:(from:now/w,to:now-4h))&_a=(mlTimeSeriesExplorer:(entities:(service.name:opbeans-test,transaction.type:request)))"`
`"/app/ml/timeseriesexplorer?_g=(ml:(jobIds:!(myservicename-mytransactiontype-high_mean_response_time)),refreshInterval:(pause:!t,value:0),time:(from:now%2Fw,to:now-4h))&_a=(mlTimeSeriesExplorer:(entities:(service.name:opbeans-test,transaction.type:request)),zoom:(from:now%2Fw,to:now-4h))"`
);
});

it('correctly encodes time range values', async () => {
const href = await getRenderedHref(
() => (
<MLJobLink
jobId="apm-production-485b-high_mean_transaction_duration"
serviceName="opbeans-java"
transactionType="request"
/>
),
{
search:
'?rangeFrom=2020-07-29T17:27:29.000Z&rangeTo=2020-07-29T18:45:00.000Z&refreshInterval=10000&refreshPaused=true',
} as Location
);

expect(href).toMatchInlineSnapshot(
`"/app/ml/timeseriesexplorer?_g=(ml:(jobIds:!(apm-production-485b-high_mean_transaction_duration)),refreshInterval:(pause:!t,value:10000),time:(from:'2020-07-29T17:27:29.000Z',to:'2020-07-29T18:45:00.000Z'))&_a=(mlTimeSeriesExplorer:(entities:(service.name:opbeans-java,transaction.type:request)),zoom:(from:'2020-07-29T17:27:29.000Z',to:'2020-07-29T18:45:00.000Z'))"`
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@ import { MLLink } from './MLLink';

test('MLLink produces the correct URL', async () => {
const href = await getRenderedHref(
() => (
<MLLink path="/some/path" query={{ ml: { jobIds: ['something'] } }} />
),
() => <MLLink query={{ ml: { jobIds: ['something'] } }} />,
{
search:
'?rangeFrom=now-5h&rangeTo=now-2h&refreshPaused=true&refreshInterval=0',
} as Location
);

expect(href).toMatchInlineSnapshot(
`"/basepath/app/ml#/some/path?_g=(ml:(jobIds:!(something)),refreshInterval:(pause:!t,value:0),time:(from:now-5h,to:now-2h))&mlManagement=(groupIds:!(apm))"`
`"/app/ml/jobs?mlManagement=(groupIds:!(apm),jobId:!(something))&_g=(refreshInterval:(pause:!t,value:0),time:(from:now-5h,to:now-2h))"`
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@

import { EuiLink } from '@elastic/eui';
import React from 'react';
import { useLocation } from 'react-router-dom';
import rison, { RisonValue } from 'rison-node';
import url from 'url';
import { useApmPluginContext } from '../../../../hooks/useApmPluginContext';
import { getTimepickerRisonData, TimepickerRisonData } from '../rison_helpers';
import { useMlHref, ML_PAGES } from '../../../../../../ml/public';
import { useUrlParams } from '../../../../hooks/useUrlParams';

interface MlRisonData {
ml?: {
Expand All @@ -26,28 +24,41 @@ interface Props {
}

export function MLLink({ children, path = '', query = {}, external }: Props) {
const { core } = useApmPluginContext();
const location = useLocation();
const {
core,
plugins: { ml },
} = useApmPluginContext();

const risonQuery: MlRisonData & TimepickerRisonData = getTimepickerRisonData(
location.search
);

if (query.ml) {
risonQuery.ml = query.ml;
let jobIds: string[] = [];
if (query.ml?.jobIds) {
jobIds = query.ml.jobIds;
}
const { urlParams } = useUrlParams();
const { rangeFrom, rangeTo, refreshInterval, refreshPaused } = urlParams;

const href = url.format({
pathname: core.http.basePath.prepend('/app/ml'),
hash: `${path}?_g=${rison.encode(
risonQuery as RisonValue
)}&mlManagement=${rison.encode({ groupIds: ['apm'] })}`,
// default to link to ML Anomaly Detection jobs management page
const mlADLink = useMlHref(ml, core.http.basePath.get(), {
page: ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE,
pageState: {
jobId: jobIds,
groupIds: ['apm'],
globalState: {
time:
rangeFrom !== undefined && rangeTo !== undefined
? { from: rangeFrom, to: rangeTo }
: undefined,
refreshInterval:
refreshPaused !== undefined && refreshInterval !== undefined
? { pause: refreshPaused, value: refreshInterval }
: undefined,
},
},
});

return (
<EuiLink
children={children}
href={href}
href={mlADLink}
external={external}
target={external ? '_blank' : undefined}
/>
Expand Down

This file was deleted.

Loading

0 comments on commit 896f7f3

Please sign in to comment.