-
Notifications
You must be signed in to change notification settings - Fork 9
/
ingress.go
111 lines (91 loc) · 3.46 KB
/
ingress.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Copyright 2022 Namespace Labs Inc; All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
package deploy
import (
"context"
"namespacelabs.dev/foundation/internal/compute"
"namespacelabs.dev/foundation/internal/executor"
"namespacelabs.dev/foundation/internal/fnerrors"
"namespacelabs.dev/foundation/internal/runtime"
"namespacelabs.dev/foundation/schema"
"namespacelabs.dev/foundation/std/cfg"
"namespacelabs.dev/foundation/std/tasks"
)
type ComputeIngressResult struct {
Fragments []*schema.IngressFragment
rootenv cfg.Context
stack *schema.Stack
}
func ComputeIngress(rootenv cfg.Context, planner runtime.Planner, stack *schema.Stack, plans compute.Computable[[]*schema.IngressFragment], allocate bool) compute.Computable[*ComputeIngressResult] {
return &computeIngress{rootenv: rootenv, planner: planner, stack: stack, fragments: plans, allocate: allocate}
}
func PlanIngressDeployment(rc runtime.Planner, c compute.Computable[*ComputeIngressResult]) compute.Computable[*runtime.DeploymentPlan] {
return compute.Transform("plan ingress", c, func(ctx context.Context, res *ComputeIngressResult) (*runtime.DeploymentPlan, error) {
return rc.PlanIngress(ctx, res.stack, res.Fragments)
})
}
type computeIngress struct {
rootenv cfg.Context
planner runtime.Planner
stack *schema.Stack
fragments compute.Computable[[]*schema.IngressFragment]
allocate bool // Actually fetch SSL certificates etc.
compute.LocalScoped[*ComputeIngressResult]
}
func (ci *computeIngress) Action() *tasks.ActionEvent { return tasks.Action("deploy.compute-ingress") }
func (ci *computeIngress) Inputs() *compute.In {
return compute.Inputs().
Indigestible("cluster", ci.planner).
Indigestible("rootenv", ci.rootenv).
Proto("stack", ci.stack).
Computable("fragments", ci.fragments)
}
func (ci *computeIngress) Output() compute.Output {
return compute.Output{NotCacheable: true}
}
func (ci *computeIngress) Compute(ctx context.Context, deps compute.Resolved) (*ComputeIngressResult, error) {
allFragments, err := computeDeferredIngresses(ctx, ci.rootenv, ci.planner, ci.stack)
if err != nil {
return nil, err
}
computed := compute.MustGetDepValue(deps, ci.fragments, "fragments")
allFragments = append(allFragments, computed...)
eg := executor.New(ctx, "compute.ingress")
for _, fragment := range allFragments {
fragment := fragment // Close fragment.
eg.Go(func(ctx context.Context) error {
sch := ci.stack.GetServer(schema.PackageName(fragment.Owner))
if sch == nil {
return fnerrors.BadInputError("%s: not present in the stack", fragment.Owner)
}
if ci.allocate {
fragment.DomainCertificate, err = runtime.MaybeAllocateDomainCertificate(ctx, ci.rootenv.Environment(), sch, fragment.Domain)
if err != nil {
return err
}
}
return nil
})
}
if err := eg.Wait(); err != nil {
return nil, err
}
return &ComputeIngressResult{
rootenv: ci.rootenv,
stack: ci.stack,
Fragments: allFragments,
}, nil
}
func computeDeferredIngresses(ctx context.Context, env cfg.Context, planner runtime.Planner, stack *schema.Stack) ([]*schema.IngressFragment, error) {
var fragments []*schema.IngressFragment
// XXX parallelism.
for _, srv := range stack.Entry {
frags, err := runtime.ComputeIngress(ctx, env, planner, srv, stack.Endpoint)
if err != nil {
return nil, err
}
fragments = append(fragments, frags...)
}
return fragments, nil
}