Skip to content

Commit fef79ee

Browse files
authored
Break up trafficpolicy objects (openservicemesh#5146)
* Break up trafficpolicy objects Signed-off-by: nshankar13 <[email protected]>
1 parent c048937 commit fef79ee

27 files changed

+2514
-2356
lines changed

pkg/catalog/egress.go

Lines changed: 109 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,15 @@ const (
2424
upstreamTrafficSettingKind = "UpstreamTrafficSetting"
2525
)
2626

27-
// GetEgressTrafficPolicy returns the Egress traffic policy associated with the given service identity
28-
func (mc *MeshCatalog) GetEgressTrafficPolicy(serviceIdentity identity.ServiceIdentity) (*trafficpolicy.EgressTrafficPolicy, error) {
27+
// GetEgressClusterConfigs returns the cluster configs for the Egress traffic policy associated with the given service identity
28+
func (mc *MeshCatalog) GetEgressClusterConfigs(serviceIdentity identity.ServiceIdentity) ([]*trafficpolicy.EgressClusterConfig, error) {
2929
if mc.GetMeshConfig().Spec.Traffic.EnableEgress {
3030
// Mesh-wide global egress is enabled, so EgressPolicy is implicitly disabled
3131
return nil, nil
3232
}
3333

34-
var trafficMatches []*trafficpolicy.TrafficMatch
3534
var clusterConfigs []*trafficpolicy.EgressClusterConfig
36-
portToRouteConfigMap := make(map[int][]*trafficpolicy.EgressHTTPRouteConfig)
35+
3736
egressResources := mc.ListEgressPoliciesForServiceAccount(serviceIdentity.ToK8sServiceAccount())
3837

3938
for _, egress := range egressResources {
@@ -47,11 +46,60 @@ func (mc *MeshCatalog) GetEgressTrafficPolicy(serviceIdentity identity.ServiceId
4746
switch strings.ToLower(portSpec.Protocol) {
4847
case constants.ProtocolHTTP:
4948
// ---
50-
// Build the HTTP route configs for the given Egress policy
51-
httpRouteConfigs, httpClusterConfigs := mc.buildHTTPRouteConfigs(egress, portSpec.Number, upstreamTrafficSetting)
52-
portToRouteConfigMap[portSpec.Number] = append(portToRouteConfigMap[portSpec.Number], httpRouteConfigs...)
49+
// Build the cluster configs for the given Egress policy
50+
httpClusterConfigs := mc.buildClusterConfigs(egress, portSpec.Number, upstreamTrafficSetting)
5351
clusterConfigs = append(clusterConfigs, httpClusterConfigs...)
5452

53+
case constants.ProtocolTCP, constants.ProtocolTCPServerFirst, constants.ProtocolHTTPS:
54+
// ---
55+
// Build the TCP cluster config or HTTPS cluster config for this port
56+
// HTTPS is TLS encrypted, so will be proxied as a TCP stream
57+
58+
clusterConfig := &trafficpolicy.EgressClusterConfig{
59+
Name: fmt.Sprintf("%d", portSpec.Number),
60+
Port: portSpec.Number,
61+
}
62+
63+
if upstreamTrafficSetting != nil {
64+
clusterConfig.UpstreamConnectionSettings = upstreamTrafficSetting.Spec.ConnectionSettings
65+
}
66+
clusterConfigs = append(clusterConfigs, clusterConfig)
67+
}
68+
}
69+
}
70+
71+
var err error
72+
73+
// Deduplicate the list of EgressClusterConfig objects
74+
clusterConfigs, err = trafficpolicy.DeduplicateClusterConfigs(clusterConfigs)
75+
if err != nil {
76+
log.Error().Err(err).Str(errcode.Kind, errcode.GetErrCodeWithMetric(errcode.ErrDedupEgressClusterConfigs)).
77+
Msgf("Error deduplicating egress clusters configs for service identity %s", serviceIdentity)
78+
return nil, err
79+
}
80+
81+
return clusterConfigs, nil
82+
}
83+
84+
// GetEgressTrafficMatches returns the traffic matches for the Egress traffic policy associated with the given service identity
85+
func (mc *MeshCatalog) GetEgressTrafficMatches(serviceIdentity identity.ServiceIdentity) ([]*trafficpolicy.TrafficMatch, error) {
86+
if mc.GetMeshConfig().Spec.Traffic.EnableEgress {
87+
// Mesh-wide global egress is enabled, so EgressPolicy is implicitly disabled
88+
return nil, nil
89+
}
90+
91+
var trafficMatches []*trafficpolicy.TrafficMatch
92+
egressResources := mc.ListEgressPoliciesForServiceAccount(serviceIdentity.ToK8sServiceAccount())
93+
94+
for _, egress := range egressResources {
95+
_, err := mc.getUpstreamTrafficSettingForEgress(egress)
96+
if err != nil {
97+
log.Error().Err(err).Msg("Ignoring invalid Egress policy")
98+
continue
99+
}
100+
for _, portSpec := range egress.Spec.Ports {
101+
switch strings.ToLower(portSpec.Protocol) {
102+
case constants.ProtocolHTTP:
55103
// Configure port based TrafficMatch for HTTP port
56104
trafficMatches = append(trafficMatches, &trafficpolicy.TrafficMatch{
57105
Name: trafficpolicy.GetEgressTrafficMatchName(portSpec.Number, portSpec.Protocol),
@@ -60,14 +108,6 @@ func (mc *MeshCatalog) GetEgressTrafficPolicy(serviceIdentity identity.ServiceId
60108
})
61109

62110
case constants.ProtocolTCP, constants.ProtocolTCPServerFirst:
63-
// ---
64-
// Build the TCP cluster config for this port
65-
clusterConfigs = append(clusterConfigs, &trafficpolicy.EgressClusterConfig{
66-
Name: fmt.Sprintf("%d", portSpec.Number),
67-
Port: portSpec.Number,
68-
UpstreamTrafficSetting: upstreamTrafficSetting,
69-
})
70-
71111
// Configure port + IP range TrafficMatches
72112
trafficMatches = append(trafficMatches, &trafficpolicy.TrafficMatch{
73113
Name: trafficpolicy.GetEgressTrafficMatchName(portSpec.Number, portSpec.Protocol),
@@ -78,15 +118,6 @@ func (mc *MeshCatalog) GetEgressTrafficPolicy(serviceIdentity identity.ServiceId
78118
})
79119

80120
case constants.ProtocolHTTPS:
81-
// ---
82-
// Build the HTTPS cluster config for this port
83-
// HTTPS is TLS encrypted, so will be proxied as a TCP stream
84-
clusterConfigs = append(clusterConfigs, &trafficpolicy.EgressClusterConfig{
85-
Name: fmt.Sprintf("%d", portSpec.Number),
86-
Port: portSpec.Number,
87-
UpstreamTrafficSetting: upstreamTrafficSetting,
88-
})
89-
90121
// Configure port + IP range TrafficMatches
91122
trafficMatches = append(trafficMatches, &trafficpolicy.TrafficMatch{
92123
Name: trafficpolicy.GetEgressTrafficMatchName(portSpec.Number, portSpec.Protocol),
@@ -109,19 +140,30 @@ func (mc *MeshCatalog) GetEgressTrafficPolicy(serviceIdentity identity.ServiceId
109140
return nil, err
110141
}
111142

112-
// Deduplicate the list of EgressClusterConfig objects
113-
clusterConfigs, err = trafficpolicy.DeduplicateClusterConfigs(clusterConfigs)
114-
if err != nil {
115-
log.Error().Err(err).Str(errcode.Kind, errcode.GetErrCodeWithMetric(errcode.ErrDedupEgressClusterConfigs)).
116-
Msgf("Error deduplicating egress clusters configs for service identity %s", serviceIdentity)
117-
return nil, err
143+
return trafficMatches, nil
144+
}
145+
146+
// GetEgressHTTPRouteConfigsPerPort returns the map of Egress http route configs per port for the Egress traffic policy associated with the given service identity
147+
func (mc *MeshCatalog) GetEgressHTTPRouteConfigsPerPort(serviceIdentity identity.ServiceIdentity) map[int][]*trafficpolicy.EgressHTTPRouteConfig {
148+
if mc.GetMeshConfig().Spec.Traffic.EnableEgress {
149+
// Mesh-wide global egress is enabled, so EgressPolicy is implicitly disabled
150+
return nil
151+
}
152+
153+
portToRouteConfigMap := make(map[int][]*trafficpolicy.EgressHTTPRouteConfig)
154+
egressResources := mc.ListEgressPoliciesForServiceAccount(serviceIdentity.ToK8sServiceAccount())
155+
156+
for _, egress := range egressResources {
157+
for _, portSpec := range egress.Spec.Ports {
158+
if strings.ToLower(portSpec.Protocol) == constants.ProtocolHTTP {
159+
// Build the HTTP route configs for the given Egress policy
160+
httpRouteConfigs := mc.buildHTTPRouteConfigs(egress, portSpec.Number)
161+
portToRouteConfigMap[portSpec.Number] = append(portToRouteConfigMap[portSpec.Number], httpRouteConfigs...)
162+
}
163+
}
118164
}
119165

120-
return &trafficpolicy.EgressTrafficPolicy{
121-
HTTPRouteConfigsPerPort: portToRouteConfigMap,
122-
TrafficMatches: trafficMatches,
123-
ClustersConfigs: clusterConfigs,
124-
}, nil
166+
return portToRouteConfigMap
125167
}
126168

127169
func (mc *MeshCatalog) getUpstreamTrafficSettingForEgress(egressPolicy *policyv1alpha1.Egress) (*policyv1alpha1.UpstreamTrafficSetting, error) {
@@ -149,14 +191,41 @@ func (mc *MeshCatalog) getUpstreamTrafficSettingForEgress(egressPolicy *policyv1
149191
return nil, nil
150192
}
151193

152-
func (mc *MeshCatalog) buildHTTPRouteConfigs(egressPolicy *policyv1alpha1.Egress, port int,
153-
upstreamTrafficSetting *policyv1alpha1.UpstreamTrafficSetting) ([]*trafficpolicy.EgressHTTPRouteConfig, []*trafficpolicy.EgressClusterConfig) {
194+
func (mc *MeshCatalog) buildClusterConfigs(egressPolicy *policyv1alpha1.Egress, port int,
195+
upstreamTrafficSetting *policyv1alpha1.UpstreamTrafficSetting) []*trafficpolicy.EgressClusterConfig {
196+
var clusterConfigs []*trafficpolicy.EgressClusterConfig
197+
198+
// Parse the hosts specified and build routing rules for the specified hosts
199+
for _, host := range egressPolicy.Spec.Hosts {
200+
// A route matching an HTTP host will include host header matching for the following:
201+
// 1. host (ex. foo.com)
202+
// 2. host:port (ex. foo.com:80)
203+
hostnameWithPort := fmt.Sprintf("%s:%d", host, port)
204+
205+
// Create cluster config for this host and port combination
206+
clusterName := hostnameWithPort
207+
clusterConfig := &trafficpolicy.EgressClusterConfig{
208+
Name: clusterName,
209+
Host: host,
210+
Port: port,
211+
}
212+
213+
if upstreamTrafficSetting != nil {
214+
clusterConfig.UpstreamConnectionSettings = upstreamTrafficSetting.Spec.ConnectionSettings
215+
}
216+
217+
clusterConfigs = append(clusterConfigs, clusterConfig)
218+
}
219+
220+
return clusterConfigs
221+
}
222+
223+
func (mc *MeshCatalog) buildHTTPRouteConfigs(egressPolicy *policyv1alpha1.Egress, port int) []*trafficpolicy.EgressHTTPRouteConfig {
154224
if egressPolicy == nil {
155-
return nil, nil
225+
return nil
156226
}
157227

158228
var routeConfigs []*trafficpolicy.EgressHTTPRouteConfig
159-
var clusterConfigs []*trafficpolicy.EgressClusterConfig
160229

161230
// Before building the route configs, pre-compute the allowed IP ranges since they
162231
// will be the same for every HTTP route config derived from the given Egress policy.
@@ -214,13 +283,6 @@ func (mc *MeshCatalog) buildHTTPRouteConfigs(egressPolicy *policyv1alpha1.Egress
214283

215284
// Create cluster config for this host and port combination
216285
clusterName := hostnameWithPort
217-
clusterConfig := &trafficpolicy.EgressClusterConfig{
218-
Name: clusterName,
219-
Host: host,
220-
Port: port,
221-
UpstreamTrafficSetting: upstreamTrafficSetting,
222-
}
223-
clusterConfigs = append(clusterConfigs, clusterConfig)
224286

225287
// Build egress routing rules from the given HTTP route matches and allowed destination attributes
226288
var httpRoutingRules []*trafficpolicy.EgressHTTPRoutingRule
@@ -248,7 +310,7 @@ func (mc *MeshCatalog) buildHTTPRouteConfigs(egressPolicy *policyv1alpha1.Egress
248310
routeConfigs = append(routeConfigs, hostSpecificRouteConfig)
249311
}
250312

251-
return routeConfigs, clusterConfigs
313+
return routeConfigs
252314
}
253315

254316
func getHTTPRouteMatchesFromHTTPRouteGroup(httpRouteGroup *smiSpecs.HTTPRouteGroup) []trafficpolicy.HTTPRouteMatch {

0 commit comments

Comments
 (0)