Skip to content

Commit

Permalink
feat: wrangler secret * --local
Browse files Browse the repository at this point in the history
This PR implements `wrangler secret` for `--local` mode. The implementation is simply a no-op, since we don't want to actually write secret values to disk (I think?). I also got the messaging for remote mode right by copying from wrangler 1. Further, I added tests for all the `wrangler secret commands`.
  • Loading branch information
threepointone committed Jan 25, 2022
1 parent 71b0fab commit 55a087e
Show file tree
Hide file tree
Showing 3 changed files with 263 additions and 26 deletions.
7 changes: 7 additions & 0 deletions .changeset/grumpy-gifts-end.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"wrangler": patch
---

feat: `wrangler secret * --local`

This PR implements `wrangler secret` for `--local` mode. The implementation is simply a no-op, since we don't want to actually write secret values to disk (I think?). I also got the messaging for remote mode right by copying from wrangler 1. Further, I added tests for all the `wrangler secret commands`.
208 changes: 208 additions & 0 deletions packages/wrangler/src/__tests__/secret.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
import { setMockResponse, unsetAllMocks } from "./mock-cfetch";
import { runWrangler } from "./run-wrangler";
import { runInTempDir } from "./run-in-tmp";
import { mockConfirm, mockPrompt } from "./mock-dialogs";

