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

Bradley/r2 event notification get #6652

Merged
merged 3 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/nice-beds-raise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wrangler": minor
---

feat: Update R2 Get Event Notification response, display, and actions
78 changes: 67 additions & 11 deletions packages/wrangler/src/__tests__/r2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ describe("r2", () => {
wrangler r2 bucket list List R2 buckets
wrangler r2 bucket delete <name> Delete an R2 bucket
wrangler r2 bucket sippy Manage Sippy incremental migration on an R2 bucket
wrangler r2 bucket notification Manage event notifications for an R2 bucket
wrangler r2 bucket notification Manage event notifications for an R2 bucket [open beta]

GLOBAL FLAGS
-j, --experimental-json-config Experimental: support wrangler.json [boolean]
Expand Down Expand Up @@ -130,7 +130,7 @@ describe("r2", () => {
wrangler r2 bucket list List R2 buckets
wrangler r2 bucket delete <name> Delete an R2 bucket
wrangler r2 bucket sippy Manage Sippy incremental migration on an R2 bucket
wrangler r2 bucket notification Manage event notifications for an R2 bucket
wrangler r2 bucket notification Manage event notifications for an R2 bucket [open beta]

GLOBAL FLAGS
-j, --experimental-json-config Experimental: support wrangler.json [boolean]
Expand Down Expand Up @@ -772,6 +772,61 @@ describe("r2", () => {
describe("notification", () => {
describe("get", () => {
it("follows happy path as expected", async () => {
const bucketName = "my-bucket";
const queueId = "471537e8-6e5a-4163-a4d4-9478087c32c3";
const queueName = "my-queue";
msw.use(
http.get(
"*/accounts/:accountId/event_notifications/r2/:bucketName/configuration",
async ({ request, params }) => {
const { accountId, bucketName: bucketParam } = params;
expect(accountId).toEqual("some-account-id");
expect(bucketName).toEqual(bucketParam);
expect(request.headers.get("authorization")).toEqual(
"Bearer some-api-token"
);
const getResponse = {
bucketName,
queues: [
{
queueId: queueId,
queueName,
rules: [
{
ruleId: "8cdcce8a-89b3-474f-a087-3eb4fcacfa37",
createdAt: "2024-09-05T01:02:03.000Z",
prefix: "",
suffix: "",
actions: [
"PutObject",
"CompleteMultipartUpload",
"CopyObject",
],
},
],
},
],
};
return HttpResponse.json(createFetchResult(getResponse));
},
{ once: true }
)
);
await expect(
await runWrangler(`r2 bucket notification get ${bucketName}`)
).toBe(undefined);
expect(std.out).toMatchInlineSnapshot(`
"Fetching notification configuration for bucket my-bucket...
rule_id: 8cdcce8a-89b3-474f-a087-3eb4fcacfa37
created_at: 2024-09-05T01:02:03.000Z
queue_name: my-queue
prefix:
suffix:
event_type: PutObject,CompleteMultipartUpload,CopyObject"
`);
});

it("is backwards compatible with old API version", async () => {
const bucketName = "my-bucket";
const queueId = "471537e8-6e5a-4163-a4d4-9478087c32c3";
const queueName = "my-queue";
Expand Down Expand Up @@ -828,11 +883,12 @@ describe("r2", () => {
).toBe(undefined);
expect(std.out).toMatchInlineSnapshot(`
"Fetching notification configuration for bucket my-bucket...
┌────────────┬────────┬────────┬───────────────┐
│ queue_name │ prefix │ suffix │ event_type │
├────────────┼────────┼────────┼───────────────┤
│ my-queue │ │ │ object-create │
└────────────┴────────┴────────┴───────────────┘"
rule_id:
created_at:
queue_name: my-queue
prefix:
suffix:
event_type: PutObject,CompleteMultipartUpload,CopyObject"
`);
});

Expand All @@ -846,7 +902,7 @@ describe("r2", () => {
"
wrangler r2 bucket notification get <bucket>

Get event notification configuration for a bucket
Get event notification configuration for a bucket [open beta]

POSITIONALS
bucket The name of the bucket for which notifications will be emitted [string] [required]
Expand Down Expand Up @@ -937,7 +993,7 @@ describe("r2", () => {
)
).resolves.toBe(undefined);
expect(std.out).toMatchInlineSnapshot(`
"Creating event notification rule for object creation and deletion (PutObject,CompleteMultipartUpload,CopyObject,DeleteObject)
"Creating event notification rule for object creation and deletion (PutObject,CompleteMultipartUpload,CopyObject,DeleteObject,LifecycleDeletion)
Configuration created successfully!"
`);
});
Expand All @@ -952,7 +1008,7 @@ describe("r2", () => {
"
wrangler r2 bucket notification create <bucket>

Create new event notification configuration for an R2 bucket
Create new event notification configuration for an R2 bucket [open beta]

POSITIONALS
bucket The name of the bucket for which notifications will be emitted [string] [required]
Expand Down Expand Up @@ -1044,7 +1100,7 @@ describe("r2", () => {
"
wrangler r2 bucket notification delete <bucket>

Delete event notification configuration for an R2 bucket and queue
Delete event notification configuration for an R2 bucket and queue [open beta]

POSITIONALS
bucket The name of the bucket for which notifications will be emitted [string] [required]
Expand Down
74 changes: 38 additions & 36 deletions packages/wrangler/src/__tests__/r2/helpers.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import crypto from "crypto";
import { vi } from "vitest";
import { logger } from "../../logger";
import {
eventNotificationHeaders,
tableFromNotificationGetResponse,
} from "../../r2/helpers";
import formatLabelledValues from "../../utils/render-labelled-values";
import { mockConsoleMethods } from "../helpers/mock-console";
import type { Config } from "../../config";
import type { GetNotificationConfigResponse } from "../../r2/helpers";
import type { ApiCredentials } from "../../user";

Expand All @@ -16,63 +14,67 @@ describe("event notifications", () => {
test("tableFromNotificationsGetResponse", async () => {
const bucketName = "my-bucket";
const config = { account_id: "my-account" };
const queueMap: Record<string, string> = {
"471537e8-6e5a-4163-a4d4-9478087c32c3": "my-queue-1",
"be6b6a37-ae49-4eea-9032-5e8d3ad1d29b": "my-queue-2",
};
const response: GetNotificationConfigResponse = {
[bucketName]: {
"9d738cb7-be18-433a-957f-a9b88793de2c": {
queue: "471537e8-6e5a-4163-a4d4-9478087c32c3",
bucketName,
queues: [
{
queueId: "471537e8-6e5a-4163-a4d4-9478087c32c3",
queueName: "my-queue-1",
rules: [
{
ruleId: "68746106-12f8-4bba-a57b-adaf37fe11ca",
prefix: "/p1",
suffix: "s1/",
actions: [
"PutObject",
"CompleteMultipartUpload",
"CopyObject",
"DeleteObject",
],
actions: ["PutObject", "CopyObject", "DeleteObject"],
},
{
ruleId: "5aa280bb-39d7-48ed-8c21-405fcd078192",
actions: ["DeleteObject"],
},
],
},
[crypto.randomUUID()]: {
queue: "be6b6a37-ae49-4eea-9032-5e8d3ad1d29b",
{
queueId: "be6b6a37-ae49-4eea-9032-5e8d3ad1d29b",
queueName: "my-queue-2",
rules: [
{
ruleId: "c4725929-3799-477a-a8d9-2d300f957e51",
createdAt: "2024-09-05T01:02:03.000Z",
prefix: "//1",
suffix: "2//",
actions: ["DeleteObject"],
actions: ["LifecycleDeletion"],
},
],
},
},
],
};
const tableOutput = await tableFromNotificationGetResponse(
config,
response[bucketName],
vi
.fn()
.mockImplementation((_: Pick<Config, "account_id">, queue: string) => ({
queue_name: queueMap[queue],
}))
response
);
logger.table(tableOutput);
logger.log(tableOutput.map((x) => formatLabelledValues(x)).join("\n\n"));

await expect(std.out).toMatchInlineSnapshot(`
"┌────────────┬────────┬────────┬─────────────────────────────┐
│ queue_name │ prefix │ suffix │ event_type │
├────────────┼────────┼────────┼─────────────────────────────┤
│ my-queue-1 │ /p1 │ s1/ │ object-create,object-delete │
├────────────┼────────┼────────┼─────────────────────────────┤
│ my-queue-1 │ │ │ object-delete │
├────────────┼────────┼────────┼─────────────────────────────┤
│ my-queue-2 │ //1 │ 2// │ object-delete │
└────────────┴────────┴────────┴─────────────────────────────┘"
"rule_id: 68746106-12f8-4bba-a57b-adaf37fe11ca
created_at:
queue_name: my-queue-1
prefix: /p1
suffix: s1/
event_type: PutObject,CopyObject,DeleteObject

rule_id: 5aa280bb-39d7-48ed-8c21-405fcd078192
created_at:
queue_name: my-queue-1
prefix:
suffix:
event_type: DeleteObject

rule_id: c4725929-3799-477a-a8d9-2d300f957e51
created_at: 2024-09-05T01:02:03.000Z
queue_name: my-queue-2
prefix: //1
suffix: 2//
event_type: LifecycleDeletion"
`);
});
test("auth email eventNotificationHeaders", () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/wrangler/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ import type { Arguments } from "yargs";

const resetColor = "\x1b[0m";
const fgGreenColor = "\x1b[32m";
const betaCmdColor = "#BD5B08";
export const betaCmdColor = "#BD5B08";

export const DEFAULT_LOCAL_PORT = 8787;
export const DEFAULT_INSPECTOR_PORT = 9229;
Expand Down
3 changes: 1 addition & 2 deletions packages/wrangler/src/queues/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,9 @@ async function ensureQueuesExist(config: Config, queueNames: string[]) {
}

export async function getQueueById(
config: Pick<Config, "account_id">,
accountId: string,
queueId: string
): Promise<QueueResponse> {
const accountId = await requireAuth(config);
return fetchResult(queuesUrl(accountId, queueId), {});
}

Expand Down
Loading
Loading