Skip to content

Commit

Permalink
Adds image, location, and ipv4 to cloudchamber config (#6300)
Browse files Browse the repository at this point in the history
* Adds image, location, and use_ipv4 to cloudchamber config

* Added support for wrangler.toml image and location in modify command

* updates cloudchamber create and modify tests

* add configuration validation tests

---------

Co-authored-by: Carmen Popoviciu <cpopoviciu@cloudflare.com>
  • Loading branch information
mikenomitch and CarmenPopoviciu authored Aug 16, 2024
1 parent fcc7129 commit 82c069f
Show file tree
Hide file tree
Showing 8 changed files with 296 additions and 138 deletions.
178 changes: 100 additions & 78 deletions packages/wrangler/src/__tests__/cloudchamber/create.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as fs from "node:fs";
import * as TOML from "@iarna/toml";
import { http, HttpResponse } from "msw";
import patchConsole from "patch-console";
import { mockAccountId, mockApiToken } from "../helpers/mock-account-id";
Expand All @@ -10,6 +12,58 @@ import { runWrangler } from "../helpers/run-wrangler";
import { mockAccount, setWranglerConfig } from "./utils";
import type { SSHPublicKeyItem } from "../../cloudchamber/client";

const MOCK_DEPLOYMENTS_COMPLEX_RESPONSE = `
"{
\\"id\\": \\"1\\",
\\"type\\": \\"default\\",
\\"created_at\\": \\"123\\",
\\"account_id\\": \\"123\\",
\\"vcpu\\": 4,
\\"memory\\": \\"400MB\\",
\\"version\\": 1,
\\"image\\": \\"hello\\",
\\"location\\": {
\\"name\\": \\"sfo06\\",
\\"enabled\\": true
},
\\"network\\": {
\\"ipv4\\": \\"1.1.1.1\\"
},
\\"placements_ref\\": \\"http://ref\\",
\\"node_group\\": \\"metal\\"
}"
`;

function mockDeploymentPost() {
msw.use(
http.post(
"*/deployments/v2",
async ({ request }) => {
expect(await request.text()).toMatchInlineSnapshot(
`"{\\"image\\":\\"hello:world\\",\\"location\\":\\"sfo06\\",\\"ssh_public_key_ids\\":[],\\"environment_variables\\":[{\\"name\\":\\"HELLO\\",\\"value\\":\\"WORLD\\"},{\\"name\\":\\"YOU\\",\\"value\\":\\"CONQUERED\\"}],\\"vcpu\\":3,\\"memory\\":\\"400GB\\",\\"network\\":{\\"assign_ipv4\\":\\"predefined\\"}}"`
);
return HttpResponse.json(MOCK_DEPLOYMENTS_COMPLEX[0]);
},
{ once: true }
)
);
}

function mockGetKey() {
msw.use(
http.get(
"*/ssh-public-keys",
async () => {
const keys = [
{ id: "1", name: "hello", public_key: "hello-world" },
] as SSHPublicKeyItem[];
return HttpResponse.json(keys);
},
{ once: true }
)
);
}

describe("cloudchamber create", () => {
const std = mockConsoleMethods();
const { setIsTTY } = useMockIsTTY();
Expand Down Expand Up @@ -62,6 +116,25 @@ describe("cloudchamber create", () => {
);
});

it("should fail with a nice message when parameters are mistyped", async () => {
setIsTTY(false);
fs.writeFileSync(
"./wrangler.toml",
TOML.stringify({
name: "my-container",
cloudchamber: { image: true },
}),

"utf-8"
);
await expect(
runWrangler("cloudchamber create ")
).rejects.toThrowErrorMatchingInlineSnapshot(
` [Error: Processing wrangler.toml configuration:
- "cloudchamber" bindings should, optionally, have a string "image" field but got {"image":true}.]`
);
});

it("should fail with a nice message when parameters are missing (json)", async () => {
setIsTTY(false);
setWranglerConfig({});
Expand All @@ -75,57 +148,37 @@ describe("cloudchamber create", () => {
it("should create deployment (detects no interactivity)", async () => {
setIsTTY(false);
setWranglerConfig({});
msw.use(
http.get(
"*/ssh-public-keys",
async () => {
const keys = [
{ id: "1", name: "hello", public_key: "hello-world" },
] as SSHPublicKeyItem[];
return HttpResponse.json(keys);
},
{ once: true }
)
);
msw.use(
http.post(
"*/deployments/v2",
async ({ request }) => {
expect(await request.text()).toMatchInlineSnapshot(
`"{\\"image\\":\\"hello:world\\",\\"location\\":\\"sfo06\\",\\"ssh_public_key_ids\\":[],\\"environment_variables\\":[{\\"name\\":\\"HELLO\\",\\"value\\":\\"WORLD\\"},{\\"name\\":\\"YOU\\",\\"value\\":\\"CONQUERED\\"}],\\"vcpu\\":3,\\"memory\\":\\"400GB\\",\\"network\\":{\\"assign_ipv4\\":\\"predefined\\"}}"`
);
return HttpResponse.json(MOCK_DEPLOYMENTS_COMPLEX[0]);
},
{ once: true }
)
);
mockGetKey();
mockDeploymentPost();
expect(std.err).toMatchInlineSnapshot(`""`);
await runWrangler(
"cloudchamber create --image hello:world --location sfo06 --var HELLO:WORLD --var YOU:CONQUERED --vcpu 3 --memory 400GB --ipv4 true"
);
// so testing the actual UI will be harder than expected
// TODO: think better on how to test UI actions
expect(std.out).toMatchInlineSnapshot(`
"{
\\"id\\": \\"1\\",
\\"type\\": \\"default\\",
\\"created_at\\": \\"123\\",
\\"account_id\\": \\"123\\",
\\"vcpu\\": 4,
\\"memory\\": \\"400MB\\",
\\"version\\": 1,
\\"image\\": \\"hello\\",
\\"location\\": {
\\"name\\": \\"sfo06\\",
\\"enabled\\": true
},
\\"network\\": {
\\"ipv4\\": \\"1.1.1.1\\"
},
\\"placements_ref\\": \\"http://ref\\",
\\"node_group\\": \\"metal\\"
}"
`);
expect(std.out).toMatchInlineSnapshot(MOCK_DEPLOYMENTS_COMPLEX_RESPONSE);
});

it("properly reads wrangler config", async () => {
// This is very similar to the previous test except config
// is set in wrangler and not overridden by the CLI
setIsTTY(false);
setWranglerConfig({
image: "hello:world",
ipv4: true,
vcpu: 3,
memory: "400GB",
location: "sfo06",
});
// if values are not read by wrangler, this mock won't work
// since the wrangler command wont get the right parameters
mockGetKey();
mockDeploymentPost();
await runWrangler(
"cloudchamber create --var HELLO:WORLD --var YOU:CONQUERED"
);
expect(std.out).toMatchInlineSnapshot(MOCK_DEPLOYMENTS_COMPLEX_RESPONSE);
expect(std.err).toMatchInlineSnapshot(`""`);
});

it("should create deployment indicating ssh keys (detects no interactivity)", async () => {
Expand All @@ -134,18 +187,7 @@ describe("cloudchamber create", () => {
vcpu: 40,
memory: "300MB",
});
msw.use(
http.get(
"*/ssh-public-keys",
async () => {
const keys = [
{ id: "1", name: "hello", public_key: "hello-world" },
] as SSHPublicKeyItem[];
return HttpResponse.json(keys);
},
{ once: true }
)
);
mockGetKey();
msw.use(
http.post(
"*/deployments/v2",
Expand All @@ -161,27 +203,7 @@ describe("cloudchamber create", () => {
await runWrangler(
"cloudchamber create --image hello:world --location sfo06 --var HELLO:WORLD --var YOU:CONQUERED --all-ssh-keys --ipv4"
);
expect(std.out).toMatchInlineSnapshot(`
"{
\\"id\\": \\"1\\",
\\"type\\": \\"default\\",
\\"created_at\\": \\"123\\",
\\"account_id\\": \\"123\\",
\\"vcpu\\": 4,
\\"memory\\": \\"400MB\\",
\\"version\\": 1,
\\"image\\": \\"hello\\",
\\"location\\": {
\\"name\\": \\"sfo06\\",
\\"enabled\\": true
},
\\"network\\": {
\\"ipv4\\": \\"1.1.1.1\\"
},
\\"placements_ref\\": \\"http://ref\\",
\\"node_group\\": \\"metal\\"
}"
`);
expect(std.out).toMatchInlineSnapshot(MOCK_DEPLOYMENTS_COMPLEX_RESPONSE);
});

it("can't create deployment due to lack of fields (json)", async () => {
Expand Down
90 changes: 56 additions & 34 deletions packages/wrangler/src/__tests__/cloudchamber/modify.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,43 @@ import { runInTempDir } from "../helpers/run-in-tmp";
import { runWrangler } from "../helpers/run-wrangler";
import { mockAccount, setWranglerConfig } from "./utils";

function mockDeployment() {
msw.use(
http.patch(
"*/deployments/1234/v2",
async ({ request }) => {
expect(await request.text()).toMatchInlineSnapshot(
`"{\\"image\\":\\"hello:modify\\",\\"location\\":\\"sfo06\\",\\"environment_variables\\":[{\\"name\\":\\"HELLO\\",\\"value\\":\\"WORLD\\"},{\\"name\\":\\"YOU\\",\\"value\\":\\"CONQUERED\\"}],\\"vcpu\\":3,\\"memory\\":\\"40MB\\"}"`
);
return HttpResponse.json(MOCK_DEPLOYMENTS_COMPLEX[0]);
},
{ once: true }
)
);
}

const EXPECTED_RESULT = `
"{
\\"id\\": \\"1\\",
\\"type\\": \\"default\\",
\\"created_at\\": \\"123\\",
\\"account_id\\": \\"123\\",
\\"vcpu\\": 4,
\\"memory\\": \\"400MB\\",
\\"version\\": 1,
\\"image\\": \\"hello\\",
\\"location\\": {
\\"name\\": \\"sfo06\\",
\\"enabled\\": true
},
\\"network\\": {
\\"ipv4\\": \\"1.1.1.1\\"
},
\\"placements_ref\\": \\"http://ref\\",
\\"node_group\\": \\"metal\\"
}"
`;

describe("cloudchamber modify", () => {
const std = mockConsoleMethods();
const { setIsTTY } = useMockIsTTY();
Expand Down Expand Up @@ -55,45 +92,30 @@ describe("cloudchamber modify", () => {
it("should modify deployment (detects no interactivity)", async () => {
setIsTTY(false);
setWranglerConfig({});
msw.use(
http.patch(
"*/deployments/1234/v2",
async ({ request }) => {
expect(await request.text()).toMatchInlineSnapshot(
`"{\\"image\\":\\"hello:modify\\",\\"environment_variables\\":[{\\"name\\":\\"HELLO\\",\\"value\\":\\"WORLD\\"},{\\"name\\":\\"YOU\\",\\"value\\":\\"CONQUERED\\"}],\\"vcpu\\":3,\\"memory\\":\\"40MB\\"}"`
);
return HttpResponse.json(MOCK_DEPLOYMENTS_COMPLEX[0]);
},
{ once: true }
)
);
mockDeployment();
await runWrangler(
"cloudchamber modify 1234 --image hello:modify --var HELLO:WORLD --var YOU:CONQUERED --vcpu 3 --memory 40MB"
"cloudchamber modify 1234 --image hello:modify --location sfo06 --var HELLO:WORLD --var YOU:CONQUERED --vcpu 3 --memory 40MB"
);
expect(std.err).toMatchInlineSnapshot(`""`);
// so testing the actual UI will be harder than expected
// TODO: think better on how to test UI actions
expect(std.out).toMatchInlineSnapshot(`
"{
\\"id\\": \\"1\\",
\\"type\\": \\"default\\",
\\"created_at\\": \\"123\\",
\\"account_id\\": \\"123\\",
\\"vcpu\\": 4,
\\"memory\\": \\"400MB\\",
\\"version\\": 1,
\\"image\\": \\"hello\\",
\\"location\\": {
\\"name\\": \\"sfo06\\",
\\"enabled\\": true
},
\\"network\\": {
\\"ipv4\\": \\"1.1.1.1\\"
},
\\"placements_ref\\": \\"http://ref\\",
\\"node_group\\": \\"metal\\"
}"
`);
expect(std.out).toMatchInlineSnapshot(EXPECTED_RESULT);
});

it("should modify deployment with wrangler args (detects no interactivity)", async () => {
setIsTTY(false);
setWranglerConfig({
image: "hello:modify",
vcpu: 3,
memory: "40MB",
location: "sfo06",
});
mockDeployment();
await runWrangler(
"cloudchamber modify 1234 --var HELLO:WORLD --var YOU:CONQUERED"
);
expect(std.err).toMatchInlineSnapshot(`""`);
expect(std.out).toMatchInlineSnapshot(EXPECTED_RESULT);
});

it("can't modify deployment due to lack of deploymentId (json)", async () => {
Expand Down
Loading

0 comments on commit 82c069f

Please sign in to comment.