From ae668c2a77fa2f3bd704dd4d62ecb59b8167bdef Mon Sep 17 00:00:00 2001 From: Michal Vala Date: Wed, 6 Oct 2021 19:11:14 +0200 Subject: [PATCH] fix when main endpoint is unique Signed-off-by: Michal Vala --- .../devworkspace/solver/che_routing.go | 28 ++++--- .../devworkspace/solver/che_routing_test.go | 77 ++++++++++++++++++- 2 files changed, 93 insertions(+), 12 deletions(-) diff --git a/controllers/devworkspace/solver/che_routing.go b/controllers/devworkspace/solver/che_routing.go index 821a1377ad..bdf1fdea0f 100644 --- a/controllers/devworkspace/solver/che_routing.go +++ b/controllers/devworkspace/solver/che_routing.go @@ -481,8 +481,9 @@ func routeForHealthzEndpoint(cfg *gateway.TraefikConfig, dwId string, endpoints if infrastructure.IsOpenShift() { middlewares = append(middlewares, dwId+gateway.HeaderRewriteMiddlewareSuffix) } - cfg.HTTP.Routers[dwId+"-healthz"] = &gateway.TraefikConfigRouter{ - Rule: fmt.Sprintf("Path(`%s`)", fmt.Sprintf("/%s/%s/%d/healthz", dwId, componentName, e.TargetPort)), + routeName, endpointPath := createEndpointPath(&e, componentName) + cfg.HTTP.Routers[routeName+"-healthz"] = &gateway.TraefikConfigRouter{ + Rule: fmt.Sprintf("Path(`/%s%s/healthz`)", dwId, endpointPath), Service: dwId, Middlewares: middlewares, Priority: 101, @@ -493,15 +494,7 @@ func routeForHealthzEndpoint(cfg *gateway.TraefikConfig, dwId string, endpoints } func addEndpointToTraefikConfig(componentName string, e dw.Endpoint, cfg *gateway.TraefikConfig, cheCluster *v2alpha1.CheCluster, routing *dwo.DevWorkspaceRouting) { - var routeName string - if e.Attributes.GetString(uniqueEndpointAttributeName, nil) == "true" { - // if endpoint is unique, we're exposing on /componentName/ - routeName = e.Name - } else { - // if endpoint is NOT unique, we're exposing on /componentName/ - routeName = strconv.Itoa(e.TargetPort) - } - prefix := fmt.Sprintf("/%s/%s", componentName, routeName) + routeName, prefix := createEndpointPath(&e, componentName) rulePrefix := fmt.Sprintf("PathPrefix(`%s`)", prefix) // skip if exact same route is already exposed @@ -536,6 +529,19 @@ func addEndpointToTraefikConfig(componentName string, e dw.Endpoint, cfg *gatewa } } +func createEndpointPath(e *dw.Endpoint, componentName string) (routeName string, path string) { + if e.Attributes.GetString(uniqueEndpointAttributeName, nil) == "true" { + // if endpoint is unique, we're exposing on /componentName/ + routeName = e.Name + } else { + // if endpoint is NOT unique, we're exposing on /componentName/ + routeName = strconv.Itoa(e.TargetPort) + } + path = fmt.Sprintf("/%s/%s", componentName, routeName) + + return routeName, path +} + func findServiceForPort(port int32, objs *solvers.RoutingObjects) *corev1.Service { for i := range objs.Services { svc := &objs.Services[i] diff --git a/controllers/devworkspace/solver/che_routing_test.go b/controllers/devworkspace/solver/che_routing_test.go index 8f94461a0b..fcf089e171 100644 --- a/controllers/devworkspace/solver/che_routing_test.go +++ b/controllers/devworkspace/solver/che_routing_test.go @@ -392,7 +392,7 @@ func TestCreateRelocatedObjectsOpenshift(t *testing.T) { } t.Run("testHealthzEndpointInMainWorkspaceRoute", func(t *testing.T) { - healthzName := "wsid-healthz" + healthzName := "9999-healthz" assert.Contains(t, workspaceMainConfig.HTTP.Routers, healthzName) assert.Equal(t, workspaceMainConfig.HTTP.Routers[healthzName].Service, wsid) assert.Equal(t, workspaceMainConfig.HTTP.Routers[healthzName].Rule, "Path(`/wsid/m1/9999/healthz`)") @@ -412,6 +412,81 @@ func TestCreateRelocatedObjectsOpenshift(t *testing.T) { }) } +func TestUniqueMainEndpoint(t *testing.T) { + wsid := "wsid123" + + infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + cl, _, _ := getSpecObjects(t, &dwo.DevWorkspaceRouting{ + ObjectMeta: metav1.ObjectMeta{ + Name: "routing", + Namespace: "ws", + }, + Spec: dwo.DevWorkspaceRoutingSpec{ + DevWorkspaceId: wsid, + RoutingClass: "che", + Endpoints: map[string]dwo.EndpointList{ + "m1": { + { + Name: "e1", + TargetPort: 9999, + Exposure: dw.PublicEndpointExposure, + Protocol: "https", + Path: "/1/", + Attributes: attributes.Attributes{ + urlRewriteSupportedEndpointAttributeName: apiext.JSON{Raw: []byte("\"true\"")}, + string(dwo.TypeEndpointAttribute): apiext.JSON{Raw: []byte("\"main\"")}, + uniqueEndpointAttributeName: apiext.JSON{Raw: []byte("\"true\"")}, + }, + }, + }, + }, + }, + }) + + cms := &corev1.ConfigMapList{} + cl.List(context.TODO(), cms) + + assert.Len(t, cms.Items, 2) + + var workspaceMainCfg *corev1.ConfigMap + var workspaceCfg *corev1.ConfigMap + for _, cfg := range cms.Items { + if cfg.Name == wsid+"-route" && cfg.Namespace == "ns" { + workspaceMainCfg = cfg.DeepCopy() + } + if cfg.Name == wsid+"-route" && cfg.Namespace == "ws" { + workspaceCfg = cfg.DeepCopy() + } + } + + traefikWorkspaceConfig := workspaceCfg.Data["workspace.yml"] + workspaceConfig := gateway.TraefikConfig{} + assert.NoError(t, yaml.Unmarshal([]byte(traefikWorkspaceConfig), &workspaceConfig)) + + traefikMainWorkspaceConfig := workspaceMainCfg.Data[wsid+".yml"] + workspaceMainConfig := gateway.TraefikConfig{} + assert.NoError(t, yaml.Unmarshal([]byte(traefikMainWorkspaceConfig), &workspaceMainConfig)) + + t.Run("testHealthzEndpointInMainWorkspaceRoute", func(t *testing.T) { + healthzName := "e1-healthz" + assert.Contains(t, workspaceMainConfig.HTTP.Routers, healthzName) + assert.Equal(t, workspaceMainConfig.HTTP.Routers[healthzName].Service, wsid) + assert.Equal(t, workspaceMainConfig.HTTP.Routers[healthzName].Rule, "Path(`/"+wsid+"/m1/e1/healthz`)") + assert.NotContains(t, workspaceMainConfig.HTTP.Routers[healthzName].Middlewares, wsid+gateway.AuthMiddlewareSuffix) + assert.Contains(t, workspaceMainConfig.HTTP.Routers[healthzName].Middlewares, wsid+gateway.StripPrefixMiddlewareSuffix) + assert.Contains(t, workspaceMainConfig.HTTP.Routers[healthzName].Middlewares, wsid+gateway.HeaderRewriteMiddlewareSuffix) + }) + + t.Run("testHealthzEndpointInWorkspaceRoute", func(t *testing.T) { + healthzName := wsid + "-m1-e1-healthz" + assert.Contains(t, workspaceConfig.HTTP.Routers, healthzName) + assert.Equal(t, workspaceConfig.HTTP.Routers[healthzName].Service, healthzName) + assert.Equal(t, workspaceConfig.HTTP.Routers[healthzName].Rule, "Path(`/m1/e1/healthz`)") + assert.NotContains(t, workspaceConfig.HTTP.Routers[healthzName].Middlewares, healthzName+gateway.AuthMiddlewareSuffix) + assert.Contains(t, workspaceConfig.HTTP.Routers[healthzName].Middlewares, healthzName+gateway.StripPrefixMiddlewareSuffix) + }) +} + func TestCreateSubDomainObjects(t *testing.T) { testCommon := func(infra infrastructure.Type) solvers.RoutingObjects { infrastructure.InitializeForTesting(infra)