/
mesh.go
118 lines (103 loc) 路 4.03 KB
/
mesh.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
112
113
114
115
116
117
118
package mesh
import (
"context"
"fmt"
"strings"
"sync"
"github.com/pkg/errors"
"golang.org/x/exp/slices"
"github.com/kumahq/kuma/pkg/core"
"github.com/kumahq/kuma/pkg/core/resources/manager"
"github.com/kumahq/kuma/pkg/core/resources/model"
"github.com/kumahq/kuma/pkg/core/resources/store"
"github.com/kumahq/kuma/pkg/core/tokens"
kuma_log "github.com/kumahq/kuma/pkg/log"
"github.com/kumahq/kuma/pkg/tokens/builtin/issuer"
)
var log = core.Log.WithName("defaults").WithName("mesh")
// ensureMux protects concurrent EnsureDefaultMeshResources invocation.
// On Kubernetes, EnsureDefaultMeshResources is called both from MeshManager when creating default Mesh and from the MeshController
// When they run concurrently:
// 1 invocation can check that TrafficPermission is absent and then create it.
// 2 invocation can check that TrafficPermission is absent, but it was just created, so it tries to created it which results in error
var ensureMux = sync.Mutex{}
func EnsureDefaultMeshResources(
ctx context.Context,
resManager manager.ResourceManager,
mesh model.Resource,
skippedPolicies []string,
extensions context.Context,
createMeshDefaultRoutingResources bool,
k8sStore bool,
systemNamespace string,
) error {
ensureMux.Lock()
defer ensureMux.Unlock()
meshName := mesh.GetMeta().GetName()
logger := kuma_log.AddFieldsFromCtx(log, ctx, extensions).WithValues("mesh", meshName)
logger.Info("ensuring default resources for Mesh exist")
created, err := ensureDataplaneTokenSigningKey(ctx, resManager, mesh)
if err != nil {
return errors.Wrap(err, "could not create default Dataplane Token Signing Key")
}
if created {
resKey := tokens.SigningKeyResourceKey(issuer.DataplaneTokenSigningKeyPrefix(meshName), tokens.DefaultKeyID, meshName)
logger.Info("default Dataplane Token Signing Key created", "name", resKey.Name)
} else {
logger.Info("Dataplane Token Signing Key already exists")
}
if slices.Contains(skippedPolicies, "*") {
logger.Info("skipping all default policy creation")
return nil
}
defaultResourceBuilders := map[string]func() model.Resource{
"mesh-gateways-timeout-all": defaulMeshGatewaysTimeoutResource,
"mesh-timeout-all": defaultMeshTimeoutResource,
"mesh-circuit-breaker-all": defaultMeshCircuitBreakerResource,
"mesh-retry-all": defaultMeshRetryResource,
}
if createMeshDefaultRoutingResources {
defaultResourceBuilders["allow-all"] = defaultTrafficPermissionResource
defaultResourceBuilders["route-all"] = defaultTrafficRouteResource
}
for prefix, resourceBuilder := range defaultResourceBuilders {
resourceName := fmt.Sprintf("%s-%s", prefix, meshName)
// new policies are created in a kuma system namespace
if k8sStore && strings.HasPrefix(prefix, "mesh-") {
resourceName = fmt.Sprintf("%s.%s", resourceName, systemNamespace)
}
key := model.ResourceKey{
Mesh: meshName,
Name: resourceName,
}
resource := resourceBuilder()
var msg string
if !slices.Contains(skippedPolicies, string(resource.Descriptor().Name)) {
err, created := ensureDefaultResource(ctx, resManager, resource, key)
if err != nil {
return errors.Wrapf(err, "could not create default %s %q", resource.Descriptor().Name, key.Name)
}
msg = fmt.Sprintf("default %s already exists", resource.Descriptor().Name)
if created {
msg = fmt.Sprintf("default %s created", resource.Descriptor().Name)
}
} else {
msg = fmt.Sprintf("skipping default %s creation", resource.Descriptor().Name)
}
logger.Info(msg, "name", key.Name)
}
return nil
}
func ensureDefaultResource(ctx context.Context, resManager manager.ResourceManager, res model.Resource, resourceKey model.ResourceKey) (error, bool) {
err := resManager.Get(ctx, res, store.GetBy(resourceKey), store.GetConsistent())
if err == nil {
return nil, false
}
if !store.IsResourceNotFound(err) {
return errors.Wrap(err, "could not retrieve a resource"), false
}
if err := resManager.Create(ctx, res, store.CreateBy(resourceKey)); err != nil {
return errors.Wrap(err, "could not create a resource"), false
}
return nil, true
}