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

Update provider name field's validation rules to align with k8s rules #713

Merged
merged 1 commit into from
Sep 5, 2023

Conversation

sgratch
Copy link
Collaborator

@sgratch sgratch commented Sep 3, 2023

Fixes: #712

The current UI validation rules for the Provider resource name field are not aligned with Kubernetes DNS Subdomain Name standards:

(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names)

  • The '.' character should be allowed
  • Allow starting with an alphanumeric character.

This patch fixes the validation rules for this field.

@sgratch sgratch requested review from yaacov and rszwajko September 3, 2023 18:24
@yaacov
Copy link
Member

yaacov commented Sep 4, 2023

can you separate this PR to:
a. PR that fix the validation method in common
b. PR that enhance the help strings
?

@yaacov yaacov added the bug Categorizes issue or PR as related to a bug. label Sep 4, 2023
@yaacov yaacov added this to the 2.5.0 milestone Sep 4, 2023
Comment on lines 47 to 50
const DNS_LABEL_NAME_REGEXP = '[a-z0-9]([-a-z0-9]*[a-z0-9])?';
const DNS_SUBDOMAINS_NAME_REGEXP = new RegExp(
`^(${DNS_LABEL_NAME_REGEXP}([.]${DNS_LABEL_NAME_REGEXP})*)$`,
);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
const DNS_LABEL_NAME_REGEXP = '[a-z0-9]([-a-z0-9]*[a-z0-9])?';
const DNS_SUBDOMAINS_NAME_REGEXP = new RegExp(
`^(${DNS_LABEL_NAME_REGEXP}([.]${DNS_LABEL_NAME_REGEXP})*)$`,
);
const DNS_SUBDOMAINS_NAME_REGEXP = /^[a-z0-9][a-z0-9-.]{0,251}[a-z0-9]$/;

this changes:
a. add numeric char as valid first char
b. add [.] as valid char in the middle of the name.

problems with current solution:
a. removes the length check, ( so it is required it in the validation method )
b. allow the last char to be . or - , the documentation say "end with an alphanumeric character
"

note: this change in the regexp requires removal of the length check in the method below because it is now done in the regexp, like we do in the rest of the regexp in this file.

Copy link
Collaborator Author

@sgratch sgratch Sep 5, 2023

Choose a reason for hiding this comment

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

Few comments:

  • The current solution doesn't allow the last char to be '.' or '-'. Why do you think it is?
  • The difference between your suggested solution to current is that the following examples are invalid in current and valid in suggested:
    "a..b" (2 sequential dots)
    "a.-b" ("-" following ".")
    "a-.b" ("." following "-")

The current code that I used was copied from backend forklift validation code and is also relevant to other k8s entities, for example Pod name.
So even though the k8s doc doesn't mention that 2 sequential dots are invalid, it's verified for other entities and used in backend, I guess for validating domain names.
I didn't mention that in our validation text message since it's detailed and not mentioned in k8s validation text message as well. But can be added if you think otherwise.

Copy link
Member

Choose a reason for hiding this comment

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

The current code that I used was copied from backend forklift validation code and is also relevant to other k8s entities, for example Pod name.

you should follow RFC 1123

the fix I suggest will not block users from entering correct names, but you are correct it can be more restrictive (not sure it's a good thing ... ), here is a more restrictive option:

Suggested change
const DNS_LABEL_NAME_REGEXP = '[a-z0-9]([-a-z0-9]*[a-z0-9])?';
const DNS_SUBDOMAINS_NAME_REGEXP = new RegExp(
`^(${DNS_LABEL_NAME_REGEXP}([.]${DNS_LABEL_NAME_REGEXP})*)$`,
);
const DNS_SUBDOMAINS_NAME_REGEXP = /^(?=.{1,253}$)[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$/;

this regexp is more complex, but does the job, i don't see the benefit of separating it to label name and subdomain name.

Copy link
Member

Choose a reason for hiding this comment

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

I'm ok with the simple (less restrictive) regexp, and more restrictive options too, both will not block users from entring valid names, one is simple but will allow invalid names, the other more restrictive but also more complex.

a comment in the code with refernce to RFC 1123 or link to k8s documentation will be nice touch

Copy link
Member

Choose a reason for hiding this comment

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

The current code that I used was copied from backend forklift validation

I can't find the reference code in forklift, can you add a link to the reference implementation in forklift ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

i don't see the benefit of separating it to label name and subdomain name.

If there will be no need to validate DNS-LABEL based names then ok. I thought it's more flexible to use the SUBDOMAIN based on the LABEL format, as done on k8s api validation, but sure. We can always add it later on if needed.

can't find the reference code in forklift, can you add a link to the reference implementation in forklift ?

The API validation code for DNS-SUBDOMAIN names (e.g. pod name) is: https://github.com/kubernetes/apimachinery/blob/0d057e543013c79e20abb000df19bc16d286b777/pkg/util/validation/validation.go#L205

In Forklift we mainly validate based on the DNS-LABEL format for the VM name (e.g. https://github.com/kubev2v/forklift/blob/a1671edf995a93d728c50e90cccff007a6fec3fc/pkg/controller/plan/validation.go#L398)
No validation for the provider name, but since other k8s entities names uses the DNS-SUBDOMAIN validation then I thought we should do the same.

Copy link
Member

Choose a reason for hiding this comment

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

If there will be no need to validate DNS-LABEL based names then ok. I thought it's more flexible to use the SUBDOMAIN based on the LABEL format, as done on k8s api validation, but sure. We can always add it later on if needed.

Nice 👍

The API validation code for DNS-SUBDOMAIN names (e.g. pod name) is: https://github.com/kubernetes/apimachinery/blob/0d057e543013c79e20abb000df19bc16d286b777/pkg/util/validation/validation.go#L205

Greate, we can add a link as remark in our code 🔥

If there will be no need to validate DNS-LABEL based names then ok.

Yes, they have more specific needs, we only need to be more or less accurate, the "real" validation will happen when the API call is made, and then we will show the msg we get.

Lets do something simple (restrictive or less restrictive ) in our end, we can trust the back-end to do the full validation.

@@ -74,7 +77,7 @@ export function validateFingerprint(fingerprint: string) {
}

export function validateK8sName(k8sName: string) {
return DNS_SUBDOMAINS_NAME_REGEXP.test(k8sName);
return DNS_SUBDOMAINS_NAME_REGEXP.test(k8sName) && k8sName?.length <= 253;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return DNS_SUBDOMAINS_NAME_REGEXP.test(k8sName) && k8sName?.length <= 253;
return DNS_SUBDOMAINS_NAME_REGEXP.test(k8sName);

the change in https://github.com/kubev2v/forklift-console-plugin/pull/713/files#r1314450788 make it unnecessary to check the length here

});

it('invalidates k8s names with invalid characters', () => {
expect(validateK8sName('k8s_name')).toBe(false);
expect(validateK8sName('k8s.name')).toBe(false);
expect(validateK8sName('k8s%name')).toBe(false);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
expect(validateK8sName('k8s%name')).toBe(false);
expect(validateK8sName('k8s%name')).toBe(false);
expect(validateK8sName('k8sname.')).toBe(false);
expect(validateK8sName('.k8sname')).toBe(false);

@@ -97,7 +97,7 @@
"Error: CA Certificate must be valid.": "Error: CA Certificate must be valid.",
"Error: Fingerprint is required and must be valid.": "Error: Fingerprint is required and must be valid.",
"Error: Insecure Skip Verify must be a boolean value.": "Error: Insecure Skip Verify must be a boolean value.",
"Error: Name is required and must be a unique and valid Kubernetes name.": "Error: Name is required and must be a unique and valid Kubernetes name.",
"Error: Name is required and must be a unique within a namespace and valid Kubernetes name (i.e. must contain no more than 253 characters, consists of lower case alphanumeric characters , '-' or '.' and starts and ends with an alphanumeric character).": "Error: Name is required and must be a unique within a namespace and valid Kubernetes name (i.e. must contain no more than 253 characters, consists of lower case alphanumeric characters , '-' or '.' and starts and ends with an alphanumeric character).",
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"Error: Name is required and must be a unique within a namespace and valid Kubernetes name (i.e. must contain no more than 253 characters, consists of lower case alphanumeric characters , '-' or '.' and starts and ends with an alphanumeric character).": "Error: Name is required and must be a unique within a namespace and valid Kubernetes name (i.e. must contain no more than 253 characters, consists of lower case alphanumeric characters , '-' or '.' and starts and ends with an alphanumeric character).",
"Error: Name is required and must be a unique within a namespace and valid Kubernetes name (i.e., must contain no more than 253 characters, consists of lower case alphanumeric characters , '-' or '.' and starts and ends with an alphanumeric character).": "Error: Name is required and must be a unique within a namespace and valid Kubernetes name (i.e., must contain no more than 253 characters, consists of lower case alphanumeric characters , '-' or '.' and starts and ends with an alphanumeric character).",

@@ -106,7 +106,7 @@ export const ProvidersCreateForm: React.FC<ProvidersCreateFormProps> = ({
helperText={t('Unique Kubernetes resource name identifier')}
validated={state.validation.name}
helperTextInvalid={t(
'Error: Name is required and must be a unique and valid Kubernetes name.',
"Error: Name is required and must be a unique within a namespace and valid Kubernetes name (i.e. must contain no more than 253 characters, consists of lower case alphanumeric characters , '-' or '.' and starts and ends with an alphanumeric character).",
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"Error: Name is required and must be a unique within a namespace and valid Kubernetes name (i.e. must contain no more than 253 characters, consists of lower case alphanumeric characters , '-' or '.' and starts and ends with an alphanumeric character).",
"Error: Name is required and must be a unique within a namespace and valid Kubernetes name (i.e., must contain no more than 253 characters, consists of lower case alphanumeric characters , '-' or '.' and starts and ends with an alphanumeric character).",

@ahadas ahadas modified the milestones: 2.5.0, 2.5.1 Sep 5, 2023
@sgratch
Copy link
Collaborator Author

sgratch commented Sep 5, 2023

can you separate this PR to: a. PR that fix the validation method in common b. PR that enhance the help strings ?

@yaacov sure, but what's the purpose of separating if this fix won't be part of 2.5?

@yaacov
Copy link
Member

yaacov commented Sep 5, 2023

what's the purpose of separating if this fix won't be part of 2.5?

fixing RFC 952 to RFC 1123 (#712) is a bug in the way we do validations, we need it tracked and verified

fixing the tooltips (#646) is about help texts, this can change and update as we know more about the fields and what users know and don't know when the use the form.

@sgratch sgratch force-pushed the fix-provider-name-validation branch from 8b5f966 to 40ac479 Compare September 5, 2023 14:06
@sgratch sgratch changed the title Update provider name field's validation rules and validation text to align with k8s rules Update provider name field's validation rules to align with k8s rules Sep 5, 2023
@sgratch sgratch requested a review from yaacov September 5, 2023 15:02
The current UI validation rules for the Provider resource name value
are not aligned with Kubernetes DNS Subdomain Name standards:
(https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names)

- The '.' character should be allowed
- Allow starting with an alphanumeric character.

Signed-off-by: Sharon Gratch <[email protected]>
@sgratch sgratch force-pushed the fix-provider-name-validation branch from 40ac479 to 8151241 Compare September 5, 2023 15:13
@sonarqubecloud
Copy link

sonarqubecloud bot commented Sep 5, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

@yaacov yaacov merged commit 3f6a515 into kubev2v:main Sep 5, 2023
sgratch added a commit to sgratch/forklift-console-plugin that referenced this pull request Sep 7, 2023
Update the validation error message for the 'Provider resource name' field
to align with k8s rules.
This is following the validation fix: kubev2v#713

Signed-off-by: Sharon Gratch <[email protected]>
sgratch added a commit to sgratch/forklift-console-plugin that referenced this pull request Sep 7, 2023
Update the validation error message for the 'Provider resource name' field
to align with k8s rules.
This is following the validation fix: kubev2v#713

Signed-off-by: Sharon Gratch <[email protected]>
sgratch added a commit to sgratch/forklift-console-plugin that referenced this pull request Sep 7, 2023
Update the validation error message for the 'Provider resource name' field
to align with k8s rules.
This is following the validation fix: kubev2v#713

Signed-off-by: Sharon Gratch <[email protected]>
@sgratch sgratch deleted the fix-provider-name-validation branch September 7, 2023 17:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Categorizes issue or PR as related to a bug.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

UI validation rules for the Provider resource name are not aligned with Kubernetes standards
3 participants