Skip to content
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

CON-9080 Remove checkLimit validation in favor of forbidden response when creating a volume #481

Conversation

llDrLove
Copy link
Contributor

Given that the volume limit is to be generalized and raised to 5,000 (which should be more than enough for any [DOKS] customer), showing the actual limit does not provide any value anymore. Thus, we favor handling the http forbidden response from godo for a Forbidden http code (403) with some specific response string than to use the checkLimit method.

@llDrLove llDrLove added the WIP label Mar 14, 2023
@llDrLove llDrLove self-assigned this Mar 14, 2023
log.WithField("volume_req", volumeReq).Info("creating volume")
vol, _, err := d.storage.CreateVolume(ctx, volumeReq)
vol, cvResp, err := d.storage.CreateVolume(ctx, volumeReq)
if err != nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@timoreimann ,

Here we have a payload ressembling this :

{
  "message": "failed to create volume: volume/snapshot capacity limit exceeded",
  "id":"forbidden",
  "request_id": "7c230c90-c7a0-4e79-a40d-b8e3ca003bd4"
}

I'm not looking at the id field of the CreateVolume response for the exact match of forbidden since it is not exported by godo. Instead, I'm relying on the http code of the response which is kind of the same check IMO. What do you think ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, wasn't aware it's not exported. I think your approach makes sense then. 👍

@llDrLove llDrLove removed the WIP label Mar 15, 2023
@llDrLove llDrLove marked this pull request as ready for review March 15, 2023 15:45
@llDrLove llDrLove requested a review from timoreimann March 15, 2023 15:45
if err != nil {
var errorResponse *godo.ErrorResponse
if errors.As(err, &errorResponse) && strings.Contains(err.(*godo.ErrorResponse).Message, "capacity limit exceeded") &&
Copy link
Contributor

Choose a reason for hiding this comment

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

If we use errors.As , then we should also inspect Message on errorResponse instead of doing another type cast.

Note though how this remark is obsolete now given my next comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Won't do based on comment below.

if err != nil {
var errorResponse *godo.ErrorResponse
if errors.As(err, &errorResponse) && strings.Contains(err.(*godo.ErrorResponse).Message, "capacity limit exceeded") &&
Copy link
Contributor

Choose a reason for hiding this comment

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

I just realized that we do not need to check for and cast into an ErrorResponse now that we have discovered that the error ID isn't exported and that we can only check for a portion of the error message: the Error() implementation always includes it, which means it suffices to check err.Error() for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True, I refactored the code to check the substring from the basic err.Error().

if err != nil {
var errorResponse *godo.ErrorResponse
if errors.As(err, &errorResponse) && strings.Contains(err.(*godo.ErrorResponse).Message, "capacity limit exceeded") &&
cvResp.StatusCode == http.StatusForbidden {
Copy link
Contributor

Choose a reason for hiding this comment

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

We can add some extra safety by also checking that cvResp is not nil.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.

@@ -213,6 +215,10 @@ func (f *fakeStorageDriver) GetVolume(ctx context.Context, id string) (*godo.Vol
}

func (f *fakeStorageDriver) CreateVolume(ctx context.Context, req *godo.VolumeCreateRequest) (*godo.Volume, *godo.Response, error) {
if f.createVolumeErr != nil && f.createVolumeErrResponse != nil {
return nil, f.createVolumeErrResponse, f.createVolumeErr
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we return as soon as one of f.createVolumeErr or f.createVolumeErrResponse is non-nil (as opposed to requiring both)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure! It gives more flexibility in the tests. Added.

Copy link
Contributor

@timoreimann timoreimann left a comment

Choose a reason for hiding this comment

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

One tiny suggestion and a typo, otherwise good.

if err != nil {
if cvResp != nil && cvResp.Response != nil && cvResp.StatusCode == http.StatusForbidden && strings.Contains(err.Error(), "capacity limit exceeded") {
Copy link
Contributor

Choose a reason for hiding this comment

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

Small nit / simplification suggestion: I think it's common to check the outer *godo.Response for nil-ness only, not the inner *http.Response since godo always populates them together.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, I've removed the cvResp.Response != nil check and only kept cvResp != nil.

name string
listVolumesErr error
getSnapshotErr error
snapchots map[string]*godo.Snapshot
Copy link
Contributor

Choose a reason for hiding this comment

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

typo: snapchots -> snapshots

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice catch! Fixed.

Copy link
Contributor

@timoreimann timoreimann left a comment

Choose a reason for hiding this comment

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

✅ good to be squash-merged.

@llDrLove llDrLove merged commit 5ecb20c into master Mar 17, 2023
@llDrLove llDrLove deleted the CON-9080-do-not-check-volumes-limit-in-csi-driver-for-limits-v3 branch March 17, 2023 19:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants