Skip to content

Commit

Permalink
feat: secrets + environments
Browse files Browse the repository at this point in the history
This implements environment support for `wrangler secret` (both legacy and services). We now consistently generate the right script name across commands with the `getScriptName()` helper.
  • Loading branch information
threepointone committed Feb 24, 2022
1 parent 72f035e commit ff8ea80
Show file tree
Hide file tree
Showing 6 changed files with 256 additions and 73 deletions.
9 changes: 9 additions & 0 deletions .changeset/angry-badgers-beam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"wrangler": patch
---

feat: secrets + environments

This implements environment support for `wrangler secret` (both legacy and services). We now consistently generate the right script name across commands with the `getScriptName()` helper.

Based on the work by @mitchelvanbever in https://github.com/cloudflare/wrangler2/pull/95.
11 changes: 9 additions & 2 deletions packages/wrangler/src/__tests__/publish.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2008,11 +2008,14 @@ function mockUpdateWorkerRequest({
setMockResponse(
`/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/subdomain`,
"POST",
([_url, accountId, scriptName], { body }) => {
([_url, accountId, scriptName, envName], { body }) => {
expect(accountId).toEqual("some-account-id");
expect(scriptName).toEqual(
legacyEnv && env ? `test-name-${env}` : "test-name"
);
if (!legacyEnv) {
expect(envName).toEqual(env);
}
expect(JSON.parse(body as string)).toEqual({ enabled });
return null;
}
Expand All @@ -2035,11 +2038,15 @@ function mockPublishRoutesRequest({
setMockResponse(
`/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/routes`,
"PUT",
([_url, accountId, scriptName], { body }) => {
([_url, accountId, scriptName, envName], { body }) => {
expect(accountId).toEqual("some-account-id");
expect(scriptName).toEqual(
legacyEnv && env ? `test-name-${env}` : "test-name"
);
if (!legacyEnv) {
expect(envName).toEqual(env);
}

expect(JSON.parse(body as string)).toEqual(
routes.map((pattern) => ({ pattern }))
);
Expand Down
188 changes: 170 additions & 18 deletions packages/wrangler/src/__tests__/secret.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,24 @@ describe("wrangler secret", () => {
});

describe("put", () => {
function mockPutRequest(input: { name: string; text: string }) {
function mockPutRequest(
input: { name: string; text: string },
env?: string,
legacyEnv = false
) {
const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
const environment = env && !legacyEnv ? "/environments/:envName" : "";
setMockResponse(
"/accounts/:accountId/workers/scripts/:scriptName/secrets",
`/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/secrets`,
"PUT",
([_url, accountId], { body }) => {
([_url, accountId, scriptName, envName], { body }) => {
expect(accountId).toEqual("some-account-id");
expect(scriptName).toEqual(
legacyEnv && env ? `script-name-${env}` : "script-name"
);
if (!legacyEnv) {
expect(envName).toEqual(env);
}
const { name, text, type } = JSON.parse(body as string);
expect(type).toEqual("secret_text");
expect(name).toEqual(input.name);
Expand Down Expand Up @@ -49,6 +61,50 @@ describe("wrangler secret", () => {
expect(std.err).toMatchInlineSnapshot(`""`);
});

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

mockPutRequest(
{ name: "the-secret-name", text: "the-secret" },
"some-env",
true
);
await runWrangler(
"secret put the-key --name script-name --env some-env --legacy-env"
);

expect(std.out).toMatchInlineSnapshot(`
"🌀 Creating the secret for script script-name-some-env
✨ Success! Uploaded secret the-key"
`);
expect(std.err).toMatchInlineSnapshot(`""`);
});

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

mockPutRequest(
{ name: "the-secret-name", text: "the-secret" },
"some-env",
false
);
await runWrangler("secret put the-key --name script-name --env some-env");

expect(std.out).toMatchInlineSnapshot(`
"🌀 Creating the secret for script script-name (some-env)
✨ Success! Uploaded secret the-key"
`);
expect(std.err).toMatchInlineSnapshot(`""`);
});

it("should error without a script name", async () => {
let error: Error | undefined;
try {
Expand Down Expand Up @@ -84,18 +140,34 @@ describe("wrangler secret", () => {
});

describe("delete", () => {
function mockDeleteRequest(input: {
scriptName: string;
secretName: string;
}) {
function mockDeleteRequest(
input: {
scriptName: string;
secretName: string;
},
env?: string,
legacyEnv = false
) {
const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
const environment = env && !legacyEnv ? "/environments/:envName" : "";
setMockResponse(
"/accounts/:accountId/workers/scripts/:scriptName/secrets/:secretName",
`/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/secrets/:secretName`,
"DELETE",
([_url, accountId, scriptName, secretName]) => {
([_url, accountId, scriptName, envOrSecretName, secretName]) => {
expect(accountId).toEqual("some-account-id");
expect(scriptName).toEqual(input.scriptName);
expect(secretName).toEqual(input.secretName);

expect(scriptName).toEqual(
legacyEnv && env ? `script-name-${env}` : "script-name"
);
if (!legacyEnv) {
if (env) {
expect(envOrSecretName).toEqual(env);
expect(secretName).toEqual(input.secretName);
} else {
expect(envOrSecretName).toEqual(input.secretName);
}
} else {
expect(envOrSecretName).toEqual(input.secretName);
}
return null;
}
);
Expand All @@ -108,7 +180,46 @@ describe("wrangler secret", () => {
});
await runWrangler("secret delete the-key --name script-name");
expect(std.out).toMatchInlineSnapshot(`
"🌀 Deleting the secret the-key on script script-name.
"🌀 Deleting the secret the-key on script script-name
✨ Success! Deleted secret the-key"
`);
expect(std.err).toMatchInlineSnapshot(`""`);
});

it("should delete a secret: legacy envs", async () => {
mockDeleteRequest(
{ scriptName: "script-name", secretName: "the-key" },
"some-env",
true
);
mockConfirm({
text: "Are you sure you want to permanently delete the variable the-key on the script script-name-some-env?",
result: true,
});
await runWrangler(
"secret delete the-key --name script-name --env some-env --legacy-env"
);
expect(std.out).toMatchInlineSnapshot(`
"🌀 Deleting the secret the-key on script script-name-some-env
✨ Success! Deleted secret the-key"
`);
expect(std.err).toMatchInlineSnapshot(`""`);
});

it("should delete a secret: service envs", async () => {
mockDeleteRequest(
{ scriptName: "script-name", secretName: "the-key" },
"some-env"
);
mockConfirm({
text: "Are you sure you want to permanently delete the variable the-key on the script script-name (some-env)?",
result: true,
});
await runWrangler(
"secret delete the-key --name script-name --env some-env"
);
expect(std.out).toMatchInlineSnapshot(`
"🌀 Deleting the secret the-key on script script-name (some-env)
✨ Success! Deleted secret the-key"
`);
expect(std.err).toMatchInlineSnapshot(`""`);
Expand Down Expand Up @@ -139,7 +250,7 @@ describe("wrangler secret", () => {
});
await runWrangler("secret delete the-key --name script-name --local");
expect(std.out).toMatchInlineSnapshot(
`"🌀 Deleting the secret the-key on script script-name."`
`"🌀 Deleting the secret the-key on script script-name"`
);
expect(std.err).toMatchInlineSnapshot(`""`);
expect(std.warn).toMatchInlineSnapshot(
Expand All @@ -149,13 +260,24 @@ describe("wrangler secret", () => {
});

describe("list", () => {
function mockListRequest(input: { scriptName: string }) {
function mockListRequest(
input: { scriptName: string },
env?: string,
legacyEnv = false
) {
const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
const environment = env && !legacyEnv ? "/environments/:envName" : "";
setMockResponse(
"/accounts/:accountId/workers/scripts/:scriptName/secrets",
`/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/secrets`,
"GET",
([_url, accountId, scriptName]) => {
([_url, accountId, scriptName, envName]) => {
expect(accountId).toEqual("some-account-id");
expect(scriptName).toEqual(input.scriptName);
expect(scriptName).toEqual(
legacyEnv && env ? `script-name-${env}` : "script-name"
);
if (!legacyEnv) {
expect(envName).toEqual(env);
}

return [
{
Expand All @@ -181,6 +303,36 @@ describe("wrangler secret", () => {
expect(std.err).toMatchInlineSnapshot(`""`);
});

it("should list secrets: legacy envs", async () => {
mockListRequest({ scriptName: "script-name" }, "some-env", true);
await runWrangler(
"secret list --name script-name --env some-env --legacy-env"
);
expect(std.out).toMatchInlineSnapshot(`
"[
{
\\"name\\": \\"the-secret-name\\",
\\"type\\": \\"secret_text\\"
}
]"
`);
expect(std.err).toMatchInlineSnapshot(`""`);
});

it("should list secrets: service envs", async () => {
mockListRequest({ scriptName: "script-name" }, "some-env");
await runWrangler("secret list --name script-name --env some-env");
expect(std.out).toMatchInlineSnapshot(`
"[
{
\\"name\\": \\"the-secret-name\\",
\\"type\\": \\"secret_text\\"
}
]"
`);
expect(std.err).toMatchInlineSnapshot(`""`);
});

it("should error without a script name", async () => {
let error: Error | undefined;
try {
Expand Down
5 changes: 1 addition & 4 deletions packages/wrangler/src/dev.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,7 @@ function Dev(props: DevProps): JSX.Element {
);

useTunnel(toggles.tunnel);
let scriptName = props.name || path.basename(props.entry.file);
if (props.legacyEnv) {
scriptName = `${scriptName}${props.env ? `-${props.env}` : ""}`;
}
const scriptName = props.name || path.basename(props.entry.file);

return (
<>
Expand Down
Loading

0 comments on commit ff8ea80

Please sign in to comment.