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

Add R2 basic support #85

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

microstudi
Copy link

@microstudi microstudi commented Feb 6, 2025

This PR adds support for some actions regarding the R2 api in Cloudflare.

Allows to:

  • List buckets in an account
  • Create buckets in an account
  • Create CORS policy for a bucket
  • Attach a domain to a bucket (for public serving files)

Examples:

Listing available buckets:

connection ||= Async { Cloudflare.connect(token: ENV["CLOUDFLARE_TOKEN"]) }.wait
account ||= Async { connection.accounts.find_by_id(account_id: ENV["CLOUDFLARE_ACCOUNT_ID"]) }.wait
puts Async { account.r2_buckets.result }.wait

Obtaining a specific bucket

puts Async { account.r2_buckets.find_by_name("a-nice-bucket") .inspect }.wait

Creating a bucket:

Async { account.r2_buckets.create("a-new-bucket")  }.wait

Attaching a domain to a bucket:

payload = {
  "cf-r2-jurisdiction" => "eu", 
  "zoneId" => ENV["CLOUDFLARE_ZONE_ID"],
  "enabled" => true
}
domain = Async { bucket.domains.attach(domain_name, **payload) }.wait

Creating a cors policy:

rules = [
  {
    allowed: {
      origins: ["domain.tld", "anotherdomain.tld"],
      methods: ["GET", "PUT"],
      headers: ["*"],
    },
    exposeHeaders: [
      "Origin",
      "Content-Type",
      "Content-MD5",
      "Content-Disposition"
    ],
    maxAgeSeconds: 3600
  }
]
payload = {
  "cf-r2-jurisdiction" => "eu", 
  "account_id" => ENV["CLOUDFLARE_ACCOUNT_ID"],
  "bucket_name" => "a-nice-bucket",
  "rules" => rules
}
Async { bucket.create_cors(**payload) }.wait

Obtaining the current CORS (the API throws an exception if there's none yet):

cors = Async do
  begin
    bucket.cors.result
  rescue Cloudflare::RequestError
    nil
  end
end.wait

puts cors

Types of Changes

  • New feature.

Contribution

@microstudi
Copy link
Author

I you kindly approve the workflow, I'll add more tests

@ioquatix
Copy link
Member

ioquatix commented Feb 7, 2025

Let me know when you'd like me to review the code. Testing is a bit tricky but you have access to a "test" sandbox account.

@@ -60,7 +60,7 @@ end

### Using a Bearer Token

You can read more about [bearer tokens here](https://blog.cloudflare.com/api-tokens-general-availability/). This allows you to limit priviledges.
You can read more about [bearer tokens here](https://blog.cloudflare.com/api-tokens-general-availability/). This allows you to limit privileges.
Copy link
Member

Choose a reason for hiding this comment

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

Thanks :p

@microstudi
Copy link
Author

@ioquatix what do you mean with "you have access to a "test" sandbox account"? I guess i have to put my credentials as secrets in my fork for the tests to work?

BTW, do you want me to add those examples in the readme too?

@ioquatix
Copy link
Member

ioquatix commented Feb 7, 2025

what do you mean with "you have access to a "test" sandbox account"? I guess i have to put my credentials as secrets in my fork for the tests to work?

I have put my credentials into GitHub secrets so that the tests run in a sandbox account. You don't need to do anything, but what I intended to communicate was that the CI will run against Cloudflare's APIs.

BTW, do you want me to add those examples in the readme too?

Sure, if you think it's a good idea then feel free to do it.

@microstudi
Copy link
Author

I see what you mean, unfortunately PR from external forks do not have access to secrets in your repository (that's understandable for security reason). If you give me write permission to your repo, I'll upload the branch in your repo and will make the PR from there.
If not, no worries, I'll try to make a dummy account myself but that might take me a little as I have many things to do.

Thanks

@ioquatix
Copy link
Member

I think the tests are running correctly but something is wrong with the code. The CI runs with my test credentials. Do we need something else on my account for the tests to pass? How are you testing this locally?

@microstudi
Copy link
Author

I do exactly as the examples in the description. As I needed to automate the bucket/CORS creation I was testing in my real Cloudflare account. But not with the test suite, on my script. I was trying to avoid having to create a dummy cloudflare account.

Here is the info about the secrets not shared with PR from forks:
https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions#using-secrets-in-a-workflow

@microstudi
Copy link
Author

I've ended adding my own secrets in my repository. It's passing in my fork.

I've added some tests. It's a little bit difficult due the lack of documentation of the test suite and the sometimes poor documentation of error from Cloudflare. In any case, the features added work. Maybe some of the services would benefit from mocking the requests (using the OpenAPI defintion) instead of directly making connections.

BTW; for the bucket related tests, the test account needs to have the R2 service enabled.

Thanks for the project, if you want to review this go ahead.

@microstudi microstudi requested a review from ioquatix February 11, 2025 17:20
@ioquatix
Copy link
Member

R2 service enabled

Okay, that may be why it's not paying here, let me check the test account.

@ioquatix
Copy link
Member

Unfortunately, I can't add R2 to my account without also adding a credit card, which I'm not keen to do with a test sandbox:

image

@ioquatix
Copy link
Member

@jacobbednarz I am pulling you into this discussion, here is a brief summary:

  1. A user here has made a PR to add support for the R2 API.
  2. They have added tests, which hit my "test" account (registered with [email protected]).
  3. However, I'm unable to enable R2, even the free tier, without providing a credit card (feels hostile, especially for a testing sandbox which could be a security issue).

Are you able to help us with enabling these tests? Thanks.

@jacobbednarz
Copy link

what is your cloudflare email address? (email me if you don't want to paste it here). i can add you to our acceptance test account and you can run these tests there.

@ioquatix
Copy link
Member

@jacobbednarz I set up a test account using the email address [email protected]. However, if you are going to give me new credentials (to put in this repo for CI), feel free to email me at [email protected].

@jacobbednarz
Copy link

i've shot you an invite to an account that you can use.

@ioquatix
Copy link
Member

I've updated my test account to use the invite sent out, so in theory we have access to R2 now? I'll try kicking off the tests again.

@ioquatix
Copy link
Member

Okay, I also totally missed this: https://github.com/orgs/community/discussions/26242 lol so yes, you are correct, I'll have to rebase this into a local branch to test it.

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.

3 participants