-
Notifications
You must be signed in to change notification settings - Fork 324
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
Validate CR namespaces based on consul namespaces #375
Conversation
b879076
to
4e01b71
Compare
} | ||
} | ||
|
||
func TestServiceIntentions_ValidateNamespaces(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests were slightly modified and moved into the TestServiceIntentions_Validate tests since as of this PR ValidateNamespaces is no longer its own exported method, but rather a private method called by Validate()
expectedErrMsg: []string{ | ||
`namespace: Invalid value: "namespaceA": consul namespaces must be enabled to set source.namespace`, | ||
`namespace: Invalid value: "namespaceB": consul namespaces must be enabled to set source.namespace`, | ||
`namespace: Invalid value: "namespaceC": consul namespaces must be enabled to set source.namespace`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that when there are multiple errors I did not assert on every character in the error message. Since the order is not deterministic, we don't know if spec.sources[0].namespace
is going to refer to namespaceA
or namespaceB
or namespaceC
, so I omitted that part of the assertion. From the current assertion, we will know that all 3 of these strings are in the error message, so we are asserting on multiple errors, but not every character.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my suggestion below, since this is an array I think we can safely assert on the index. spec.source[0].namespace
should hopefully always be namespaceA
since order matters in these sources.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah thank you for this catch! Makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! I really like the refactor moving ValidateNamespaces
inside Validate
and the attention to detail.
In addition to my inline comments, I wonder if we should use Consul Enterprise namespaces must be enabled
instead of consul namespaces must be enabled
as our error message? That way we don't have OSS folks trying to enable consul namespaces.
expectedErrMsg string | ||
input *ServiceResolver | ||
namespacesEnabled bool | ||
expectedErrMsg []string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
expectedErrMsg []string | |
expectedErrMsgs []string |
require.EqualError(t, err, testCase.expectedErrMsg) | ||
err := testCase.input.Validate(testCase.namespacesEnabled) | ||
if len(testCase.expectedErrMsg) != 0 { | ||
for _, s := range testCase.expectedErrMsg { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for _, s := range testCase.expectedErrMsg { | |
require.Error(t, err) | |
for _, s := range testCase.expectedErrMsg { |
You need this check otherwise if err == nil
then I think err.Error()
will panic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(this is true for the other tests I believe)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, I'll make this change to all of the tests 💯
4e01b71
to
4a66632
Compare
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "does-not-matter", | ||
}, | ||
Spec: ServiceIntentionsSpec{ | ||
Destination: Destination{ | ||
Name: "dest-service", | ||
Namespace: "foo", | ||
Namespace: "namespaceA", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor nit here, but I ran into this problem the other day when building a test that had an upper case letter for Namespaces in consul. Consul will automatically convert this to all lowercase letters, so if you're asserting later that the output is namespaceA
(which I don't believe you are) from Consul it will not pass. I think it's best to keep our tests with lowercase namespaces as those are valid for both k8s and Consul.
What do you think?
Namespace: "namespaceA", | |
Namespace: "namespace-a", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's best to keep our tests with lowercase namespaces as those are valid for both k8s and Consul.
Yeah, I agree, I'll make this change!
Are the namespaces in consul tied to the corresponding k8s namespace? Would anyone ever write a serviceintention for example with a namespace with capital letters? Or because the namespace is inherently linked between consul and k8s it will only ever be lowercase in both?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually capital letters are not even valid in k8s, so it would cover both!
kyle@kyles-mbp consul-helm % kubectl create namespace ABCD
The Namespace "ABCD" is invalid: metadata.name: Invalid value: "ABCD": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')
And I do not think anyone would ever write a service intention to a consul namespace with capitals because consul wouldn't ever have a namespace with capitals - that being said I'm not sure if it silently converts them to lowercase and returns success or would return failure in this scenario.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, thanks for the explanation!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah great catch!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great!
I added a couple comments which aren't blockers.
e267e48
to
ca08cc0
Compare
ServiceRouters, ServiceResolvers, ServiceSplitters, and ServiceIntentions should only have namespaces set in their spec when consul namespaces are enabled. When consul namespaces are disabled, the webhook now returns a validation error if these CRs have a namespace. Previously, users could apply CRs with namespaces set even when consul namespaces are disabled, causing them to think the namespaces might be having an effect when they are not. Co-authored-by: Ashwin Venkatesh <ashwin@hashicorp.com>
This would make it easier for a user to understand that they need Consul Enterprise in order to enable namespaces.
ca08cc0
to
00bc0f1
Compare
* Support auto-encrypt Setting the global.tls.enableAutoEncrypt will now enable auto-encrypt for clients and servers and switch consul-k8s components that need to talk to the clients (connect injector, mesh gateway, sync catalog, and snapshot agent) to now get the CA through the API from the Consul server before they start. Optionally, allow configuring external server information to be used for HTTPS API. Currently, this is only used to retrieve client's CA when using auto-encrypt, but it could potentially be extended for other use cases (e.g. ACL bootstrapping) when the Consul server cluster is outside of k8s.
ServiceRouters, ServiceResolvers, ServiceSplitters, and
ServiceIntentions should only have namespaces set in their spec when
consul namespaces are enabled. When consul namespaces are disabled, the
webhook now returns a validation error if these CRs have a namespace.
Previously, users could apply CRs with namespaces set even when consul
namespaces are disabled, causing them to think the namespaces might be
having an effect when they are not.
Co-authored-by: Ashwin Venkatesh ashwin@hashicorp.com
How I've tested this PR:
make test
)gcr.io/nitya-293720/consul-k8s-dev@sha256:80044a89e92a32dc782117b7bc9626f8aebecf2b5253a6996d141969ef81bf7b
gcr.io/nitya-293720/consul-k8s-dev@sha256:80044a89e92a32dc782117b7bc9626f8aebecf2b5253a6996d141969ef81bf7b
and applied the following ServiceIntention, ServiceResolver, ServiceRouter, ServiceSplitter with namespaces and verified I saw the right errors in each case.Sample Error from ServiceIntention:
How I expect reviewers to test this PR:
Checklist: