-
Notifications
You must be signed in to change notification settings - Fork 12
/
snapshot.go
127 lines (105 loc) · 4.49 KB
/
snapshot.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
119
120
121
122
123
124
125
126
127
package discoveryservice
import (
"github.com/3scale-ops/marin3r/pkg/envoy"
envoy_resources_v3 "github.com/3scale-ops/marin3r/pkg/envoy/resources/v3"
envoy_serializer "github.com/3scale-ops/marin3r/pkg/envoy/serializer"
"github.com/3scale-ops/marin3r/pkg/util"
envoy_config_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
envoy_config_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
envoy_config_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
envoy_config_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
envoy_extensions_transport_sockets_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3"
envoy_service_runtime_v3 "github.com/envoyproxy/go-control-plane/envoy/service/runtime/v3"
cache_types "github.com/envoyproxy/go-control-plane/pkg/cache/types"
cache_v3 "github.com/envoyproxy/go-control-plane/pkg/cache/v3"
)
// Snapshot implements "github.com/3scale-ops/marin3r/pkg/discoveryservice/xdss".Snapshot for envoy API v3.
type Snapshot struct {
v3 *cache_v3.Snapshot
}
// NewSnapshot returns a Snapshot object.
func NewSnapshot(v3 *cache_v3.Snapshot) Snapshot {
return Snapshot{v3: v3}
}
// Consistent check verifies that the dependent resources are exactly listed in the
// snapshot:
// - all EDS resources are listed by name in CDS resources
// - all RDS resources are listed by name in LDS resources
//
// Note that clusters and listeners are requested without name references, so
// Envoy will accept the snapshot list of clusters as-is even if it does not match
// all references found in xDS.
func (s Snapshot) Consistent() error {
return s.v3.Consistent()
}
// SetResource writes the given v3 resource in the Snapshot object.
func (s Snapshot) SetResource(name string, res envoy.Resource) {
var rType envoy.Type
switch o := res.(type) {
case *envoy_config_endpoint_v3.ClusterLoadAssignment:
rType = envoy.Endpoint
s.v3.Resources[v3CacheResources(rType)].Items[name] = cache_types.ResourceWithTTL{Resource: o}
case *envoy_config_cluster_v3.Cluster:
rType = envoy.Cluster
s.v3.Resources[v3CacheResources(rType)].Items[name] = cache_types.ResourceWithTTL{Resource: o}
case *envoy_config_route_v3.RouteConfiguration:
rType = envoy.Route
s.v3.Resources[v3CacheResources(rType)].Items[name] = cache_types.ResourceWithTTL{Resource: o}
case *envoy_config_route_v3.ScopedRouteConfiguration:
rType = envoy.ScopedRoute
s.v3.Resources[v3CacheResources(rType)].Items[name] = cache_types.ResourceWithTTL{Resource: o}
case *envoy_config_listener_v3.Listener:
rType = envoy.Listener
s.v3.Resources[v3CacheResources(rType)].Items[name] = cache_types.ResourceWithTTL{Resource: o}
case *envoy_extensions_transport_sockets_tls_v3.Secret:
rType = envoy.Secret
s.v3.Resources[v3CacheResources(rType)].Items[name] = cache_types.ResourceWithTTL{Resource: o}
case *envoy_service_runtime_v3.Runtime:
rType = envoy.Runtime
s.v3.Resources[v3CacheResources(rType)].Items[name] = cache_types.ResourceWithTTL{Resource: o}
}
s.SetVersion(rType, s.recalculateVersion(rType))
}
// GetResources selects snapshot resources by type.
func (s Snapshot) GetResources(rType envoy.Type) map[string]envoy.Resource {
typeURLs := envoy_resources_v3.Mappings()
resources := map[string]envoy.Resource{}
for k, v := range s.v3.GetResources(typeURLs[rType]) {
resources[k] = v.(envoy.Resource)
}
return resources
}
// GetVersion returns the version for a resource type.
func (s Snapshot) GetVersion(rType envoy.Type) string {
typeURLs := envoy_resources_v3.Mappings()
return s.v3.GetVersion(typeURLs[rType])
}
// SetVersion sets the version for a resource type.
func (s Snapshot) SetVersion(rType envoy.Type, version string) {
s.v3.Resources[v3CacheResources(rType)].Version = version
}
func (s Snapshot) recalculateVersion(rType envoy.Type) string {
resources := map[string]string{}
encoder := envoy_serializer.NewResourceMarshaller(envoy_serializer.JSON, envoy.APIv3)
for n, r := range s.v3.Resources[v3CacheResources(rType)].Items {
j, _ := encoder.Marshal(r.Resource)
resources[n] = string(j)
}
if len(resources) > 0 {
return util.Hash(resources)
}
return ""
}
func v3CacheResources(rType envoy.Type) int {
types := map[envoy.Type]int{
envoy.Endpoint: 0,
envoy.Cluster: 1,
envoy.Route: 2,
envoy.ScopedRoute: 3,
envoy.Listener: 4,
envoy.Secret: 5,
envoy.Runtime: 6,
envoy.ExtensionConfig: 7,
}
return types[rType]
}