describe("wrangler secret", () => {
runInTempDir();
afterEach(() => {
unsetAllMocks();
});

describe("put", () => {
function mockPutRequest(input: { name: string; text: string }) {
setMockResponse(
"/accounts/:accountId/workers/scripts/:scriptName/secrets",
"PUT",
([_url, accountId], { body }) => {
expect(accountId).toEqual("some-account-id");
const { name, text, type } = JSON.parse(body as string);
expect(type).toEqual("secret_text");
expect(name).toEqual(input.name);
expect(text).toEqual(input.text);

return { name, type };
}
);
}

it("should create a secret", async () => {
mockPrompt({
text: "Enter a secret value:",
type: "password",
result: "the-secret",
});

mockPutRequest({ name: "the-secret-name", text: "the-secret" });
const { stdout, stderr, error } = await runWrangler(
"secret put the-key --name script-name"
);

expect(stdout).toMatchInlineSnapshot(`
"🌀 Creating the secret for script script-name
✨ Success! Uploaded secret the-key"
`);
expect(stderr).toMatchInlineSnapshot(`""`);
expect(error).toMatchInlineSnapshot(`undefined`);
});

it("should error without a script name", async () => {
const { stdout, stderr, error } = await runWrangler("secret put the-key");
expect(stdout).toMatchInlineSnapshot(`""`);
expect(stderr).toMatchInlineSnapshot(`
"Missing script name
%s
If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
`);
expect(error).toMatchInlineSnapshot(`[Error: Missing script name]`);
});

it("warns about being a no-op in local mode", async () => {
mockPrompt({
text: "Enter a secret value:",
type: "password",
result: "the-secret",
});

mockPutRequest({ name: "the-secret-name", text: "the-secret" });
const { stdout, stderr, warnings, error } = await runWrangler(
"secret put the-key --name script-name --local"
);
expect(stdout).toMatchInlineSnapshot(`""`);
expect(stderr).toMatchInlineSnapshot(`""`);
expect(warnings).toMatchInlineSnapshot(
`"\`wrangler secret put\` is a no-op in --local mode"`
);
expect(error).toMatchInlineSnapshot(`undefined`);
});
});

describe("delete", () => {
function mockDeleteRequest(input: {
scriptName: string;
secretName: string;
}) {
setMockResponse(
"/accounts/:accountId/workers/scripts/:scriptName/secrets/:secretName",
"DELETE",
([_url, accountId, scriptName, secretName]) => {
expect(accountId).toEqual("some-account-id");
expect(scriptName).toEqual(input.scriptName);
expect(secretName).toEqual(input.secretName);

return null;
}
);
}
it("should delete a secret", async () => {
mockDeleteRequest({ scriptName: "script-name", secretName: "the-key" });
mockConfirm({
text: "Are you sure you want to permanently delete the variable the-key on the script script-name?",
result: true,
});
const { stdout, stderr, error } = await runWrangler(
"secret delete the-key --name script-name"
);
expect(stdout).toMatchInlineSnapshot(`
"🌀 Deleting the secret the-key on script script-name.
✨ Success! Deleted secret the-key"
`);
expect(stderr).toMatchInlineSnapshot(`""`);
expect(error).toMatchInlineSnapshot(`undefined`);
});

it("should error without a script name", async () => {
const { stdout, stderr, error } = await runWrangler(
"secret delete the-key"
);
expect(stdout).toMatchInlineSnapshot(`""`);
expect(stderr).toMatchInlineSnapshot(`
"Missing script name
%s
If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
`);
expect(error).toMatchInlineSnapshot(`[Error: Missing script name]`);
});

it("warns about being a no-op in local mode", async () => {
mockConfirm({
text: "Are you sure you want to permanently delete the variable the-key on the script script-name?",
result: true,
});
const { stdout, stderr, warnings, error } = await runWrangler(
"secret delete the-key --name script-name --local"
);
expect(stdout).toMatchInlineSnapshot(
`"🌀 Deleting the secret the-key on script script-name."`
);
expect(stderr).toMatchInlineSnapshot(`""`);
expect(warnings).toMatchInlineSnapshot(
`"\`wrangler secret delete\` is a no-op in --local mode"`
);
expect(error).toMatchInlineSnapshot(`undefined`);
});
});

describe("list", () => {
function mockListRequest(input: { scriptName: string }) {
setMockResponse(
"/accounts/:accountId/workers/scripts/:scriptName/secrets",
"GET",
([_url, accountId, scriptName]) => {
expect(accountId).toEqual("some-account-id");
expect(scriptName).toEqual(input.scriptName);

return [
{
name: "the-secret-name",
type: "secret_text",
},
];
}
);
}

it("should list secrets", async () => {
mockListRequest({ scriptName: "script-name" });
const { stdout, stderr, error } = await runWrangler(
"secret list --name script-name"
);
expect(stdout).toMatchInlineSnapshot(`
"[
{
\\"name\\": \\"the-secret-name\\",
\\"type\\": \\"secret_text\\"
}
]"
`);
expect(stderr).toMatchInlineSnapshot(`""`);
expect(error).toMatchInlineSnapshot(`undefined`);
});

it("should error without a script name", async () => {
const { stdout, stderr, error } = await runWrangler("secret list");
expect(stdout).toMatchInlineSnapshot(`""`);
expect(stderr).toMatchInlineSnapshot(`
"Missing script name
%s
If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
`);
expect(error).toMatchInlineSnapshot(`[Error: Missing script name]`);
});

it("warns about being a no-op in local mode", async () => {
const { stdout, stderr, warnings, error } = await runWrangler(
"secret list --name script-name --local"
);
expect(stdout).toMatchInlineSnapshot(`""`);
expect(stderr).toMatchInlineSnapshot(`""`);
expect(warnings).toMatchInlineSnapshot(
`"\`wrangler secret list\` is a no-op in --local mode"`
);
expect(error).toMatchInlineSnapshot(`undefined`);
});
});
});
74 changes: 48 additions & 26 deletions packages/wrangler/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1008,11 +1008,6 @@ export async function main(argv: string[]): Promise<void> {
});
},
async (args) => {
if (args.local) {
throw new NotImplementedError(
"--local not implemented for this command yet"
);
}
const config = args.config as Config;

// TODO: use environment (how does current wrangler do it?)
Expand All @@ -1021,6 +1016,10 @@ export async function main(argv: string[]): Promise<void> {
throw new Error("Missing script name");
}

if (args.local) {
console.warn("`wrangler secret put` is a no-op in --local mode");
}

if (!args.local) {
// -- snip, extract --
const loggedIn = await loginOrRefreshIfRequired();
Expand All @@ -1043,6 +1042,13 @@ export async function main(argv: string[]): Promise<void> {
"Enter a secret value:",
"password"
);

if (args.local) {
return;
}

console.log(`🌀 Creating the secret for script ${scriptName}`);

async function submitSecret() {
return await fetchResult(
`/accounts/${config.account_id}/workers/scripts/${scriptName}/secrets/`,
Expand All @@ -1059,7 +1065,7 @@ export async function main(argv: string[]): Promise<void> {
}

try {
console.log(await submitSecret());
await submitSecret();
} catch (e) {
if (e.code === 10007) {
// upload a draft worker
Expand All @@ -1085,10 +1091,11 @@ export async function main(argv: string[]): Promise<void> {
);

// and then try again
console.log(await submitSecret());
await submitSecret();
// TODO: delete the draft worker if this failed too?
}
}
console.log(`✨ Success! Uploaded secret ${args.key}`);
}
)
.command(
Expand All @@ -1111,11 +1118,6 @@ export async function main(argv: string[]): Promise<void> {
});
},
async (args) => {
if (args.local) {
throw new NotImplementedError(
"--local not implemented for this command yet"
);
}
const config = args.config as Config;

// TODO: use environment (how does current wrangler do it?)
Expand All @@ -1124,6 +1126,12 @@ export async function main(argv: string[]): Promise<void> {
throw new Error("Missing script name");
}

if (args.local) {
console.warn(
"`wrangler secret delete` is a no-op in --local mode"
);
}

if (!args.local) {
// -- snip, extract --
const loggedIn = await loginOrRefreshIfRequired();
Expand All @@ -1142,17 +1150,24 @@ export async function main(argv: string[]): Promise<void> {
// -- snip, end --
}

if (await confirm("Are you sure you want to delete this secret?")) {
if (
await confirm(
`Are you sure you want to permanently delete the variable ${args.key} on the script ${scriptName}?`
)
) {
console.log(
`Deleting the secret ${args.key} on script ${scriptName}.`
`🌀 Deleting the secret ${args.key} on script ${scriptName}.`
);

console.log(
await fetchResult(
`/accounts/${config.account_id}/workers/scripts/${scriptName}/secrets/${args.key}`,
{ method: "DELETE" }
)
if (args.local) {
return;
}

await fetchResult(
`/accounts/${config.account_id}/workers/scripts/${scriptName}/secrets/${args.key}`,
{ method: "DELETE" }
);
console.log(`✨ Success! Deleted secret ${args.key}`);
}
}
)
Expand All @@ -1172,11 +1187,6 @@ export async function main(argv: string[]): Promise<void> {
});
},
async (args) => {
if (args.local) {
throw new NotImplementedError(
"--local not implemented for this command yet"
);
}
const config = args.config as Config;

// TODO: use environment (how does current wrangler do it?)
Expand All @@ -1185,6 +1195,10 @@ export async function main(argv: string[]): Promise<void> {
throw new Error("Missing script name");
}

if (args.local) {
console.warn("`wrangler secret list` is a no-op in --local mode");
}

if (!args.local) {
// -- snip, extract --
const loggedIn = await loginOrRefreshIfRequired();
Expand All @@ -1203,9 +1217,17 @@ export async function main(argv: string[]): Promise<void> {
// -- snip, end --
}

if (args.local) {
return;
}

console.log(
await fetchResult(
`/accounts/${config.account_id}/workers/scripts/${scriptName}/secrets`
JSON.stringify(
await fetchResult(
`/accounts/${config.account_id}/workers/scripts/${scriptName}/secrets`
),
null,
" "
)
);
}
Expand Down

0 comments on commit 55a087e

Please sign in to comment.