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
internal/dag: Initial implementation for gateway-api #3278
Conversation
Codecov Report
@@ Coverage Diff @@
## main #3278 +/- ##
==========================================
+ Coverage 75.60% 75.70% +0.10%
==========================================
Files 98 98
Lines 6353 6396 +43
==========================================
+ Hits 4803 4842 +39
- Misses 1444 1446 +2
- Partials 106 108 +2
|
f0ed4bc
to
976a877
Compare
Ok this is a bit better with tests, but I think a reasonable start. It doesn't have any status information which I think would be a good next step to get integrated, but want to limit the changes since it's turning into a large PR. |
// on the HTTPRoute is set to "FromList". | ||
for _, route := range p.source.httproutes { | ||
switch route.Spec.Gateways.Allow { | ||
case serviceapis.GatewayAllowFromList: |
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.
Should case statements be added for "All" and "SameNamespace" allow types? I would expect a route to be precluded from valid
if allow: All
and no gateways exist in any namespace. I would also expect a route to be precluded from valid
if allow: SameNamespace
and no gateways exist in the route's 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.
Let me take this logic out all together, then reference resolution in a new issue? I think that would be best if you're ok with that. (#3351)
if len(route.Spec.Hostnames) == 0 { | ||
hosts = append(hosts, "*") | ||
} else { | ||
for _, host := range route.Spec.Hostnames { |
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 suggest validating each hostname. The first phase of hostname validation can be:
- Ensure the hostname is not an IP address. xref: https://golang.org/pkg/net/#ParseIP
- Ensure the hostname does not contain a port. xref: https://golang.org/pkg/net/#SplitHostPort
As a second phase, the hostname
spec states "Hostname is the fully qualified domain name of a network host, as defined by RFC 3986." We should be able to use https://golang.org/pkg/net/?m=all#isDomainName (verify that it supports wildcard prefixes or augment to support wildcards).
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.
meta := types.NamespacedName{Name: *forward.ServiceName, Namespace: route.Namespace} | ||
|
||
// TODO: Refactor EnsureService to take an int32 so conversion to intstr is not needed. | ||
service, err := p.dag.EnsureService(meta, intstr.FromInt(int(forward.Port)), p.source) |
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 if kubernetes-sigs/gateway-api#538 merges, port will be optional. With this PR, when port is unspecified, the implementation should forward the request with the port unmodified. Take a look and comment if this is an issue.
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.
Handful of initial comments. This looks like a good start on MVP functionality. In general, I'd say let's just be explicit about which subset of functionality we're supporting as we go, and logging errors/not processing config that we can't support yet.
case serviceapis.PathMatchPrefix: | ||
pathPrefixes = append(pathPrefixes, stringOrDefault(match.Path.Value, "/")) | ||
default: | ||
p.Error("NOT IMPLEMENTED: Only PathMatchPrefix is currently implemented.") |
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.
should we skip the entire rule if we can't parse one of the matches? (I'm not totally sure)
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's an exact
match as well which Contour doesn't have support for yet. I was trying to not get backed into the current HTTPProxy issue of one error
makes the entire resource invalid.
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 are places where we need to raise status condition errors. I think we should try and not throw away the entire resource for things that are either not implemented yet or are in error (ref #3145).
} | ||
|
||
func (p *ServiceAPIsProcessor) computeHTTPRoute(route *serviceapis.HTTPRoute) { | ||
|
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.
we should probably check for TLS config and error/not process the route if it's set, since we don't support it yet.
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.
👍
// httpRoutes returns a slice of *serviceapis.HTTPRoute objects. | ||
// invalid HTTPRoute objects are excluded from the slice and their status | ||
// updated accordingly. | ||
func (p *ServiceAPIsProcessor) validHTTPRoutes() []*serviceapis.HTTPRoute { |
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 limiting the routes we process to only those that map to this Contour's gateway is probably essential functionality for an MVP here - we have the config option in the config file, so should be able to wire that through.
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 opened #3351 to track this. Do you think it's ok to merge this as-is, then follow up with that? I do understand that right now we'll process ALL gateways. =)
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.
ef62b34
to
d643389
Compare
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.
Couple of small things from me, but this looks okay as a first pass. Definitely plenty of work to do still though.
|
||
for _, rule := range route.Spec.Rules { | ||
|
||
// Paths are a set of paths that are |
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.
Comment needs finishing up?
internal/dag/builder_test.go
Outdated
) | ||
|
||
func TestDAGInsertServiceAPIs(t *testing.T) { | ||
|
||
svc1 := &v1.Service{ |
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'd recommend calling these kuardSvc and blogSvc respectively, that saves one lookup when you're writing more tests.
// ServiceAPIsProcessor translates Service API types into DAG | ||
// objects and adds them to the DAG. | ||
type ServiceAPIsProcessor struct { | ||
logrus.FieldLogger |
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.
All the usages of the FieldLogger (p.Error,p.Errorf...) panic, as it seems to not be initialized (nil).
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 added this to the init of the processor.
ffe5e62
to
95ac280
Compare
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 good to me!
On testing, left a comment about adding a new issue to track the test coverage we will need
Also, since the conformance suite is not ready, should we add some basic integration tests that we can throw away later once we can start contributing upstream? Worth adding an issue for that?
) | ||
|
||
func TestDAGInsertServiceAPIs(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.
Worth adding tests (or maybe a tracking issue for adding tests) around the interactions between different resources (HTTPProxy, Ingress, Gateway APIs etc.)
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.
👍 #3367
for _, forward := range rule.ForwardTo { | ||
// Verify the service is valid | ||
if forward.ServiceName == nil { | ||
p.Error("ServiceName must not specified and is currently only implemented!") |
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.
nit: Should this error be reworded?
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.
haha yup! 👍
Super rough initial implementation for service-apis. Updates projectcontour#2287 Signed-off-by: Steve Sloka <slokas@vmware.com>
fa07e05
to
7a7b12c
Compare
…#3278) Super rough initial implementation for service-apis. Updates projectcontour#2287 Signed-off-by: Steve Sloka <slokas@vmware.com> Signed-off-by: iyacontrol <gaohj2015@yeah.net>
…#3278) Super rough initial implementation for service-apis. Updates projectcontour#2287 Signed-off-by: Steve Sloka <slokas@vmware.com> Signed-off-by: iyacontrol <gaohj2015@yeah.net>
Super rough initial implementation for gateway-api.
Needs a lot of love, but at least has started to work while still behind the feature flag in Contour. Using this sample yaml I can get things to route properly:
Updates #2287
Signed-off-by: Steve Sloka slokas@vmware.com