-
Notifications
You must be signed in to change notification settings - Fork 256
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
Add support for the subuser calls in the rgw admin interface #644
Conversation
One problem that I already spotted with my approach is, that the documentation does not seem to be complete with respect to the supported query parameters, e.g. the feature from #600 (getting users by access key), is not documented in the api docs: https://docs.ceph.com/en/latest/radosgw/adminops/#get-user-info, there only the |
// NOTE: we use linear search here, as none of the API endpoints | ||
// supports more than 10 parameters, in this case asymptotics don't | ||
// matter and we are likely faster this way (even when compared to a | ||
// map). |
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.
Great comment, BTW.
I'd like to know more about what you think could cause backwards incompatibility issues. The go-ceph library is v0 and we don't guarantee no breaking changes but we do try to avoid them as much as possible as the library is used in various codebases. Personally, nothing just jumped out at me as having a breaking API change but I may have overlooked something. I'll also tag @leseb who helps maintain the rgw admin part of go-ceph and is more knoledgeable about rgw admin than I am. |
The potential problem I see, is that I restrict the parameters that are serialized and passed to the API. Although I do so based on the official documentation of the API, this means that there could be code out there, that passed in more parameters before the change and those parameters did something though they were not specified – I know the API documentation isn't fully reliable. This in turn would break real use cases. I know of one example where I don't allow a parameter that isn't specified in the API documentation, but passing it does actually work when it's included in the API call, namely Nevertheless, if this potential breakage is acceptable to you, it feels safer to me, to only send selected parameters the API (in the sense of "be conservative in what you send"). (The change will, of course, also break code that accessed the swift-related parts of the User structure – so far typed I'll have a look at the RGW source code, perhaps the supported parameter sets can be extracted from there. |
Okay, that looks like the right place: https://github.com/ceph/ceph/blob/193895ffba4245787a2f50bbd5b80132f0e76e74/src/rgw/rgw_rest_user.cc#L72 I guess we can take the supported parameters from there. Then we can be sure that we don't break code, because any other parameters someone might send, will just be ignored by rgw. |
b4eb471
to
5577cef
Compare
I have now updated the lists based on determining the supported parameters from the ceph source code and I have documented parameters supported by RGW that we do not yet support (as we don't have a field to specify them in our structs). This should make the change safe, in the sense that code using this library do to an API call will have the same effect before and after this change (although the API call on the wire will potentially change, as fields ignored by the RGW Adminops API will not be serialized). In the process I've noted a few irregularities in the typing of the API parameters in this code base (but I guess that is not for this PR to address). E.g. |
5577cef
to
8cc6ff8
Compare
I've marked the new API methods as PREVIEW (as the development documentation advises). Should the new types also be marked PREVIEW in some way, or are they not covered by the API stability tracking? |
Great thanks.
Types currently do not need to be marked PREVIEW. As you surmised they're not (directly) part of the API tracking. We maintainers are currently discussing the possibility of dropping "PREVIEW" in the doc comment and relying entirely on the "ceph_preview" build tag. Aside from the annoyance of having to deal with another process change, we think this would be simpler to document and ask contributors to implement. However, the tooling will need to be updated to match. |
30a24e0
to
4eae29b
Compare
I've now improved the validation of API parameters (and corresponding errors) and expanded the tests. Additionally, I've added some comments to the source that explain some irregularities in the RGW Admin OPS API (and how this impacts the API library/the choices made in the code because of this). The tests could be expanded and have tighter matchers in places, but I'll un-draft this now, as I think it is mostly ready and those short-comings can be fixed together with any issues raised in further review. |
4eae29b
to
382b5cf
Compare
@@ -132,7 +134,7 @@ func (api *API) GetBucketPolicy(ctx context.Context, bucket Bucket) (Policy, err | |||
|
|||
// RemoveBucket will remove a given token from the object store | |||
func (api *API) RemoveBucket(ctx context.Context, bucket Bucket) error { | |||
_, err := api.call(ctx, http.MethodDelete, "/bucket", valueToURLParams(bucket)) | |||
_, err := api.call(ctx, http.MethodDelete, "/bucket", valueToURLParams(bucket, []string{"bucket", "purge-objects"})) |
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.
Is this purging all the objects from the bucket? If so, isn't that dangerous? Would it be good to have validation or something passed to the API by the user to do 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.
I did not touch change the behaviour of this API call. I only added the filtering in valueToURLParams
(so only those parameters that are actually supported by the API according to the ceph-rgw source code are serialized to the query string).
It is certainly a dangerous operation (even without purge objects, given that all obejcts that are only in this bucket will be deleted independently of the purge-objects
setting), but the way it behaves does not change with this commit.
With purge-objects
set to true all the objects in the bucket will be deleted, before deleting the bucket (I guess that means they will also be deleted from other buckets that may contain them).
For purge-objects to happen *bucket.PurgeObjects
must be set to true, this will never be the case for Bucket objects returned from the API, so explicit action is necessary on the side of the user.
rgw/admin/usage.go
Outdated
@@ -50,7 +50,8 @@ type Usage struct { | |||
|
|||
// GetUsage request bandwidth usage information on the object store | |||
func (api *API) GetUsage(ctx context.Context, usage Usage) (Usage, error) { | |||
body, err := api.call(ctx, http.MethodGet, "/usage", valueToURLParams(usage)) | |||
// unsupported parameters: category, bucket |
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.
Can we clarify? Unsupported by this API or by the RGW admin ops API?
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 clarified to // valid parameters not supported by go-ceph
If someone will implement support for the currently unsupported parameters in the structs, the parameter in question will also have to be added to the whitelists in the corresponding methods.
rgw/admin/usage.go
Outdated
@@ -65,6 +66,7 @@ func (api *API) GetUsage(ctx context.Context, usage Usage) (Usage, error) { | |||
|
|||
// TrimUsage removes bandwidth usage information. With no dates specified, removes all usage information. | |||
func (api *API) TrimUsage(ctx context.Context, usage Usage) error { | |||
_, err := api.call(ctx, http.MethodDelete, "/usage", valueToURLParams(usage)) | |||
// unsupported parameters: bucket |
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.
ditto
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.
All the comments have been updated.
382b5cf
to
c7368c9
Compare
This pull request now has conflicts with the target branch. Could you please resolve conflicts and force push the corrected changes? 🙏 |
The following changes have been done: * Up until now everything in the argument objects was serialized to the API calls. This was updated to restrict the serialization to the API call parameters that are parsed in the Ceph RGW source code. Parameters not yet supported by us are documented as comments. Note, that a superset of the documented parameters is supported. Documentation for the API: <https://docs.ceph.com/en/pacific/radosgw/adminops/> Link to the used source tree: <https://github.com/ceph/ceph/tree/193895ffba4245787a2f50bbd5b80132f0e76e74/src/rgw> The argument parsing happens in the rgw_rest_*.cc files. * The serialization code (valueToURLParams) has been updated to be more in line with other serialization methods: - A tag "-" causes the field to be ignored - Only the first item in a list of tag items is interpreted as name. - The handling of pointer and direct data types has been harmonized (the same rules for the names and value apply now). * There is still room for improvement to make things more consistent: A pointer to a non-elementary data type will emit unexpected request parameters. * Presence of required parameters is not validated by the library, this is left to the API. Signed-off-by: Sebastian Riese <[email protected]>
Only one of the two code paths of buildQueryPath was tested so far. This makes the test harness tight by testing the second one (where the path already contains a query parameter). Signed-off-by: Sebastian Riese <[email protected]>
THIS POTENTIALLY BREAKY DOWNSTREAM CODE (as it changes the types of exported fields in an existing, exported struct). The fields of the User structure representing the Subuser information have been specified to parse this data strictly and typesafe. The fields SwiftKeys and Subusers need the url:"-" annotation, because otherwise url-keys in that substructure would clash with those in the User structure. Signed-off-by: Sebastian Riese <[email protected]>
c7368c9
to
3be227a
Compare
Rebased to the newest master. |
3be227a
to
8f78854
Compare
Thanks for the reviews. I've slightly squashed the history and did some minor improvements to the tests – from my side it is ready to merge now. |
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.
Hi there! Thanks a lot for working with @leseb on the functionality. Now that is squared away I do notice a few small book keeping related issues that need to be resolved.
I'm aware that these can be kind of annoying. I do wish I had noticed the file/ceph_preview build flag issue sooner, but I hope you wont find that too difficult to resolve.
rgw/admin/user.go
Outdated
} | ||
|
||
// CreateSubuser - https://docs.ceph.com/en/latest/radosgw/adminops/#create-subuser | ||
// PREVIEW |
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.
New functions that are in preview state must be located in files marked with the "ceph_preview" build tag. I thought the CI would have caught this but I guess not, sorry. I suggest moving the net new functions to "subuser.go"
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.
Let me know if you have any questions about this process.
docs/api-status.json
Outdated
{ | ||
"name": "API.CreateSubuser", | ||
"comment": "CreateSubuser - https://docs.ceph.com/en/latest/radosgw/adminops/#create-subuser\n PREVIEW\n", | ||
"added_in_version": "v0.14.0", |
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.
Release v0.14 is already out. The added_in_version and expected_stable_version need to be incremented. You can do it by hand or by deleting the new entries and re-running the make api-update
commands.
We are aware that this is annoying and time consuming and are looking into ways to avoid putting the burden on contributors... but we don't have a solution yet.
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, I tried to fix this manually, but obviously didn't catch all occurrences – I'll use the tools to regenerate it properly.
docs/api-status.json
Outdated
{ | ||
"name": "API.RemoveSubuser", | ||
"comment": "RemoveSubuser - https://docs.ceph.com/en/latest/radosgw/adminops/#remove-subuser\n PREVIEW\n", | ||
"added_in_version": "v0.14.0", |
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.
docs/api-status.json
Outdated
{ | ||
"name": "API.ModifySubuser", | ||
"comment": "ModifySubuser - https://docs.ceph.com/en/latest/radosgw/adminops/#modify-subuser\n PREVIEW\n", | ||
"added_in_version": "v0.14.0", |
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
docs/api-status.md
Outdated
@@ -8,57 +8,59 @@ | |||
|
|||
### Deprecated APIs | |||
|
|||
Name | Deprecated in Version | Expected Removal Version | |
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 suggest regenerating this file too.
Signed-off-by: Sebastian Riese <[email protected]>
Some unit tests for the validation and integration tests. Signed-off-by: Sebastian Riese <[email protected]>
8f78854
to
fac2574
Compare
@phlogistonjohn The issues you raised should be fixed now. Thanks again for guiding me through the process! |
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.
LGTM, thanks a bunch for working on this!
These commits add support for the subuser calls in the rgw admin interface.
Closes #521.
Implementing the subuser commands required a restructuring of the way the objects are serialized to API parameters. The way this was done is up to review and I am open to changes.
This is a breaking change, since the User type changes (by adding detailed type information for the fields related to subusers to support type safe parsing from the json responses). The API calls on the wire may change as well (as go-ceph now only serializes those parameters that are actually supported by the Ceph RGW Adminops API, not all parameters that are set in the "mirror" object on the go-ceph side).
See also the related discussion: #641.
Checklist