Skip to content
This repository has been archived by the owner on Jun 14, 2018. It is now read-only.

Add support for source-based routing #225

Merged
merged 2 commits into from
Feb 27, 2017
Merged

Conversation

kyessenov
Copy link
Contributor

No description provided.

func (i *IstioRegistry) RouteRulesBySource(namespace string, instances []*ServiceInstance) []*proxyconfig.RouteRule {
out := make([]*proxyconfig.RouteRule, 0)
for _, rule := range i.RouteRules(namespace) {
if rule.Match != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(optional) you could invert the rule.match != nil check here and get rid of the extra found variable, e.g.

if rule.Match == nil {
    continue
}
for _, instance := range instances {
    if rule.Match.Source != "" && rule.Match.Source != instance.Service.Hostname {
        continue
    }
    var tags Tags = rule.Match.SourceTags
    if !tags.SubsetOf(instance.Tags) {
        continue
    }
    out = append(out, rule)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, thanks. also need a break statement after append.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, we'd have to duplicate code for rule.Match == nil. maybe leave it as is?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, yeah. Leave it as is and ignore my comment.

@istio-testing
Copy link
Contributor

Jenkins job manager/presubmit passed

@codecov
Copy link

codecov bot commented Feb 27, 2017

Codecov Report

Merging #225 into master will decrease coverage by -0.16%.
The diff coverage is 0%.

@@            Coverage Diff            @@
##           master    #225      +/-   ##
=========================================
- Coverage   31.05%   30.9%   -0.16%     
=========================================
  Files          19      19              
  Lines        1803    1812       +9     
=========================================
  Hits          560     560              
- Misses       1187    1196       +9     
  Partials       56      56
Impacted Files Coverage Δ
model/service.go 77.66% <ø> (ø)
proxy/envoy/watcher.go 0% <ø> (ø)
proxy/envoy/config.go 0% <0%> (ø)
proxy/envoy/route.go 19.84% <0%> (+1.04%)
model/config.go 0% <0%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1421d2d...2e389cf. Read the comment docs.

@kyessenov
Copy link
Contributor Author

Let's merge this, and send coverage tests in another PR.

@kyessenov kyessenov merged commit 4832466 into istio:master Feb 27, 2017
@kyessenov kyessenov deleted the source_tags branch February 27, 2017 22:55
@@ -146,7 +146,7 @@ type IstioRegistry struct {
ConfigRegistry
}

// RouteRules lists all routing rules in a namespace (or all rules if namespace is "")
// RouteRules lists all unsorted routing rules in a namespace (or all rules if namespace is "")
func (i *IstioRegistry) RouteRules(namespace string) []*proxyconfig.RouteRule {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't this be sorted by precedence and destination?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We certainly need to sort route rules by all its fields. I documented precendece since that's how it works now.

@@ -184,13 +184,28 @@ func buildOutboundFilters(instances []*model.ServiceInstance, services []*model.
suffix := sharedInstanceHost(instances)
httpConfigs := make(HTTPRouteConfigs)

// get all the route rules applicable to the instances
rules := config.RouteRulesBySource("", instances)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If instances is the set of all destination services in k8s, then this function basically does that rulesByDestination did.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, instances is co-located instances, not external destinations.

precedence: 2
match:
source: {{.source}}.{{.namespace}}.svc.cluster.local
source_tags:
version: v1
http:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to go as a separate test to ensure that other services are unable to call service "worldl

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need two versions of world?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Two versions of hello, hello v1 can only call world v1, so on. Otherwise this test as is, is not checking whether service hello-v2 can access service world-v1 or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we can do a follow-up test PR. I will get mocks set-up as well.

@@ -184,13 +184,28 @@ func buildOutboundFilters(instances []*model.ServiceInstance, services []*model.
suffix := sharedInstanceHost(instances)
httpConfigs := make(HTTPRouteConfigs)

// get all the route rules applicable to the instances
rules := config.RouteRulesBySource("", instances)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this code expected to run? When running in a pod, this will be a single instance and not an array. This cannot run on the host as a daemon set. And even if it does, same concept applies.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's in a pod. If there are two services pointing to the pod, or two services with distinct ports, we'd get two elements in the array, wouldn't we?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true. We really need to rename these variables in future for better readability. May be call these as localSvcInstances ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The top-level call takes instances and services, so I was just following that naming pattern. Pretend instance is always local instances throughout.

found := false
for _, instance := range instances {
if rule.Match.Source != "" && rule.Match.Source != instance.Service.Hostname {
continue
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need arrays here. It's just the pod filtering out rules before generating the config.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's for per-node case, but I don't think it makes any difference how many instances are behind the proxy.

@rshriram
Copy link
Member

Please wait

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants