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

storage: introduce requesterPays #2392

Merged
merged 14 commits into from
Jun 29, 2017

Conversation

stephenplusplus
Copy link
Contributor

@stephenplusplus stephenplusplus commented Jun 15, 2017

Fixes #2371

To Dos

  • Encrypt new service account JSON for AppVeyor
  • Encrypt new service account JSON for Circle
  • Set environment variables for new system tests project in AppVeyor
  • Set environment variables for new system tests project in Circle
  • Get a new system tests project to test functionality (cc @swcloud)
  • Support userProject in gcs-resumable-upload (done)
  • Docs
  • Tests
    • System
    • Unit
      • storage/index.js
      • storage/bucket.js
      • storage/file.js

Bucket Operations

storage.createBucket({ requesterPays: true })
bucket.create({ requesterPays: true })
bucket.disableRequesterPays()
bucket.enableRequesterPays()
bucket.combine(sourceFiles, destinationFile, { userProject: 'project-id' })
bucket.createChannel(id, config, { userProject: 'project-id' })
bucket.delete({ userProject: 'project-id' })
bucket.deleteFiles({ userProject: 'project-id' })
bucket.exists({ userProject: 'project-id' }) // calls bucket.getMetadata
bucket.get({ userProject: 'project-id' }) // calls bucket.getMetadata
bucket.getFiles({ userProject: 'project-id' })
bucket.getFilesStream({ userProject: 'project-id' })
bucket.getMetadata({ userProject: 'project-id' })
bucket.makePrivate({ userProject: 'project-id' }) // calls bucket.getFiles and bucket.setMetadata
bucket.setMetadata({ userProject: 'project-id' })
bucket.upload('file.txt', { userProject: 'project-id' }) // calls file.createWriteStream

File Operations

file.copy('newfile.txt', { userProject: 'project-id' })
file.createReadStream({ userProject: 'project-id' })
file.createResumableUpload({ userProject: 'project-id' })
file.createWriteStream({ userProject: 'project-id' })
file.delete({ userProject: 'project-id' })
file.download({ userProject: 'project-id' }) // calls file.createReadStream
file.exists({ userProject: 'project-id' }) // calls file.getMetadata
file.get({ userProject: 'project-id' }) // calls file.getMetadata
file.getMetadata({ userProject: 'project-id' })
file.makePrivate({ userProject: 'project-id' }) // calls file.setMetadata
file.move({ userProject: 'project-id' }) // calls file.copy
file.save(data, { userProject: 'project-id' }) // calls file.createWriteStream
file.setMetadata(metadata, { userProject: 'project-id' })
file.setStorageClass(storageClass, { userProject: 'project-id' }) // calls file.copy

@stephenplusplus stephenplusplus added the api: storage Issues related to the Cloud Storage API. label Jun 15, 2017
@googlebot googlebot added the cla: yes This human has signed the Contributor License Agreement. label Jun 15, 2017
@tswast tswast requested a review from frankyn June 15, 2017 16:03
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.001%) to 99.987% when pulling c66bb60 on stephenplusplus:spp--2371 into 02afcef on GoogleCloudPlatform:master.

@googleapis googleapis deleted a comment from coveralls Jun 16, 2017
@stephenplusplus
Copy link
Contributor Author

Storage coverage is 100% - the drop is just from #2342.

@stephenplusplus
Copy link
Contributor Author

I've run into a problem when writing the system tests. A series of requests are outlined here:

USER A: nth-circlet-705
USER B: stephen-sawchuk@gcloud-node-whitelist-ci-tests.iam.gserviceaccount.com

// USER A
// enables requesterPays on a bucket
{
  "method": "PATCH",
  "uri": "https://www.googleapis.com/storage/v1/b/gcloud-test-155fe610-5786-11e7-afc5-0991cf1123b2",
  "json": {
    "billing": {
      "requesterPays": true
    }
  }
}

