Skip to content

Commit 493999c

Browse files
author
Adrian Gracia
committed
SQC-480 implement sslmode field for hyperdrive
1 parent 639c136 commit 493999c

File tree

4 files changed

+117
-13
lines changed

4 files changed

+117
-13
lines changed

.changeset/every-wolves-roll.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"wrangler": minor
3+
---
4+
5+
add sslmode to hyperdrive and update mtls flags

packages/wrangler/src/__tests__/hyperdrive.test.ts

Lines changed: 91 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -625,16 +625,17 @@ describe("hyperdrive commands", () => {
625625
`);
626626
});
627627

628-
it("should create a hyperdrive with mtls config", async () => {
628+
it("should successfully create a hyperdrive with mtls config and sslmode=verify-full", async () => {
629629
const reqProm = mockHyperdriveCreate();
630630
await runWrangler(
631-
"hyperdrive create test123 --host=example.com --database=neondb --user=test --password=password --port=1234 --ca-certificate-id=12345 --mtls-certificate-id=1234"
631+
"hyperdrive create test123 --host=example.com --database=neondb --user=test --password=password --port=1234 --ca-certificate-id=12345 --mtls-certificate-id=1234 --sslmode=verify-full"
632632
);
633633
await expect(reqProm).resolves.toMatchInlineSnapshot(`
634634
Object {
635635
"mtls": Object {
636636
"ca_certificate_id": "12345",
637637
"mtls_certificate_id": "1234",
638+
"sslmode": "verify-full",
638639
},
639640
"name": "test123",
640641
"origin": Object {
@@ -663,20 +664,94 @@ describe("hyperdrive commands", () => {
663664
`);
664665
});
665666

667+
it("should successfully create a hyperdrive with mtls config and sslmode=require", async () => {
668+
await runWrangler(
669+
"hyperdrive create test123 --host=example.com --database=neondb --user=test --password=password --port=1234 --mtls-certificate-id=1234 --sslmode=require"
670+
);
671+
expect(std.out).toMatchInlineSnapshot(`
672+
"🚧 Creating 'test123'
673+
✅ Created new Hyperdrive PostgreSQL config: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
674+
📋 To start using your config from a Worker, add the following binding configuration to your Wrangler configuration file:
675+
676+
{
677+
\\"hyperdrive\\": [
678+
{
679+
\\"binding\\": \\"HYPERDRIVE\\",
680+
\\"id\\": \\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\\"
681+
}
682+
]
683+
}"
684+
`);
685+
});
686+
687+
it("should error on create hyperdrive with mtls config sslmode=require and CA flag set", async () => {
688+
await expect(() =>
689+
runWrangler(
690+
"hyperdrive create test123 --host=example.com --database=neondb --user=test --password=password --port=1234 --ca-certificate-id=1234 --sslmode=require"
691+
)
692+
).rejects.toThrow();
693+
expect(std.err).toMatchInlineSnapshot(`
694+
"X [ERROR] CA not allowed when sslmode = 'require' is set
695+
696+
"
697+
`);
698+
});
699+
700+
it("should error on create hyperdrive with mtls config sslmode=verify-ca missing CA", async () => {
701+
await expect(() =>
702+
runWrangler(
703+
"hyperdrive create test123 --host=example.com --database=neondb --user=test --password=password --port=1234 --mtls-certificate-id=1234 --sslmode=verify-ca"
704+
)
705+
).rejects.toThrow();
706+
expect(std.err).toMatchInlineSnapshot(`
707+
"X [ERROR] CA required when sslmode = 'verify-ca' or 'verify-full' is set
708+
709+
"
710+
`);
711+
});
712+
713+
it("should error on create hyperdrive with mtls config sslmode=verify-full missing CA", async () => {
714+
await expect(() =>
715+
runWrangler(
716+
"hyperdrive create test123 --host=example.com --database=neondb --user=test --password=password --port=1234 --mtls-certificate-id=1234 --sslmode=verify-full"
717+
)
718+
).rejects.toThrow();
719+
expect(std.err).toMatchInlineSnapshot(`
720+
"X [ERROR] CA required when sslmode = 'verify-ca' or 'verify-full' is set
721+
722+
"
723+
`);
724+
});
725+
726+
it("should error on create hyperdrive with mtls config sslmode=random", async () => {
727+
await expect(() =>
728+
runWrangler(
729+
"hyperdrive create test123 --host=example.com --database=neondb --user=test --password=password --port=1234 --mtls-certificate-id=1234 --sslmode=random"
730+
)
731+
).rejects.toThrow();
732+
expect(std.err).toMatchInlineSnapshot(`
733+
"X [ERROR] Invalid values:
734+
735+
Argument: sslmode, Given: \\"random\\", Choices: \\"require\\", \\"verify-ca\\", \\"verify-full\\"
736+
737+
"
738+
`);
739+
});
740+
666741
it("should handle listing configs", async () => {
667742
mockHyperdriveGetListOrDelete();
668743
await runWrangler("hyperdrive list");
669744
expect(std.out).toMatchInlineSnapshot(`
670745
"📋 Listing Hyperdrive configs
671-
┌──────────────────────────────────────┬─────────────┬─────────┬────────────────┬──────┬────────────┬───────────┬──────────┬───────────────────────────────────────────────────────────┐
672-
│ id │ name │ user │ host │ port │ scheme │ database │ caching │ mtls │
673-
├──────────────────────────────────────┼─────────────┼─────────┼────────────────┼──────┼────────────┼───────────┼──────────┼───────────────────────────────────────────────────────────┤
674-
│ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx │ test123 │ test │ example.com │ 5432 │ PostgreSQL │ neondb │ enabled │ │
675-
├──────────────────────────────────────┼─────────────┼─────────┼────────────────┼──────┼────────────┼───────────┼──────────┼───────────────────────────────────────────────────────────┤
676-
│ yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy │ new-db │ dbuser │ www.google.com │ 3211 │ PostgreSQL │ mydb │ disabled │ │
677-
├──────────────────────────────────────┼─────────────┼─────────┼────────────────┼──────┼────────────┼───────────┼──────────┼───────────────────────────────────────────────────────────┤
678-
│ zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz │ new-db-mtls │ pg-mtls │ www.mtls.com │ 3212 │ │ mydb-mtls │ enabled │ {\\"ca_certificate_id\\":\\"1234\\",\\"mtls_certificate_id\\":\\"1234\\"} │
679-
└──────────────────────────────────────┴─────────────┴─────────┴────────────────┴──────┴────────────┴───────────┴──────────┴───────────────────────────────────────────────────────────┘"
746+
┌──────────────────────────────────────┬─────────────┬─────────┬────────────────┬──────┬────────────┬───────────┬──────────┬───────────────────────────────────────────────────────────────────────────────────
747+
│ id │ name │ user │ host │ port │ scheme │ database │ caching │ mtls
748+
├──────────────────────────────────────┼─────────────┼─────────┼────────────────┼──────┼────────────┼───────────┼──────────┼───────────────────────────────────────────────────────────────────────────────────
749+
│ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx │ test123 │ test │ example.com │ 5432 │ PostgreSQL │ neondb │ enabled │
750+
├──────────────────────────────────────┼─────────────┼─────────┼────────────────┼──────┼────────────┼───────────┼──────────┼───────────────────────────────────────────────────────────────────────────────────
751+
│ yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy │ new-db │ dbuser │ www.google.com │ 3211 │ PostgreSQL │ mydb │ disabled │
752+
├──────────────────────────────────────┼─────────────┼─────────┼────────────────┼──────┼────────────┼───────────┼──────────┼───────────────────────────────────────────────────────────────────────────────────
753+
│ zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz │ new-db-mtls │ pg-mtls │ www.mtls.com │ 3212 │ │ mydb-mtls │ enabled │ {\\"ca_certificate_id\\":\\"1234\\",\\"mtls_certificate_id\\":\\"1234\\",\\"sslmode\\":\\"verify-full\\"} │
754+
└──────────────────────────────────────┴─────────────┴─────────┴────────────────┴──────┴────────────┴───────────┴──────────┴───────────────────────────────────────────────────────────────────────────────────┘"
680755
`);
681756
});
682757

@@ -985,13 +1060,14 @@ describe("hyperdrive commands", () => {
9851060
it("should handle updating a hyperdrive config's mtls configuration", async () => {
9861061
const reqProm = mockHyperdriveUpdate();
9871062
await runWrangler(
988-
"hyperdrive update xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx --ca-certificate-id=2345 --mtls-certificate-id=234"
1063+
"hyperdrive update xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx --ca-certificate-id=2345 --mtls-certificate-id=234 --sslmode=verify-full"
9891064
);
9901065
await expect(reqProm).resolves.toMatchInlineSnapshot(`
9911066
Object {
9921067
"mtls": Object {
9931068
"ca_certificate_id": "2345",
9941069
"mtls_certificate_id": "234",
1070+
"sslmode": "verify-full",
9951071
},
9961072
}
9971073
`);
@@ -1010,7 +1086,8 @@ describe("hyperdrive commands", () => {
10101086
},
10111087
\\"mtls\\": {
10121088
\\"ca_certificate_id\\": \\"2345\\",
1013-
\\"mtls_certificate_id\\": \\"234\\"
1089+
\\"mtls_certificate_id\\": \\"234\\",
1090+
\\"sslmode\\": \\"verify-full\\"
10141091
}
10151092
}"
10161093
`);
@@ -1080,6 +1157,7 @@ function mockHyperdriveGetListOrDelete() {
10801157
mtls: {
10811158
ca_certificate_id: "1234",
10821159
mtls_certificate_id: "1234",
1160+
sslmode: "verify-full",
10831161
},
10841162
},
10851163
],

packages/wrangler/src/hyperdrive/client.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,11 @@ export type PatchHyperdriveBody = {
8787
export type Mtls = {
8888
ca_certificate_id?: string;
8989
mtls_certificate_id?: string;
90+
sslmode?: string;
9091
};
9192

93+
export const Sslmode = ['require', 'verify-ca', 'verify-full'];
94+
9295
export async function createConfig(
9396
config: Config,
9497
body: CreateUpdateHyperdriveBody

packages/wrangler/src/hyperdrive/index.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@ export function upsertOptions<T>(yargs: Argv<T>) {
127127
describe:
128128
"Sets custom mTLS client certificates when connecting to origin database. Must be valid UUID of already uploaded public/private key certificates.",
129129
},
130+
"sslmode": {
131+
type: "string",
132+
choices: ["require", "verify-ca", "verify-full"],
133+
describe:
134+
"Sets CA sslmode for connecting to database.",
135+
},
130136
})
131137
.group(
132138
["connection-string"],
@@ -323,11 +329,23 @@ export function getMtlsFromArgs(
323329
const mtls = {
324330
ca_certificate_id: args.caCertificateId,
325331
mtls_certificate_id: args.mtlsCertificateId,
332+
sslmode: args.sslmode,
326333
};
327334

328335
if (JSON.stringify(mtls) === "{}") {
329336
return undefined;
330337
} else {
338+
if(mtls.sslmode == "require" && mtls.ca_certificate_id?.trim()) {
339+
throw new UserError(
340+
"CA not allowed when sslmode = 'require' is set"
341+
);
342+
}
343+
344+
if((mtls.sslmode == "verify-ca" || mtls.sslmode == "verify-full") && !mtls.ca_certificate_id?.trim()) {
345+
throw new UserError(
346+
"CA required when sslmode = 'verify-ca' or 'verify-full' is set"
347+
);
348+
}
331349
return mtls;
332350
}
333351
}

0 commit comments

Comments
 (0)