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

Potential overrides in name caused by lack of namespace #17

Open
asimpleidea opened this issue Dec 15, 2020 · 14 comments
Open

Potential overrides in name caused by lack of namespace #17

asimpleidea opened this issue Dec 15, 2020 · 14 comments
Assignees
Labels
documentation Improvements or additions to documentation enhancement New feature or request

Comments

@asimpleidea
Copy link
Member

asimpleidea commented Dec 15, 2020

TL;DR

In some cases, especially with manual insertions and dns, some services may overlap.
To avoid this, from now on Names sent as Event will follow the same convention as Kubernetes service names and have a dns-like format, e.g.: nodejs-k89sv54jf7.production, although the first part really being the endpoint name.

Current situation

Currently, a service is sent to adaptors as following:

Name Type Description Notes
Name string The observed name of the endpoint.
Address string The observed IP address of the endpoint. Can be IPv4 or IPv6.
Port int32 The observed port of the endpoint.
Metadata []Metadata [optional]

This is fine, but I just noticed that the two equal names my-service but in two different namespaces will cause a adaptors to override pre-existing values.

Service Directory

If I remember right, when testing with the services pulled from Service Directory with @jordipv, we found that the names contain the full path as found in there - something along the lines of /projects/my-project/locations/us-west-4/namespaces/prod/services/my-service/endpoints/my-service-sjr8ksf0 (I realized I wasn't re-formatting names, but this wasn't really necessary at that time). So this prevented overrides until now, but may cause issues for other services. Apart from being very un-readable of course.

When can this happen

This can happen very easily with DNS when a service has multiple A or AAAA records. TBF, the chances of this happening are high only for records inserted manually, as the Operator already takes care of this.

Name convention

In order to avoid confusion, Name will follow the same convention as Kubernetes service names and have a dns-like format, e.g.: nodejs-k89sv54jf7.production, although the first part really being the endpoint name. Retrieving the service name is easy: if the metadata contains owner: cnwan-operator, then the name can be extracted by removing the last -<10 characters> from the endpoint name.
A PR will come and introduce this for Service Directory as well. Also, this convention will be mentioned in the docs.

@asimpleidea asimpleidea added documentation Improvements or additions to documentation enhancement New feature or request labels Dec 15, 2020
@asimpleidea asimpleidea self-assigned this Dec 15, 2020
@ljakab
Copy link
Member

ljakab commented Dec 15, 2020

Why not add the namespace explicitly in every Event?

@asimpleidea
Copy link
Member Author

Yes, that's definitely an option, but I did not include it as a solution because I thought that maybe is not a useful information for the adaptor as it does not bring anything meaningful for it. But it is definitely an option.

@arnatal
Copy link
Member

arnatal commented Dec 16, 2020

I like what @ljakab proposes about including the Namespace with each Event. The Adaptor can just ignore it if it wants to. And now that we're discussing this, should we have Service and Endpoint as separate entities in each Event update?

On the other hand, I also wonder if we are creating too much parsing/handling for the Adaptor. One of the roles of the Reader was to make the Adaptor life easier so I don't know how much complexity we want to introduce in the Reader-Adaptor API.

@asimpleidea
Copy link
Member Author

asimpleidea commented Dec 16, 2020

I think the simplest thing is to just having it like this plus the Namespace, but renaming Service to Endpoint as we are mostly interested in that. Alternatively, if the explicit service name is needed without wanting to extract it from the endpoint's name, we could have Endpoint with everything that we already have right now, plus NamespaceName and ServiceName, both as strings. Appending Name is a best practice in this case, as Namespace alone usually means we are providing more information about it.

Example:

Name Type Description Notes
Name string The observed name of the endpoint.
ServiceName string The observed name of the parent service of this endpoint.
NamespaceName string The observed name of the namespace this endpoint belongs to.
Address string The observed IP address of the endpoint. Can be IPv4 or IPv6.
Port int32 The observed port of the endpoint.
Metadata []Metadata [optional]

As for the adaptor, I don't remember how Jordi stores the objects but I think it doesn't need to do any parsing as it already has all the information it needs at first glance on the Event object.

@jordipv
Copy link

jordipv commented Dec 16, 2020

Yes, the open API spec for the adaptor restricts Events to an enum of three values. Right now the adaptor ignores the Name.

On the other hand, it is unclear how the SDWAN controller will handle the same endpoint with different NamespaceName. Would this translate to a different Virtual Network?

@asimpleidea
Copy link
Member Author

On the other hand, it is unclear how the SDWAN controller will handle the same endpoint with different NamespaceName. Would this translate to a different Virtual Network?

I don't really have a deep knowledge about SD WAN, but it's something that we have already been doing, if you remember: when I was delivering events to you, the namespace name was already included, just not explicitly.
So I think that for the adaptor it'll just be a matter of concatenating its name as Endpoint.Name + Endpoint.NamespaceName and continue the job as always :)

@arnatal
Copy link
Member

arnatal commented Dec 17, 2020

Based on the discussion, I'm leaning towards having just Endpoint in the Events API, where the value for Endpoint could be the concatenation that @SunSince90 suggests. In that case I'd concatenate Endpoint+Service+Namespace. What do you think?

@asimpleidea
Copy link
Member Author

asimpleidea commented Dec 17, 2020

Based on the discussion, I'm leaning towards having just Endpoint in the Events API, where the value for Endpoint could be the concatenation that @SunSince90 suggests. In that case I'd concatenate Endpoint+Service+Namespace. What do you think?

I like this because it gives a sort of fully qualified name for the endpoint and is fine on reader's side, but it is not for adaptors if they have a need to know parent namespace an service names (I don't know the reason, maybe for grouping things or for future features, I don't know). Which fortunately I'm guessing it is not the case.

This is because every Kubernetes object name must respect RFC1123 (link) and this means that . is accepted in the name.
To make an example: an endpoint full name my.endpoint.name.my.service.name.my.namespace.name is valid and fine if adaptors don't need to know the parents. Otherwise, with a name like that it is impossible to know which one is which.

@jordipv
Copy link

jordipv commented Dec 17, 2020

Makes sense for me, and since the adaptor only uses IP address and port, it won't be a problem, and can help in the future. However, is it possible to have the same endpoint value in two different namespaces?

@ljakab
Copy link
Member

ljakab commented Dec 17, 2020

Name Type Description Notes
Name string The observed name of the endpoint.
ServiceName string The observed name of the parent service of this endpoint.
NamespaceName string The observed name of the namespace this endpoint belongs to.
Address string The observed IP address of the endpoint. Can be IPv4 or IPv6.
Port int32 The observed port of the endpoint.
Metadata []Metadata [optional]

I like this struct or object definition for Endpoints, we can reuse this in all stages of the CN-WAN pipeline (operator, service registry, reader, adaptor), and then every component uses whatever they need (and stores stuff in internal data structures accordingly). But we standardize on one object schema for information exchange.

@asimpleidea
Copy link
Member Author

Makes sense for me, and since the adaptor only uses IP address and port, it won't be a problem, and can help in the future. However, is it possible to have the same endpoint value in two different namespaces?

If you mean names yes. You could have nginx.prod and nginx.dev, but they can't share the same address, if that's what you mean :)

Name Type Description Notes
Name string The observed name of the endpoint.
ServiceName string The observed name of the parent service of this endpoint.
NamespaceName string The observed name of the namespace this endpoint belongs to.
Address string The observed IP address of the endpoint. Can be IPv4 or IPv6.
Port int32 The observed port of the endpoint.
Metadata []Metadata [optional]

I like this struct or object definition for Endpoints, we can reuse this in all stages of the CN-WAN pipeline (operator, service registry, reader, adaptor), and then every component uses whatever they need (and stores stuff in internal data structures accordingly). But we standardize on one object schema for information exchange.

Yes I agree that having everything in separate fields is probably the best solution. @jordipv: are you storing state in your dictionary by Name right now? To resolve conflicts maybe you can index endpoints by address:port in your dictionary or by concatenating EndpointName.ServiceName.NamespaceName.

@jordipv
Copy link

jordipv commented Dec 17, 2020

Great, as long as there is no address overlap works fine for me!

Yep, the adaptor indexes buy Address:port, and ignores the Name. But I agree it'd be a good idea indexing also by name.

@arnatal
Copy link
Member

arnatal commented Dec 18, 2020

Name Type Description Notes
Name string The observed name of the endpoint.
ServiceName string The observed name of the parent service of this endpoint.
NamespaceName string The observed name of the namespace this endpoint belongs to.
Address string The observed IP address of the endpoint. Can be IPv4 or IPv6.
Port int32 The observed port of the endpoint.
Metadata []Metadata [optional]

I like this struct or object definition for Endpoints, we can reuse this in all stages of the CN-WAN pipeline (operator, service registry, reader, adaptor), and then every component uses whatever they need (and stores stuff in internal data structures accordingly). But we standardize on one object schema for information exchange.

If we are to use this structure, would it make sense to use EndpointName instead of just Name?

@asimpleidea
Copy link
Member Author

Name Type Description Notes
Name string The observed name of the endpoint.
ServiceName string The observed name of the parent service of this endpoint.
NamespaceName string The observed name of the namespace this endpoint belongs to.
Address string The observed IP address of the endpoint. Can be IPv4 or IPv6.
Port int32 The observed port of the endpoint.
Metadata []Metadata [optional]

I like this struct or object definition for Endpoints, we can reuse this in all stages of the CN-WAN pipeline (operator, service registry, reader, adaptor), and then every component uses whatever they need (and stores stuff in internal data structures accordingly). But we standardize on one object schema for information exchange.

If we are to use this structure, would it make sense to use EndpointName instead of just Name?

We could, but I would not do it as it would be redundant, as the object is already of type Endpoint. So you would see in code something like endpoint.EndpointName instead of just endpoint.Name

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants