forked from pulumi/examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mongoHelpers.ts
55 lines (51 loc) · 2.34 KB
/
mongoHelpers.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// Copyright 2016-2019, Pulumi Corporation. All rights reserved.
import * as pulumi from "@pulumi/pulumi";
export function parseConnString(
conns: pulumi.Output<string[]>,
): pulumi.Output<{ [key: string]: string }> {
// Per the official docs[1], the format of this connection string is:
//
// mongodb://username:password@host:port/[database]?ssl=true
//
// Where these could have the following values:
//
// {
// username: "cosmosdb93a4133a",
// password: "23maXrWsrzZ1LmPe4w6XNGRJJTHsqGZPDTjyVQNbPaw119KCoCNpStH0DQms5MKdyAecisBM9uWbpV7lUnyNeQ==",
// host: "cosmosdb93a4133a.documents.azure.com",
// port: "10255",
// database: "mydatabase"
// }
//
// There are a few subtleties involved in getting the Bitnami node Chart to actually be able to
// use this:
//
// 1. The `database` field is optional, we default to `test`, as the API expects.
// 2. The node Chart expects the components of this connection string to be parsed and
// presented in files in a `Secret`. The CosmosDb API doesn't natively expose this, so we
// must parse it ourselves.
// 3. The node Chart uses mongoose to speak the MongoDB wire protocol to CosmosDB. Mongoose
// fails to parse base64-encoded passwords because it doesn't like the `=` character. This
// means we have to (1) URI-encode the password component ourselves, and (2) base64-encode
// that URI-encoded password, because this is the format Kubernetes expects.
//
// [1]: https://docs.microsoft.com/en-us/azure/cosmos-db/connect-mongodb-account
function toBase64(s: string): string {
return Buffer.from(s).toString("base64");
}
return conns.apply(conns => {
const conn = conns[0];
const noProtocol = conn.replace(/^mongodb\:\/\//, "");
const [username, rest1, rest2] = noProtocol.split(":", 3);
const [password, host] = rest1.split("@", 2);
const [port, rest3] = rest2.split("/", 2);
const database = rest3.replace(/\?ssl=true$/, "");
return {
host: toBase64(host),
port: toBase64(port),
username: toBase64(username),
password: toBase64(encodeURIComponent(password)),
database: toBase64(database === "" ? "test" : database),
};
});
}