-
Notifications
You must be signed in to change notification settings - Fork 584
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
asserts,registry: define confdb-control assertion #14705
base: master
Are you sure you want to change the base?
Conversation
86f5f1a
to
8123a6d
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #14705 +/- ##
==========================================
- Coverage 78.95% 77.99% -0.96%
==========================================
Files 1084 1135 +51
Lines 146638 150521 +3883
==========================================
+ Hits 115773 117403 +1630
- Misses 23667 25854 +2187
- Partials 7198 7264 +66
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
8123a6d
to
eaf6576
Compare
For posterity, this was split off of #14508 |
asserts/confdb_asserts.go
Outdated
cc := &ConfdbControl{ | ||
assertionBase: assert, | ||
operators: make(map[string]*confdb.Operator), | ||
} | ||
if err := parseConfdbControlGroups(cc, groups); err != nil { | ||
return nil, err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, I'd say it's better to have parseConfdbControlGroups
return a map[string]*confdb.Operator
which gets put into cc rather than modify a parameter directly
asserts/confdb_asserts.go
Outdated
|
||
func parseConfdbControlGroups(cc *ConfdbControl, rawGroups []interface{}) error { | ||
for i, rawGroup := range rawGroups { | ||
errPrefix := fmt.Sprintf("group at position %d", i+1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
errPrefix := fmt.Sprintf("group at position %d", i+1) | |
errPrefix := fmt.Sprintf("cannot parse group at position %d", i+1) |
asserts/confdb_asserts.go
Outdated
if err != nil { | ||
return fmt.Errorf(`%s: "authentication" %w`, errPrefix, err) | ||
} | ||
if auth == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also needs to check that the auth method is operator-key
or store
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The check ends up happening inside registry/confdb_control/(AddGroup -> convertToAuthenticationMethod -> isValidAuthenticationMethod)
. It's a bit nested but if we do it here, we'll end up running the check twice. I could bump up the check though
confdb/confdb_control.go
Outdated
if len(auth) == 0 { | ||
return fmt.Errorf(`"authentication" must be a non-empty list`) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no "authentication" here. I know this comes from the field in the assertion but out of that context it's not clear what this is referring to. The check should be reformulated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed the errors to cannot add group: "auth" must be a non-empty list
& cannot add group: "views" must be a non-empty list
to be more descriptive. auth
& views
are the parameters passed to op.AddGroup
confdb/confdb_control.go
Outdated
} | ||
|
||
if len(views) == 0 { | ||
return fmt.Errorf(`"views" must be a non-empty list`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
confdb/confdb_control.go
Outdated
return nil | ||
} | ||
|
||
func compact[T comparable](s []T) []T { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could use a comment mentioning that s
has to be sorted
asserts/confdb_asserts.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this assertion can go into the file with the registry (soon to be confdb) assertion?
features/features.go
Outdated
@@ -150,6 +154,7 @@ var featuresExported = map[SnapdFeature]bool{ | |||
|
|||
RefreshAppAwarenessUX: true, | |||
Registries: true, | |||
ConfdbControl: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to export this flag? Based on the spec I don't see a reason to, at the moment, but maybe there's more to it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, that flag shouldn't have been exported. Removed.
confdb/confdb_control.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd say lets put this in registry/
for now so it's grouped up with the other code. Once I open rename, it will all get moved together
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you
registry/confdb_control.go
Outdated
} | ||
|
||
// Group holds a set of views delegated through the given authentication. | ||
type Group struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering whether DelegatedViews
or ControlGroup
wouldn't be better as Group is fairly generic but it's minor anyway
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to match the spec but I agree, something like ControlGroup
is clearer.
Thanks for the review!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
given that is shows up as registry.Group I think we definitely need a more precise name, "group" in the context of the assertion is fine as it is scoped to the assertion, but the type name here is not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pedronis, I've renamed it to ControlGroup
... registry.ControlGroup
or confdb.ControlGroup
seems better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you, did a pass, main comment is how we store views in ControlGroup for usage
@@ -142,7 +142,7 @@ func (*viewSuite) TestNewRegistry(c *C) { | |||
c.Assert(err.Error(), Equals, tc.err, cmt) | |||
} else { | |||
c.Assert(err, IsNil, cmt) | |||
c.Check(registry, Not(IsNil), cmt) | |||
c.Check(registry, NotNil, cmt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for next time: it's best to do this kind of small tweaks/fixes as their own PR or commit with something like "drive-by" in the commit message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I'll keep this in mind for future changes.
@@ -450,7 +450,7 @@ func getPlaceholders(viewStr string) map[string]bool { | |||
return placeholders | |||
} | |||
|
|||
// View returns an view from the registry. | |||
// View returns a view from the registry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
validAccountID = regexp.MustCompile("^(?:[a-z0-9A-Z]{32}|[-a-z0-9]{2,28})$") | ||
) | ||
|
||
type AuthenticationMethod string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this probably merits a doc comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a comment here and to the OperatorKey
& Store
options
registry/confdb_control.go
Outdated
// ControlGroup holds a set of views delegated through the given authentication. | ||
type ControlGroup struct { | ||
Authentication []AuthenticationMethod | ||
Views []string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this contain structs already parsed into account/confdb/view ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the assertion, the list of groups is flat.. like so:
groups:
- operator-id: john
authentication: [ operator-key, store ]
views:
- a/b/c
- d/e/f
- operator-id: john
authentication: [ store ]
views:
- x/y/z
Internally though, we're grouping by operator to make this easier to look up later since all the API operations revolve around an operator. For instance, isDelegated(operator, view)
, delegate(operator, views, authMethods)
, revoke(operator, ...)
.
operators:
john:
ID: john
Groups:
- Authentication: [ operator-key, store ]
Views:
- a/b/c
- d/e/f
- Authentication: [ store ]
Views:
- x/y/z
Edit:
Or do you mean we should store the Views
as a "set" for faster lookup.. Something like map[string]struct{}
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean of doing something like this after the parsing:
Views []*ViewRef
type ViewRef struct {
Account string
Confdb string
View string
}
or similar
does this make sense to you @miguelpires as well ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, okay. That makes sense. I've made the necessary changes to reflect this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense to me 👍
registry/confdb_control.go
Outdated
|
||
// compact replaces consecutive runs of equal elements with a single copy. | ||
// The provided slice s should be sorted. | ||
func compact[T comparable](s []T) []T { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unique might be a more common name for this
asserts/registry.go
Outdated
@@ -108,3 +109,110 @@ func assembleRegistry(assert assertionBase) (Assertion, error) { | |||
timestamp: timestamp, | |||
}, nil | |||
} | |||
|
|||
// ConfdbControl holds a confdb-control assertion, which holds lists of | |||
// views delegated by the device to an operator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/to an operator/to operators/
registry/confdb_control.go
Outdated
} | ||
|
||
// convertToAuthenticationMethod converts and validates a []string to []AuthenticationMethod | ||
func convertToAuthenticationMethod(methods []string) ([]AuthenticationMethod, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe "...Methods" as it is producing a slice
registry/confdb_control.go
Outdated
}) | ||
|
||
// remove duplicates | ||
methods = compact(methods) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see code in the tests that check that this is done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit hidden but this test checks that behavior
changed enough that might be a good idea to re-review
Define the
confdb-control
assertion and add a feature flag. The bits on the API (delegating, revoking, etc) will be added later when the design discussions are finalized.