Skip to content

Commit

Permalink
Merge branch 'main' into add-excludes-to-options-list_2022-10-04
Browse files Browse the repository at this point in the history
  • Loading branch information
Heenawter authored Oct 24, 2022
2 parents 9367369 + 21c7f5e commit fe520ed
Show file tree
Hide file tree
Showing 168 changed files with 7,049 additions and 5,424 deletions.
1 change: 1 addition & 0 deletions .buildkite/ftr_configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ enabled:
- x-pack/test/detection_engine_api_integration/security_and_spaces/group8/config.ts
- x-pack/test/detection_engine_api_integration/security_and_spaces/group9/config.ts
- x-pack/test/detection_engine_api_integration/security_and_spaces/group10/config.ts
- x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/config.ts
- x-pack/test/encrypted_saved_objects_api_integration/config.ts
- x-pack/test/endpoint_api_integration_no_ingest/config.ts
- x-pack/test/examples/config.ts
Expand Down
2 changes: 0 additions & 2 deletions docs/spaces/index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ image::images/change-space.png["Change current space menu"]

The `kibana_admin` role or equivalent is required to manage **Spaces**.

TIP: Looking to support multiple tenants? Refer to <<xpack-security-multiple-tenants, the Security documentation>> for more information.

[float]
[[spaces-managing]]
=== View, create, and delete spaces
Expand Down
16 changes: 0 additions & 16 deletions docs/user/security/authorization/index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,6 @@ The Elastic Stack comes with the `kibana_admin` {ref}/built-in-roles.html[built-

When you assign a user multiple roles, the user receives a union of the roles’ privileges. Therefore, assigning the `kibana_admin` role in addition to a custom role that grants {kib} privileges is ineffective because `kibana_admin` has access to all the features in all spaces.

[[xpack-security-multiple-tenants]]
==== Supporting multiple tenants

There are two approaches to supporting multi-tenancy in {kib}:

1. *Recommended:* Create a space and a limited role for each tenant, and configure each user with the appropriate role. See
<<tutorial-secure-access-to-kibana, Securing access to {kib}>> for more details.
2. deprecated:[7.13.0,"In 8.0 and later, the `kibana.index` setting will no longer be supported."] Set up separate {kib} instances to work
with a single {es} cluster by changing the `kibana.index` setting in your `kibana.yml` file.
+
NOTE: When using multiple {kib} instances this way, you cannot use the `kibana_admin` role to grant access. You must create custom roles
that authorize the user for each specific instance.

Whichever approach you use, be careful when granting cluster privileges and index privileges. Both of these approaches share the same {es}
cluster, and {kib} spaces do not prevent you from granting users of two different tenants access to the same index.

[role="xpack"]
[[kibana-role-management]]
=== {kib} role management
Expand Down
18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
},
"dependencies": {
"@appland/sql-parser": "^1.5.1",
"@babel/runtime": "^7.19.0",
"@babel/runtime": "^7.19.4",
"@dnd-kit/core": "^3.1.1",
"@dnd-kit/sortable": "^4.0.0",
"@dnd-kit/utilities": "^2.0.0",
Expand Down Expand Up @@ -673,25 +673,25 @@
"devDependencies": {
"@apidevtools/swagger-parser": "^10.0.3",
"@babel/cli": "^7.19.3",
"@babel/core": "^7.19.3",
"@babel/core": "^7.19.6",
"@babel/eslint-parser": "^7.19.1",
"@babel/eslint-plugin": "^7.19.1",
"@babel/generator": "^7.19.3",
"@babel/generator": "^7.19.6",
"@babel/helper-plugin-utils": "^7.19.0",
"@babel/parser": "^7.19.3",
"@babel/parser": "^7.19.6",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-export-namespace-from": "^7.18.9",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
"@babel/plugin-proposal-object-rest-spread": "^7.18.9",
"@babel/plugin-proposal-object-rest-spread": "^7.19.4",
"@babel/plugin-proposal-optional-chaining": "^7.18.9",
"@babel/plugin-proposal-private-methods": "^7.18.6",
"@babel/plugin-transform-runtime": "^7.19.1",
"@babel/preset-env": "^7.19.3",
"@babel/plugin-transform-runtime": "^7.19.6",
"@babel/preset-env": "^7.19.4",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@babel/register": "^7.18.9",
"@babel/traverse": "^7.19.3",
"@babel/types": "^7.19.3",
"@babel/traverse": "^7.19.6",
"@babel/types": "^7.19.4",
"@bazel/ibazel": "^0.16.2",
"@bazel/typescript": "4.6.2",
"@cypress/code-coverage": "^3.10.0",
Expand Down
17 changes: 17 additions & 0 deletions packages/kbn-es-query/src/kuery/functions/is.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,23 @@ describe('kuery functions', () => {

expect(result).toEqual(expected);
});

test('should use a term query for keyword fields', () => {
const node = nodeTypes.function.buildNode('is', 'machine.os.keyword', 'Win 7');
const result = is.toElasticsearchQuery(node, indexPattern);
expect(result).toEqual({
bool: {
should: [
{
term: {
'machine.os.keyword': 'Win 7',
},
},
],
minimum_should_match: 1,
},
});
});
});
});
});
5 changes: 3 additions & 2 deletions packages/kbn-es-query/src/kuery/functions/is.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export function toElasticsearchQuery(
}

const queries = fields!.reduce((accumulator: any, field: DataViewFieldBase) => {
const isKeywordField = field.esTypes?.length === 1 && field.esTypes.includes('keyword');
const wrapWithNestedQuery = (query: any) => {
// Wildcards can easily include nested and non-nested fields. There isn't a good way to let
// users handle this themselves so we automatically add nested queries in this scenario.
Expand Down Expand Up @@ -142,7 +143,7 @@ export function toElasticsearchQuery(
}),
];
} else if (wildcard.isNode(valueArg)) {
const query = field.esTypes?.includes('keyword')
const query = isKeywordField
? {
wildcard: {
[field.name]: value,
Expand Down Expand Up @@ -177,7 +178,7 @@ export function toElasticsearchQuery(
}),
];
} else {
const queryType = type === 'phrase' ? 'match_phrase' : 'match';
const queryType = isKeywordField ? 'term' : type === 'phrase' ? 'match_phrase' : 'match';
return [
...accumulator,
wrapWithNestedQuery({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ it('persists comments in the original file', () => {
`);
expect(newJson).toMatchInlineSnapshot(`
// @managed
/**
* This is a top level comment
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,62 @@ import {
EuiFormControlLayout,
EuiFormLabel,
EuiFormRow,
EuiIcon,
EuiLink,
EuiLoadingChart,
EuiPopover,
EuiText,
EuiToolTip,
} from '@elastic/eui';

import { FormattedMessage } from '@kbn/i18n-react';
import { Markdown } from '@kbn/kibana-react-plugin/public';
import { useReduxContainerContext } from '@kbn/presentation-util-plugin/public';
import { ErrorEmbeddable } from '@kbn/embeddable-plugin/public';
import { ControlGroupReduxState } from '../types';
import { pluginServices } from '../../services';
import { EditControlButton } from '../editor/edit_control';
import { ControlGroupStrings } from '../control_group_strings';
import { useChildEmbeddable } from '../../hooks/use_child_embeddable';
import { TIME_SLIDER_CONTROL } from '../../../common';

interface ControlFrameErrorProps {
error: Error;
}

const ControlFrameError = ({ error }: ControlFrameErrorProps) => {
const [isPopoverOpen, setPopoverOpen] = useState(false);
const popoverButton = (
<EuiText className="errorEmbeddableCompact__button" size="xs">
<EuiLink
className="eui-textTruncate"
color="subdued"
onClick={() => setPopoverOpen((open) => !open)}
>
<EuiIcon type="alert" color="danger" />
<FormattedMessage
id="controls.frame.error.message"
defaultMessage="An error has occurred. Read more"
/>
</EuiLink>
</EuiText>
);

return (
<EuiPopover
button={popoverButton}
isOpen={isPopoverOpen}
anchorClassName="errorEmbeddableCompact__popoverAnchor"
closePopover={() => setPopoverOpen(false)}
>
<Markdown
markdown={error.message}
openLinksInNewTab={true}
data-test-subj="errorMessageMarkdown"
/>
</EuiPopover>
);
};

export interface ControlFrameProps {
customPrepend?: JSX.Element;
enableActions?: boolean;
Expand All @@ -40,7 +83,7 @@ export const ControlFrame = ({
embeddableType,
}: ControlFrameProps) => {
const embeddableRoot: React.RefObject<HTMLDivElement> = useMemo(() => React.createRef(), []);
const [hasFatalError, setHasFatalError] = useState(false);
const [fatalError, setFatalError] = useState<Error>();

const {
useEmbeddableSelector: select,
Expand All @@ -61,19 +104,14 @@ export const ControlFrame = ({
const usingTwoLineLayout = controlStyle === 'twoLine';

useEffect(() => {
if (embeddableRoot.current && embeddable) {
embeddable.render(embeddableRoot.current);
if (embeddableRoot.current) {
embeddable?.render(embeddableRoot.current);
}
const inputSubscription = embeddable
?.getInput$()
.subscribe((newInput) => setTitle(newInput.title));
const errorSubscription = embeddable?.getOutput$().subscribe({
error: (error: Error) => {
if (!embeddableRoot.current) return;
const errorEmbeddable = new ErrorEmbeddable(error, { id: embeddable.id }, undefined, true);
errorEmbeddable.render(embeddableRoot.current);
setHasFatalError(true);
},
error: setFatalError,
});
return () => {
inputSubscription?.unsubscribe();
Expand All @@ -88,7 +126,7 @@ export const ControlFrame = ({
'controlFrameFloatingActions--oneLine': !usingTwoLineLayout,
})}
>
{!hasFatalError && embeddableType !== TIME_SLIDER_CONTROL && (
{!fatalError && embeddableType !== TIME_SLIDER_CONTROL && (
<EuiToolTip content={ControlGroupStrings.floatingActions.getEditButtonTitle()}>
<EditControlButton embeddableId={embeddableId} />
</EuiToolTip>
Expand Down Expand Up @@ -119,7 +157,7 @@ export const ControlFrame = ({
const embeddableParentClassNames = classNames('controlFrame__control', {
'controlFrame--twoLine': controlStyle === 'twoLine',
'controlFrame--oneLine': controlStyle === 'oneLine',
'controlFrame--fatalError': hasFatalError,
'controlFrame--fatalError': !!fatalError,
});

function renderEmbeddablePrepend() {
Expand Down Expand Up @@ -149,12 +187,19 @@ export const ControlFrame = ({
</>
}
>
{embeddable && (
{embeddable && !fatalError && (
<div
className={embeddableParentClassNames}
id={`controlFrame--${embeddableId}`}
ref={embeddableRoot}
/>
>
{fatalError && <ControlFrameError error={fatalError} />}
</div>
)}
{fatalError && (
<div className={embeddableParentClassNames} id={`controlFrame--${embeddableId}`}>
{<ControlFrameError error={fatalError} />}
</div>
)}
{!embeddable && (
<div className={embeddableParentClassNames} id={`controlFrame--${embeddableId}`}>
Expand Down
Loading

0 comments on commit fe520ed

Please sign in to comment.