Skip to content

Commit

Permalink
feat: add resourcename.RangeParents
Browse files Browse the repository at this point in the history
Returns every possible parent, including collection segments.

Useful for resolving IAM permissions without further knowledge of
patterns for specific resource names.
  • Loading branch information
odsod committed Apr 22, 2021
1 parent 904ee9b commit 9c398c9
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 2 deletions.
4 changes: 2 additions & 2 deletions resourcename/hasparent.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package resourcename

// HasParent tests whether name has the specified parent. Wildcard segments (-) are considered.
func HasParent(name, parent string) bool {
if name == "" || parent == "" {
return false // empty is never a valid child or parent
if name == "" || parent == "" || name == parent {
return false
}
var parentScanner, nameScanner Scanner
parentScanner.Init(parent)
Expand Down
14 changes: 14 additions & 0 deletions resourcename/hasparent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ func TestHasParent(t *testing.T) {
expected: true,
},

{
test: "not parent of self",
name: "shippers/1/sites/1/settings",
parent: "shippers/1/sites/1/settings",
expected: false,
},

{
test: "empty parent",
name: "shippers/1/sites/1",
Expand Down Expand Up @@ -63,6 +70,13 @@ func TestHasParent(t *testing.T) {
expected: true,
},

{
test: "full parent",
name: "shippers/1/sites/1",
parent: "//freight-example.einride.tech/shippers/-",
expected: true,
},

{
test: "full parent and child with different service names",
name: "//other-example.einride.tech/shippers/1/sites/1",
Expand Down
24 changes: 24 additions & 0 deletions resourcename/rangeparents.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package resourcename

// RangeParents iterates over all parents of the provided resource name.
// The iteration order is from root ancestor down to the closest parent.
// Collection segments are included in the iteration, so as to not require knowing the pattern.
// For full resource names, the service is omitted.
func RangeParents(name string, fn func(parent string) bool) {
var sc Scanner
sc.Init(name)
// First segment: special-case to handle full resource names.
if !sc.Scan() {
return
}
start := sc.Start()
if sc.End() != len(name) && !fn(name[start:sc.End()]) {
return
}
// Scan remaining segments.
for sc.Scan() {
if sc.End() != len(name) && !fn(name[start:sc.End()]) {
return
}
}
}
65 changes: 65 additions & 0 deletions resourcename/rangeparents_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package resourcename

import (
"testing"

"gotest.tools/v3/assert"
)

func TestRangeParents(t *testing.T) {
t.Parallel()
for _, tt := range []struct {
name string
input string
expected []string
}{
{
name: "empty",
input: "",
},

{
name: "singleton",
input: "foo",
},

{
name: "single",
input: "foo/bar",
expected: []string{
"foo",
},
},

{
name: "multiple",
input: "foo/bar/baz/123",
expected: []string{
"foo",
"foo/bar",
"foo/bar/baz",
},
},

{
name: "full",
input: "//test.example.com/foo/bar/baz/123",
expected: []string{
"foo",
"foo/bar",
"foo/bar/baz",
},
},
} {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
var actual []string
RangeParents(tt.input, func(parent string) bool {
actual = append(actual, parent)
return true
})
assert.DeepEqual(t, tt.expected, actual)
})
}
}
10 changes: 10 additions & 0 deletions resourcename/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ func (s *Scanner) Scan() bool {
return true
}

// Start returns the start index (inclusive) of the current segment.
func (s *Scanner) Start() int {
return s.start
}

// End returns the end index (exclusive) of the current segment.
func (s *Scanner) End() int {
return s.end
}

// Segment returns the current segment.
func (s *Scanner) Segment() Segment {
return Segment(s.name[s.start:s.end])
Expand Down

0 comments on commit 9c398c9

Please sign in to comment.