-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add internal RPC endpoint to compute upstreams from intentions
- Loading branch information
Showing
18 changed files
with
1,123 additions
and
250 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package connect | ||
|
||
import ( | ||
"github.com/hashicorp/consul/agent/structs" | ||
) | ||
|
||
// AuthorizeIntentionTarget determines whether the destination is covered by the given intention | ||
// and whether the intention action allows a connection. | ||
// This is a generalized version of the old CertURI.Authorize(), and can be evaluated against sources or destinations. | ||
// | ||
// The return value of `auth` is only valid if the second value `match` is true. | ||
// If `match` is false, then the intention doesn't match this target and any result should be ignored. | ||
func AuthorizeIntentionTarget( | ||
target, targetNS string, | ||
ixn *structs.Intention, | ||
matchType structs.IntentionMatchType, | ||
) (auth bool, match bool) { | ||
|
||
switch matchType { | ||
case structs.IntentionMatchDestination: | ||
if ixn.DestinationNS != structs.WildcardSpecifier && ixn.DestinationNS != targetNS { | ||
// Non-matching namespace | ||
return false, false | ||
} | ||
|
||
if ixn.DestinationName != structs.WildcardSpecifier && ixn.DestinationName != target { | ||
// Non-matching name | ||
return false, false | ||
} | ||
|
||
case structs.IntentionMatchSource: | ||
if ixn.SourceNS != structs.WildcardSpecifier && ixn.SourceNS != targetNS { | ||
// Non-matching namespace | ||
return false, false | ||
} | ||
|
||
if ixn.SourceName != structs.WildcardSpecifier && ixn.SourceName != target { | ||
// Non-matching name | ||
return false, false | ||
} | ||
|
||
default: | ||
// Reject on any un-recognized match type | ||
return false, false | ||
} | ||
|
||
// The name and namespace match, so the destination is covered | ||
return ixn.Action == structs.IntentionActionAllow, true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
package connect | ||
|
||
import ( | ||
"github.com/hashicorp/consul/agent/structs" | ||
"github.com/stretchr/testify/assert" | ||
"testing" | ||
) | ||
|
||
func TestAuthorizeIntentionTarget(t *testing.T) { | ||
cases := []struct { | ||
name string | ||
target string | ||
targetNS string | ||
ixn *structs.Intention | ||
matchType structs.IntentionMatchType | ||
auth bool | ||
match bool | ||
}{ | ||
// Source match type | ||
{ | ||
name: "match exact source, not matching namespace", | ||
target: "web", | ||
targetNS: structs.IntentionDefaultNamespace, | ||
ixn: &structs.Intention{ | ||
SourceName: "db", | ||
SourceNS: "different", | ||
}, | ||
matchType: structs.IntentionMatchSource, | ||
auth: false, | ||
match: false, | ||
}, | ||
{ | ||
name: "match exact source, not matching name", | ||
target: "web", | ||
targetNS: structs.IntentionDefaultNamespace, | ||
ixn: &structs.Intention{ | ||
SourceName: "db", | ||
SourceNS: structs.IntentionDefaultNamespace, | ||
}, | ||
matchType: structs.IntentionMatchSource, | ||
auth: false, | ||
match: false, | ||
}, | ||
{ | ||
name: "match exact source, allow", | ||
target: "web", | ||
targetNS: structs.IntentionDefaultNamespace, | ||
ixn: &structs.Intention{ | ||
SourceName: "web", | ||
SourceNS: structs.IntentionDefaultNamespace, | ||
Action: structs.IntentionActionAllow, | ||
}, | ||
matchType: structs.IntentionMatchSource, | ||
auth: true, | ||
match: true, | ||
}, | ||
{ | ||
name: "match exact source, deny", | ||
target: "web", | ||
targetNS: structs.IntentionDefaultNamespace, | ||
ixn: &structs.Intention{ | ||
SourceName: "web", | ||
SourceNS: structs.IntentionDefaultNamespace, | ||
Action: structs.IntentionActionDeny, | ||
}, | ||
matchType: structs.IntentionMatchSource, | ||
auth: false, | ||
match: true, | ||
}, | ||
{ | ||
name: "match exact sourceNS for wildcard service, deny", | ||
target: "web", | ||
targetNS: structs.IntentionDefaultNamespace, | ||
ixn: &structs.Intention{ | ||
SourceName: structs.WildcardSpecifier, | ||
SourceNS: structs.IntentionDefaultNamespace, | ||
Action: structs.IntentionActionDeny, | ||
}, | ||
matchType: structs.IntentionMatchSource, | ||
auth: false, | ||
match: true, | ||
}, | ||
{ | ||
name: "match exact sourceNS for wildcard service, allow", | ||
target: "web", | ||
targetNS: structs.IntentionDefaultNamespace, | ||
ixn: &structs.Intention{ | ||
SourceName: structs.WildcardSpecifier, | ||
SourceNS: structs.IntentionDefaultNamespace, | ||
Action: structs.IntentionActionAllow, | ||
}, | ||
matchType: structs.IntentionMatchSource, | ||
auth: true, | ||
match: true, | ||
}, | ||
|
||
// Destination match type | ||
{ | ||
name: "match exact destination, not matching namespace", | ||
target: "web", | ||
targetNS: structs.IntentionDefaultNamespace, | ||
ixn: &structs.Intention{ | ||
DestinationName: "db", | ||
DestinationNS: "different", | ||
}, | ||
matchType: structs.IntentionMatchDestination, | ||
auth: false, | ||
match: false, | ||
}, | ||
{ | ||
name: "match exact destination, not matching name", | ||
target: "web", | ||
targetNS: structs.IntentionDefaultNamespace, | ||
ixn: &structs.Intention{ | ||
DestinationName: "db", | ||
DestinationNS: structs.IntentionDefaultNamespace, | ||
}, | ||
matchType: structs.IntentionMatchDestination, | ||
auth: false, | ||
match: false, | ||
}, | ||
{ | ||
name: "match exact destination, allow", | ||
target: "web", | ||
targetNS: structs.IntentionDefaultNamespace, | ||
ixn: &structs.Intention{ | ||
DestinationName: "web", | ||
DestinationNS: structs.IntentionDefaultNamespace, | ||
Action: structs.IntentionActionAllow, | ||
}, | ||
matchType: structs.IntentionMatchDestination, | ||
auth: true, | ||
match: true, | ||
}, | ||
{ | ||
name: "match exact destination, deny", | ||
target: "web", | ||
targetNS: structs.IntentionDefaultNamespace, | ||
ixn: &structs.Intention{ | ||
DestinationName: "web", | ||
DestinationNS: structs.IntentionDefaultNamespace, | ||
Action: structs.IntentionActionDeny, | ||
}, | ||
matchType: structs.IntentionMatchDestination, | ||
auth: false, | ||
match: true, | ||
}, | ||
{ | ||
name: "match exact destinationNS for wildcard service, deny", | ||
target: "web", | ||
targetNS: structs.IntentionDefaultNamespace, | ||
ixn: &structs.Intention{ | ||
DestinationName: structs.WildcardSpecifier, | ||
DestinationNS: structs.IntentionDefaultNamespace, | ||
Action: structs.IntentionActionDeny, | ||
}, | ||
matchType: structs.IntentionMatchDestination, | ||
auth: false, | ||
match: true, | ||
}, | ||
{ | ||
name: "match exact destinationNS for wildcard service, allow", | ||
target: "web", | ||
targetNS: structs.IntentionDefaultNamespace, | ||
ixn: &structs.Intention{ | ||
DestinationName: structs.WildcardSpecifier, | ||
DestinationNS: structs.IntentionDefaultNamespace, | ||
Action: structs.IntentionActionAllow, | ||
}, | ||
matchType: structs.IntentionMatchDestination, | ||
auth: true, | ||
match: true, | ||
}, | ||
{ | ||
name: "unknown match type", | ||
target: "web", | ||
targetNS: structs.IntentionDefaultNamespace, | ||
ixn: &structs.Intention{ | ||
DestinationName: structs.WildcardSpecifier, | ||
DestinationNS: structs.IntentionDefaultNamespace, | ||
Action: structs.IntentionActionAllow, | ||
}, | ||
matchType: structs.IntentionMatchType("unknown"), | ||
auth: false, | ||
match: false, | ||
}, | ||
} | ||
|
||
for _, tc := range cases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
auth, match := AuthorizeIntentionTarget(tc.target, tc.targetNS, tc.ixn, tc.matchType) | ||
assert.Equal(t, tc.auth, auth) | ||
assert.Equal(t, tc.match, match) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.