mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Fleet] Validate namespace restriction per space client side (#188424)
This commit is contained in:
parent
4960bb38ac
commit
492e29a943
27 changed files with 281 additions and 49 deletions
|
@ -61,4 +61,8 @@ describe('getInheritedNamespace', () => {
|
||||||
it('should return default namespace when there are no agent policies', () => {
|
it('should return default namespace when there are no agent policies', () => {
|
||||||
expect(getInheritedNamespace([])).toEqual('default');
|
expect(getInheritedNamespace([])).toEqual('default');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should allow to override default namespace when there are no agent policies', () => {
|
||||||
|
expect(getInheritedNamespace([], 'test')).toEqual('test');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -45,9 +45,9 @@ function policyHasIntegration(agentPolicy: AgentPolicy, packageName: string) {
|
||||||
return agentPolicy.package_policies?.some((p) => p.package?.name === packageName);
|
return agentPolicy.package_policies?.some((p) => p.package?.name === packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getInheritedNamespace(agentPolicies: AgentPolicy[]): string {
|
export function getInheritedNamespace(agentPolicies: AgentPolicy[], defaultValue?: string): string {
|
||||||
if (agentPolicies.length === 1) {
|
if (agentPolicies.length === 1) {
|
||||||
return agentPolicies[0].namespace;
|
return agentPolicies[0].namespace;
|
||||||
}
|
}
|
||||||
return 'default';
|
return defaultValue ?? 'default';
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,10 @@ describe('Fleet - isValidNamespace', () => {
|
||||||
expect(isValidNamespace('testlength😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀').valid).toBe(
|
expect(isValidNamespace('testlength😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀').valid).toBe(
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
expect(isValidNamespace('', true).valid).toBe(true);
|
||||||
|
expect(isValidNamespace('', true, ['test']).valid).toBe(true);
|
||||||
|
expect(isValidNamespace('test', false, ['test']).valid).toBe(true);
|
||||||
|
expect(isValidNamespace('test_dev', false, ['test']).valid).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false for invalid namespaces', () => {
|
it('returns false for invalid namespaces', () => {
|
||||||
|
@ -36,5 +40,6 @@ describe('Fleet - isValidNamespace', () => {
|
||||||
'testlength😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀'
|
'testlength😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀'
|
||||||
).valid
|
).valid
|
||||||
).toBe(false);
|
).toBe(false);
|
||||||
|
expect(isValidNamespace('default', false, ['test']).valid).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,9 +12,43 @@ import { i18n } from '@kbn/i18n';
|
||||||
// and implements a limit based on https://github.com/elastic/kibana/issues/75846
|
// and implements a limit based on https://github.com/elastic/kibana/issues/75846
|
||||||
export function isValidNamespace(
|
export function isValidNamespace(
|
||||||
namespace: string,
|
namespace: string,
|
||||||
allowBlankNamespace?: boolean
|
allowBlankNamespace?: boolean,
|
||||||
|
allowedNamespacePrefixes?: string[]
|
||||||
): { valid: boolean; error?: string } {
|
): { valid: boolean; error?: string } {
|
||||||
return isValidEntity(namespace, 'Namespace', allowBlankNamespace);
|
if (!namespace.trim() && allowBlankNamespace) {
|
||||||
|
return { valid: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
const { valid, error } = isValidEntity(namespace, 'Namespace', allowBlankNamespace);
|
||||||
|
if (!valid) {
|
||||||
|
return { valid, error };
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const prefix of allowedNamespacePrefixes || []) {
|
||||||
|
if (!namespace.trim().startsWith(prefix)) {
|
||||||
|
return allowedNamespacePrefixes?.length === 1
|
||||||
|
? {
|
||||||
|
valid: false,
|
||||||
|
error: i18n.translate('xpack.fleet.namespaceValidation.notAllowedPrefixError', {
|
||||||
|
defaultMessage: 'Namespace should start with {allowedNamespacePrefixes}',
|
||||||
|
values: {
|
||||||
|
allowedNamespacePrefixes: allowedNamespacePrefixes?.[0],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
valid: false,
|
||||||
|
error: i18n.translate('xpack.fleet.namespaceValidation.notAllowedPrefixesError', {
|
||||||
|
defaultMessage:
|
||||||
|
'Namespace should start with one of these prefixes {allowedNamespacePrefixes}',
|
||||||
|
values: {
|
||||||
|
allowedNamespacePrefixes: allowedNamespacePrefixes?.join(', ') ?? '',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { valid: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isValidDataset(
|
export function isValidDataset(
|
||||||
|
|
|
@ -287,6 +287,7 @@ export const settingsRoutesService = {
|
||||||
getInfoPath: () => SETTINGS_API_ROUTES.INFO_PATTERN,
|
getInfoPath: () => SETTINGS_API_ROUTES.INFO_PATTERN,
|
||||||
getUpdatePath: () => SETTINGS_API_ROUTES.UPDATE_PATTERN,
|
getUpdatePath: () => SETTINGS_API_ROUTES.UPDATE_PATTERN,
|
||||||
getEnrollmentInfoPath: () => SETTINGS_API_ROUTES.ENROLLMENT_INFO_PATTERN,
|
getEnrollmentInfoPath: () => SETTINGS_API_ROUTES.ENROLLMENT_INFO_PATTERN,
|
||||||
|
getSpaceInfoPath: () => SETTINGS_API_ROUTES.SPACE_INFO_PATTERN,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const appRoutesService = {
|
export const appRoutesService = {
|
||||||
|
|
|
@ -56,7 +56,8 @@ export type PackagePolicyValidationResults = {
|
||||||
export const validatePackagePolicy = (
|
export const validatePackagePolicy = (
|
||||||
packagePolicy: NewPackagePolicy,
|
packagePolicy: NewPackagePolicy,
|
||||||
packageInfo: PackageInfo,
|
packageInfo: PackageInfo,
|
||||||
safeLoadYaml: (yaml: string) => any
|
safeLoadYaml: (yaml: string) => any,
|
||||||
|
spaceSettings?: { allowedNamespacePrefixes?: string[] }
|
||||||
): PackagePolicyValidationResults => {
|
): PackagePolicyValidationResults => {
|
||||||
const hasIntegrations = doesPackageHaveIntegrations(packageInfo);
|
const hasIntegrations = doesPackageHaveIntegrations(packageInfo);
|
||||||
const validationResults: PackagePolicyValidationResults = {
|
const validationResults: PackagePolicyValidationResults = {
|
||||||
|
@ -75,7 +76,11 @@ export const validatePackagePolicy = (
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packagePolicy?.namespace) {
|
if (packagePolicy?.namespace) {
|
||||||
const namespaceValidation = isValidNamespace(packagePolicy?.namespace, true);
|
const namespaceValidation = isValidNamespace(
|
||||||
|
packagePolicy?.namespace,
|
||||||
|
true,
|
||||||
|
spaceSettings?.allowedNamespacePrefixes
|
||||||
|
);
|
||||||
if (!namespaceValidation.valid && namespaceValidation.error) {
|
if (!namespaceValidation.valid && namespaceValidation.error) {
|
||||||
validationResults.namespace = [namespaceValidation.error];
|
validationResults.namespace = [namespaceValidation.error];
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
|
||||||
import type { FleetConfigType, FleetStartServices } from '../../plugin';
|
import type { FleetConfigType, FleetStartServices } from '../../plugin';
|
||||||
|
|
||||||
import { PackageInstallProvider } from '../integrations/hooks';
|
import { PackageInstallProvider } from '../integrations/hooks';
|
||||||
|
import { SpaceSettingsContextProvider } from '../../hooks/use_space_settings_context';
|
||||||
|
|
||||||
import { type FleetStatusProviderProps, useAuthz, useFleetStatus, useFlyoutContext } from './hooks';
|
import { type FleetStatusProviderProps, useAuthz, useFleetStatus, useFlyoutContext } from './hooks';
|
||||||
|
|
||||||
|
@ -213,11 +214,13 @@ export const FleetAppContext: React.FC<{
|
||||||
<ReactQueryDevtools initialIsOpen={false} />
|
<ReactQueryDevtools initialIsOpen={false} />
|
||||||
<UIExtensionsContext.Provider value={extensions}>
|
<UIExtensionsContext.Provider value={extensions}>
|
||||||
<FleetStatusProvider defaultFleetStatus={fleetStatus}>
|
<FleetStatusProvider defaultFleetStatus={fleetStatus}>
|
||||||
<Router history={history}>
|
<SpaceSettingsContextProvider>
|
||||||
<PackageInstallProvider startServices={startServices}>
|
<Router history={history}>
|
||||||
<FlyoutContextProvider>{children}</FlyoutContextProvider>
|
<PackageInstallProvider startServices={startServices}>
|
||||||
</PackageInstallProvider>
|
<FlyoutContextProvider>{children}</FlyoutContextProvider>
|
||||||
</Router>
|
</PackageInstallProvider>
|
||||||
|
</Router>
|
||||||
|
</SpaceSettingsContextProvider>
|
||||||
</FleetStatusProvider>
|
</FleetStatusProvider>
|
||||||
</UIExtensionsContext.Provider>
|
</UIExtensionsContext.Provider>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
|
|
|
@ -63,6 +63,7 @@ import { CustomFields } from './custom_fields';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
agentPolicy: Partial<NewAgentPolicy | AgentPolicy>;
|
agentPolicy: Partial<NewAgentPolicy | AgentPolicy>;
|
||||||
|
allowedNamespacePrefixes?: string[];
|
||||||
updateAgentPolicy: (u: Partial<NewAgentPolicy | AgentPolicy>) => void;
|
updateAgentPolicy: (u: Partial<NewAgentPolicy | AgentPolicy>) => void;
|
||||||
validation: ValidationResults;
|
validation: ValidationResults;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
|
|
@ -22,14 +22,12 @@ import { FormattedMessage } from '@kbn/i18n-react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
|
import { useSpaceSettingsContext } from '../../../../../hooks/use_space_settings_context';
|
||||||
import type { AgentPolicy, NewAgentPolicy } from '../../../types';
|
import type { AgentPolicy, NewAgentPolicy } from '../../../types';
|
||||||
|
|
||||||
import { sendCreateAgentPolicy, useStartServices, useAuthz } from '../../../hooks';
|
import { sendCreateAgentPolicy, useStartServices, useAuthz } from '../../../hooks';
|
||||||
|
|
||||||
import { generateNewAgentPolicyWithDefaults } from '../../../../../../common/services/generate_new_agent_policy';
|
import { generateNewAgentPolicyWithDefaults } from '../../../../../../common/services/generate_new_agent_policy';
|
||||||
|
|
||||||
import { agentPolicyFormValidation } from '.';
|
import { agentPolicyFormValidation } from '.';
|
||||||
|
|
||||||
import { AgentPolicyAdvancedOptionsContent } from './agent_policy_advanced_fields';
|
import { AgentPolicyAdvancedOptionsContent } from './agent_policy_advanced_fields';
|
||||||
import { AgentPolicyFormSystemMonitoringCheckbox } from './agent_policy_system_monitoring_field';
|
import { AgentPolicyFormSystemMonitoringCheckbox } from './agent_policy_system_monitoring_field';
|
||||||
|
|
||||||
|
@ -58,11 +56,13 @@ export const AgentPolicyCreateInlineForm: React.FunctionComponent<Props> = ({
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const isDisabled = !authz.fleet.allAgentPolicies || isLoading;
|
const isDisabled = !authz.fleet.allAgentPolicies || isLoading;
|
||||||
|
const spaceSettings = useSpaceSettingsContext();
|
||||||
|
|
||||||
const [newAgentPolicy, setNewAgentPolicy] = useState<NewAgentPolicy>(
|
const [newAgentPolicy, setNewAgentPolicy] = useState<NewAgentPolicy>(
|
||||||
generateNewAgentPolicyWithDefaults({
|
generateNewAgentPolicyWithDefaults({
|
||||||
name: agentPolicyName,
|
name: agentPolicyName,
|
||||||
has_fleet_server: isFleetServerPolicy,
|
has_fleet_server: isFleetServerPolicy,
|
||||||
|
namespace: spaceSettings.defaultNamespace,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -76,7 +76,9 @@ export const AgentPolicyCreateInlineForm: React.FunctionComponent<Props> = ({
|
||||||
[setNewAgentPolicy, newAgentPolicy]
|
[setNewAgentPolicy, newAgentPolicy]
|
||||||
);
|
);
|
||||||
|
|
||||||
const validation = agentPolicyFormValidation(newAgentPolicy);
|
const validation = agentPolicyFormValidation(newAgentPolicy, {
|
||||||
|
allowedNamespacePrefixes: spaceSettings.allowedNamespacePrefixes,
|
||||||
|
});
|
||||||
|
|
||||||
const createAgentPolicy = useCallback(async () => {
|
const createAgentPolicy = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -15,10 +15,15 @@ export interface ValidationResults {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const agentPolicyFormValidation = (
|
export const agentPolicyFormValidation = (
|
||||||
agentPolicy: Partial<NewAgentPolicy | AgentPolicy>
|
agentPolicy: Partial<NewAgentPolicy | AgentPolicy>,
|
||||||
|
options?: { allowedNamespacePrefixes?: string[] }
|
||||||
): ValidationResults => {
|
): ValidationResults => {
|
||||||
const errors: ValidationResults = {};
|
const errors: ValidationResults = {};
|
||||||
const namespaceValidation = isValidNamespace(agentPolicy.namespace || '');
|
const namespaceValidation = isValidNamespace(
|
||||||
|
agentPolicy.namespace || '',
|
||||||
|
false,
|
||||||
|
options?.allowedNamespacePrefixes
|
||||||
|
);
|
||||||
|
|
||||||
if (!agentPolicy.name?.trim()) {
|
if (!agentPolicy.name?.trim()) {
|
||||||
errors.name = [
|
errors.name = [
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { safeLoad } from 'js-yaml';
|
||||||
|
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash';
|
||||||
|
|
||||||
|
import { useSpaceSettingsContext } from '../../../../../../../hooks/use_space_settings_context';
|
||||||
import type {
|
import type {
|
||||||
AgentPolicy,
|
AgentPolicy,
|
||||||
NewPackagePolicy,
|
NewPackagePolicy,
|
||||||
|
@ -152,6 +153,7 @@ export function useOnSubmit({
|
||||||
}) {
|
}) {
|
||||||
const { notifications } = useStartServices();
|
const { notifications } = useStartServices();
|
||||||
const confirmForceInstall = useConfirmForceInstall();
|
const confirmForceInstall = useConfirmForceInstall();
|
||||||
|
const spaceSettings = useSpaceSettingsContext();
|
||||||
// only used to store the resulting package policy once saved
|
// only used to store the resulting package policy once saved
|
||||||
const [savedPackagePolicy, setSavedPackagePolicy] = useState<PackagePolicy>();
|
const [savedPackagePolicy, setSavedPackagePolicy] = useState<PackagePolicy>();
|
||||||
// Form state
|
// Form state
|
||||||
|
@ -204,7 +206,8 @@ export function useOnSubmit({
|
||||||
const newValidationResult = validatePackagePolicy(
|
const newValidationResult = validatePackagePolicy(
|
||||||
newPackagePolicy || packagePolicy,
|
newPackagePolicy || packagePolicy,
|
||||||
packageInfo,
|
packageInfo,
|
||||||
safeLoad
|
safeLoad,
|
||||||
|
spaceSettings
|
||||||
);
|
);
|
||||||
setValidationResults(newValidationResult);
|
setValidationResults(newValidationResult);
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
|
@ -213,7 +216,7 @@ export function useOnSubmit({
|
||||||
return newValidationResult;
|
return newValidationResult;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[packagePolicy, packageInfo]
|
[packagePolicy, packageInfo, spaceSettings]
|
||||||
);
|
);
|
||||||
// Update package policy method
|
// Update package policy method
|
||||||
const updatePackagePolicy = useCallback(
|
const updatePackagePolicy = useCallback(
|
||||||
|
|
|
@ -25,6 +25,7 @@ import {
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
import type { EuiStepProps } from '@elastic/eui/src/components/steps/step';
|
import type { EuiStepProps } from '@elastic/eui/src/components/steps/step';
|
||||||
|
|
||||||
|
import { useSpaceSettingsContext } from '../../../../../../hooks/use_space_settings_context';
|
||||||
import { SECRETS_MINIMUM_FLEET_SERVER_VERSION } from '../../../../../../../common/constants';
|
import { SECRETS_MINIMUM_FLEET_SERVER_VERSION } from '../../../../../../../common/constants';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -111,12 +112,18 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({
|
||||||
const { params } = useRouteMatch<AddToPolicyParams>();
|
const { params } = useRouteMatch<AddToPolicyParams>();
|
||||||
const fleetStatus = useFleetStatus();
|
const fleetStatus = useFleetStatus();
|
||||||
const { docLinks } = useStartServices();
|
const { docLinks } = useStartServices();
|
||||||
|
const spaceSettings = useSpaceSettingsContext();
|
||||||
const [newAgentPolicy, setNewAgentPolicy] = useState<NewAgentPolicy>(
|
const [newAgentPolicy, setNewAgentPolicy] = useState<NewAgentPolicy>(
|
||||||
generateNewAgentPolicyWithDefaults({ name: 'Agent policy 1' })
|
generateNewAgentPolicyWithDefaults({
|
||||||
|
name: 'Agent policy 1',
|
||||||
|
namespace: spaceSettings.defaultNamespace,
|
||||||
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const [withSysMonitoring, setWithSysMonitoring] = useState<boolean>(true);
|
const [withSysMonitoring, setWithSysMonitoring] = useState<boolean>(true);
|
||||||
const validation = agentPolicyFormValidation(newAgentPolicy);
|
const validation = agentPolicyFormValidation(newAgentPolicy, {
|
||||||
|
allowedNamespacePrefixes: spaceSettings.allowedNamespacePrefixes,
|
||||||
|
});
|
||||||
|
|
||||||
const [selectedPolicyTab, setSelectedPolicyTab] = useState<SelectedPolicyTab>(
|
const [selectedPolicyTab, setSelectedPolicyTab] = useState<SelectedPolicyTab>(
|
||||||
queryParamsPolicyId ? SelectedPolicyTab.EXISTING : SelectedPolicyTab.NEW
|
queryParamsPolicyId ? SelectedPolicyTab.EXISTING : SelectedPolicyTab.NEW
|
||||||
|
@ -379,7 +386,10 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({
|
||||||
) : packageInfo ? (
|
) : packageInfo ? (
|
||||||
<>
|
<>
|
||||||
<StepDefinePackagePolicy
|
<StepDefinePackagePolicy
|
||||||
namespacePlaceholder={getInheritedNamespace(agentPolicies)}
|
namespacePlaceholder={getInheritedNamespace(
|
||||||
|
agentPolicies,
|
||||||
|
spaceSettings?.allowedNamespacePrefixes?.[0]
|
||||||
|
)}
|
||||||
packageInfo={packageInfo}
|
packageInfo={packageInfo}
|
||||||
packagePolicy={packagePolicy}
|
packagePolicy={packagePolicy}
|
||||||
updatePackagePolicy={updatePackagePolicy}
|
updatePackagePolicy={updatePackagePolicy}
|
||||||
|
@ -424,6 +434,7 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({
|
||||||
integrationInfo?.name,
|
integrationInfo?.name,
|
||||||
extensionView,
|
extensionView,
|
||||||
handleExtensionViewOnChange,
|
handleExtensionViewOnChange,
|
||||||
|
spaceSettings?.allowedNamespacePrefixes,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ import {
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedMessage } from '@kbn/i18n-react';
|
import { FormattedMessage } from '@kbn/i18n-react';
|
||||||
|
|
||||||
|
import { useSpaceSettingsContext } from '../../../../../../../hooks/use_space_settings_context';
|
||||||
|
|
||||||
import type { AgentPolicy } from '../../../../../types';
|
import type { AgentPolicy } from '../../../../../types';
|
||||||
import {
|
import {
|
||||||
useStartServices,
|
useStartServices,
|
||||||
|
@ -74,11 +76,15 @@ export const SettingsView = memo<{ agentPolicy: AgentPolicy }>(
|
||||||
const [agentPolicy, setAgentPolicy] = useState<AgentPolicy>({
|
const [agentPolicy, setAgentPolicy] = useState<AgentPolicy>({
|
||||||
...originalAgentPolicy,
|
...originalAgentPolicy,
|
||||||
});
|
});
|
||||||
|
const spaceSettings = useSpaceSettingsContext();
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||||
const [hasChanges, setHasChanges] = useState<boolean>(false);
|
const [hasChanges, setHasChanges] = useState<boolean>(false);
|
||||||
const [agentCount, setAgentCount] = useState<number>(0);
|
const [agentCount, setAgentCount] = useState<number>(0);
|
||||||
const [withSysMonitoring, setWithSysMonitoring] = useState<boolean>(true);
|
const [withSysMonitoring, setWithSysMonitoring] = useState<boolean>(true);
|
||||||
const validation = agentPolicyFormValidation(agentPolicy);
|
const validation = agentPolicyFormValidation(agentPolicy, {
|
||||||
|
allowedNamespacePrefixes: spaceSettings?.allowedNamespacePrefixes,
|
||||||
|
});
|
||||||
const [hasAdvancedSettingsErrors, setHasAdvancedSettingsErrors] = useState<boolean>(false);
|
const [hasAdvancedSettingsErrors, setHasAdvancedSettingsErrors] = useState<boolean>(false);
|
||||||
|
|
||||||
const updateAgentPolicy = (updatedFields: Partial<AgentPolicy>) => {
|
const updateAgentPolicy = (updatedFields: Partial<AgentPolicy>) => {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { isEqual } from 'lodash';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import type { EuiStepProps } from '@elastic/eui';
|
import type { EuiStepProps } from '@elastic/eui';
|
||||||
|
|
||||||
|
import { useSpaceSettingsContext } from '../../../../../../hooks/use_space_settings_context';
|
||||||
import type { AgentPolicy, NewAgentPolicy, NewPackagePolicy } from '../../../../../../../common';
|
import type { AgentPolicy, NewAgentPolicy, NewPackagePolicy } from '../../../../../../../common';
|
||||||
import { generateNewAgentPolicyWithDefaults } from '../../../../../../../common/services';
|
import { generateNewAgentPolicyWithDefaults } from '../../../../../../../common/services';
|
||||||
import { SelectedPolicyTab, StepSelectHosts } from '../../create_package_policy_page/components';
|
import { SelectedPolicyTab, StepSelectHosts } from '../../create_package_policy_page/components';
|
||||||
|
@ -49,8 +50,12 @@ export function usePackagePolicySteps({
|
||||||
packagePolicyId,
|
packagePolicyId,
|
||||||
setNewAgentPolicyName,
|
setNewAgentPolicyName,
|
||||||
}: Params) {
|
}: Params) {
|
||||||
|
const spaceSettings = useSpaceSettingsContext();
|
||||||
const [newAgentPolicy, setNewAgentPolicy] = useState<NewAgentPolicy>(
|
const [newAgentPolicy, setNewAgentPolicy] = useState<NewAgentPolicy>(
|
||||||
generateNewAgentPolicyWithDefaults({ name: 'Agent policy 1' })
|
generateNewAgentPolicyWithDefaults({
|
||||||
|
name: 'Agent policy 1',
|
||||||
|
namespace: spaceSettings.defaultNamespace,
|
||||||
|
})
|
||||||
);
|
);
|
||||||
const [withSysMonitoring, setWithSysMonitoring] = useState<boolean>(true);
|
const [withSysMonitoring, setWithSysMonitoring] = useState<boolean>(true);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import {
|
||||||
EuiSpacer,
|
EuiSpacer,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
|
|
||||||
|
import { useSpaceSettingsContext } from '../../../../../../hooks/use_space_settings_context';
|
||||||
import type { NewAgentPolicy, AgentPolicy } from '../../../../types';
|
import type { NewAgentPolicy, AgentPolicy } from '../../../../types';
|
||||||
import { MAX_FLYOUT_WIDTH } from '../../../../constants';
|
import { MAX_FLYOUT_WIDTH } from '../../../../constants';
|
||||||
import { useAuthz, useStartServices, sendCreateAgentPolicy } from '../../../../hooks';
|
import { useAuthz, useStartServices, sendCreateAgentPolicy } from '../../../../hooks';
|
||||||
|
@ -48,12 +49,17 @@ export const CreateAgentPolicyFlyout: React.FunctionComponent<Props> = ({
|
||||||
}) => {
|
}) => {
|
||||||
const { notifications } = useStartServices();
|
const { notifications } = useStartServices();
|
||||||
const hasFleetAllAgentPoliciesPrivileges = useAuthz().fleet.allAgentPolicies;
|
const hasFleetAllAgentPoliciesPrivileges = useAuthz().fleet.allAgentPolicies;
|
||||||
|
const spaceSettings = useSpaceSettingsContext();
|
||||||
const [agentPolicy, setAgentPolicy] = useState<NewAgentPolicy>(
|
const [agentPolicy, setAgentPolicy] = useState<NewAgentPolicy>(
|
||||||
generateNewAgentPolicyWithDefaults()
|
generateNewAgentPolicyWithDefaults({
|
||||||
|
namespace: spaceSettings.defaultNamespace,
|
||||||
|
})
|
||||||
);
|
);
|
||||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||||
const [withSysMonitoring, setWithSysMonitoring] = useState<boolean>(true);
|
const [withSysMonitoring, setWithSysMonitoring] = useState<boolean>(true);
|
||||||
const validation = agentPolicyFormValidation(agentPolicy);
|
const validation = agentPolicyFormValidation(agentPolicy, {
|
||||||
|
allowedNamespacePrefixes: spaceSettings?.allowedNamespacePrefixes,
|
||||||
|
});
|
||||||
const [hasAdvancedSettingsErrors, setHasAdvancedSettingsErrors] = useState<boolean>(false);
|
const [hasAdvancedSettingsErrors, setHasAdvancedSettingsErrors] = useState<boolean>(false);
|
||||||
|
|
||||||
const updateAgentPolicy = (updatedFields: Partial<NewAgentPolicy>) => {
|
const updateAgentPolicy = (updatedFields: Partial<NewAgentPolicy>) => {
|
||||||
|
|
|
@ -51,6 +51,7 @@ describe('AgentDetailsActionMenu', () => {
|
||||||
readAgents: true,
|
readAgents: true,
|
||||||
allAgents: true,
|
allAgents: true,
|
||||||
},
|
},
|
||||||
|
integrations: {},
|
||||||
} as any);
|
} as any);
|
||||||
mockedUseAgentVersion.mockReturnValue('8.10.2');
|
mockedUseAgentVersion.mockReturnValue('8.10.2');
|
||||||
});
|
});
|
||||||
|
@ -133,6 +134,7 @@ describe('AgentDetailsActionMenu', () => {
|
||||||
fleet: {
|
fleet: {
|
||||||
readAgents: false,
|
readAgents: false,
|
||||||
},
|
},
|
||||||
|
integrations: {},
|
||||||
} as any);
|
} as any);
|
||||||
const res = renderAndGetDiagnosticsButton({
|
const res = renderAndGetDiagnosticsButton({
|
||||||
agent: {
|
agent: {
|
||||||
|
|
|
@ -61,6 +61,7 @@ describe('TableRowActions', () => {
|
||||||
readAgents: true,
|
readAgents: true,
|
||||||
allAgents: true,
|
allAgents: true,
|
||||||
},
|
},
|
||||||
|
integrations: {},
|
||||||
} as any);
|
} as any);
|
||||||
mockedUseAgentVersion.mockReturnValue('8.10.2');
|
mockedUseAgentVersion.mockReturnValue('8.10.2');
|
||||||
});
|
});
|
||||||
|
@ -97,6 +98,7 @@ describe('TableRowActions', () => {
|
||||||
fleet: {
|
fleet: {
|
||||||
allAgents: false,
|
allAgents: false,
|
||||||
},
|
},
|
||||||
|
integrations: {},
|
||||||
} as any);
|
} as any);
|
||||||
const res = renderAndGetDiagnosticsButton({
|
const res = renderAndGetDiagnosticsButton({
|
||||||
agent: {
|
agent: {
|
||||||
|
@ -192,6 +194,7 @@ describe('TableRowActions', () => {
|
||||||
fleet: {
|
fleet: {
|
||||||
readAgents: false,
|
readAgents: false,
|
||||||
},
|
},
|
||||||
|
integrations: {},
|
||||||
} as any);
|
} as any);
|
||||||
const res = renderAndGetRestartUpgradeButton({
|
const res = renderAndGetRestartUpgradeButton({
|
||||||
agent: {
|
agent: {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { useFleetStatus } from '../../../../hooks/use_fleet_status';
|
||||||
import { useAuthz } from '../../../../hooks/use_authz';
|
import { useAuthz } from '../../../../hooks/use_authz';
|
||||||
|
|
||||||
import { AgentsApp } from '.';
|
import { AgentsApp } from '.';
|
||||||
|
import { useGetSpaceSettings } from '../../hooks';
|
||||||
|
|
||||||
jest.mock('../../../../hooks/use_fleet_status', () => ({
|
jest.mock('../../../../hooks/use_fleet_status', () => ({
|
||||||
...jest.requireActual('../../../../hooks/use_fleet_status'),
|
...jest.requireActual('../../../../hooks/use_fleet_status'),
|
||||||
|
@ -49,7 +50,9 @@ describe('AgentApp', () => {
|
||||||
readAgents: true,
|
readAgents: true,
|
||||||
allAgents: true,
|
allAgents: true,
|
||||||
},
|
},
|
||||||
|
integrations: {},
|
||||||
} as any);
|
} as any);
|
||||||
|
jest.mocked(useGetSpaceSettings).mockReturnValue({} as any);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render the loading component if the status is loading', async () => {
|
it('should render the loading component if the status is loading', async () => {
|
||||||
|
|
|
@ -28,6 +28,7 @@ import {
|
||||||
KibanaVersionContext,
|
KibanaVersionContext,
|
||||||
useFleetStatus,
|
useFleetStatus,
|
||||||
} from '../../hooks';
|
} from '../../hooks';
|
||||||
|
import { SpaceSettingsContextProvider } from '../../hooks/use_space_settings_context';
|
||||||
|
|
||||||
import { FleetServerFlyout } from '../fleet/components';
|
import { FleetServerFlyout } from '../fleet/components';
|
||||||
|
|
||||||
|
@ -104,24 +105,26 @@ export const IntegrationsAppContext: React.FC<{
|
||||||
<ReactQueryDevtools initialIsOpen={false} />
|
<ReactQueryDevtools initialIsOpen={false} />
|
||||||
<UIExtensionsContext.Provider value={extensions}>
|
<UIExtensionsContext.Provider value={extensions}>
|
||||||
<FleetStatusProvider defaultFleetStatus={fleetStatus}>
|
<FleetStatusProvider defaultFleetStatus={fleetStatus}>
|
||||||
<startServices.customIntegrations.ContextProvider>
|
<SpaceSettingsContextProvider>
|
||||||
<CloudContext>
|
<startServices.customIntegrations.ContextProvider>
|
||||||
<Router history={history}>
|
<CloudContext>
|
||||||
<ReadOnlyContextProvider>
|
<Router history={history}>
|
||||||
<AgentPolicyContextProvider>
|
<ReadOnlyContextProvider>
|
||||||
<PackageInstallProvider startServices={startServices}>
|
<AgentPolicyContextProvider>
|
||||||
<FlyoutContextProvider>
|
<PackageInstallProvider startServices={startServices}>
|
||||||
<IntegrationsHeader
|
<FlyoutContextProvider>
|
||||||
{...{ setHeaderActionMenu, startServices }}
|
<IntegrationsHeader
|
||||||
/>
|
{...{ setHeaderActionMenu, startServices }}
|
||||||
{children}
|
/>
|
||||||
</FlyoutContextProvider>
|
{children}
|
||||||
</PackageInstallProvider>
|
</FlyoutContextProvider>
|
||||||
</AgentPolicyContextProvider>
|
</PackageInstallProvider>
|
||||||
</ReadOnlyContextProvider>
|
</AgentPolicyContextProvider>
|
||||||
</Router>
|
</ReadOnlyContextProvider>
|
||||||
</CloudContext>
|
</Router>
|
||||||
</startServices.customIntegrations.ContextProvider>
|
</CloudContext>
|
||||||
|
</startServices.customIntegrations.ContextProvider>
|
||||||
|
</SpaceSettingsContextProvider>
|
||||||
</FleetStatusProvider>
|
</FleetStatusProvider>
|
||||||
</UIExtensionsContext.Provider>
|
</UIExtensionsContext.Provider>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
|
|
|
@ -21,6 +21,7 @@ jest.mock('../../hooks', () => {
|
||||||
addAgents: true,
|
addAgents: true,
|
||||||
addFleetServers: true,
|
addFleetServers: true,
|
||||||
},
|
},
|
||||||
|
integrations: {},
|
||||||
}),
|
}),
|
||||||
useFleetStatus: jest.fn().mockReturnValue({ isReady: true }),
|
useFleetStatus: jest.fn().mockReturnValue({ isReady: true }),
|
||||||
};
|
};
|
||||||
|
@ -41,6 +42,7 @@ jest.mock('../../hooks/use_request', () => {
|
||||||
sendGetOneAgentPolicy: jest.fn().mockResolvedValue({
|
sendGetOneAgentPolicy: jest.fn().mockResolvedValue({
|
||||||
data: { item: { package_policies: [] } },
|
data: { item: { package_policies: [] } },
|
||||||
}),
|
}),
|
||||||
|
useGetSpaceSettings: jest.fn().mockReturnValue({}),
|
||||||
useGetAgentPolicies: jest.fn(),
|
useGetAgentPolicies: jest.fn(),
|
||||||
useGetEnrollmentSettings: jest.fn().mockReturnValue({
|
useGetEnrollmentSettings: jest.fn().mockReturnValue({
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
|
|
|
@ -22,8 +22,6 @@ import { useFleetServerUnhealthy } from '../../applications/fleet/sections/agent
|
||||||
import type { FlyOutProps } from './types';
|
import type { FlyOutProps } from './types';
|
||||||
import { AgentEnrollmentFlyout } from '.';
|
import { AgentEnrollmentFlyout } from '.';
|
||||||
|
|
||||||
jest.mock('../../hooks/use_authz');
|
|
||||||
|
|
||||||
const render = (props?: Partial<FlyOutProps>) => {
|
const render = (props?: Partial<FlyOutProps>) => {
|
||||||
cleanup();
|
cleanup();
|
||||||
const renderer = createFleetTestRendererMock();
|
const renderer = createFleetTestRendererMock();
|
||||||
|
@ -53,6 +51,7 @@ describe('<AgentEnrollmentFlyout />', () => {
|
||||||
fleet: {
|
fleet: {
|
||||||
readAgentPolicies: true,
|
readAgentPolicies: true,
|
||||||
},
|
},
|
||||||
|
integrations: {},
|
||||||
} as any);
|
} as any);
|
||||||
jest.mocked(useFleetServerStandalone).mockReturnValue({ isFleetServerStandalone: false });
|
jest.mocked(useFleetServerStandalone).mockReturnValue({ isFleetServerStandalone: false });
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ import type {
|
||||||
GetSettingsResponse,
|
GetSettingsResponse,
|
||||||
GetEnrollmentSettingsRequest,
|
GetEnrollmentSettingsRequest,
|
||||||
GetEnrollmentSettingsResponse,
|
GetEnrollmentSettingsResponse,
|
||||||
|
GetSpaceSettingsResponse,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
|
|
||||||
import { API_VERSIONS } from '../../../common/constants';
|
import { API_VERSIONS } from '../../../common/constants';
|
||||||
|
@ -42,6 +43,19 @@ export function useGetSettings() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useGetSpaceSettings({ enabled }: { enabled?: boolean }) {
|
||||||
|
return useQuery<GetSpaceSettingsResponse, RequestError>({
|
||||||
|
queryKey: ['space_settings'],
|
||||||
|
enabled,
|
||||||
|
queryFn: () =>
|
||||||
|
sendRequestForRq<GetSpaceSettingsResponse>({
|
||||||
|
method: 'get',
|
||||||
|
path: settingsRoutesService.getSpaceInfoPath(),
|
||||||
|
version: API_VERSIONS.public.v1,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function sendGetSettings() {
|
export function sendGetSettings() {
|
||||||
return sendRequest<GetSettingsResponse>({
|
return sendRequest<GetSettingsResponse>({
|
||||||
method: 'get',
|
method: 'get',
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* 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 from 'react';
|
||||||
|
|
||||||
|
import { createFleetTestRendererMock } from '../mock';
|
||||||
|
import { ExperimentalFeaturesService } from '../services';
|
||||||
|
|
||||||
|
import { useGetSpaceSettings } from './use_request';
|
||||||
|
import {
|
||||||
|
SpaceSettingsContextProvider,
|
||||||
|
useSpaceSettingsContext,
|
||||||
|
} from './use_space_settings_context';
|
||||||
|
|
||||||
|
jest.mock('./use_request');
|
||||||
|
jest.mock('../services');
|
||||||
|
|
||||||
|
describe('useSpaceSettingsContext', () => {
|
||||||
|
function renderHook() {
|
||||||
|
return createFleetTestRendererMock().renderHook(
|
||||||
|
() => useSpaceSettingsContext(),
|
||||||
|
({ children }: { children: any }) => (
|
||||||
|
<SpaceSettingsContextProvider>{children}</SpaceSettingsContextProvider>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.mocked(ExperimentalFeaturesService.get).mockReturnValue({
|
||||||
|
useSpaceAwareness: true,
|
||||||
|
} as any);
|
||||||
|
jest.mocked(useGetSpaceSettings).mockReturnValue({} as any);
|
||||||
|
});
|
||||||
|
it('should return default defaultNamespace if no restrictions', () => {
|
||||||
|
const res = renderHook();
|
||||||
|
expect(res.result.current.defaultNamespace).toBe('default');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return restricted defaultNamespace if there is namespace prefix restrictions', () => {
|
||||||
|
jest.mocked(useGetSpaceSettings).mockReturnValue({
|
||||||
|
isInitialLoading: false,
|
||||||
|
data: {
|
||||||
|
item: {
|
||||||
|
allowed_namespace_prefixes: ['test'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as any);
|
||||||
|
const res = renderHook();
|
||||||
|
expect(res.result.current.defaultNamespace).toBe('test');
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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, { createContext, useContext } from 'react';
|
||||||
|
|
||||||
|
import { ExperimentalFeaturesService } from '../services';
|
||||||
|
|
||||||
|
import { useAuthz } from './use_authz';
|
||||||
|
import { useGetSpaceSettings } from './use_request';
|
||||||
|
|
||||||
|
const spaceSettingsContext = createContext<{
|
||||||
|
isInitialLoading?: boolean;
|
||||||
|
allowedNamespacePrefixes: string[];
|
||||||
|
defaultNamespace: string;
|
||||||
|
}>({
|
||||||
|
allowedNamespacePrefixes: [],
|
||||||
|
defaultNamespace: 'default',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const SpaceSettingsContextProvider: React.FC<{
|
||||||
|
enabled?: boolean;
|
||||||
|
children?: React.ReactNode;
|
||||||
|
}> = ({ enabled = true, children }) => {
|
||||||
|
const useSpaceAwareness = ExperimentalFeaturesService.get()?.useSpaceAwareness ?? false;
|
||||||
|
const authz = useAuthz();
|
||||||
|
const isAllowed =
|
||||||
|
authz.fleet.allAgentPolicies ||
|
||||||
|
authz.fleet.allSettings ||
|
||||||
|
authz.integrations.writeIntegrationPolicies;
|
||||||
|
const spaceSettingsReq = useGetSpaceSettings({
|
||||||
|
enabled: useSpaceAwareness && enabled && isAllowed,
|
||||||
|
});
|
||||||
|
|
||||||
|
const settings = React.useMemo(() => {
|
||||||
|
return {
|
||||||
|
isInitialLoading: spaceSettingsReq.isInitialLoading,
|
||||||
|
allowedNamespacePrefixes: spaceSettingsReq.data?.item.allowed_namespace_prefixes ?? [],
|
||||||
|
defaultNamespace: spaceSettingsReq.data?.item.allowed_namespace_prefixes?.[0] ?? 'default',
|
||||||
|
};
|
||||||
|
}, [spaceSettingsReq.isInitialLoading, spaceSettingsReq.data]);
|
||||||
|
|
||||||
|
return <spaceSettingsContext.Provider value={settings}>{children}</spaceSettingsContext.Provider>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function useSpaceSettingsContext() {
|
||||||
|
return useContext(spaceSettingsContext);
|
||||||
|
}
|
|
@ -112,9 +112,17 @@ export const createFleetTestRendererMock = (): TestRenderer => {
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
HookWrapper,
|
HookWrapper,
|
||||||
renderHook: (callback) => {
|
renderHook: (
|
||||||
|
callback,
|
||||||
|
ExtraWrapper: WrapperComponent<any> = memo(({ children }) => <>{children}</>)
|
||||||
|
) => {
|
||||||
|
const wrapper: WrapperComponent<any> = ({ children }) => (
|
||||||
|
<testRendererMocks.HookWrapper>
|
||||||
|
<ExtraWrapper>{children}</ExtraWrapper>
|
||||||
|
</testRendererMocks.HookWrapper>
|
||||||
|
);
|
||||||
return renderHook(callback, {
|
return renderHook(callback, {
|
||||||
wrapper: testRendererMocks.HookWrapper,
|
wrapper,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
render: (ui, options) => {
|
render: (ui, options) => {
|
||||||
|
@ -135,6 +143,7 @@ export const createFleetTestRendererMock = (): TestRenderer => {
|
||||||
export const createIntegrationsTestRendererMock = (): TestRenderer => {
|
export const createIntegrationsTestRendererMock = (): TestRenderer => {
|
||||||
const basePath = '/mock';
|
const basePath = '/mock';
|
||||||
const extensions: UIExtensionsStorage = {};
|
const extensions: UIExtensionsStorage = {};
|
||||||
|
ExperimentalFeaturesService.init(allowedExperimentalValues);
|
||||||
const startServices = createStartServices(basePath);
|
const startServices = createStartServices(basePath);
|
||||||
const HookWrapper = memo(({ children }: { children?: React.ReactNode }) => {
|
const HookWrapper = memo(({ children }: { children?: React.ReactNode }) => {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -144,6 +144,7 @@ export type {
|
||||||
EnrollmentSettingsFleetServerPolicy,
|
EnrollmentSettingsFleetServerPolicy,
|
||||||
GetEnrollmentSettingsRequest,
|
GetEnrollmentSettingsRequest,
|
||||||
GetEnrollmentSettingsResponse,
|
GetEnrollmentSettingsResponse,
|
||||||
|
GetSpaceSettingsResponse,
|
||||||
} from '../../common/types';
|
} from '../../common/types';
|
||||||
export {
|
export {
|
||||||
entries,
|
entries,
|
||||||
|
|
|
@ -42,7 +42,7 @@ export const putSpaceSettingsHandler: FleetRequestHandler<
|
||||||
},
|
},
|
||||||
spaceId: soClient.getCurrentNamespace(),
|
spaceId: soClient.getCurrentNamespace(),
|
||||||
});
|
});
|
||||||
const settings = await settingsService.getSettings(soClient);
|
const settings = await getSpaceSettings(soClient.getCurrentNamespace());
|
||||||
const body = {
|
const body = {
|
||||||
item: settings,
|
item: settings,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue