Skip to content

Commit

Permalink
expose endpoints with traefik
Browse files Browse the repository at this point in the history
Signed-off-by: Michal Vala <mvala@redhat.com>
  • Loading branch information
sparkoo committed Sep 3, 2021
1 parent 77c5d8c commit a41d73c
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 38 deletions.
94 changes: 63 additions & 31 deletions controllers/devworkspace/solver/che_routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ package solver
import (
"context"
"fmt"
"github.com/eclipse-che/che-operator/pkg/deploy/gateway"
"k8s.io/apimachinery/pkg/util/intstr"
"path"
"strings"
Expand Down Expand Up @@ -56,6 +57,7 @@ type portMapping map[int32]map[string]portMappingValue
type portMappingValue struct {
endpointScheme string
order int
unique bool
}

func (c *CheRoutingSolver) cheSpecObjects(cheManager *v2alpha1.CheCluster, routing *dwo.DevWorkspaceRouting, workspaceMeta solvers.DevWorkspaceMetadata) (solvers.RoutingObjects, error) {
Expand All @@ -69,12 +71,14 @@ func (c *CheRoutingSolver) cheSpecObjects(cheManager *v2alpha1.CheCluster, routi

commonService := solvers.GetServiceForEndpoints(routing.Spec.Endpoints, workspaceMeta, false, dw.PublicEndpointExposure, dw.InternalEndpointExposure)
if commonService != nil {
commonService.Spec.Ports = append(commonService.Spec.Ports, corev1.ServicePort{
Name: common.EndpointName("ws-route"),
Protocol: corev1.ProtocolTCP,
Port: int32(55555),
TargetPort: intstr.FromInt(55555),
})
commonService.Spec.Ports = []corev1.ServicePort{
{
Name: common.EndpointName("ws-route"),
Protocol: corev1.ProtocolTCP,
Port: int32(55555),
TargetPort: intstr.FromInt(55555),
},
}
objs.Services = append(objs.Services, *commonService)
}

Expand Down Expand Up @@ -270,10 +274,8 @@ func (c *CheRoutingSolver) getGatewayConfigsAndFillRoutingObjects(cheManager *v2
ObjectMeta: v1.ObjectMeta{
Name: defaults.GetGatewayWorkpaceConfigMapName(workspaceID),
Namespace: routing.Namespace,
Labels: labels,
Annotations: map[string]string{
defaults.ConfigAnnotationDevWorkspaceRoutingName: routing.Name,
defaults.ConfigAnnotationDevWorkspaceRoutingNamespace: routing.Namespace,
Labels: map[string]string{
constants.DevWorkspaceIDLabel: workspaceID,
},
},
Data: map[string]string{},
Expand Down Expand Up @@ -319,10 +321,10 @@ func (c *CheRoutingSolver) getGatewayConfigsAndFillRoutingObjects(cheManager *v2
return []corev1.ConfigMap{}, err
}

//exposeAllEndpoints(&order, cheManager, routing, &config, objs, func(info *EndpointInfo) {
// ingress := exposer.getIngressForService(info)
// objs.Ingresses = append(objs.Ingresses, ingress)
//})
exposeAllEndpoints(&order, cheManager, routing, &config, &wsConfig, objs, func(info *EndpointInfo) {
ingress := exposer.getIngressForService(info)
objs.Ingresses = append(objs.Ingresses, ingress)
})
}

configs := make([]corev1.ConfigMap, 0)
Expand Down Expand Up @@ -368,12 +370,37 @@ log:
func exposeAllEndpoints(order *int, cheManager *v2alpha1.CheCluster, routing *dwo.DevWorkspaceRouting, config *traefikConfig, wsConfig *traefikConfig, objs *solvers.RoutingObjects, ingressExpose func(*EndpointInfo)) {
info := &EndpointInfo{}
addMasterRouteToTraefikConfig(routing.Namespace, routing.Spec.DevWorkspaceId, config)
var commonService *corev1.Service = nil

for i, svc := range objs.Services {
if svc.Name == common.ServiceName(routing.Spec.DevWorkspaceId) {
commonService = &objs.Services[i]
}
}
if commonService == nil {
return
}

for componentName, endpoints := range routing.Spec.Endpoints {
info.componentName = componentName
singlehostPorts, multihostPorts := classifyEndpoints(cheManager.Spec.Gateway.IsEnabled(), order, &endpoints)

addToTraefikConfig(routing.Namespace, routing.Spec.DevWorkspaceId, componentName, singlehostPorts, wsConfig)

for port, names := range multihostPorts {
for endpointName := range names {
if !containPort(commonService, port) {
logger.Info("adding port", "name", endpointName, "port", port)
commonService.Spec.Ports = append(commonService.Spec.Ports, corev1.ServicePort{
Name: common.EndpointName(endpointName),
Protocol: corev1.ProtocolTCP,
Port: port,
TargetPort: intstr.FromInt(int(port)),
})
}
}
}

for port, names := range multihostPorts {
backingService := findServiceForPort(port, objs)
for endpointName, val := range names {
Expand All @@ -389,6 +416,15 @@ func exposeAllEndpoints(order *int, cheManager *v2alpha1.CheCluster, routing *dw
}
}

func containPort(service *corev1.Service, port int32) bool {
for _, p := range service.Spec.Ports {
if p.Port == port {
return true
}
}
return false
}

func getTrackedEndpointName(endpoint *dw.Endpoint) string {
name := ""
if endpoint.Attributes.GetString(uniqueEndpointAttributeName, nil) == "true" {
Expand All @@ -409,26 +445,21 @@ func classifyEndpoints(gatewayEnabled bool, order *int, endpoints *dwo.EndpointL
continue
}

i := int32(e.TargetPort)

name := ""
if e.Attributes.GetString(uniqueEndpointAttributeName, nil) == "true" {
name = e.Name
}

ports := multihostPorts
if gatewayEnabled && e.Attributes.GetString(urlRewriteSupportedEndpointAttributeName, nil) == "true" {
ports = singlehostPorts
}

if ports[i] == nil {
ports[i] = map[string]portMappingValue{}
targetPort := int32(e.TargetPort)
if ports[targetPort] == nil {
ports[targetPort] = map[string]portMappingValue{}
}

if _, ok := ports[i][name]; !ok {
ports[i][name] = portMappingValue{
if _, ok := ports[targetPort][e.Name]; !ok {
ports[targetPort][e.Name] = portMappingValue{
order: *order,
endpointScheme: determineEndpointScheme(gatewayEnabled, e),
unique: e.Attributes.GetString(uniqueEndpointAttributeName, nil) == "true",
}
*order = *order + 1
}
Expand Down Expand Up @@ -488,12 +519,12 @@ func addToTraefikConfig(namespace string, workspaceID string, machineName string
mdls := cfg.HTTP.Middlewares

for port, names := range portMapping {
for endpointName := range names {
for endpointName, endpointMapping := range names {
name := getEndpointExposingObjectName(machineName, workspaceID, port, endpointName)
var prefix string
var serviceURL string

prefix = getLocalURLPrefix(machineName, port, endpointName)
prefix = getLocalURLPrefix(machineName, port, endpointName, endpointMapping.unique)
serviceURL = fmt.Sprintf("http://127.0.0.1:%d", port)

rtrs[name] = traefikConfigRouter{
Expand Down Expand Up @@ -521,7 +552,7 @@ func addToTraefikConfig(namespace string, workspaceID string, machineName string

mdls[name+"-auth"] = traefikConfigMiddleware{
ForwardAuth: &traefikConfigForwardAuth{
Address: "http://che-gateway.eclipse-che:8089?namespace=" + namespace,
Address: fmt.Sprintf("http://%s.%s:8089?namespace=%s", gateway.GatewayServiceName, "eclipse-che", namespace),
},
}
}
Expand Down Expand Up @@ -631,11 +662,12 @@ func getPublicURLPrefix(workspaceID string, machineName string, port int32, uniq
return fmt.Sprintf(uniqueEndpointURLPrefixPattern, workspaceID, machineName, uniqueEndpointName)
}

func getLocalURLPrefix(machineName string, port int32, uniqueEndpointName string) string {
if uniqueEndpointName == "" {
func getLocalURLPrefix(machineName string, port int32, uniqueEndpointName string, unique bool) string {
if unique {
return fmt.Sprintf("/%s/%s", machineName, uniqueEndpointName)
} else {
return fmt.Sprintf("/%s/%d", machineName, port)
}
return fmt.Sprintf("/%s/%s", machineName, uniqueEndpointName)
}

func determineEndpointScheme(gatewayEnabled bool, e dw.Endpoint) string {
Expand Down
16 changes: 9 additions & 7 deletions pkg/deploy/gateway/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ import (
const (
// GatewayServiceName is the name of the service which through which the gateway can be accessed
GatewayServiceName = "che-gateway"
GatewayServicePort = 8080

gatewayServerConfigName = "che-gateway-route-server"
gatewayKubeAuthConfigName = "che-gateway-route-kube-auth"
gatewayConfigComponentName = "che-gateway-config"
gatewayOauthSecretName = "che-gateway-oauth-secret"
)
Expand Down Expand Up @@ -408,7 +410,7 @@ func getGatewayOauthProxyConfigSpec(instance *orgv1.CheCluster, cookieSecret str
},
Data: map[string]string{
"oauth-proxy.cfg": fmt.Sprintf(`
http_address = ":8080"
http_address = ":%d"
https_address = ""
provider = "openshift"
redirect_url = "https://%s/oauth/callback"
Expand All @@ -424,7 +426,7 @@ cookie_expire = "24h0m0s"
email_domains = "*"
cookie_httponly = false
pass_access_token = true
skip_provider_button = true`, instance.Spec.Server.CheHost, instance.Spec.Auth.OAuthClientName, instance.Spec.Auth.OAuthSecret, GatewayServiceName, cookieSecret),
skip_provider_button = true`, GatewayServicePort, instance.Spec.Server.CheHost, instance.Spec.Auth.OAuthClientName, instance.Spec.Auth.OAuthSecret, GatewayServiceName, cookieSecret),
},
}
}
Expand Down Expand Up @@ -490,7 +492,7 @@ func getGatewayHeaderRewritePluginConfigSpec(instance *orgv1.CheCluster) (*corev
}

func getGatewayTraefikConfigSpec(instance *orgv1.CheCluster) corev1.ConfigMap {
traefikPort := 8080
traefikPort := GatewayServicePort
if util.IsNativeUserModeEnabled(instance) {
traefikPort = 8081
}
Expand Down Expand Up @@ -639,7 +641,7 @@ func getContainersSpec(instance *orgv1.CheCluster) []corev1.Container {
},
},
Ports: []corev1.ContainerPort{
{ContainerPort: 8080},
{ContainerPort: GatewayServicePort},
},
},
corev1.Container{
Expand Down Expand Up @@ -762,12 +764,12 @@ func getGatewayServiceSpec(instance *orgv1.CheCluster) corev1.Service {
Ports: []corev1.ServicePort{
{
Name: "gateway-http",
Port: 8080,
Port: GatewayServicePort,
Protocol: corev1.ProtocolTCP,
TargetPort: intstr.FromInt(8080),
TargetPort: intstr.FromInt(GatewayServicePort),
},
{
Name: "gateway-kube-rbac-proxy",
Name: "gateway-kube-authz",
Port: 8089,
Protocol: corev1.ProtocolTCP,
TargetPort: intstr.FromInt(8089),
Expand Down

0 comments on commit a41d73c

Please sign in to comment.