Skip to content
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

Prevent Spaces from being disabled #115283

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions docs/settings/spaces-settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@

By default, spaces is enabled in {kib}. To secure spaces, <<security-settings-kb,enable security>>.

`xpack.spaces.enabled`::
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't leave a comment on an unedited file, but we should update our docs to reflect the fact that we can't disable Spaces anymore. My preference is to keep the section, but change the wording to indicate that this is no longer possible as of 8.0. That said, I'll be ok if you'd rather remove this altogether.

We should also remove the language about all objects existing in the Default space after upgrade. That was only really relevant for folks upgrading from pre-6.5 to >= 6.5, and I sincerely hope that everyone has done that by now. It's just confusing/misleading for everyone else at this point.

[float]
[[spaces-delete-started]]
=== Disable and version updates
Spaces are automatically enabled in {kib}. If you don't want use this feature,
you can disable it. For more information, refer to <<spaces-settings-kb,Spaces settings in {kib}>>.
When you upgrade {kib}, the default space contains all of your existing saved objects.

Copy link
Contributor Author

@jportner jportner Oct 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch, I'll change this section to:

Starting in {kib} 8.0, the Spaces feature cannot be disabled.

deprecated:[7.16.0,"In 8.0 and later, this setting will no longer be supported and it will not be possible to disable this plugin."]
To enable spaces, set to `true`.
The default is `true`.

`xpack.spaces.maxSpaces`::
The maximum number of spaces that you can use with the {kib} instance. Some {kib} operations
return all spaces using a single `_search` from {es}, so you must
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,6 @@ kibana_vars=(
xpack.securitySolution.packagerTaskInterval
xpack.securitySolution.prebuiltRulesFromFileSystem
xpack.securitySolution.prebuiltRulesFromSavedObjects
xpack.spaces.enabled
xpack.spaces.maxSpaces
xpack.task_manager.index
xpack.task_manager.max_attempts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import { userAPIClientMock } from '../../users/index.mock';
import { createRawKibanaPrivileges } from '../__fixtures__/kibana_privileges';
import { indicesAPIClientMock, privilegesAPIClientMock, rolesAPIClientMock } from '../index.mock';
import { EditRolePage } from './edit_role_page';
import { SimplePrivilegeSection } from './privileges/kibana/simple_privilege_section';
import { SpaceAwarePrivilegeSection } from './privileges/kibana/space_aware_privilege_section';
import { TransformErrorSection } from './privileges/kibana/transform_error_section';

Expand Down Expand Up @@ -132,12 +131,10 @@ function getProps({
action,
role,
canManageSpaces = true,
spacesEnabled = true,
}: {
action: 'edit' | 'clone';
role?: Role;
canManageSpaces?: boolean;
spacesEnabled?: boolean;
}) {
const rolesAPIClient = rolesAPIClientMock.create();
rolesAPIClient.getRole.mockResolvedValue(role);
Expand Down Expand Up @@ -165,12 +162,7 @@ function getProps({
const { http, docLinks, notifications } = coreMock.createStart();
http.get.mockImplementation(async (path: any) => {
if (path === '/api/spaces/space') {
if (spacesEnabled) {
return buildSpaces();
}

const notFoundError = { response: { status: 404 } };
throw notFoundError;
return buildSpaces();
}
});

Expand Down Expand Up @@ -335,152 +327,6 @@ describe('<EditRolePage />', () => {
});
});

describe('with spaces disabled', () => {
it('can render a reserved role', async () => {
const wrapper = mountWithIntl(
<EditRolePage
{...getProps({
action: 'edit',
spacesEnabled: false,
role: {
name: 'superuser',
metadata: { _reserved: true },
elasticsearch: { cluster: ['all'], indices: [], run_as: ['*'] },
kibana: [{ spaces: ['*'], base: ['all'], feature: {} }],
},
})}
/>
);

await waitForRender(wrapper);

expect(wrapper.find('[data-test-subj="reservedRoleBadgeTooltip"]')).toHaveLength(1);
expect(wrapper.find(SimplePrivilegeSection)).toHaveLength(1);
expect(wrapper.find('[data-test-subj="userCannotManageSpacesCallout"]')).toHaveLength(0);
expectReadOnlyFormButtons(wrapper);
});

it('can render a user defined role', async () => {
const wrapper = mountWithIntl(
<EditRolePage
{...getProps({
action: 'edit',
spacesEnabled: false,
role: {
name: 'my custom role',
metadata: {},
elasticsearch: { cluster: ['all'], indices: [], run_as: ['*'] },
kibana: [{ spaces: ['*'], base: ['all'], feature: {} }],
},
})}
/>
);

await waitForRender(wrapper);

expect(wrapper.find('[data-test-subj="reservedRoleBadgeTooltip"]')).toHaveLength(0);
expect(wrapper.find(SimplePrivilegeSection)).toHaveLength(1);
expect(wrapper.find('[data-test-subj="userCannotManageSpacesCallout"]')).toHaveLength(0);
expectSaveFormButtons(wrapper);
});

it('can render when creating a new role', async () => {
const wrapper = mountWithIntl(
<EditRolePage {...getProps({ action: 'edit', spacesEnabled: false })} />
);

await waitForRender(wrapper);

expect(wrapper.find(SimplePrivilegeSection)).toHaveLength(1);
expectSaveFormButtons(wrapper);
});

it('can render when cloning an existing role', async () => {
const wrapper = mountWithIntl(
<EditRolePage
{...getProps({
action: 'edit',
spacesEnabled: false,
role: {
metadata: { _reserved: false },
name: '',
elasticsearch: {
cluster: ['all', 'manage'],
indices: [
{
names: ['foo*'],
privileges: ['all'],
field_security: { except: ['f'], grant: ['b*'] },
},
],
run_as: ['elastic'],
},
kibana: [{ spaces: ['*'], base: ['all'], feature: {} }],
},
})}
/>
);

await waitForRender(wrapper);

expect(wrapper.find(SimplePrivilegeSection)).toHaveLength(1);
expectSaveFormButtons(wrapper);
});

it('does not care if user cannot manage spaces', async () => {
const wrapper = mountWithIntl(
<EditRolePage
{...getProps({
action: 'edit',
spacesEnabled: false,
canManageSpaces: false,
role: {
name: 'my custom role',
metadata: {},
elasticsearch: { cluster: ['all'], indices: [], run_as: ['*'] },
kibana: [{ spaces: ['*'], base: ['all'], feature: {} }],
},
})}
/>
);

await waitForRender(wrapper);

expect(wrapper.find('[data-test-subj="reservedRoleBadgeTooltip"]')).toHaveLength(0);

expect(
wrapper.find('EuiCallOut[data-test-subj="userCannotManageSpacesCallout"]')
).toHaveLength(0);

expect(wrapper.find(SimplePrivilegeSection)).toHaveLength(1);
expectSaveFormButtons(wrapper);
});

it('renders a partial read-only view when there is a transform error', async () => {
const wrapper = mountWithIntl(
<EditRolePage
{...getProps({
action: 'edit',
spacesEnabled: false,
canManageSpaces: false,
role: {
name: 'my custom role',
metadata: {},
elasticsearch: { cluster: ['all'], indices: [], run_as: ['*'] },
kibana: [],
_transform_error: ['kibana'],
},
})}
/>
);

await waitForRender(wrapper);

expect(wrapper.find(TransformErrorSection)).toHaveLength(1);
expectReadOnlyFormButtons(wrapper);
});
});

it('registers fatal error if features endpoint fails unexpectedly', async () => {
const error = { response: { status: 500 } };
const getFeatures = jest.fn().mockRejectedValue(error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,6 @@ export const EditRolePage: FunctionComponent<Props> = ({
<KibanaPrivilegesRegion
kibanaPrivileges={new KibanaPrivileges(kibanaPrivileges, features)}
spaces={spaces.list}
spacesEnabled={spaces.enabled}
uiCapabilities={uiCapabilities}
canCustomizeSubFeaturePrivileges={license.getFeatures().allowSubFeaturePrivileges}
editable={!isRoleReadOnly}
Expand Down Expand Up @@ -521,7 +520,7 @@ export const EditRolePage: FunctionComponent<Props> = ({
setFormError(null);

try {
await rolesAPIClient.saveRole({ role, spacesEnabled: spaces.enabled });
await rolesAPIClient.saveRole({ role });
} catch (error) {
notifications.toasts.addDanger(
error?.body?.message ??
Expand Down Expand Up @@ -566,24 +565,17 @@ export const EditRolePage: FunctionComponent<Props> = ({
backToRoleList();
};

const description = spaces.enabled ? (
<FormattedMessage
id="xpack.security.management.editRole.setPrivilegesToKibanaSpacesDescription"
defaultMessage="Set privileges on your Elasticsearch data and control access to your Kibana spaces."
/>
) : (
<FormattedMessage
id="xpack.security.management.editRole.setPrivilegesToKibanaDescription"
defaultMessage="Set privileges on your Elasticsearch data and control access to Kibana."
/>
);

return (
<div className="editRolePage">
<EuiForm {...formError}>
{getFormTitle()}
<EuiSpacer />
<EuiText size="s">{description}</EuiText>
<EuiText size="s">
<FormattedMessage
id="xpack.security.management.editRole.setPrivilegesToKibanaSpacesDescription"
defaultMessage="Set privileges on your Elasticsearch data and control access to your Kibana spaces."
/>
</EuiText>
{isRoleReserved && (
<Fragment>
<EuiSpacer size="s" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ import type { Role } from '../../../../../../common/model';
import { KibanaPrivileges } from '../../../model';
import { RoleValidator } from '../../validate_role';
import { KibanaPrivilegesRegion } from './kibana_privileges_region';
import { SimplePrivilegeSection } from './simple_privilege_section';
import { SpaceAwarePrivilegeSection } from './space_aware_privilege_section';
import { TransformErrorSection } from './transform_error_section';

const buildProps = (customProps = {}) => {
const buildProps = () => {
return {
role: {
name: '',
Expand All @@ -27,7 +26,6 @@ const buildProps = (customProps = {}) => {
},
kibana: [],
},
spacesEnabled: true,
spaces: [
{
id: 'default',
Expand Down Expand Up @@ -64,7 +62,6 @@ const buildProps = (customProps = {}) => {
onChange: jest.fn(),
validator: new RoleValidator(),
canCustomizeSubFeaturePrivileges: true,
...customProps,
};
};

Expand All @@ -73,26 +70,17 @@ describe('<KibanaPrivileges>', () => {
expect(shallow(<KibanaPrivilegesRegion {...buildProps()} />)).toMatchSnapshot();
});

it('renders the simple privilege form when spaces is disabled', () => {
const props = buildProps({ spacesEnabled: false });
it('renders the space-aware privilege form', () => {
const props = buildProps();
const wrapper = shallow(<KibanaPrivilegesRegion {...props} />);
expect(wrapper.find(SimplePrivilegeSection)).toHaveLength(1);
expect(wrapper.find(SpaceAwarePrivilegeSection)).toHaveLength(0);
});

it('renders the space-aware privilege form when spaces is enabled', () => {
const props = buildProps({ spacesEnabled: true });
const wrapper = shallow(<KibanaPrivilegesRegion {...props} />);
expect(wrapper.find(SimplePrivilegeSection)).toHaveLength(0);
expect(wrapper.find(SpaceAwarePrivilegeSection)).toHaveLength(1);
});

it('renders the transform error section when the role has a transform error', () => {
const props = buildProps({ spacesEnabled: true });
const props = buildProps();
(props.role as Role)._transform_error = ['kibana'];

const wrapper = shallow(<KibanaPrivilegesRegion {...props} />);
expect(wrapper.find(SimplePrivilegeSection)).toHaveLength(0);
expect(wrapper.find(SpaceAwarePrivilegeSection)).toHaveLength(0);
expect(wrapper.find(TransformErrorSection)).toHaveLength(1);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@ import type { Role } from '../../../../../../common/model';
import type { KibanaPrivileges } from '../../../model';
import { CollapsiblePanel } from '../../collapsible_panel';
import type { RoleValidator } from '../../validate_role';
import { SimplePrivilegeSection } from './simple_privilege_section';
import { SpaceAwarePrivilegeSection } from './space_aware_privilege_section';
import { TransformErrorSection } from './transform_error_section';

interface Props {
role: Role;
spacesEnabled: boolean;
canCustomizeSubFeaturePrivileges: boolean;
spaces?: Space[];
uiCapabilities: Capabilities;
Expand All @@ -44,7 +42,6 @@ export class KibanaPrivilegesRegion extends Component<Props, {}> {
const {
kibanaPrivileges,
role,
spacesEnabled,
canCustomizeSubFeaturePrivileges,
spaces = [],
uiCapabilities,
Expand All @@ -58,30 +55,18 @@ export class KibanaPrivilegesRegion extends Component<Props, {}> {
return <TransformErrorSection />;
}

if (spacesEnabled) {
return (
<SpaceAwarePrivilegeSection
kibanaPrivileges={kibanaPrivileges}
role={role}
spaces={spaces}
uiCapabilities={uiCapabilities}
onChange={onChange}
editable={editable}
canCustomizeSubFeaturePrivileges={canCustomizeSubFeaturePrivileges}
validator={validator}
spacesApiUi={spacesApiUi!}
/>
);
} else {
return (
<SimplePrivilegeSection
kibanaPrivileges={kibanaPrivileges}
role={role}
onChange={onChange}
editable={editable}
canCustomizeSubFeaturePrivileges={canCustomizeSubFeaturePrivileges}
/>
);
}
return (
<SpaceAwarePrivilegeSection
kibanaPrivileges={kibanaPrivileges}
role={role}
spaces={spaces}
uiCapabilities={uiCapabilities}
onChange={onChange}
editable={editable}
canCustomizeSubFeaturePrivileges={canCustomizeSubFeaturePrivileges}
validator={validator}
spacesApiUi={spacesApiUi!}
/>
);
};
}
Loading