-
Notifications
You must be signed in to change notification settings - Fork 345
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
Add link to openshift console #1142
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1142 +/- ##
==========================================
+ Coverage 88.22% 88.28% +0.05%
==========================================
Files 86 89 +3
Lines 5351 5496 +145
==========================================
+ Hits 4721 4852 +131
- Misses 466 474 +8
- Partials 164 170 +6
Continue to review full report at Codecov.
|
Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>
0a2dc74
to
5e0607e
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.
Seems to be going in the right direction!
@@ -82,6 +84,9 @@ func newAllInOneStrategy(ctx context.Context, jaeger *v1.Jaeger) S { | |||
if viper.GetString("platform") == v1.FlagPlatformOpenShift { | |||
if q := route.NewQueryRoute(jaeger).Get(); nil != q { | |||
c.routes = append(c.routes, *q) | |||
if link := consolelink.Get(jaeger, q); link != 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.
This whole block looks strange, as neither route.NewQueryRoute
nor consolelink.Get
return nils. I think it can be simplified, can't it? They might even return the values directly instead of pointers.
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.
Well, route.NewQueryRoute(jaeger).Get() could potentially return nil if ingress is not enable.
jaeger-operator/pkg/route/query.go
Line 25 in fd64f15
return nil |
In the case of consoleLink Would we want to have a flag for disable/enable it? If not of course I can simplify those lines. :)
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.
If we don't have a query, do we want a console link? I have a feeling that this will not run cleanly in plain Kubernetes. It might work right now because this is shielded at the controller, though.
IMO, if the route is protecting itself by checking whether the platform is openshift, then the console link should do the same.
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 what is happening here, isn't it? If there is no query, (if query returns nil) it won't create a link. Indeed this is checking the platform two lines above. It check the platform, then try to create a queryRoute
, if query router is successfully created, then try to create a consoleLink
.
… if consoleLink apply fails Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>
Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>
Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>
…the href is updated Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>
9f5d27b
to
f62ed66
Compare
Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>
Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>
@@ -336,6 +336,9 @@ func (r *ReconcileJaeger) apply(ctx context.Context, jaeger v1.Jaeger, str strat | |||
if err := r.applyRoutes(ctx, jaeger, str.Routes()); err != nil { | |||
return jaeger, tracing.HandleError(err, span) | |||
} | |||
if err := r.applyConsoleLinks(ctx, jaeger, r.updateHref(ctx, jaeger, str.ConsoleLinks())); err != 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.
The controller shouldn't know how to transform the existing console link into desired. In other words, the updateHref
logic shouldn't happen here.
The way our operator works, this code here should only call applyConsoleLinks
passing str.ConsoleLinks()
as parameter, which builds the list of desired console links. The applyConsoleLinks
will then get this list over to the inventory, which will compare the existing with the desired and build a map of operations: what should be created, what should be updated, and what should be deleted. The inventory should take care of carrying over the value from the desired to the existing, in case of an update (which is what your updateHref
is doing). Take a look at what we are doing with the secret or deployment. The batch job isn't a good example.
pkg/consolelink/main.go
Outdated
Location: consolev1.ApplicationMenu, | ||
ApplicationMenu: &consolev1.ApplicationMenuSpec{}, | ||
Link: consolev1.Link{ | ||
Text: "Jaeger [" + jaeger.Name + "." + jaeger.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.
Can you remove the namespace from the link text, as it will only be shown when viewing that namespace in the console.
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
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.
Done
Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>
Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>
There's something odd. I have two instances in two namespaces, with the same instance name: $ kubectl get jaegers --all-namespaces
NAMESPACE NAME STATUS VERSION STRATEGY STORAGE AGE
myapp simplest Running 1.18.1 allinone memory 2d2h
observability simplest Running 1.18.1 allinone memory 2m42s And somehow, the console links got kinda messed up: $ kubectl get consolelinks --all-namespaces
NAME TEXT URL MENU AGE
myapp.jaeger-consolelink-simplest Jaeger [simplest] https://simplest-observability.apps-crc.testing 9m2s The link ended showing up in the web console for the |
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 the comment about the scope for console links. The same premise we have for almost/all other objects isn't valid for console links, as it's cluster-scoped (as opposed to "namespaced").
pkg/consolelink/main.go
Outdated
// RouteAnnotation used to annotate the link with the route name | ||
var RouteAnnotation = "consolelink.jaegertracing.io/route" | ||
|
||
// Get returns an ConsoleLink specification for the current instance |
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.
// Get returns an ConsoleLink specification for the current instance | |
// Get returns a ConsoleLink specification for the current instance |
pkg/consolelink/main.go
Outdated
|
||
return &consolev1.ConsoleLink{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: jaeger.Namespace + ".jaeger-consolelink-" + jaeger.Name, |
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 name could be improved: this is a ConsoleLink
object, so, we don't need consolelink
in the name. The ConsoleLink
resides in a specific namespace, so, the namespace doesn't need to be part of the name either. It's also using dots, which is uncommon for names. Here's how it turns up in a real case: observability.jaeger-consolelink-simplest
.
I'd say that you can just use the jaeger.Name
, like we have for the Route
:
$ kubectl get routes -n observability
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
simplest simplest-observability.apps-crc.testing simplest-query <all> reencrypt None
For reference, here's how the some built-in console links look like:
$ kubectl get consolelinks --all-namespaces
NAME TEXT URL MENU AGE
observability.jaeger-consolelink-simplest Jaeger [simplest] https://simplest-observability.apps-crc.testing 8m14s
openshift-blog OpenShift Blog https://blog.openshift.com 19d
openshift-learning-portal Learning Portal https://learn.openshift.com/?ref=webconsole 19d
pkg/consolelink/main_test.go
Outdated
func TestConsoleLinkGet(t *testing.T) { | ||
jaegerName := "TestConsoleLinkJaeger" | ||
jaegerNamespace := "TestNS" | ||
routerNamer := "TestConsoleLinkRoute" |
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.
routerNamer := "TestConsoleLinkRoute" | |
routerName := "TestConsoleLinkRoute" |
pkg/controller/jaeger/consolelink.go
Outdated
defer span.End() | ||
|
||
opts := []client.ListOption{ | ||
client.InNamespace(jaeger.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.
As mentioned in the comment right before this review, I had two instances with the same name in different namespaces. One thing that was weird, is that only one console link was created. Turns out, console links are cluster-scoped, so, this logic here will make one instance remove another instance's console link. You can see this when running make run-debug
and have two instances in the cluster:
DEBU[0008] Reconciling Jaeger execution="2020-07-31 14:32:38.767272647 +0000 UTC" instance=simplest namespace=myapp
DEBU[0009] creating console link consoleLink=myapp.jaeger-consolelink-simplest instance=simplest namespace=myapp
DEBU[0009] deleting console link consoleLink=observability.jaeger-consolelink-simplest instance=simplest namespace=
DEBU[0009] Reconciling Jaeger completed execution="2020-07-31 14:32:38.767272647 +0000 UTC" instance=simplest namespace=myapp
DEBU[0009] Reconciling Jaeger execution="2020-07-31 14:32:39.084445352 +0000 UTC" instance=simplest namespace=observability
DEBU[0009] creating console link consoleLink=observability.jaeger-consolelink-simplest instance=simplest namespace=observability
DEBU[0009] deleting console link consoleLink=myapp.jaeger-consolelink-simplest instance=simplest namespace=
DEBU[0009] Reconciling Jaeger completed execution="2020-07-31 14:32:39.084445352 +0000 UTC" instance=simplest namespace=observability
Note how the namespace in the "deleting console link" log entries is empty, which was the clue that led me to check the CRD's scope:
$ kubectl get crds consolelinks.console.openshift.io -o jsonpath='{.spec.scope}'
Cluster
A couple of things to keep in mind then:
- when the operator isn't running in
cluster admin
mode, it shouldn't even attempt to create a cluster object. Try running the operator with lower permissions, and see what happens - when the user running the operator does have cluster admin rights, the logic in this controller shouldn't filter entries by the namespace. Rather, it should instead check the
app.kubernetes.io/instance
andapp.kubernetes.io/managed-by
labels. If the instance in the label isn't the same in the current reconciliation, leave it alone (don't update, don't delete).
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'm ok with 1), We should check for cluster admin before trying to create cluster object.
- Is not clear to me, I can fetch all consolelinks but checking for
app.kubernetes.io/instance
? In the case of two instances with same name in different namespaces, I'll have two of them with the same name... and we will have the same problem... or am I missunderstanding something? I was thinking on adding a new label with the namespace, so I can filter by namespace AND jaeger instance name. Does that make sense?
Name: nsnExisting.Name, | ||
Namespace: nsnExisting.Namespace, | ||
Annotations: map[string]string{ | ||
consolelink.RouteAnnotation: "my-route-1", |
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.
When would this happen? If I'm understanding this correctly, this is testing that a ConsoleLink can point to a route in another namespace. Is that right?
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 should test when the route, and jaeger instance names are the same, but they are on different namespaces. We neet to make sure that the associated route is the correct one, the one that is in the same namespace as the jaeger instance.
}, | ||
}}).WithRoutes([]osroutev1.Route{{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "my-route-1", |
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 this test needs a better description, and a few comments in the code. I spent quite a few minutes trying to figure out why you had host2
for my-route-1
when you specified host1
for my-route-1
before, until I realized that they were two different namespaces :-)
jaeger.Logger().WithError(tracing.HandleError(err, span)).Warn("failed to reconcile console links") | ||
} | ||
} else { | ||
jaeger.Logger().WithError(tracing.HandleError(err, span)).Warn("failed to reconcile console links") |
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.
jaeger.Logger().WithError(tracing.HandleError(err, span)).Warn("failed to reconcile console links") | |
jaeger.Logger().WithError(tracing.HandleError(err, span)).Warn("failed to obtain a list of routes to reconcile consolelinks") |
a5759be
to
d7189fd
Compare
…espaces, improve log messages, fix some code style issues Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>
d7189fd
to
6a4a3df
Compare
Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>
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 - one nit, but just want to test it out (hopefully sometime today).
pkg/consolelink/main.go
Outdated
@@ -22,10 +22,12 @@ func Get(jaeger *v1.Jaeger, route *routev1.Route) *consolev1.ConsoleLink { | |||
|
|||
return &consolev1.ConsoleLink{ | |||
ObjectMeta: metav1.ObjectMeta{ | |||
Name: jaeger.Namespace + ".jaeger-consolelink-" + jaeger.Name, | |||
Namespace: jaeger.Namespace, | |||
Name: "jaeger-" + jaeger.Namespace + "-" + jaeger.Name, |
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: Could you create a function to derive the name from the jaeger
instance? and then also use from the tests (main_test, but also the various strategy tests).
Signed-off-by: Ruben Vargas <ruben.vp8510@gmail.com>
8c1704f
to
7eba146
Compare
Signed-off-by: Ruben Vargas ruben.vp8510@gmail.com