@highstate/common 0.7.1 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,138 @@
1
+ // src/shared/server.ts
2
+ import { remote } from "@pulumi/command";
3
+ import { output } from "@highstate/pulumi";
4
+ import "@highstate/library";
5
+ function getServerConnection(server) {
6
+ return output(server).apply((server2) => ({
7
+ host: server2.endpoint,
8
+ port: server2.sshCredentials?.port ?? 22,
9
+ user: server2.sshCredentials?.user ?? "root",
10
+ password: server2.sshCredentials?.password,
11
+ privateKey: server2.sshCredentials?.privateKey,
12
+ dialErrorLimit: 3
13
+ }));
14
+ }
15
+ var Server = class {
16
+ server;
17
+ connection;
18
+ get endpoint() {
19
+ return this.server.endpoint;
20
+ }
21
+ get hostname() {
22
+ return this.server.hostname;
23
+ }
24
+ constructor(server) {
25
+ this.server = output(server);
26
+ this.connection = getServerConnection(this.server);
27
+ }
28
+ command(options) {
29
+ return new remote.Command(
30
+ options.id,
31
+ {
32
+ connection: this.connection,
33
+ create: options.create,
34
+ update: options.update,
35
+ delete: options.delete
36
+ },
37
+ { dependsOn: options.dependsOn }
38
+ );
39
+ }
40
+ };
41
+
42
+ // src/shared/dns.ts
43
+ import {
44
+ ComponentResource,
45
+ output as output2
46
+ } from "@highstate/pulumi";
47
+
48
+ // ../../node_modules/remeda/dist/chunk-D6FCK2GA.js
49
+ function u(o, n2, a) {
50
+ let t = (r) => o(r, ...n2);
51
+ return a === void 0 ? t : Object.assign(t, { lazy: a, lazyArgs: n2 });
52
+ }
53
+
54
+ // ../../node_modules/remeda/dist/chunk-WIMGWYZL.js
55
+ function u2(r, n2, o) {
56
+ let a = r.length - n2.length;
57
+ if (a === 0) return r(...n2);
58
+ if (a === 1) return u(r, n2, o);
59
+ throw new Error("Wrong number of arguments");
60
+ }
61
+
62
+ // ../../node_modules/remeda/dist/chunk-VG2NVNXT.js
63
+ function n(...t) {
64
+ return u2(e, t);
65
+ }
66
+ var e = (t) => `${t[0]?.toUpperCase() ?? ""}${t.slice(1)}`;
67
+
68
+ // src/shared/dns.ts
69
+ var DnsRecord = class extends ComponentResource {
70
+ /**
71
+ * The underlying dns record resource.
72
+ */
73
+ dnsRecord;
74
+ constructor(name, args, opts) {
75
+ super("highstate:common:DnsRecord", name, args, opts);
76
+ this.dnsRecord = output2(args).apply((args2) => {
77
+ return output2(this.create(name, args2, { ...opts, parent: this }));
78
+ });
79
+ this.registerOutputs({ dnsRecord: this.dnsRecord });
80
+ }
81
+ static create(name, args, opts) {
82
+ return output2(args).apply(async (args2) => {
83
+ const providerType = args2.provider.type;
84
+ const implName = `${n(providerType)}DnsRecord`;
85
+ const implModule = await import(`@highstate/${providerType}`);
86
+ const implClass = implModule[implName];
87
+ return new implClass(name, args2, opts);
88
+ });
89
+ }
90
+ };
91
+
92
+ // src/shared/passwords.ts
93
+ import { randomBytes } from "@noble/hashes/utils";
94
+ import { secureMask } from "micro-key-producer/password.js";
95
+ function generatePassword() {
96
+ return secureMask.apply(randomBytes(32)).password;
97
+ }
98
+
99
+ // src/shared/ssh.ts
100
+ import { getUnitInstanceName } from "@highstate/pulumi";
101
+ function createSshTerminal(server) {
102
+ const command = ["ssh", "-tt", "-o", "StrictHostKeyChecking=no"];
103
+ if (server.sshCredentials?.port) {
104
+ command.push("-p", server.sshCredentials.port.toString());
105
+ }
106
+ if (server.sshCredentials?.privateKey) {
107
+ command.push("-i", "/private-key");
108
+ }
109
+ const endpoint = server.sshCredentials?.endpoint ?? server.endpoint;
110
+ const user = server.sshCredentials?.user ?? "root";
111
+ command.push(`${user}@${endpoint}`);
112
+ if (server.sshCredentials?.password) {
113
+ command.unshift("sshpass", "-f", "/password");
114
+ }
115
+ return {
116
+ name: "ssh",
117
+ title: `SSH: ${getUnitInstanceName()}`,
118
+ description: "Connect to the server via SSH",
119
+ image: "ghcr.io/exeteres/highstate/terminal-ssh",
120
+ command,
121
+ files: {
122
+ "/password": server.sshCredentials?.password,
123
+ "/private-key": {
124
+ content: server.sshCredentials?.privateKey,
125
+ mode: 384
126
+ }
127
+ }
128
+ };
129
+ }
130
+
131
+ export {
132
+ getServerConnection,
133
+ Server,
134
+ DnsRecord,
135
+ generatePassword,
136
+ createSshTerminal
137
+ };
138
+ //# sourceMappingURL=chunk-M5AC7PLD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shared/server.ts","../src/shared/dns.ts","../../../node_modules/remeda/dist/chunk-D6FCK2GA.js","../../../node_modules/remeda/dist/chunk-WIMGWYZL.js","../../../node_modules/remeda/dist/chunk-VG2NVNXT.js","../src/shared/passwords.ts","../src/shared/ssh.ts"],"sourcesContent":["import { remote, type types } from \"@pulumi/command\"\nimport { output, Resource, type Input, type InputOrArray, type Output } from \"@highstate/pulumi\"\nimport { common } from \"@highstate/library\"\n\nexport function getServerConnection(\n server: Input<common.Server>,\n): Output<types.input.remote.ConnectionArgs> {\n return output(server).apply(server => ({\n host: server.endpoint,\n port: server.sshCredentials?.port ?? 22,\n user: server.sshCredentials?.user ?? \"root\",\n password: server.sshCredentials?.password,\n privateKey: server.sshCredentials?.privateKey,\n dialErrorLimit: 3,\n }))\n}\n\nexport interface CommandOptions {\n id: string\n create: Input<string>\n update?: Input<string>\n delete?: Input<string>\n dependsOn?: InputOrArray<Resource>\n}\n\nexport class Server {\n public readonly server: Output<common.Server>\n public readonly connection: Output<types.input.remote.ConnectionArgs>\n\n public get endpoint(): Output<string> {\n return this.server.endpoint\n }\n\n public get hostname(): Output<string> {\n return this.server.hostname\n }\n\n constructor(server: Input<common.Server>) {\n this.server = output(server)\n this.connection = getServerConnection(this.server)\n }\n\n public command(options: CommandOptions): remote.Command {\n return new remote.Command(\n options.id,\n {\n connection: this.connection,\n create: options.create,\n update: options.update,\n delete: options.delete,\n },\n { dependsOn: options.dependsOn },\n )\n }\n}\n","import type { dns } from \"@highstate/library\"\nimport {\n ComponentResource,\n output,\n Output,\n Resource,\n type Input,\n type ResourceOptions,\n type Unwrap,\n} from \"@highstate/pulumi\"\nimport { capitalize } from \"remeda\"\n\nexport type DnsRecordArgs = {\n /**\n * The DNS provider to use.\n */\n provider: Input<dns.Provider>\n\n /**\n * The name of the DNS record.\n * If not provided, the name of the resource will be used.\n */\n name?: Input<string>\n\n /**\n * The type of the DNS record.\n */\n type: Input<string>\n\n /**\n * The value of the DNS record.\n */\n value: Input<string>\n\n /**\n * Whether the DNS record is proxied (e.g. to provide DDoS protection).\n *\n * Available only for public IPs and some DNS providers like Cloudflare.\n * If not supported, the DNS provider will ignore this value.\n */\n proxied?: Input<boolean>\n}\n\nexport abstract class DnsRecord extends ComponentResource {\n /**\n * The underlying dns record resource.\n */\n public readonly dnsRecord: Output<Resource>\n\n constructor(name: string, args: DnsRecordArgs, opts?: ResourceOptions) {\n super(\"highstate:common:DnsRecord\", name, args, opts)\n\n this.dnsRecord = output(args).apply(args => {\n return output(this.create(name, args, { ...opts, parent: this }))\n })\n\n this.registerOutputs({ dnsRecord: this.dnsRecord })\n }\n\n protected abstract create(\n name: string,\n args: Unwrap<DnsRecordArgs>,\n opts?: ResourceOptions,\n ): Input<Resource>\n\n static create(name: string, args: DnsRecordArgs, opts?: ResourceOptions): Output<DnsRecord> {\n return output(args).apply(async args => {\n const providerType = args.provider.type\n const implName = `${capitalize(providerType)}DnsRecord`\n const implModule = (await import(`@highstate/${providerType}`)) as Record<string, unknown>\n\n const implClass = implModule[implName] as new (\n name: string,\n args: Unwrap<DnsRecordArgs>,\n opts?: ResourceOptions,\n ) => DnsRecord\n\n return new implClass(name, args, opts)\n })\n }\n}\n","function u(o,n,a){let t=r=>o(r,...n);return a===void 0?t:Object.assign(t,{lazy:a,lazyArgs:n})}export{u as a};\n","import{a as t}from\"./chunk-D6FCK2GA.js\";function u(r,n,o){let a=r.length-n.length;if(a===0)return r(...n);if(a===1)return t(r,n,o);throw new Error(\"Wrong number of arguments\")}export{u as a};\n","import{a as i}from\"./chunk-WIMGWYZL.js\";function n(...t){return i(e,t)}var e=t=>`${t[0]?.toUpperCase()??\"\"}${t.slice(1)}`;export{n as a};\n","import { randomBytes } from \"@noble/hashes/utils\"\nimport { secureMask } from \"micro-key-producer/password.js\"\n\nexport function generatePassword() {\n return secureMask.apply(randomBytes(32)).password\n}\n","import type { common } from \"@highstate/library\"\nimport { getUnitInstanceName, type InstanceTerminal } from \"@highstate/pulumi\"\n\nexport function createSshTerminal(server: common.Server): InstanceTerminal {\n const command = [\"ssh\", \"-tt\", \"-o\", \"StrictHostKeyChecking=no\"]\n\n if (server.sshCredentials?.port) {\n command.push(\"-p\", server.sshCredentials.port.toString())\n }\n\n if (server.sshCredentials?.privateKey) {\n command.push(\"-i\", \"/private-key\")\n }\n\n const endpoint = server.sshCredentials?.endpoint ?? server.endpoint\n const user = server.sshCredentials?.user ?? \"root\"\n\n command.push(`${user}@${endpoint}`)\n\n if (server.sshCredentials?.password) {\n command.unshift(\"sshpass\", \"-f\", \"/password\")\n }\n\n return {\n name: \"ssh\",\n title: `SSH: ${getUnitInstanceName()}`,\n description: \"Connect to the server via SSH\",\n image: \"ghcr.io/exeteres/highstate/terminal-ssh\",\n command,\n\n files: {\n \"/password\": server.sshCredentials?.password,\n\n \"/private-key\": {\n content: server.sshCredentials?.privateKey,\n mode: 0o600,\n },\n },\n }\n}\n"],"mappings":"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","names":["server","output","n","u","n","u","output","args"]}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,13 +1,14 @@
1
- import { common } from '@highstate/library';
2
- import { forUnit, output } from '@highstate/pulumi';
3
- import { remote } from '@pulumi/command';
4
- import '@noble/hashes/utils';
5
- import 'micro-key-producer/password.js';
6
- import { c as createSshTerminal } from '../ssh-CNgI5FJI.js';
1
+ import {
2
+ createSshTerminal
3
+ } from "../chunk-M5AC7PLD.js";
7
4
 
8
- const { args, inputs, secrets, outputs } = forUnit(common.existingServer);
9
- const privateKey = inputs.sshKeyPair?.privateKey ?? secrets.sshPrivateKey;
10
- const hostnameResult = new remote.Command("hostname", {
5
+ // src/existing-server/index.ts
6
+ import { common } from "@highstate/library";
7
+ import { forUnit, output } from "@highstate/pulumi";
8
+ import { remote } from "@pulumi/command";
9
+ var { args, inputs, secrets, outputs } = forUnit(common.existingServer);
10
+ var privateKey = inputs.sshKeyPair?.privateKey ?? secrets.sshPrivateKey;
11
+ var hostnameResult = new remote.Command("hostname", {
11
12
  connection: output({
12
13
  host: args.endpoint,
13
14
  port: args.sshPort,
@@ -19,8 +20,8 @@ const hostnameResult = new remote.Command("hostname", {
19
20
  create: "hostname",
20
21
  triggers: [Date.now()]
21
22
  });
22
- const hostname = hostnameResult.stdout.apply((x) => x.trim());
23
- const server = output({
23
+ var hostname = hostnameResult.stdout.apply((x) => x.trim());
24
+ var server = output({
24
25
  endpoint: args.endpoint,
25
26
  hostname,
26
27
  sshCredentials: {
@@ -30,7 +31,7 @@ const server = output({
30
31
  privateKey
31
32
  }
32
33
  });
33
- var index = outputs({
34
+ var existing_server_default = outputs({
34
35
  server,
35
36
  $status: {
36
37
  hostname: {
@@ -41,5 +42,7 @@ var index = outputs({
41
42
  ssh: server.apply(createSshTerminal)
42
43
  }
43
44
  });
44
-
45
- export { index as default };
45
+ export {
46
+ existing_server_default as default
47
+ };
48
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/existing-server/index.ts"],"sourcesContent":["import { common } from \"@highstate/library\"\nimport { forUnit, Output, output } from \"@highstate/pulumi\"\nimport { remote } from \"@pulumi/command\"\nimport { createSshTerminal } from \"../shared\"\n\nconst { args, inputs, secrets, outputs } = forUnit(common.existingServer)\n\nconst privateKey = inputs.sshKeyPair?.privateKey ?? secrets.sshPrivateKey\n\nconst hostnameResult = new remote.Command(\"hostname\", {\n connection: output({\n host: args.endpoint,\n port: args.sshPort,\n user: args.sshUser,\n password: secrets.sshPassword,\n privateKey,\n dialErrorLimit: 3,\n }),\n create: \"hostname\",\n triggers: [Date.now()],\n})\n\nconst hostname = hostnameResult.stdout.apply(x => x.trim())\n\nconst server: Output<common.Server> = output({\n endpoint: args.endpoint,\n hostname,\n sshCredentials: {\n user: args.sshUser,\n port: args.sshPort,\n password: secrets.sshPassword,\n privateKey,\n },\n})\n\nexport default outputs({\n server,\n $status: {\n hostname: {\n value: hostname,\n },\n },\n $terminals: {\n ssh: server.apply(createSshTerminal),\n },\n})\n"],"mappings":";;;;;AAAA,SAAS,cAAc;AACvB,SAAS,SAAiB,cAAc;AACxC,SAAS,cAAc;AAGvB,IAAM,EAAE,MAAM,QAAQ,SAAS,QAAQ,IAAI,QAAQ,OAAO,cAAc;AAExE,IAAM,aAAa,OAAO,YAAY,cAAc,QAAQ;AAE5D,IAAM,iBAAiB,IAAI,OAAO,QAAQ,YAAY;AAAA,EACpD,YAAY,OAAO;AAAA,IACjB,MAAM,KAAK;AAAA,IACX,MAAM,KAAK;AAAA,IACX,MAAM,KAAK;AAAA,IACX,UAAU,QAAQ;AAAA,IAClB;AAAA,IACA,gBAAgB;AAAA,EAClB,CAAC;AAAA,EACD,QAAQ;AAAA,EACR,UAAU,CAAC,KAAK,IAAI,CAAC;AACvB,CAAC;AAED,IAAM,WAAW,eAAe,OAAO,MAAM,OAAK,EAAE,KAAK,CAAC;AAE1D,IAAM,SAAgC,OAAO;AAAA,EAC3C,UAAU,KAAK;AAAA,EACf;AAAA,EACA,gBAAgB;AAAA,IACd,MAAM,KAAK;AAAA,IACX,MAAM,KAAK;AAAA,IACX,UAAU,QAAQ;AAAA,IAClB;AAAA,EACF;AACF,CAAC;AAED,IAAO,0BAAQ,QAAQ;AAAA,EACrB;AAAA,EACA,SAAS;AAAA,IACP,UAAU;AAAA,MACR,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,YAAY;AAAA,IACV,KAAK,OAAO,MAAM,iBAAiB;AAAA,EACrC;AACF,CAAC;","names":[]}
@@ -0,0 +1,8 @@
1
+ {
2
+ "sourceHashes": {
3
+ "./dist/index.js": "253ad5381ecccf003daf18f14d0f0a23c799be580eadd9cf071a93a444e092dd",
4
+ "./dist/dns/record/index.js": "e4f4558eaa29c589553e0c99b2f12e29e55e3db434977685b4f0e033e5666ac3",
5
+ "./dist/existing-server/index.js": "1870e7a49741f1a66edce3b2c8b65eac31a6b977afec81441be7ec2a1c048954",
6
+ "./dist/ssh/key-pair/index.js": "1d2674a104fc8419405c820ffe00986940806e3c999a992ef9feea2c69ee66b8"
7
+ }
8
+ }
package/dist/index.js CHANGED
@@ -1,89 +1,15 @@
1
- import { remote } from '@pulumi/command';
2
- import { output, ComponentResource } from '@highstate/pulumi';
3
- import '@highstate/library';
4
- import { randomBytes } from '@noble/hashes/utils';
5
- import { secureMask } from 'micro-key-producer/password.js';
6
- export { c as createSshTerminal } from './ssh-CNgI5FJI.js';
7
-
8
- function getServerConnection(server) {
9
- return output(server).apply((server2) => ({
10
- host: server2.endpoint,
11
- port: server2.sshCredentials?.port ?? 22,
12
- user: server2.sshCredentials?.user ?? "root",
13
- password: server2.sshCredentials?.password,
14
- privateKey: server2.sshCredentials?.privateKey,
15
- dialErrorLimit: 3
16
- }));
17
- }
18
- class Server {
19
- server;
20
- connection;
21
- get endpoint() {
22
- return this.server.endpoint;
23
- }
24
- get hostname() {
25
- return this.server.hostname;
26
- }
27
- constructor(server) {
28
- this.server = output(server);
29
- this.connection = getServerConnection(this.server);
30
- }
31
- command(options) {
32
- return new remote.Command(
33
- options.id,
34
- {
35
- connection: this.connection,
36
- create: options.create,
37
- update: options.update,
38
- delete: options.delete
39
- },
40
- { dependsOn: options.dependsOn }
41
- );
42
- }
43
- }
44
-
45
- function u$1(o, n, a) {
46
- let t = (r) => o(r, ...n);
47
- return a === void 0 ? t : Object.assign(t, { lazy: a, lazyArgs: n });
48
- }
49
-
50
- function u(r, n, o) {
51
- let a = r.length - n.length;
52
- if (a === 0) return r(...n);
53
- if (a === 1) return u$1(r, n, o);
54
- throw new Error("Wrong number of arguments");
55
- }
56
-
57
- function n(...t) {
58
- return u(e, t);
59
- }
60
- var e = (t) => `${t[0]?.toUpperCase() ?? ""}${t.slice(1)}`;
61
-
62
- class DnsRecord extends ComponentResource {
63
- /**
64
- * The underlying dns record resource.
65
- */
66
- dnsRecord;
67
- constructor(name, args, opts) {
68
- super("highstate:common:DnsRecord", name, args, opts);
69
- this.dnsRecord = output(args).apply((args2) => {
70
- return output(this.create(name, args2, { ...opts, parent: this }));
71
- });
72
- this.registerOutputs({ dnsRecord: this.dnsRecord });
73
- }
74
- static create(name, args, opts) {
75
- return output(args).apply(async (args2) => {
76
- const providerType = args2.provider.type;
77
- const implName = `${n(providerType)}DnsRecord`;
78
- const implModule = await import(`@highstate/${providerType}`);
79
- const implClass = implModule[implName];
80
- return new implClass(name, args2, opts);
81
- });
82
- }
83
- }
84
-
85
- function generatePassword() {
86
- return secureMask.apply(randomBytes(32)).password;
87
- }
88
-
89
- export { DnsRecord, Server, generatePassword, getServerConnection };
1
+ import {
2
+ DnsRecord,
3
+ Server,
4
+ createSshTerminal,
5
+ generatePassword,
6
+ getServerConnection
7
+ } from "./chunk-M5AC7PLD.js";
8
+ export {
9
+ DnsRecord,
10
+ Server,
11
+ createSshTerminal,
12
+ generatePassword,
13
+ getServerConnection
14
+ };
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,10 +1,10 @@
1
- import { ssh } from '@highstate/library';
2
- import { forUnit, getOrCreateSecret, unsecret } from '@highstate/pulumi';
3
- import { getKeys, PrivateExport } from 'micro-key-producer/ssh.js';
4
- import { randomBytes } from 'micro-key-producer/utils.js';
5
-
6
- const { secrets, outputs } = forUnit(ssh.keyPair);
7
- const privateKey = getOrCreateSecret(secrets, "privateKey", () => {
1
+ // src/ssh/key-pair/index.ts
2
+ import { ssh } from "@highstate/library";
3
+ import { forUnit, getOrCreateSecret, unsecret } from "@highstate/pulumi";
4
+ import { getKeys, PrivateExport } from "micro-key-producer/ssh.js";
5
+ import { randomBytes } from "micro-key-producer/utils.js";
6
+ var { secrets, outputs } = forUnit(ssh.keyPair);
7
+ var privateKey = getOrCreateSecret(secrets, "privateKey", () => {
8
8
  const seed = randomBytes(32);
9
9
  return getKeys(seed).privateKey;
10
10
  });
@@ -13,8 +13,8 @@ function getKeysFromString(privateKey2) {
13
13
  const privKey = privateKeyStruct.keys[0].privKey.privKey;
14
14
  return getKeys(privKey.slice(0, 32));
15
15
  }
16
- const keys = privateKey.apply(getKeysFromString);
17
- var index = outputs({
16
+ var keys = privateKey.apply(getKeysFromString);
17
+ var key_pair_default = outputs({
18
18
  keyPair: {
19
19
  type: "ed25519",
20
20
  privateKey: keys.privateKey,
@@ -29,5 +29,7 @@ var index = outputs({
29
29
  }
30
30
  }
31
31
  });
32
-
33
- export { index as default };
32
+ export {
33
+ key_pair_default as default
34
+ };
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/ssh/key-pair/index.ts"],"sourcesContent":["import { ssh } from \"@highstate/library\"\nimport { forUnit, getOrCreateSecret, unsecret } from \"@highstate/pulumi\"\nimport { getKeys, PrivateExport } from \"micro-key-producer/ssh.js\"\nimport { randomBytes } from \"micro-key-producer/utils.js\"\n\nconst { secrets, outputs } = forUnit(ssh.keyPair)\n\nconst privateKey = getOrCreateSecret(secrets, \"privateKey\", () => {\n const seed = randomBytes(32)\n\n return getKeys(seed).privateKey\n})\n\nfunction getKeysFromString(privateKey: string) {\n const privateKeyStruct = PrivateExport.decode(privateKey)\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const privKey = privateKeyStruct.keys[0].privKey.privKey as Uint8Array\n\n return getKeys(privKey.slice(0, 32))\n}\n\nconst keys = privateKey.apply(getKeysFromString)\n\nexport default outputs({\n keyPair: {\n type: \"ed25519\",\n privateKey: keys.privateKey,\n publicKey: unsecret(keys.publicKey),\n },\n $status: {\n fingerprint: {\n value: unsecret(keys.fingerprint),\n },\n publicKey: {\n value: unsecret(keys.publicKey),\n },\n },\n})\n"],"mappings":";AAAA,SAAS,WAAW;AACpB,SAAS,SAAS,mBAAmB,gBAAgB;AACrD,SAAS,SAAS,qBAAqB;AACvC,SAAS,mBAAmB;AAE5B,IAAM,EAAE,SAAS,QAAQ,IAAI,QAAQ,IAAI,OAAO;AAEhD,IAAM,aAAa,kBAAkB,SAAS,cAAc,MAAM;AAChE,QAAM,OAAO,YAAY,EAAE;AAE3B,SAAO,QAAQ,IAAI,EAAE;AACvB,CAAC;AAED,SAAS,kBAAkBA,aAAoB;AAC7C,QAAM,mBAAmB,cAAc,OAAOA,WAAU;AAGxD,QAAM,UAAU,iBAAiB,KAAK,CAAC,EAAE,QAAQ;AAEjD,SAAO,QAAQ,QAAQ,MAAM,GAAG,EAAE,CAAC;AACrC;AAEA,IAAM,OAAO,WAAW,MAAM,iBAAiB;AAE/C,IAAO,mBAAQ,QAAQ;AAAA,EACrB,SAAS;AAAA,IACP,MAAM;AAAA,IACN,YAAY,KAAK;AAAA,IACjB,WAAW,SAAS,KAAK,SAAS;AAAA,EACpC;AAAA,EACA,SAAS;AAAA,IACP,aAAa;AAAA,MACX,OAAO,SAAS,KAAK,WAAW;AAAA,IAClC;AAAA,IACA,WAAW;AAAA,MACT,OAAO,SAAS,KAAK,SAAS;AAAA,IAChC;AAAA,EACF;AACF,CAAC;","names":["privateKey"]}
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@highstate/common",
3
- "version": "0.7.1",
3
+ "version": "0.7.3",
4
4
  "type": "module",
5
5
  "files": [
6
- "dist"
6
+ "dist",
7
+ "src"
7
8
  ],
8
- "module": "dist/index.js",
9
- "types": "dist/index.d.ts",
10
9
  "exports": {
11
10
  ".": {
12
- "import": "./dist/index.js",
13
- "types": "./dist/index.d.ts"
11
+ "types": "./src/index.ts",
12
+ "default": "./dist/index.js"
14
13
  },
14
+ "./dns/record": "./dist/dns/record/index.js",
15
15
  "./existing-server": "./dist/existing-server/index.js",
16
16
  "./ssh/key-pair": "./dist/ssh/key-pair/index.js"
17
17
  },
@@ -19,10 +19,10 @@
19
19
  "access": "public"
20
20
  },
21
21
  "scripts": {
22
- "build": "pkgroll --tsconfig=tsconfig.build.json"
22
+ "build": "highstate build"
23
23
  },
24
24
  "dependencies": {
25
- "@highstate/pulumi": "^0.7.1",
25
+ "@highstate/pulumi": "^0.7.3",
26
26
  "@noble/hashes": "^1.7.1",
27
27
  "@pulumi/command": "^1.0.2",
28
28
  "micro-key-producer": "^0.7.3"
@@ -31,7 +31,7 @@
31
31
  "@highstate/library": "workspace:^0.4.4"
32
32
  },
33
33
  "devDependencies": {
34
- "pkgroll": "^2.5.1"
34
+ "@highstate/cli": "^0.7.3"
35
35
  },
36
- "gitHead": "76c38ce5dbf7a710cf0e6339f52e86358537a99a"
36
+ "gitHead": "5cf7cec27262c8fa1d96f6478833b94841459d64"
37
37
  }
File without changes
@@ -0,0 +1,46 @@
1
+ import { common } from "@highstate/library"
2
+ import { forUnit, Output, output } from "@highstate/pulumi"
3
+ import { remote } from "@pulumi/command"
4
+ import { createSshTerminal } from "../shared"
5
+
6
+ const { args, inputs, secrets, outputs } = forUnit(common.existingServer)
7
+
8
+ const privateKey = inputs.sshKeyPair?.privateKey ?? secrets.sshPrivateKey
9
+
10
+ const hostnameResult = new remote.Command("hostname", {
11
+ connection: output({
12
+ host: args.endpoint,
13
+ port: args.sshPort,
14
+ user: args.sshUser,
15
+ password: secrets.sshPassword,
16
+ privateKey,
17
+ dialErrorLimit: 3,
18
+ }),
19
+ create: "hostname",
20
+ triggers: [Date.now()],
21
+ })
22
+
23
+ const hostname = hostnameResult.stdout.apply(x => x.trim())
24
+
25
+ const server: Output<common.Server> = output({
26
+ endpoint: args.endpoint,
27
+ hostname,
28
+ sshCredentials: {
29
+ user: args.sshUser,
30
+ port: args.sshPort,
31
+ password: secrets.sshPassword,
32
+ privateKey,
33
+ },
34
+ })
35
+
36
+ export default outputs({
37
+ server,
38
+ $status: {
39
+ hostname: {
40
+ value: hostname,
41
+ },
42
+ },
43
+ $terminals: {
44
+ ssh: server.apply(createSshTerminal),
45
+ },
46
+ })
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./shared"
@@ -0,0 +1,81 @@
1
+ import type { dns } from "@highstate/library"
2
+ import {
3
+ ComponentResource,
4
+ output,
5
+ Output,
6
+ Resource,
7
+ type Input,
8
+ type ResourceOptions,
9
+ type Unwrap,
10
+ } from "@highstate/pulumi"
11
+ import { capitalize } from "remeda"
12
+
13
+ export type DnsRecordArgs = {
14
+ /**
15
+ * The DNS provider to use.
16
+ */
17
+ provider: Input<dns.Provider>
18
+
19
+ /**
20
+ * The name of the DNS record.
21
+ * If not provided, the name of the resource will be used.
22
+ */
23
+ name?: Input<string>
24
+
25
+ /**
26
+ * The type of the DNS record.
27
+ */
28
+ type: Input<string>
29
+
30
+ /**
31
+ * The value of the DNS record.
32
+ */
33
+ value: Input<string>
34
+
35
+ /**
36
+ * Whether the DNS record is proxied (e.g. to provide DDoS protection).
37
+ *
38
+ * Available only for public IPs and some DNS providers like Cloudflare.
39
+ * If not supported, the DNS provider will ignore this value.
40
+ */
41
+ proxied?: Input<boolean>
42
+ }
43
+
44
+ export abstract class DnsRecord extends ComponentResource {
45
+ /**
46
+ * The underlying dns record resource.
47
+ */
48
+ public readonly dnsRecord: Output<Resource>
49
+
50
+ constructor(name: string, args: DnsRecordArgs, opts?: ResourceOptions) {
51
+ super("highstate:common:DnsRecord", name, args, opts)
52
+
53
+ this.dnsRecord = output(args).apply(args => {
54
+ return output(this.create(name, args, { ...opts, parent: this }))
55
+ })
56
+
57
+ this.registerOutputs({ dnsRecord: this.dnsRecord })
58
+ }
59
+
60
+ protected abstract create(
61
+ name: string,
62
+ args: Unwrap<DnsRecordArgs>,
63
+ opts?: ResourceOptions,
64
+ ): Input<Resource>
65
+
66
+ static create(name: string, args: DnsRecordArgs, opts?: ResourceOptions): Output<DnsRecord> {
67
+ return output(args).apply(async args => {
68
+ const providerType = args.provider.type
69
+ const implName = `${capitalize(providerType)}DnsRecord`
70
+ const implModule = (await import(`@highstate/${providerType}`)) as Record<string, unknown>
71
+
72
+ const implClass = implModule[implName] as new (
73
+ name: string,
74
+ args: Unwrap<DnsRecordArgs>,
75
+ opts?: ResourceOptions,
76
+ ) => DnsRecord
77
+
78
+ return new implClass(name, args, opts)
79
+ })
80
+ }
81
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./server"
2
+ export * from "./dns"
3
+ export * from "./passwords"
4
+ export * from "./ssh"
@@ -0,0 +1,6 @@
1
+ import { randomBytes } from "@noble/hashes/utils"
2
+ import { secureMask } from "micro-key-producer/password.js"
3
+
4
+ export function generatePassword() {
5
+ return secureMask.apply(randomBytes(32)).password
6
+ }
@@ -0,0 +1,55 @@
1
+ import { remote, type types } from "@pulumi/command"
2
+ import { output, Resource, type Input, type InputOrArray, type Output } from "@highstate/pulumi"
3
+ import { common } from "@highstate/library"
4
+
5
+ export function getServerConnection(
6
+ server: Input<common.Server>,
7
+ ): Output<types.input.remote.ConnectionArgs> {
8
+ return output(server).apply(server => ({
9
+ host: server.endpoint,
10
+ port: server.sshCredentials?.port ?? 22,
11
+ user: server.sshCredentials?.user ?? "root",
12
+ password: server.sshCredentials?.password,
13
+ privateKey: server.sshCredentials?.privateKey,
14
+ dialErrorLimit: 3,
15
+ }))
16
+ }
17
+
18
+ export interface CommandOptions {
19
+ id: string
20
+ create: Input<string>
21
+ update?: Input<string>
22
+ delete?: Input<string>
23
+ dependsOn?: InputOrArray<Resource>
24
+ }
25
+
26
+ export class Server {
27
+ public readonly server: Output<common.Server>
28
+ public readonly connection: Output<types.input.remote.ConnectionArgs>
29
+
30
+ public get endpoint(): Output<string> {
31
+ return this.server.endpoint
32
+ }
33
+
34
+ public get hostname(): Output<string> {
35
+ return this.server.hostname
36
+ }
37
+
38
+ constructor(server: Input<common.Server>) {
39
+ this.server = output(server)
40
+ this.connection = getServerConnection(this.server)
41
+ }
42
+
43
+ public command(options: CommandOptions): remote.Command {
44
+ return new remote.Command(
45
+ options.id,
46
+ {
47
+ connection: this.connection,
48
+ create: options.create,
49
+ update: options.update,
50
+ delete: options.delete,
51
+ },
52
+ { dependsOn: options.dependsOn },
53
+ )
54
+ }
55
+ }
@@ -0,0 +1,40 @@
1
+ import type { common } from "@highstate/library"
2
+ import { getUnitInstanceName, type InstanceTerminal } from "@highstate/pulumi"
3
+
4
+ export function createSshTerminal(server: common.Server): InstanceTerminal {
5
+ const command = ["ssh", "-tt", "-o", "StrictHostKeyChecking=no"]
6
+
7
+ if (server.sshCredentials?.port) {
8
+ command.push("-p", server.sshCredentials.port.toString())
9
+ }
10
+
11
+ if (server.sshCredentials?.privateKey) {
12
+ command.push("-i", "/private-key")
13
+ }
14
+
15
+ const endpoint = server.sshCredentials?.endpoint ?? server.endpoint
16
+ const user = server.sshCredentials?.user ?? "root"
17
+
18
+ command.push(`${user}@${endpoint}`)
19
+
20
+ if (server.sshCredentials?.password) {
21
+ command.unshift("sshpass", "-f", "/password")
22
+ }
23
+
24
+ return {
25
+ name: "ssh",
26
+ title: `SSH: ${getUnitInstanceName()}`,
27
+ description: "Connect to the server via SSH",
28
+ image: "ghcr.io/exeteres/highstate/terminal-ssh",
29
+ command,
30
+
31
+ files: {
32
+ "/password": server.sshCredentials?.password,
33
+
34
+ "/private-key": {
35
+ content: server.sshCredentials?.privateKey,
36
+ mode: 0o600,
37
+ },
38
+ },
39
+ }
40
+ }
@@ -0,0 +1,39 @@
1
+ import { ssh } from "@highstate/library"
2
+ import { forUnit, getOrCreateSecret, unsecret } from "@highstate/pulumi"
3
+ import { getKeys, PrivateExport } from "micro-key-producer/ssh.js"
4
+ import { randomBytes } from "micro-key-producer/utils.js"
5
+
6
+ const { secrets, outputs } = forUnit(ssh.keyPair)
7
+
8
+ const privateKey = getOrCreateSecret(secrets, "privateKey", () => {
9
+ const seed = randomBytes(32)
10
+
11
+ return getKeys(seed).privateKey
12
+ })
13
+
14
+ function getKeysFromString(privateKey: string) {
15
+ const privateKeyStruct = PrivateExport.decode(privateKey)
16
+
17
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
18
+ const privKey = privateKeyStruct.keys[0].privKey.privKey as Uint8Array
19
+
20
+ return getKeys(privKey.slice(0, 32))
21
+ }
22
+
23
+ const keys = privateKey.apply(getKeysFromString)
24
+
25
+ export default outputs({
26
+ keyPair: {
27
+ type: "ed25519",
28
+ privateKey: keys.privateKey,
29
+ publicKey: unsecret(keys.publicKey),
30
+ },
31
+ $status: {
32
+ fingerprint: {
33
+ value: unsecret(keys.fingerprint),
34
+ },
35
+ publicKey: {
36
+ value: unsecret(keys.publicKey),
37
+ },
38
+ },
39
+ })
package/dist/index.d.ts DELETED
@@ -1,62 +0,0 @@
1
- import { types, remote } from '@pulumi/command';
2
- import { Input, Output, InputOrArray, Resource, ComponentResource, ResourceOptions, Unwrap, InstanceTerminal } from '@highstate/pulumi';
3
- import { common } from '@highstate/library';
4
-
5
- declare function getServerConnection(server: Input<common.Server>): Output<types.input.remote.ConnectionArgs>;
6
- interface CommandOptions {
7
- id: string;
8
- create: Input<string>;
9
- update?: Input<string>;
10
- delete?: Input<string>;
11
- dependsOn?: InputOrArray<Resource>;
12
- }
13
- declare class Server {
14
- readonly server: Output<common.Server>;
15
- readonly connection: Output<types.input.remote.ConnectionArgs>;
16
- get endpoint(): Output<string>;
17
- get hostname(): Output<string>;
18
- constructor(server: Input<common.Server>);
19
- command(options: CommandOptions): remote.Command;
20
- }
21
-
22
- type DnsRecordArgs = {
23
- /**
24
- * The DNS provider to use.
25
- */
26
- provider: Input<common.DnsProvider>;
27
- /**
28
- * The name of the DNS record.
29
- * If not provided, the name of the resource will be used.
30
- */
31
- name?: Input<string>;
32
- /**
33
- * The type of the DNS record.
34
- */
35
- type: Input<string>;
36
- /**
37
- * The value of the DNS record.
38
- */
39
- value: Input<string>;
40
- /**
41
- * Whether the DNS record is proxied (e.g. to provide DDoS protection).
42
- *
43
- * Available only for public IPs and some DNS providers like Cloudflare.
44
- * If not supported, the DNS provider will ignore this value.
45
- */
46
- proxied?: Input<boolean>;
47
- };
48
- declare abstract class DnsRecord extends ComponentResource {
49
- /**
50
- * The underlying dns record resource.
51
- */
52
- readonly dnsRecord: Output<Resource>;
53
- constructor(name: string, args: DnsRecordArgs, opts?: ResourceOptions);
54
- protected abstract create(name: string, args: Unwrap<DnsRecordArgs>, opts?: ResourceOptions): Input<Resource>;
55
- static create(name: string, args: DnsRecordArgs, opts?: ResourceOptions): Output<DnsRecord>;
56
- }
57
-
58
- declare function generatePassword(): string;
59
-
60
- declare function createSshTerminal(server: common.Server): InstanceTerminal;
61
-
62
- export { type CommandOptions, DnsRecord, type DnsRecordArgs, Server, createSshTerminal, generatePassword, getServerConnection };
@@ -1,31 +0,0 @@
1
- function createSshTerminal(server) {
2
- const command = ["ssh", "-tt", "-o", "StrictHostKeyChecking=no"];
3
- if (server.sshCredentials?.port) {
4
- command.push("-p", server.sshCredentials.port.toString());
5
- }
6
- if (server.sshCredentials?.privateKey) {
7
- command.push("-i", "/private-key");
8
- }
9
- const endpoint = server.sshCredentials?.endpoint ?? server.endpoint;
10
- const user = server.sshCredentials?.user ?? "root";
11
- command.push(`${user}@${endpoint}`);
12
- if (server.sshCredentials?.password) {
13
- command.unshift("sshpass", "-f", "/password");
14
- }
15
- return {
16
- name: "ssh",
17
- title: "SSH",
18
- description: "Connect to the server via SSH.",
19
- image: "ghcr.io/exeteres/highstate/terminal-ssh",
20
- command,
21
- files: {
22
- "/password": server.sshCredentials?.password,
23
- "/private-key": {
24
- content: server.sshCredentials?.privateKey,
25
- mode: 384
26
- }
27
- }
28
- };
29
- }
30
-
31
- export { createSshTerminal as c };