// USER A
// adds IAM permissions to USER B
{
  "method": "PUT",
  "uri": "https://www.googleapis.com/storage/v1/b/gcloud-test-155fe610-5786-11e7-afc5-0991cf1123b2/iam",
  "json": {
    "resourceId": "projects/_/buckets/gcloud-test-155fe610-5786-11e7-afc5-0991cf1123b2",
    "kind": "storage#policy",
    "bindings": [
      {
        "role": "roles/storage.legacyBucketOwner",
        "members": [
          "projectEditor:nth-circlet-705",
          "projectOwner:nth-circlet-705"
        ]
      },
      {
        "role": "roles/storage.legacyBucketReader",
        "members": [
          "projectViewer:nth-circlet-705"
        ]
      },
      {
        "role": "roles/storage.legacyBucketWriter",
        "members": [
          "serviceAccount:stephen-sawchuk@gcloud-node-whitelist-ci-tests.iam.gserviceaccount.com"
        ]
      }
    ],
    "etag": "CAI="
  }
}

// USER B
// deletes bucket
{
  "method": "DELETE",
  "uri": "https://www.googleapis.com/storage/v1/b/gcloud-test-155fe610-5786-11e7-afc5-0991cf1123b2",
  "qs": {
    "userProject": "gcloud-node-whitelist-ci-tests"
  }
}

// which returns an error
Error: Caller does not have storage.buckets.create access to gcloud-node-whitelist-ci-tests.

"gcloud-node-whitelist-ci-tests" is User B's project ID, but not the name of the bucket we're trying to delete.

I've tried granting storage.objectViewer and storage.objectAdmin as well.

@frankyn
Copy link

frankyn commented Jun 23, 2017

@stephenplusplus I'll try to reproduce this error using the JSON API directly. I was able to get this workflow working using the Ruby client. I'll keep you posted!

@stephenplusplus
Copy link
Contributor Author

All system tests are added, however I'm having trouble testing the download behavior of a file.

The system tests are configured to use two accounts:

  • User A: The account of the user who ran npm run system-test
  • User B: The new project Song created

There is a problem when User B tries to download a file from User A. When User B provides the userProject query parameter, an error is returned: "Bad Request". When User B omits the query parameter, a different error is expected: 'Bucket is requester pays bucket but no user project provided.', however the error message is still "Bad Request".

@frankyn any ideas? Thanks!

@coveralls
Copy link

Coverage Status

Coverage increased (+0.0001%) to 99.988% when pulling 56032a0 on stephenplusplus:spp--2371 into a11c47a on GoogleCloudPlatform:master.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.0002%) to 99.988% when pulling a25a18c on stephenplusplus:spp--2371 into ca0d96c on GoogleCloudPlatform:master.

@swcloud
Copy link
Contributor

swcloud commented Jun 27, 2017

There are many code refactoring in this PR, which I'm not familiar with. @callmehiphop Can you help review this?

@stephenplusplus
Copy link
Contributor Author

The issue with downloading a file has been caught, and a solution is in the works.

The premise of the problem: In file.createReadStream(), we don't buffer data, we just hand it off to the user directly. When we get a response event from the server, and see a status code that isn't a success, we return the code & default status message for it to the user.

What we need to do: buffer the stream for the response body, right before we return that error. I've done that, and it works! I just need some time to figure out if it's going to affect other parts of the library. But, at this time, we can safely mark the surface problems as resolved.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.0002%) to 99.988% when pulling 175e6f9 on stephenplusplus:spp--2371 into ca0d96c on GoogleCloudPlatform:master.

@stephenplusplus
Copy link
Contributor Author

This is ready for a review / merge / party to celebrate @frankyn.

@swcloud swcloud requested a review from evaogbe June 27, 2017 22:55
bucketName: self.bucket.name,
fileName: encodeURIComponent(self.name)
}),
uri: '',

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

Copy link

@frankyn frankyn left a comment

Choose a reason for hiding this comment

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

Looking great, I left a question and comment. Not a strict code review and only verifying documentation for the feature.

bucketName: self.bucket.name,
fileName: encodeURIComponent(self.name)
}),
uri: '',

This comment was marked as spam.

* </p>
* </div>
*
* Enable `requesterPays` functionality for this bucket.

This comment was marked as spam.

describe('exists', function() {
it('should call get', function(done) {
bucket.get = function() {
assert.strictEqual();

This comment was marked as spam.

This comment was marked as spam.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.0002%) to 99.988% when pulling 121ce05 on stephenplusplus:spp--2371 into ca0d96c on GoogleCloudPlatform:master.

@stephenplusplus stephenplusplus merged commit 90b41d2 into googleapis:master Jun 29, 2017
Copy link

@frankyn frankyn left a comment

Choose a reason for hiding this comment

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

LGTM, not sure if it's still required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: storage Issues related to the Cloud Storage API. cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants