-
Notifications
You must be signed in to change notification settings - Fork 5.1k
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
Kubernetes support externalname service #1149
Kubernetes support externalname service #1149
Conversation
provider/kubernetes.go
Outdated
Weight: 1, | ||
endpoints, exists, err := k8sClient.GetEndpoints(service.ObjectMeta.Namespace, service.ObjectMeta.Name) | ||
if err != nil || !exists { | ||
log.Errorf("Error retrieving endpoints %s/%s: %v", service.ObjectMeta.Namespace, service.ObjectMeta.Name, err) |
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.
The log message won't be very useful if we hit the !exists
case.
I'd rather use an if/else-if or switch construct to produce two distinct messages.
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.
Happy to make the change, but that is how it was before I touched anything. Mostly I don't fully understand what the different between the two is.
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 say let's be good boy scouts and leave the place a bit tidier than how we found it. :-)
Which two do you mean? If/else-if and select?
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.
Sorry, I meant the error and exists. Not sure what the log message for each should be as I don't fully understand what they mean.
After a quick look it seems err would mean there was an error in contacting the k8s API and exists would mean there are endpoints in the response. Not 100% sure on that though.
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.
Yes, that's basically right: If some error occurs during the GetEndpoints
call (which could be prior, during, or after reaching out to the k8s API), the err
will be non-nil.
If the API call succeeds but no endpoints were found for the given namespace and name, exists
will be false.
One last note: If you split up the OR'ed statement in order to make the error message more specific, be sure to check and handle the err != nil
case first: It's conventional in Go that if an error occurs, the remaining return parameters have either arbitrary or zero values.
provider/kubernetes.go
Outdated
PassHostHeader = true | ||
case "false": | ||
PassHostHeader = false | ||
|
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.
You could add a default
case to log a warning. I'd then also add a test making sure that an invalid value does not change the PassHostHeader
value.
…ice so that it now provides two unique log statements.
…d.passHostHeader results in falling back correctly.
Thanks for the feedback @timoreimann. I have made the requested changes. :) |
provider/kubernetes.go
Outdated
if err != nil { | ||
log.Errorf("Error while retrieving endpoints from k8s API %s/%s: %v", service.ObjectMeta.Namespace, service.ObjectMeta.Name, err) | ||
continue | ||
} else if !exists { |
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.
👍
(It would also suffice to just do an if
(no else
) since we continue
if we hit the first case.)
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.
Could you expand upon that a little? New to Go and not following. Will also do a bit of reading when I get home tonight.
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.
Sure! I'm basically proposing to replace (reducing/simplifying irrelevant parts):
endpoints, exists, err := k8sClient.GetEndpoints(ns, name)
if err != nil {
log.Errorf("error: %s", err)
continue
} else if !exists {
...
}
by
endpoints, exists, err := k8sClient.GetEndpoints(ns, name)
if err != nil {
log.Errorf("error: %s", err)
continue
}
if !exists {
...
}
(Note the difference is one less else
and an additional line break for readability reasons.)
The logic behind this is as following:
- If we run into the
err != nil
case, we'll log an error message andcontinue
to the next loop iteration. Thus, we will never reach the statement checking for!exists
. - If we run into the
err == nil
case, we want to check for!exists
. In that sense, it's not necessary to use anelse if
statement because of the previous point: We have already "protected" theerr != nil
case from doing any additional, unnecessary checks (unnecessary because in the case where an error occurred, no further actions should be taken) by acontinue
statement. So overall, a simpleif
suffices.
My rationale here is that it's usually beneficial to turn unnecessary else if
into more simple if
statements in order to minimize the cognitive load. (No else
case means I won't have to bother thinking "what other case are we in now?").
Another reason is that Go programs usually follow a pattern of
- Calling a function
- Checking for error
- in case of an error: return the error
- Otherwise, proceed to the next function call
The piece of code at hand is a variation of this pattern where we replace 3. by a log and a continue
statement.
Hope this helps!
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.
It does and makes great sense. Thank you very much for the detailed feedback and explanation. I will make the change now.
As this seems to be reasonably acceptable I will go ahead and update some docs when I have a few minutes to spare. |
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.
LGTM
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.
LGTM
Fixes #1142
Docs will need to be updated but before doing that I wanted to make sure I was at least going about this the right way.
Along with actually supporting the ExternalName service type I added support for the passHostHeader annotation. This is a requirement for actually using ExternalName.
This is basically the first Go code I have written, so very much open to any and all feedback.