Skip to content

Commit b1a0053

Browse files
committed
port to 5000 + provision flow + windows host fix + documentation
1 parent 3483f9c commit b1a0053

64 files changed

Lines changed: 2989 additions & 754 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

containers/aggregator-server/main.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
reg "aggregator/registration"
77
"context"
88
"net/http"
9+
"net/url"
910
"os"
1011
"os/signal"
1112
"strings"
@@ -32,11 +33,16 @@ func main() {
3233
logrus.SetOutput(os.Stdout)
3334

3435
// Read Network configuration from environment variables
35-
model.ExternalHost = os.Getenv("AGGREGATOR_EXTERNAL_HOST")
36-
if model.ExternalHost == "" {
36+
externalBase := strings.TrimSpace(os.Getenv("AGGREGATOR_EXTERNAL_HOST"))
37+
if externalBase == "" {
3738
logrus.Fatal("Environment variables AGGREGATOR_EXTERNAL_HOST must be set")
3839
}
3940
model.Protocol = "http"
41+
model.ExternalHost = externalBase
42+
if parsed, err := url.Parse(externalBase); err == nil && parsed.Scheme != "" {
43+
model.Protocol = strings.ToLower(parsed.Scheme)
44+
model.ExternalHost = parsed.Host
45+
}
4046

4147
// Read Authorization configuration from environment variables
4248
model.ClientId = os.Getenv("CLIENT_ID")
@@ -51,7 +57,9 @@ func main() {
5157
model.ProvisionClientID = os.Getenv("PROVISION_CLIENT_ID")
5258
model.ProvisionClientSecret = os.Getenv("PROVISION_CLIENT_SECRET")
5359
model.ProvisionWebID = os.Getenv("PROVISION_WEBID")
60+
model.ProvisionIDP = os.Getenv("PROVISION_IDP")
5461
model.ProvisionAuthorizationServer = os.Getenv("PROVISION_AUTHORIZATION_SERVER")
62+
model.IDPServerType = strings.ToLower(strings.TrimSpace(os.Getenv("IDP_SERVER_TYPE")))
5563

5664
allowedTypes := parseAllowedRegistrationTypes(os.Getenv("ALLOWED_REGISTRATION_TYPES"))
5765
model.AllowedRegistrationTypes = allowedTypes
@@ -65,6 +73,9 @@ func main() {
6573
if model.ProvisionWebID == "" {
6674
logrus.Fatal("Environment variable PROVISION_WEBID must be set when provision registration is allowed")
6775
}
76+
if model.ProvisionIDP == "" {
77+
logrus.Fatal("Environment variable PROVISION_IDP must be set when provision registration is allowed")
78+
}
6879
if model.ProvisionAuthorizationServer == "" {
6980
logrus.Fatal("Environment variable PROVISION_AUTHORIZATION_SERVER must be set when provision registration is allowed")
7081
}

containers/aggregator-server/model/registration.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ type RegistrationRequest struct {
2626
State string `json:"state,omitempty"`
2727

2828
// client_credentials flow
29-
WebID string `json:"webid,omitempty"`
3029
ClientID string `json:"client_id,omitempty"`
3130
ClientSecret string `json:"client_secret,omitempty"`
3231

@@ -39,7 +38,8 @@ type RegistrationRequest struct {
3938
type RegistrationResponse struct {
4039
AggregatorID string `json:"aggregator_id"`
4140
Aggregator string `json:"aggregator,omitempty"`
42-
WebID string `json:"webid,omitempty"`
41+
Subject string `json:"subject,omitempty"`
42+
IDP string `json:"idp,omitempty"`
4343
}
4444

4545
// AuthorizationCodeStartResponse represents the response for authorization_code start phase

containers/aggregator-server/model/vars.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ var AllowedRegistrationTypes []string
1616
var ProvisionClientID string
1717
var ProvisionClientSecret string
1818
var ProvisionWebID string
19+
var ProvisionIDP string
1920
var ProvisionAuthorizationServer string
21+
var IDPServerType string
2022

2123
var Clientset kubernetes.Interface
2224
var DynamicClient *dynamic.DynamicClient

containers/aggregator-server/registration/namespace.go

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"context"
66
"encoding/json"
77
"fmt"
8+
"net"
89
"strings"
910
"time"
1011

@@ -65,7 +66,7 @@ func deleteNamespaceResources(namespace string, ctx context.Context) error {
6566
}
6667

6768
// deployAggregatorResources deploys the Egress UMA and Aggregator Instance
68-
func deployAggregatorResources(namespace string, tokenEndpoint string, accessToken string, refreshToken string, accessTokenExpiry string, ownerWebID string, authzServerURL string, ctx context.Context) error {
69+
func deployAggregatorResources(namespace string, tokenEndpoint string, accessToken string, refreshToken string, accessTokenExpiry string, ownerWebID string, ownerToken string, authzServerURL string, registrationType string, provisionWebID string, ctx context.Context) error {
6970
replicas := int32(1)
7071
useUMA := authzServerURL != ""
7172
var err error
@@ -76,7 +77,7 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
7677
return fmt.Errorf("failed to ensure egress-uma RBAC: %w", err)
7778
}
7879

79-
tokensPayload, err := buildTokensPayload(accessToken, refreshToken, accessTokenExpiry)
80+
tokensPayload, err := buildTokensPayload(accessToken, refreshToken, accessTokenExpiry, ownerToken)
8081
if err != nil {
8182
return fmt.Errorf("failed to build egress-uma token payload: %w", err)
8283
}
@@ -299,6 +300,8 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
299300
Resource: "ingressroutes",
300301
}
301302

303+
hostMatch := hostWithoutPort(model.ExternalHost)
304+
302305
irName := "aggregator-instance-ingressroute"
303306
obj := &unstructured.Unstructured{
304307
Object: map[string]interface{}{
@@ -312,7 +315,7 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
312315
"entryPoints": []string{"web"},
313316
"routes": []interface{}{
314317
map[string]interface{}{
315-
"match": "Host(`" + model.ExternalHost + "`) && (Path(`/config/" + namespace + "`) || Path(`/config/" + namespace + "/`)) && Method(`OPTIONS`)",
318+
"match": "Host(`" + hostMatch + "`) && (Path(`/config/" + namespace + "`) || Path(`/config/" + namespace + "/`)) && Method(`OPTIONS`)",
316319
"kind": "Rule",
317320
"services": []interface{}{
318321
map[string]interface{}{
@@ -324,7 +327,7 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
324327
"middlewares": buildCorsOnlyMiddlewares(namespace, true),
325328
},
326329
map[string]interface{}{
327-
"match": "Host(`" + model.ExternalHost + "`) && (Path(`/config/" + namespace + "`) || Path(`/config/" + namespace + "/`))",
330+
"match": "Host(`" + hostMatch + "`) && (Path(`/config/" + namespace + "`) || Path(`/config/" + namespace + "/`))",
328331
"kind": "Rule",
329332
"services": []interface{}{
330333
map[string]interface{}{
@@ -336,7 +339,7 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
336339
"middlewares": buildIngressMiddlewares(useUMA, namespace, true),
337340
},
338341
map[string]interface{}{
339-
"match": "Host(`" + model.ExternalHost + "`) && PathPrefix(`/config/" + namespace + "/services`) && Method(`OPTIONS`)",
342+
"match": "Host(`" + hostMatch + "`) && PathPrefix(`/config/" + namespace + "/services`) && Method(`OPTIONS`)",
340343
"kind": "Rule",
341344
"services": []interface{}{
342345
map[string]interface{}{
@@ -348,7 +351,7 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
348351
"middlewares": buildCorsOnlyMiddlewares(namespace, false),
349352
},
350353
map[string]interface{}{
351-
"match": "Host(`" + model.ExternalHost + "`) && PathPrefix(`/config/" + namespace + "/services`)",
354+
"match": "Host(`" + hostMatch + "`) && PathPrefix(`/config/" + namespace + "/services`)",
352355
"kind": "Rule",
353356
"services": []interface{}{
354357
map[string]interface{}{
@@ -360,7 +363,7 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
360363
"middlewares": buildIngressMiddlewares(useUMA, namespace, false),
361364
},
362365
map[string]interface{}{
363-
"match": "Host(`" + model.ExternalHost + "`) && PathPrefix(`/config/" + namespace + "/transformations`) && Method(`OPTIONS`)",
366+
"match": "Host(`" + hostMatch + "`) && PathPrefix(`/config/" + namespace + "/transformations`) && Method(`OPTIONS`)",
364367
"kind": "Rule",
365368
"services": []interface{}{
366369
map[string]interface{}{
@@ -372,7 +375,7 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
372375
"middlewares": buildCorsOnlyMiddlewares(namespace, true),
373376
},
374377
map[string]interface{}{
375-
"match": "Host(`" + model.ExternalHost + "`) && PathPrefix(`/config/" + namespace + "/transformations`)",
378+
"match": "Host(`" + hostMatch + "`) && PathPrefix(`/config/" + namespace + "/transformations`)",
376379
"kind": "Rule",
377380
"services": []interface{}{
378381
map[string]interface{}{
@@ -487,13 +490,14 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
487490
{ContainerPort: 5000},
488491
},
489492
Env: []corev1.EnvVar{
490-
{Name: "AGGREGATOR_EXTERNAL_HOST", Value: model.ExternalHost},
493+
{Name: "AGGREGATOR_EXTERNAL_HOST", Value: fmt.Sprintf("%s://%s", model.Protocol, model.ExternalHost)},
491494
{Name: "CLIENT_ID", Value: model.ClientId},
492495
{Name: "CLIENT_SECRET", Value: model.ClientSecret},
493496
{Name: "LOG_LEVEL", Value: model.LogLevel.String()},
494497
{Name: "USER_NAMESPACE", Value: namespace},
495498
{Name: "USER_ID", Value: resolvedOwner},
496499
{Name: "AS_URL", Value: authzServerURL},
500+
{Name: "REGISTRATION_TYPE", Value: registrationType},
497501
{Name: "DISABLE_AUTH", Value: fmt.Sprintf("%v", model.DisableAuth)},
498502
},
499503
},
@@ -503,6 +507,13 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
503507
},
504508
}
505509

510+
if strings.TrimSpace(provisionWebID) != "" {
511+
aggDeploy.Spec.Template.Spec.Containers[0].Env = append(
512+
aggDeploy.Spec.Template.Spec.Containers[0].Env,
513+
corev1.EnvVar{Name: "PROVISION_WEBID", Value: provisionWebID},
514+
)
515+
}
516+
506517
_, err = model.Clientset.AppsV1().Deployments(namespace).Create(ctx, aggDeploy, metav1.CreateOptions{})
507518
if err != nil {
508519
return fmt.Errorf("failed to create Aggregator Instance deployment: %w", err)
@@ -512,14 +523,14 @@ func deployAggregatorResources(namespace string, tokenEndpoint string, accessTok
512523
return nil
513524
}
514525

515-
func updateAggregatorInstanceDeployments(namespace string, accessToken string, refreshToken string, accessTokenExpiry string, ctx context.Context) error {
526+
func updateAggregatorInstanceDeployments(namespace string, accessToken string, refreshToken string, accessTokenExpiry string, ownerToken string, ctx context.Context) error {
516527
if model.Clientset == nil {
517528
logrus.Warn("Kubernetes client not initialized; skipping instance deployment updates")
518529
return nil
519530
}
520531

521532
if accessToken != "" || refreshToken != "" {
522-
tokensPayload, err := buildTokensPayload(accessToken, refreshToken, accessTokenExpiry)
533+
tokensPayload, err := buildTokensPayload(accessToken, refreshToken, accessTokenExpiry, ownerToken)
523534
if err != nil {
524535
return fmt.Errorf("failed to build egress-uma token payload: %w", err)
525536
}
@@ -539,6 +550,21 @@ func updateAggregatorInstanceDeployments(namespace string, accessToken string, r
539550
return nil
540551
}
541552

553+
func hostWithoutPort(hostport string) string {
554+
if hostport == "" {
555+
return hostport
556+
}
557+
if host, _, err := net.SplitHostPort(hostport); err == nil {
558+
return host
559+
}
560+
if strings.Count(hostport, ":") == 1 {
561+
if idx := strings.LastIndex(hostport, ":"); idx > 0 {
562+
return hostport[:idx]
563+
}
564+
}
565+
return hostport
566+
}
567+
542568
func buildIngressMiddlewares(useUMA bool, namespace string, includeStrip bool) []interface{} {
543569
middlewares := make([]interface{}, 0, 3)
544570
middlewares = append(middlewares, map[string]interface{}{
@@ -575,12 +601,15 @@ func buildCorsOnlyMiddlewares(namespace string, includeStrip bool) []interface{}
575601
return middlewares
576602
}
577603

578-
func buildTokensPayload(accessToken string, refreshToken string, accessTokenExpiry string) (map[string]string, error) {
604+
func buildTokensPayload(accessToken string, refreshToken string, accessTokenExpiry string, ownerToken string) (map[string]string, error) {
579605
payload := map[string]string{
580606
"access_token": accessToken,
581607
"refresh_token": refreshToken,
582608
"access_token_expiry": accessTokenExpiry,
583609
}
610+
if strings.TrimSpace(ownerToken) != "" {
611+
payload["owner_token"] = ownerToken
612+
}
584613
data, err := json.Marshal(payload)
585614
if err != nil {
586615
return nil, err

containers/aggregator-server/registration/oidc.go

Lines changed: 0 additions & 85 deletions
This file was deleted.

0 commit comments

Comments
 (0)