Skip to content

Instantly share code, notes, and snippets.

@jakobo
Created August 31, 2023 23:14
Show Gist options
  • Save jakobo/b3203b832c28f6cac8c28225615752f7 to your computer and use it in GitHub Desktop.
Save jakobo/b3203b832c28f6cac8c28225615752f7 to your computer and use it in GitHub Desktop.
/* eslint-disable n/no-process-env, unicorn/no-process-exit */
import process from "node:process";
import * as url from "node:url";
import * as pulumi from "@pulumi/pulumi";
import { local } from "@pulumi/command";
import { acquireToken, fromEnv, fromState, toState } from "./helpers.js";
const __filename = url.fileURLToPath(import.meta.url);
// an internal mapping of cloud provider & region to mongo location arguments
const regionToLocationMap: Record<string, Record<string, string>> = {
aws: {
"us-west-2": "US-OR",
},
};
type MongoAPIResponse = {
name: string;
provider_region: string;
location: string;
deployment_model: string;
environment: string;
_id: string;
client_app_id: string;
domain_id: string;
group_id: string;
last_used: number;
last_modified: number;
product: string;
};
type CLIEnv = SaveEnv & {
MONGO_TOKEN?: string;
};
type SaveEnv = {
MONGO_CLOUD: string;
MONGO_DEPLOYMENT_MODEL: string;
MONGO_ENVIRONMENT: string;
MONGO_NAME: string;
MONGO_PRODUCT: string;
MONGO_PROJECT_ID: string;
MONGO_REGION: string;
};
if (process.env.PULUMI_RUN === "create") {
const {
MONGO_CLOUD,
MONGO_DEPLOYMENT_MODEL,
MONGO_ENVIRONMENT,
MONGO_NAME,
MONGO_PRODUCT,
MONGO_PROJECT_ID,
MONGO_REGION,
MONGO_TOKEN,
} = fromEnv({
MONGO_CLOUD: true,
MONGO_DEPLOYMENT_MODEL: true,
MONGO_ENVIRONMENT: true,
MONGO_NAME: true,
MONGO_PRODUCT: true,
MONGO_PROJECT_ID: true,
MONGO_REGION: true,
MONGO_TOKEN: true,
});
const url = `https://realm.mongodb.com/api/admin/v3.0/groups/${MONGO_PROJECT_ID}/apps?product=${
MONGO_PRODUCT ?? "data-api"
}`;
const saveEnv: SaveEnv = {
MONGO_CLOUD,
MONGO_DEPLOYMENT_MODEL,
MONGO_ENVIRONMENT,
MONGO_NAME,
MONGO_PRODUCT,
MONGO_PROJECT_ID,
MONGO_REGION,
};
// check before creating
const checkResponse = await fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: `Bearer ${MONGO_TOKEN}`,
},
});
const checkResult = (await checkResponse.json()) as MongoAPIResponse[];
if (checkResult?.[0]) {
// return existing instead of creating
process.stdout.write(toState(checkResult[0], saveEnv));
process.exit(0);
}
const location =
regionToLocationMap?.[MONGO_CLOUD ?? ""]?.[MONGO_REGION ?? ""];
if (!location && MONGO_DEPLOYMENT_MODEL === "LOCAL")
throw new TypeError("Invalid cloud or region");
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: `Bearer ${MONGO_TOKEN}`,
},
body: JSON.stringify({
name: MONGO_NAME,
provider_region:
location && MONGO_CLOUD && MONGO_REGION
? `${MONGO_CLOUD}-${MONGO_REGION}`
: "",
location: MONGO_DEPLOYMENT_MODEL === "LOCAL" ? location : "",
deployment_model: MONGO_DEPLOYMENT_MODEL,
environment: MONGO_ENVIRONMENT,
}),
});
const result = (await response.json()) as MongoAPIResponse;
// output on stdout
process.stdout.write(toState(result, saveEnv));
process.exit(0);
}
if (process.env.PULUMI_RUN === "update") {
throw new Error("Update is not implemented for pulumi command.local");
}
if (process.env.PULUMI_RUN === "delete") {
// delete flow
const { PULUMI_COMMAND_STDOUT, MONGO_TOKEN } = fromEnv({
PULUMI_COMMAND_STDOUT: true,
MONGO_TOKEN: true,
});
const last = fromState<MongoAPIResponse, SaveEnv>(PULUMI_COMMAND_STDOUT);
const url = `https://realm.mongodb.com/api/admin/v3.0/groups/${last.env.MONGO_PROJECT_ID}/apps/${last.response._id}`;
const response = await fetch(url, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: `Bearer ${MONGO_TOKEN}`,
},
});
if (response.status !== 204) {
throw new Error("Unable to delete application");
}
process.stdout.write(PULUMI_COMMAND_STDOUT ?? "{}");
process.exit(0);
}
if (process.env.PULUMI_RUN === "read") {
// Read flow
throw new Error("Read is not implemented for pulumi command.local");
}
// resource using pulumi local command
type MongoAppArgs = {
projectId: pulumi.Input<string>;
product?: pulumi.Input<"data-api">;
cloud?: pulumi.Input<"aws">;
region?: pulumi.Input<string>;
deploymentModel?: pulumi.Input<"GLOBAL" | "LOCAL">;
environment?: pulumi.Input<
"" | "development" | "testing" | "qa" | "production"
>;
};
export class MongoRealmApp extends pulumi.ComponentResource {
// inputs
public readonly name!: pulumi.Output<string>;
public readonly projectId!: pulumi.Output<string>;
public readonly product!: pulumi.Output<string>;
public readonly cloud!: pulumi.Output<string>;
public readonly region!: pulumi.Output<string>;
public readonly deploymentModel!: pulumi.Output<string>;
public readonly environment!: pulumi.Output<string>;
// outputs
public readonly id!: pulumi.Output<string>;
public readonly appId!: pulumi.Output<string>;
public readonly clientAppId!: pulumi.Output<string>;
constructor(
name: string,
args: MongoAppArgs,
options?: pulumi.ComponentResourceOptions
) {
super(
"taskless:mongo:realm:application",
name,
{
//
...args,
id: undefined /* out */,
appId: undefined /* out */,
clientAppId: undefined /* out */,
},
options
);
const env: Record<keyof CLIEnv, string | pulumi.Input<string>> = pulumi
.all([
args.cloud,
args.deploymentModel,
args.environment,
name,
args.product,
args.projectId,
args.region,
acquireToken(),
])
.apply(
([
cloud,
deploymentModel,
environment,
n,
product,
projectId,
region,
token,
]) => ({
MONGO_CLOUD: cloud ?? "aws",
MONGO_DEPLOYMENT_MODEL: deploymentModel ?? "GLOBAL",
MONGO_ENVIRONMENT: environment ?? "development",
MONGO_NAME: n,
MONGO_PRODUCT: product ?? "data-api",
MONGO_PROJECT_ID: projectId,
MONGO_REGION: region ?? "",
MONGO_TOKEN: token,
})
);
const app = new local.Command(
`${name}-cmd`,
{
create: `PULUMI_RUN=create pnpm exec ts-node ${__filename}`,
delete: `PULUMI_RUN=delete pnpm exec ts-node ${__filename}`,
environment: env,
},
{ parent: this }
);
const response = app.stdout.apply((s) => JSON.parse(s) as MongoAPIResponse);
// inputs
this.name = pulumi.output(name);
this.projectId = pulumi.output(args.projectId);
this.product = pulumi.output(args.product ?? "data-api");
this.cloud = pulumi.output(args.cloud ?? "aws");
this.region = response.apply((r) => r.provider_region);
this.deploymentModel = response.apply((r) => r.deployment_model);
this.environment = response.apply((r) => r.environment);
// outputs
this.id = response.apply((r) => r._id);
this.appId = response.apply((r) => r._id);
this.clientAppId = response.apply((r) => r.client_app_id);
}
}
/* eslint-disable n/no-process-env, unicorn/no-process-exit */
import process from "node:process";
import * as url from "node:url";
import * as pulumi from "@pulumi/pulumi";
import { local } from "@pulumi/command";
import {
acquireToken,
fromEnv,
fromState,
toState,
logger,
} from "./helpers.js";
const __filename = url.fileURLToPath(import.meta.url);
const log = logger(__filename);
type MongoAPIResponse = {
_id: string;
name: string;
type: string;
disabled: true;
};
type CLIEnv = SavedEnv & {
/* ENV vars here */
MONGO_TOKEN: string;
};
type SavedEnv = {
/* ENV vars here */
MONGO_PROJECT_ID: string;
MONGO_APP_ID: string;
MONGO_TYPE: string;
};
if (process.env.PULUMI_RUN === "create") {
log(process.env);
const { MONGO_PROJECT_ID, MONGO_APP_ID, MONGO_TOKEN, MONGO_TYPE } = fromEnv({
MONGO_PROJECT_ID: true,
MONGO_APP_ID: true,
MONGO_TOKEN: true,
MONGO_TYPE: true,
});
const saveEnv = {
MONGO_PROJECT_ID,
MONGO_APP_ID,
MONGO_TYPE,
};
// Do code
const url = `https://realm.mongodb.com/api/admin/v3.0/groups/${MONGO_PROJECT_ID}/apps/${MONGO_APP_ID}/auth_providers`;
// check if exists
const checkResponse = await fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: `Bearer ${MONGO_TOKEN}`,
},
});
const checkResult = (await checkResponse.json()) as MongoAPIResponse[];
const exists = checkResult.find((r) => r.type === MONGO_TYPE);
if (exists) {
// output on stdout
process.stdout.write(toState<MongoAPIResponse>(exists, saveEnv));
process.exit(0);
}
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: `Bearer ${MONGO_TOKEN}`,
},
body: JSON.stringify({
name: MONGO_TYPE,
type: MONGO_TYPE,
disabled: false,
}),
});
const result = (await response.json()) as MongoAPIResponse;
// output on stdout
process.stdout.write(toState<MongoAPIResponse>(result, saveEnv));
process.exit(0);
}
if (process.env.PULUMI_RUN === "update") {
throw new Error("Update is not implemented for pulumi command.local");
}
if (process.env.PULUMI_RUN === "delete") {
// delete flow
const { PULUMI_COMMAND_STDOUT, MONGO_TOKEN } = fromEnv({
PULUMI_COMMAND_STDOUT: true,
MONGO_TOKEN: true,
});
const last = fromState<MongoAPIResponse, SavedEnv>(PULUMI_COMMAND_STDOUT);
// Do code
const url = `https://realm.mongodb.com/api/admin/v3.0/groups/${last.env.MONGO_PROJECT_ID}/apps/${last.env.MONGO_APP_ID}/auth_providers/${last.response._id}`;
await fetch(url, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: `Bearer ${MONGO_TOKEN}`,
},
});
process.stdout.write(PULUMI_COMMAND_STDOUT ?? "{}");
process.exit(0);
}
if (process.env.PULUMI_RUN === "read") {
// Read flow
throw new Error("Read is not implemented for pulumi command.local");
}
// resource using pulumi local command
type MongoRealmAuthProviderArgs = {
projectId: pulumi.Input<string>;
applicationId: pulumi.Input<string>;
type: pulumi.Input<"anon-user" | "api-key">;
};
export class MongoRealmAuthProvider extends pulumi.ComponentResource {
// inputs (copy from args)
public readonly projectId!: pulumi.Output<string>;
public readonly applicationId!: pulumi.Output<string>;
public readonly type!: pulumi.Output<string>;
// outputs
public readonly id!: pulumi.Output<string>;
// public readonly clientAppId!: pulumi.Output<string>;
constructor(
name: string,
args: MongoRealmAuthProviderArgs,
options?: pulumi.ComponentResourceOptions
) {
super(
"taskless:mongo:realm:authProvider",
name,
{
//
...args,
id: undefined /* out */,
},
options
);
const env: Record<keyof CLIEnv, string | pulumi.Input<string>> = pulumi
.all([acquireToken(), args.projectId, args.applicationId, args.type])
.apply(([token, projectId, appId, type]) => ({
MONGO_TOKEN: token,
MONGO_PROJECT_ID: projectId,
MONGO_APP_ID: appId,
MONGO_TYPE: type,
}));
const app = new local.Command(
`${name}-cmd`,
{
create: `PULUMI_RUN=create pnpm exec ts-node ${__filename}`,
delete: `PULUMI_RUN=delete pnpm exec ts-node ${__filename}`,
environment: env,
},
{ parent: this }
);
const response = app.stdout.apply((s) => JSON.parse(s) as MongoAPIResponse);
// inputs
this.projectId = pulumi.output(args.projectId);
this.applicationId = pulumi.output(args.applicationId);
this.type = pulumi.output(args.type);
// outputs
this.id = response.apply((r) => r._id);
}
}
import * as pulumi from "@pulumi/pulumi";
import { MongoRealmApp } from "./modules/application.js";
import { MongoRealmDataAPIConfig } from "./modules/dataApiConfig.js";
import { MongoRealmAuthProvider } from "./modules/authProvider.js";
import { MongoRealmDataSource } from "./modules/dataSource.js";
import { MongoRealmDefaultRule } from "./modules/defaultRule.js";
type MongoRealmDataAPIArgs = {
/** The Mongo project ID. Also somtimes called the Group ID or Project ID */
projectId: pulumi.Input<string>;
/** The name of the Mongo Cluster to attach the Data API to */
clusterName: pulumi.Input<string>;
/** An environment for this mongo cluster. One of "", "development", "testing", "qa", "production" */
environment?: pulumi.Input<
"" | "development" | "testing" | "qa" | "production"
>;
/** The deployment model for the Data API */
deploymentModel?: pulumi.Input<"GLOBAL" | "LOCAL">;
/** The cloud provider. One of "aws" */
cloud: pulumi.Input<string>;
/** The region within the cloud provider. Varies by cloud provider */
region: pulumi.Input<string>;
};
/**
* Create a MongoDB Data API via App Services, and attach the necessary
* pemissions for it to function.
* Built similar to the AWS Crosswalk pattern
* See: https://www.mongodb.com/docs/atlas/app-services/admin/api/v3
*/
export class MongoRealmDataAPI extends pulumi.ComponentResource {
// inputs
/** The Mongo Organization ID. Also called a Group ID or Project ID */
public readonly projectId!: pulumi.Output<string>;
/** The ID of the Mongo Cluster this Data API was attached to */
public readonly clusterName!: pulumi.Output<string>;
/** The environment this Data API was configured with */
public readonly environment!: pulumi.Output<string>;
/** The cloud provider for this Data API gateway */
public readonly cloud!: pulumi.Output<string>;
/** The cloud provider region for this Data API gateway */
public readonly region!: pulumi.Output<string>;
// outputs
/** The internal ID of the Data API application */
public readonly appId!: pulumi.Output<string>;
/** The friendly name of the Data API application */
public readonly appName!: pulumi.Output<string>;
/** The client's app ID. Used for HTTPS requests and mongo client connections */
public readonly clientAppId!: pulumi.Output<string>;
/** An Atlas URL for environments that cannot use mongo connection strings */
public readonly httpEndpoint!: pulumi.Output<string>;
/** The Atlas Data Source name for connecting */
public readonly dataSource!: pulumi.Output<string>;
constructor(
name: string,
args: MongoRealmDataAPIArgs,
options?: pulumi.ComponentResourceOptions
) {
// checks and defaults
if (!args.projectId) throw new Error("projectId is required");
if (!args.clusterName) throw new Error("clusterName is required");
args.deploymentModel = args.deploymentModel ?? "GLOBAL";
args.cloud = args.cloud ?? "aws";
args.region = args.region ?? "us-west-2";
super(
"taskless:mongo:realm:dataAPI:pkg",
name,
{
...args,
appId: undefined /* out */,
appName: undefined /* out */,
clientAppId: undefined /* out */,
apiKey: undefined /* out */,
connectionString: undefined /* out */,
httpEndpoint: undefined /* out */,
},
options
);
// the mongo app
const app = new MongoRealmApp(
`${name}-application`,
{
projectId: args.projectId,
product: "data-api",
cloud: "aws",
region: args.region,
},
{ parent: this }
);
// the data api config for the mongo app
const dataApiConfig = new MongoRealmDataAPIConfig(
`${name}-config`,
{
projectId: args.projectId,
applicationId: app.appId,
version: "v1",
format: "EJSON",
},
{ parent: this }
);
// an auth provider for the mongo app
const authProvider = new MongoRealmAuthProvider(
`${name}-auth-provider`,
{
projectId: args.projectId,
applicationId: app.appId,
type: "api-key",
},
{ parent: this }
);
// a data source that connects the mongo app to a cluster
const dataSource = new MongoRealmDataSource(
`${name}-data-source`,
{
projectId: args.projectId,
applicationId: app.appId,
name: args.clusterName,
type: "mongodb-atlas",
config: {
clusterName: args.clusterName,
},
},
{ parent: this }
);
// default rules for the data source
const defaultRule = new MongoRealmDefaultRule(
`${name}-default-rule`,
{
projectId: args.projectId,
applicationId: app.appId,
serviceId: dataSource.id,
},
{ parent: this }
);
const httpEndpoint = pulumi
.all([
args.region,
args.cloud,
args.deploymentModel,
app.clientAppId,
dataApiConfig.version,
])
.apply(([region, cloud, deploymentModel, clientAppId, version]) => {
const domainPrefix =
deploymentModel === "GLOBAL" ? "" : `${region}.${cloud}.`;
return `https://${domainPrefix}data.mongodb-api.com/app/${clientAppId}/endpoint/data/${version}`;
});
// inputs
this.projectId = pulumi.output(args.projectId);
this.clusterName = pulumi.output(args.clusterName);
// outputs and derrived inputs
this.environment = app.environment;
this.cloud = app.cloud;
this.region = app.region;
this.appId = app.appId;
this.appName = app.name;
this.clientAppId = app.clientAppId;
this.httpEndpoint = httpEndpoint;
this.dataSource = dataSource.name;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment