mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
* Add namespace limit validation rule * Fix tests * Revise error message * Remove console.log
This commit is contained in:
parent
63cfbdba5a
commit
d9dfc5f39f
6 changed files with 95 additions and 51 deletions
|
@ -7,22 +7,32 @@ import { isValidNamespace } from './is_valid_namespace';
|
|||
|
||||
describe('Ingest Manager - isValidNamespace', () => {
|
||||
it('returns true for valid namespaces', () => {
|
||||
expect(isValidNamespace('default')).toBe(true);
|
||||
expect(isValidNamespace('namespace-with-dash')).toBe(true);
|
||||
expect(isValidNamespace('123')).toBe(true);
|
||||
expect(isValidNamespace('default').valid).toBe(true);
|
||||
expect(isValidNamespace('namespace-with-dash').valid).toBe(true);
|
||||
expect(isValidNamespace('123').valid).toBe(true);
|
||||
expect(isValidNamespace('testlength😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀').valid).toBe(
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
it('returns false for invalid namespaces', () => {
|
||||
expect(isValidNamespace('Default')).toBe(false);
|
||||
expect(isValidNamespace('namespace with spaces')).toBe(false);
|
||||
expect(isValidNamespace('foo/bar')).toBe(false);
|
||||
expect(isValidNamespace('foo\\bar')).toBe(false);
|
||||
expect(isValidNamespace('foo*bar')).toBe(false);
|
||||
expect(isValidNamespace('foo?bar')).toBe(false);
|
||||
expect(isValidNamespace('foo"bar')).toBe(false);
|
||||
expect(isValidNamespace('foo<bar')).toBe(false);
|
||||
expect(isValidNamespace('foo|bar')).toBe(false);
|
||||
expect(isValidNamespace('foo,bar')).toBe(false);
|
||||
expect(isValidNamespace('foo#bar')).toBe(false);
|
||||
expect(isValidNamespace('').valid).toBe(false);
|
||||
expect(isValidNamespace(' ').valid).toBe(false);
|
||||
expect(isValidNamespace('Default').valid).toBe(false);
|
||||
expect(isValidNamespace('namespace with spaces').valid).toBe(false);
|
||||
expect(isValidNamespace('foo/bar').valid).toBe(false);
|
||||
expect(isValidNamespace('foo\\bar').valid).toBe(false);
|
||||
expect(isValidNamespace('foo*bar').valid).toBe(false);
|
||||
expect(isValidNamespace('foo?bar').valid).toBe(false);
|
||||
expect(isValidNamespace('foo"bar').valid).toBe(false);
|
||||
expect(isValidNamespace('foo<bar').valid).toBe(false);
|
||||
expect(isValidNamespace('foo|bar').valid).toBe(false);
|
||||
expect(isValidNamespace('foo,bar').valid).toBe(false);
|
||||
expect(isValidNamespace('foo#bar').valid).toBe(false);
|
||||
expect(
|
||||
isValidNamespace(
|
||||
'testlength😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀'
|
||||
).valid
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,15 +3,49 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
// Namespace string eventually becomes part of an index name. This method partially implements index name rules from
|
||||
// https://github.com/elastic/elasticsearch/blob/master/docs/reference/indices/create-index.asciidoc
|
||||
export function isValidNamespace(namespace: string) {
|
||||
return (
|
||||
typeof namespace === 'string' &&
|
||||
// Lowercase only
|
||||
namespace === namespace.toLowerCase() &&
|
||||
// Cannot include \, /, *, ?, ", <, >, |, space character, comma, #, :
|
||||
/^[^\*\\/\?"<>|\s,#:]+$/.test(namespace)
|
||||
);
|
||||
// and implements a limit based on https://github.com/elastic/kibana/issues/75846
|
||||
export function isValidNamespace(namespace: string): { valid: boolean; error?: string } {
|
||||
if (!namespace.trim()) {
|
||||
return {
|
||||
valid: false,
|
||||
error: i18n.translate('xpack.ingestManager.namespaceValidation.requiredErrorMessage', {
|
||||
defaultMessage: 'Namespace is required',
|
||||
}),
|
||||
};
|
||||
} else if (namespace !== namespace.toLowerCase()) {
|
||||
return {
|
||||
valid: false,
|
||||
error: i18n.translate('xpack.ingestManager.namespaceValidation.lowercaseErrorMessage', {
|
||||
defaultMessage: 'Namespace must be lowercase',
|
||||
}),
|
||||
};
|
||||
} else if (/[\*\\/\?"<>|\s,#:]+/.test(namespace)) {
|
||||
return {
|
||||
valid: false,
|
||||
error: i18n.translate(
|
||||
'xpack.ingestManager.namespaceValidation.invalidCharactersErrorMessage',
|
||||
{
|
||||
defaultMessage: 'Namespace contains invalid characters',
|
||||
}
|
||||
),
|
||||
};
|
||||
}
|
||||
// Node.js doesn't have Blob, and browser doesn't have Buffer :)
|
||||
else if (
|
||||
(typeof Blob === 'function' && new Blob([namespace]).size > 100) ||
|
||||
(typeof Buffer === 'function' && Buffer.from(namespace).length > 100)
|
||||
) {
|
||||
return {
|
||||
valid: false,
|
||||
error: i18n.translate('xpack.ingestManager.namespaceValidation.tooLongErrorMessage', {
|
||||
defaultMessage: 'Namespace cannot be more than 100 bytes',
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
return { valid: true };
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import { isValidNamespace } from '../../../services';
|
|||
import { AgentPolicyDeleteProvider } from './agent_policy_delete_provider';
|
||||
|
||||
interface ValidationResults {
|
||||
[key: string]: JSX.Element[];
|
||||
[key: string]: Array<JSX.Element | string>;
|
||||
}
|
||||
|
||||
const StyledEuiAccordion = styled(EuiAccordion)`
|
||||
|
@ -41,6 +41,7 @@ export const agentPolicyFormValidation = (
|
|||
agentPolicy: Partial<NewAgentPolicy | AgentPolicy>
|
||||
): ValidationResults => {
|
||||
const errors: ValidationResults = {};
|
||||
const namespaceValidation = isValidNamespace(agentPolicy.namespace || '');
|
||||
|
||||
if (!agentPolicy.name?.trim()) {
|
||||
errors.name = [
|
||||
|
@ -51,20 +52,8 @@ export const agentPolicyFormValidation = (
|
|||
];
|
||||
}
|
||||
|
||||
if (!agentPolicy.namespace?.trim()) {
|
||||
errors.namespace = [
|
||||
<FormattedMessage
|
||||
id="xpack.ingestManager.agentPolicyForm.namespaceRequiredErrorMessage"
|
||||
defaultMessage="A namespace is required"
|
||||
/>,
|
||||
];
|
||||
} else if (!isValidNamespace(agentPolicy.namespace)) {
|
||||
errors.namespace = [
|
||||
<FormattedMessage
|
||||
id="xpack.ingestManager.agentPolicyForm.namespaceInvalidErrorMessage"
|
||||
defaultMessage="Namespace contains invalid characters"
|
||||
/>,
|
||||
];
|
||||
if (!namespaceValidation.valid && namespaceValidation.error) {
|
||||
errors.namespace = [namespaceValidation.error];
|
||||
}
|
||||
|
||||
return errors;
|
||||
|
|
|
@ -50,6 +50,7 @@ export const validatePackagePolicy = (
|
|||
namespace: null,
|
||||
inputs: {},
|
||||
};
|
||||
const namespaceValidation = isValidNamespace(packagePolicy.namespace);
|
||||
|
||||
if (!packagePolicy.name.trim()) {
|
||||
validationResults.name = [
|
||||
|
@ -59,18 +60,8 @@ export const validatePackagePolicy = (
|
|||
];
|
||||
}
|
||||
|
||||
if (!packagePolicy.namespace.trim()) {
|
||||
validationResults.namespace = [
|
||||
i18n.translate('xpack.ingestManager.packagePolicyValidation.namespaceRequiredErrorMessage', {
|
||||
defaultMessage: 'Namespace is required',
|
||||
}),
|
||||
];
|
||||
} else if (!isValidNamespace(packagePolicy.namespace)) {
|
||||
validationResults.namespace = [
|
||||
i18n.translate('xpack.ingestManager.packagePolicyValidation.namespaceInvalidErrorMessage', {
|
||||
defaultMessage: 'Namespace contains invalid characters',
|
||||
}),
|
||||
];
|
||||
if (!namespaceValidation.valid && namespaceValidation.error) {
|
||||
validationResults.namespace = [namespaceValidation.error];
|
||||
}
|
||||
|
||||
if (
|
||||
|
|
|
@ -9,8 +9,9 @@ import { isValidNamespace } from '../../../common';
|
|||
export const NamespaceSchema = schema.string({
|
||||
minLength: 1,
|
||||
validate: (value) => {
|
||||
if (!isValidNamespace(value)) {
|
||||
return 'Namespace contains invalid characters';
|
||||
const namespaceValidation = isValidNamespace(value || '');
|
||||
if (!namespaceValidation.valid && namespaceValidation.error) {
|
||||
return namespaceValidation.error;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -101,6 +101,25 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
},
|
||||
})
|
||||
.expect(400);
|
||||
await supertest
|
||||
.post(`/api/ingest_manager/package_policies`)
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.send({
|
||||
name: 'filetest-1',
|
||||
description: '',
|
||||
namespace:
|
||||
'testlength😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀',
|
||||
policy_id: agentPolicyId,
|
||||
enabled: true,
|
||||
output_id: '',
|
||||
inputs: [],
|
||||
package: {
|
||||
name: 'filetest',
|
||||
title: 'For File Tests',
|
||||
version: '0.1.0',
|
||||
},
|
||||
})
|
||||
.expect(400);
|
||||
} else {
|
||||
warnAndSkipTest(this, log);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue