@highstate/yandex 0.20.0 → 0.21.1

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,17 @@
1
+ // @bun
2
+ // src/provider.ts
3
+ import { output, toPromise } from "@highstate/pulumi";
4
+ import { Provider } from "@highstate/yandex-sdk";
5
+ async function createProvider(connection, cloudId) {
6
+ return await toPromise(output(connection).apply((connection2) => {
7
+ return new Provider(connection2.cloudId, {
8
+ serviceAccountKeyFile: connection2.authorizedKeyJson.value,
9
+ cloudId: cloudId ?? connection2.cloudId,
10
+ folderId: connection2.defaultFolderId,
11
+ zone: connection2.defaultZone,
12
+ regionId: connection2.regionId
13
+ });
14
+ }));
15
+ }
16
+
17
+ export { createProvider };
@@ -1,8 +1,8 @@
1
- import { yandex } from '@highstate/library';
2
- import { forUnit, toPromise, makeEntityOutput } from '@highstate/pulumi';
3
- import { Provider, getIamServiceAccount, getResourcemanagerFolder } from '@highstate/yandex-sdk';
4
-
1
+ // @bun
5
2
  // src/connection/index.ts
3
+ import { yandex } from "@highstate/library";
4
+ import { forUnit, makeEntityOutput, toPromise } from "@highstate/pulumi";
5
+ import { getIamServiceAccount, getResourcemanagerFolder, Provider } from "@highstate/yandex-sdk";
6
6
  var { args, secrets, outputs } = forUnit(yandex.connection);
7
7
  var serviceAccountKeyFileString = await toPromise(secrets.authorizedKeyJson);
8
8
  var keyFileData = JSON.parse(serviceAccountKeyFileString);
@@ -12,10 +12,7 @@ var provider = new Provider("yandex", {
12
12
  zone: args.region.defaultZone,
13
13
  regionId: args.region.id
14
14
  });
15
- var serviceAccount = await getIamServiceAccount(
16
- { serviceAccountId },
17
- { provider }
18
- );
15
+ var serviceAccount = await getIamServiceAccount({ serviceAccountId }, { provider });
19
16
  var folder = await getResourcemanagerFolder({ folderId: serviceAccount.folderId }, { provider });
20
17
  if (!folder.cloudId) {
21
18
  throw new Error("Could not determine cloud ID from folder");
@@ -53,7 +50,6 @@ var connection_default = outputs({
53
50
  }
54
51
  }
55
52
  });
56
-
57
- export { connection_default as default };
58
- //# sourceMappingURL=index.js.map
59
- //# sourceMappingURL=index.js.map
53
+ export {
54
+ connection_default as default
55
+ };
@@ -1,22 +1,22 @@
1
- import { createProvider } from '../chunk-ISIWD2MZ.js';
2
- import { yandex } from '@highstate/library';
3
- import { forUnit, getResourceComment, makeEntityOutput } from '@highstate/pulumi';
4
- import { ComputeDisk } from '@highstate/yandex-sdk';
1
+ // @bun
2
+ import {
3
+ createProvider
4
+ } from "../chunk-09r4wmhq.js";
5
5
 
6
+ // src/disk/index.ts
7
+ import { yandex } from "@highstate/library";
8
+ import { forUnit, getResourceComment, makeEntityOutput } from "@highstate/pulumi";
9
+ import { ComputeDisk } from "@highstate/yandex-sdk";
6
10
  var { name, args, inputs, outputs } = forUnit(yandex.disk);
7
11
  var provider = await createProvider(inputs.connection);
8
12
  var diskName = args.diskName ?? name;
9
- var disk = new ComputeDisk(
10
- "disk",
11
- {
12
- name: diskName,
13
- description: getResourceComment(),
14
- type: args.type,
15
- size: args.size,
16
- allowRecreate: false
17
- },
18
- { provider, protect: true }
19
- );
13
+ var disk = new ComputeDisk("disk", {
14
+ name: diskName,
15
+ description: getResourceComment(),
16
+ type: args.type,
17
+ size: args.size,
18
+ allowRecreate: false
19
+ }, { provider, protect: true });
20
20
  var disk_default = outputs({
21
21
  disk: makeEntityOutput({
22
22
  entity: yandex.diskEntity,
@@ -29,7 +29,6 @@ var disk_default = outputs({
29
29
  id: disk.id
30
30
  }
31
31
  });
32
-
33
- export { disk_default as default };
34
- //# sourceMappingURL=index.js.map
35
- //# sourceMappingURL=index.js.map
32
+ export {
33
+ disk_default as default
34
+ };
@@ -1,8 +1,12 @@
1
- import { createProvider } from '../chunk-ISIWD2MZ.js';
2
- import { yandex } from '@highstate/library';
3
- import { forUnit, makeEntityOutput } from '@highstate/pulumi';
4
- import { getComputeImage } from '@highstate/yandex-sdk';
1
+ // @bun
2
+ import {
3
+ createProvider
4
+ } from "../chunk-09r4wmhq.js";
5
5
 
6
+ // src/existing-image/index.ts
7
+ import { yandex } from "@highstate/library";
8
+ import { forUnit, makeEntityOutput } from "@highstate/pulumi";
9
+ import { getComputeImage } from "@highstate/yandex-sdk";
6
10
  var { args, inputs, outputs } = forUnit(yandex.existingImage);
7
11
  var provider = await createProvider(inputs.connection);
8
12
  var ycImage = await getComputeImage({ imageId: args.id }, { provider });
@@ -22,7 +26,6 @@ var existing_image_default = outputs({
22
26
  name: ycImage.name
23
27
  }
24
28
  });
25
-
26
- export { existing_image_default as default };
27
- //# sourceMappingURL=index.js.map
28
- //# sourceMappingURL=index.js.map
29
+ export {
30
+ existing_image_default as default
31
+ };
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "sourceHashes": {
3
- "./dist/connection/index.js": 1714431882,
4
- "./dist/disk/index.js": 3931067747,
5
- "./dist/existing-image/index.js": 2980200400,
6
- "./dist/virtual-machine/index.js": 2819876153,
7
- "./dist/instance-group/index.js": 3438885092
3
+ "./dist/connection/index.js": 1297805961,
4
+ "./dist/disk/index.js": 872672425,
5
+ "./dist/existing-image/index.js": 1667771667,
6
+ "./dist/virtual-machine/index.js": 1341835348,
7
+ "./dist/instance-group/index.js": 2144968854
8
8
  }
9
9
  }
@@ -1,10 +1,27 @@
1
- import { createProvider } from '../chunk-ISIWD2MZ.js';
2
- import { generateSshPrivateKey, sshPrivateKeyToKeyPair, generatePassword, parseEndpoint, createServerBundle, l3EndpointToString } from '@highstate/common';
3
- import { trimIndentation } from '@highstate/contract';
4
- import { yandex } from '@highstate/library';
5
- import { forUnit, toPromise, interpolate, getResourceComment } from '@highstate/pulumi';
6
- import { getVpcSubnet, KmsSymmetricKey, ComputeDisk, VpcAddress, ComputeInstanceGroup } from '@highstate/yandex-sdk';
1
+ // @bun
2
+ import {
3
+ createProvider
4
+ } from "../chunk-09r4wmhq.js";
7
5
 
6
+ // src/instance-group/index.ts
7
+ import {
8
+ createServerBundle,
9
+ generatePassword,
10
+ generateSshPrivateKey,
11
+ l3EndpointToString,
12
+ parseEndpoint,
13
+ sshPrivateKeyToKeyPair
14
+ } from "@highstate/common";
15
+ import { trimIndentation } from "@highstate/contract";
16
+ import { yandex } from "@highstate/library";
17
+ import { forUnit, getResourceComment, interpolate, toPromise } from "@highstate/pulumi";
18
+ import {
19
+ ComputeDisk,
20
+ ComputeInstanceGroup,
21
+ getVpcSubnet,
22
+ KmsSymmetricKey,
23
+ VpcAddress
24
+ } from "@highstate/yandex-sdk";
8
25
  var { name, args, getSecret, inputs, outputs } = forUnit(yandex.instanceGroup);
9
26
  var groupName = args.groupName ?? name;
10
27
  var provider = await createProvider(inputs.connection, args.cloudId);
@@ -13,78 +30,57 @@ var rootPassword = getSecret("rootPassword", generatePassword);
13
30
  var subnetId = args.network.subnetId;
14
31
  if (!subnetId) {
15
32
  const defaultSubnetName = await toPromise(interpolate`default-${inputs.connection.defaultZone}`);
16
- const subnet = await getVpcSubnet(
17
- {
18
- folderId: await toPromise(inputs.connection.defaultFolderId),
19
- name: defaultSubnetName
20
- },
21
- { provider }
22
- );
33
+ const subnet = await getVpcSubnet({
34
+ folderId: await toPromise(inputs.connection.defaultFolderId),
35
+ name: defaultSubnetName
36
+ }, { provider });
23
37
  if (!subnet.id) {
24
- throw new Error(
25
- `Could not find default subnet '${defaultSubnetName}' in zone ${inputs.connection.defaultZone}`
26
- );
38
+ throw new Error(`Could not find default subnet '${defaultSubnetName}' in zone ${inputs.connection.defaultZone}`);
27
39
  }
28
40
  subnetId = subnet.id;
29
41
  }
30
42
  var encryptionKeyId;
31
43
  if (args.bootDisk.encrypted) {
32
- const encryptionKey = new KmsSymmetricKey(
33
- "encryption-key",
34
- {
35
- name: groupName,
36
- description: getResourceComment(),
37
- folderId: args.folderId ?? inputs.connection.defaultFolderId
38
- },
39
- { provider }
40
- );
44
+ const encryptionKey = new KmsSymmetricKey("encryption-key", {
45
+ name: groupName,
46
+ description: getResourceComment(),
47
+ folderId: args.folderId ?? inputs.connection.defaultFolderId
48
+ }, { provider });
41
49
  encryptionKeyId = encryptionKey.id;
42
50
  }
43
51
  var disks = Array.from({ length: args.size }, (_, i) => {
44
- return new ComputeDisk(
45
- `disk-${i + 1}`,
46
- {
47
- name: `${groupName}-${i + 1}`,
48
- type: args.bootDisk.type,
49
- size: args.bootDisk.size,
50
- imageId: inputs.image.id,
51
- allowRecreate: false,
52
- folderId: args.folderId ?? inputs.connection.defaultFolderId,
53
- zone: inputs.connection.defaultZone,
54
- kmsKeyId: encryptionKeyId
55
- },
56
- { provider, ignoreChanges: ["imageId"] }
57
- );
52
+ return new ComputeDisk(`disk-${i + 1}`, {
53
+ name: `${groupName}-${i + 1}`,
54
+ type: args.bootDisk.type,
55
+ size: args.bootDisk.size,
56
+ imageId: inputs.image.id,
57
+ allowRecreate: false,
58
+ folderId: args.folderId ?? inputs.connection.defaultFolderId,
59
+ zone: inputs.connection.defaultZone,
60
+ kmsKeyId: encryptionKeyId
61
+ }, { provider, ignoreChanges: ["imageId"] });
58
62
  });
59
63
  var internalAddresses = Array.from({ length: args.size }, (_, i) => {
60
- return new VpcAddress(
61
- `internal-address-${i + 1}`,
62
- {
63
- name: `${groupName}-internal-${i + 1}`,
64
- folderId: args.folderId ?? inputs.connection.defaultFolderId,
65
- description: getResourceComment(),
66
- internalIpv4Address: {
67
- subnetId
68
- }
69
- },
70
- { provider }
71
- );
64
+ return new VpcAddress(`internal-address-${i + 1}`, {
65
+ name: `${groupName}-internal-${i + 1}`,
66
+ folderId: args.folderId ?? inputs.connection.defaultFolderId,
67
+ description: getResourceComment(),
68
+ internalIpv4Address: {
69
+ subnetId
70
+ }
71
+ }, { provider });
72
72
  });
73
73
  var publicAddresses;
74
74
  if (args.network.assignPublicIp && args.network.reservePublicIp) {
75
75
  publicAddresses = Array.from({ length: args.size }, (_, i) => {
76
- return new VpcAddress(
77
- `address-${i + 1}`,
78
- {
79
- name: `${groupName}-${i + 1}`,
80
- folderId: args.folderId ?? inputs.connection.defaultFolderId,
81
- description: getResourceComment(),
82
- externalIpv4Address: {
83
- zoneId: inputs.connection.defaultZone
84
- }
85
- },
86
- { provider }
87
- );
76
+ return new VpcAddress(`address-${i + 1}`, {
77
+ name: `${groupName}-${i + 1}`,
78
+ folderId: args.folderId ?? inputs.connection.defaultFolderId,
79
+ description: getResourceComment(),
80
+ externalIpv4Address: {
81
+ zoneId: inputs.connection.defaultZone
82
+ }
83
+ }, { provider });
88
84
  });
89
85
  }
90
86
  var userData = interpolate`
@@ -96,100 +92,90 @@ var userData = interpolate`
96
92
  - ${sshKeyPair.publicKey}
97
93
  sudo: ALL=(ALL) NOPASSWD:ALL
98
94
  `.apply(trimIndentation);
99
- var instanceGroup = new ComputeInstanceGroup(
100
- "instance-group",
101
- {
102
- name: groupName,
95
+ var instanceGroup = new ComputeInstanceGroup("instance-group", {
96
+ name: groupName,
97
+ description: getResourceComment(),
98
+ folderId: args.folderId ?? inputs.connection.defaultFolderId,
99
+ allocationPolicy: {
100
+ zones: [inputs.connection.defaultZone]
101
+ },
102
+ deployPolicy: {
103
+ maxExpansion: 0,
104
+ maxUnavailable: 1
105
+ },
106
+ scalePolicy: {
107
+ fixedScale: {
108
+ size: args.size
109
+ }
110
+ },
111
+ instanceTemplate: {
112
+ name: `${groupName}-{instance.index}`,
103
113
  description: getResourceComment(),
104
- folderId: args.folderId ?? inputs.connection.defaultFolderId,
105
- allocationPolicy: {
106
- zones: [inputs.connection.defaultZone]
114
+ platformId: args.platformId,
115
+ resources: {
116
+ cores: args.resources.cores,
117
+ memory: args.resources.memory,
118
+ coreFraction: args.resources.coreFraction
107
119
  },
108
- deployPolicy: {
109
- maxExpansion: 0,
110
- maxUnavailable: 1
120
+ schedulingPolicy: {
121
+ preemptible: args.preemptible
111
122
  },
112
- scalePolicy: {
113
- fixedScale: {
114
- size: args.size
115
- }
123
+ bootDisk: {
124
+ diskId: `{disk_{instance.index}}`
116
125
  },
117
- instanceTemplate: {
118
- name: `${groupName}-{instance.index}`,
119
- description: getResourceComment(),
120
- platformId: args.platformId,
121
- resources: {
122
- cores: args.resources.cores,
123
- memory: args.resources.memory,
124
- coreFraction: args.resources.coreFraction
125
- },
126
- schedulingPolicy: {
127
- preemptible: args.preemptible
128
- },
129
- bootDisk: {
130
- diskId: `{disk_{instance.index}}`
131
- },
132
- networkInterfaces: [
133
- {
134
- subnetIds: [subnetId],
135
- ipAddress: `{internal_address_{instance.index}}`,
136
- nat: args.network.assignPublicIp,
137
- natIpAddress: publicAddresses ? `{address_{instance.index}}` : void 0
138
- }
139
- ],
140
- metadata: {
141
- "user-data": userData
126
+ networkInterfaces: [
127
+ {
128
+ subnetIds: [subnetId],
129
+ ipAddress: `{internal_address_{instance.index}}`,
130
+ nat: args.network.assignPublicIp,
131
+ natIpAddress: publicAddresses ? `{address_{instance.index}}` : undefined
142
132
  }
143
- },
144
- variables: {
145
- ...Object.fromEntries(disks.map((_, i) => [`disk_${i + 1}`, disks[i].id])),
146
- ...Object.fromEntries(
147
- internalAddresses.map((_, i) => [
148
- `internal_address_${i + 1}`,
149
- internalAddresses[i].internalIpv4Address.apply((a) => a.address)
150
- ])
151
- ),
152
- ...publicAddresses ? Object.fromEntries(
153
- publicAddresses.map((_, i) => [
154
- `address_${i + 1}`,
155
- publicAddresses[i].externalIpv4Address.apply((a) => a.address)
156
- ])
157
- ) : {}
158
- },
159
- serviceAccountId: inputs.connection.serviceAccountId
133
+ ],
134
+ metadata: {
135
+ "user-data": userData
136
+ }
137
+ },
138
+ variables: {
139
+ ...Object.fromEntries(disks.map((_, i) => [`disk_${i + 1}`, disks[i].id])),
140
+ ...Object.fromEntries(internalAddresses.map((_, i) => [
141
+ `internal_address_${i + 1}`,
142
+ internalAddresses[i].internalIpv4Address.apply((a) => a.address)
143
+ ])),
144
+ ...publicAddresses ? Object.fromEntries(publicAddresses.map((_, i) => [
145
+ `address_${i + 1}`,
146
+ publicAddresses[i].externalIpv4Address.apply((a) => a.address)
147
+ ])) : {}
160
148
  },
161
- { provider }
162
- );
149
+ serviceAccountId: inputs.connection.serviceAccountId
150
+ }, { provider });
163
151
  var terminals = [];
164
152
  var instances = await toPromise(instanceGroup.instances);
165
- var servers = await toPromise(
166
- instances.map(async (instance, i) => {
167
- const firstInterface = instance.networkInterfaces[0];
168
- const publicIp = args.network.assignPublicIp ? firstInterface?.natIpAddress : firstInterface?.ipAddress;
169
- if (!publicIp) {
170
- throw new Error("No IP address assigned to instance");
171
- }
172
- const endpoint = parseEndpoint(publicIp, 3);
173
- const { server, terminal } = await createServerBundle({
174
- name: `${groupName}-${i + 1}`,
175
- endpoints: [endpoint],
176
- sshArgs: args.ssh,
177
- sshPassword: rootPassword,
178
- sshKeyPair
153
+ var servers = await toPromise(instances.map(async (instance, i) => {
154
+ const firstInterface = instance.networkInterfaces[0];
155
+ const publicIp = args.network.assignPublicIp ? firstInterface?.natIpAddress : firstInterface?.ipAddress;
156
+ if (!publicIp) {
157
+ throw new Error("No IP address assigned to instance");
158
+ }
159
+ const endpoint = parseEndpoint(publicIp, 3);
160
+ const { server, terminal } = await createServerBundle({
161
+ name: `${groupName}-${i + 1}`,
162
+ endpoints: [endpoint],
163
+ sshArgs: args.ssh,
164
+ sshPassword: rootPassword,
165
+ sshKeyPair
166
+ });
167
+ if (terminal) {
168
+ const rawTerminal = await toPromise(terminal);
169
+ terminals.push({
170
+ ...rawTerminal,
171
+ name: `ssh-${i + 1}`,
172
+ meta: {
173
+ title: `Shell (${i + 1})`
174
+ }
179
175
  });
180
- if (terminal) {
181
- const rawTerminal = await toPromise(terminal);
182
- terminals.push({
183
- ...rawTerminal,
184
- name: `ssh-${i + 1}`,
185
- meta: {
186
- title: `Shell (${i + 1})`
187
- }
188
- });
189
- }
190
- return server;
191
- })
192
- );
176
+ }
177
+ return server;
178
+ }));
193
179
  var instance_group_default = outputs({
194
180
  servers,
195
181
  $statusFields: {
@@ -198,7 +184,6 @@ var instance_group_default = outputs({
198
184
  },
199
185
  $terminals: terminals
200
186
  });
201
-
202
- export { instance_group_default as default };
203
- //# sourceMappingURL=index.js.map
204
- //# sourceMappingURL=index.js.map
187
+ export {
188
+ instance_group_default as default
189
+ };
@@ -1,10 +1,27 @@
1
- import { createProvider } from '../chunk-ISIWD2MZ.js';
2
- import { generateSshPrivateKey, sshPrivateKeyToKeyPair, generatePassword, parseEndpoint, createServerBundle, l3EndpointToString } from '@highstate/common';
3
- import { trimIndentation } from '@highstate/contract';
4
- import { yandex } from '@highstate/library';
5
- import { forUnit, toPromise, interpolate, getResourceComment } from '@highstate/pulumi';
6
- import { getVpcSubnet, KmsSymmetricKey, ComputeDisk, VpcAddress, ComputeInstance } from '@highstate/yandex-sdk';
1
+ // @bun
2
+ import {
3
+ createProvider
4
+ } from "../chunk-09r4wmhq.js";
7
5
 
6
+ // src/virtual-machine/index.ts
7
+ import {
8
+ createServerBundle,
9
+ generatePassword,
10
+ generateSshPrivateKey,
11
+ l3EndpointToString,
12
+ parseEndpoint,
13
+ sshPrivateKeyToKeyPair
14
+ } from "@highstate/common";
15
+ import { trimIndentation } from "@highstate/contract";
16
+ import { yandex } from "@highstate/library";
17
+ import { forUnit, getResourceComment, interpolate, toPromise } from "@highstate/pulumi";
18
+ import {
19
+ ComputeDisk,
20
+ ComputeInstance,
21
+ getVpcSubnet,
22
+ KmsSymmetricKey,
23
+ VpcAddress
24
+ } from "@highstate/yandex-sdk";
8
25
  var { name, args, getSecret, inputs, outputs } = forUnit(yandex.virtualMachine);
9
26
  var vmName = args.vmName ?? name;
10
27
  var provider = await createProvider(inputs.connection, args.cloudId);
@@ -13,47 +30,34 @@ var rootPassword = getSecret("rootPassword", generatePassword);
13
30
  var subnetId = args.network.subnetId;
14
31
  if (!subnetId) {
15
32
  const defaultSubnetName = await toPromise(interpolate`default-${inputs.connection.defaultZone}`);
16
- const subnet = await getVpcSubnet(
17
- {
18
- folderId: await toPromise(inputs.connection.defaultFolderId),
19
- name: defaultSubnetName
20
- },
21
- { provider }
22
- );
33
+ const subnet = await getVpcSubnet({
34
+ folderId: await toPromise(inputs.connection.defaultFolderId),
35
+ name: defaultSubnetName
36
+ }, { provider });
23
37
  if (!subnet.id) {
24
- throw new Error(
25
- `Could not find default subnet '${defaultSubnetName}' in zone ${inputs.connection.defaultZone}`
26
- );
38
+ throw new Error(`Could not find default subnet '${defaultSubnetName}' in zone ${inputs.connection.defaultZone}`);
27
39
  }
28
40
  subnetId = subnet.id;
29
41
  }
30
42
  var encryptionKeyId;
31
43
  if (args.bootDisk.encrypted) {
32
- const encryptionKey = new KmsSymmetricKey(
33
- "encryption-key",
34
- {
35
- name: vmName,
36
- description: getResourceComment(),
37
- folderId: args.folderId ?? inputs.connection.defaultFolderId
38
- },
39
- { provider }
40
- );
44
+ const encryptionKey = new KmsSymmetricKey("encryption-key", {
45
+ name: vmName,
46
+ description: getResourceComment(),
47
+ folderId: args.folderId ?? inputs.connection.defaultFolderId
48
+ }, { provider });
41
49
  encryptionKeyId = encryptionKey.id;
42
50
  }
43
- var disk = new ComputeDisk(
44
- "disk",
45
- {
46
- name: vmName,
47
- type: args.bootDisk.type,
48
- size: args.bootDisk.size,
49
- imageId: inputs.image.id,
50
- allowRecreate: false,
51
- folderId: args.folderId ?? inputs.connection.defaultFolderId,
52
- zone: inputs.connection.defaultZone,
53
- kmsKeyId: encryptionKeyId
54
- },
55
- { provider, ignoreChanges: ["imageId"] }
56
- );
51
+ var disk = new ComputeDisk("disk", {
52
+ name: vmName,
53
+ type: args.bootDisk.type,
54
+ size: args.bootDisk.size,
55
+ imageId: inputs.image.id,
56
+ allowRecreate: false,
57
+ folderId: args.folderId ?? inputs.connection.defaultFolderId,
58
+ zone: inputs.connection.defaultZone,
59
+ kmsKeyId: encryptionKeyId
60
+ }, { provider, ignoreChanges: ["imageId"] });
57
61
  var userData = interpolate`
58
62
  #cloud-config
59
63
  hostname: ${vmName}
@@ -65,58 +69,48 @@ var userData = interpolate`
65
69
  `.apply(trimIndentation);
66
70
  var publicAddress;
67
71
  if (args.network.assignPublicIp && args.network.reservePublicIp) {
68
- publicAddress = new VpcAddress(
69
- "address",
70
- {
71
- name: vmName,
72
- folderId: args.folderId ?? inputs.connection.defaultFolderId,
73
- description: getResourceComment(),
74
- externalIpv4Address: {
75
- zoneId: inputs.connection.defaultZone
76
- }
77
- },
78
- { provider }
79
- );
80
- }
81
- var instance = new ComputeInstance(
82
- "virtual-machine",
83
- {
72
+ publicAddress = new VpcAddress("address", {
84
73
  name: vmName,
85
- description: getResourceComment(),
86
74
  folderId: args.folderId ?? inputs.connection.defaultFolderId,
87
- zone: inputs.connection.defaultZone,
88
- platformId: args.platformId,
89
- allowStoppingForUpdate: true,
90
- resources: {
91
- cores: args.resources.cores,
92
- memory: args.resources.memory,
93
- coreFraction: args.resources.coreFraction
94
- },
95
- schedulingPolicy: {
96
- preemptible: args.preemptible
97
- },
98
- bootDisk: {
99
- diskId: disk.id
100
- },
101
- networkInterfaces: [
102
- {
103
- subnetId,
104
- nat: args.network.assignPublicIp,
105
- natIpAddress: publicAddress ? publicAddress.externalIpv4Address.apply((a) => a.address) : void 0
106
- }
107
- ],
108
- metadata: {
109
- "user-data": userData
75
+ description: getResourceComment(),
76
+ externalIpv4Address: {
77
+ zoneId: inputs.connection.defaultZone
110
78
  }
79
+ }, { provider });
80
+ }
81
+ var instance = new ComputeInstance("virtual-machine", {
82
+ name: vmName,
83
+ description: getResourceComment(),
84
+ folderId: args.folderId ?? inputs.connection.defaultFolderId,
85
+ zone: inputs.connection.defaultZone,
86
+ platformId: args.platformId,
87
+ allowStoppingForUpdate: true,
88
+ resources: {
89
+ cores: args.resources.cores,
90
+ memory: args.resources.memory,
91
+ coreFraction: args.resources.coreFraction
92
+ },
93
+ schedulingPolicy: {
94
+ preemptible: args.preemptible
111
95
  },
112
- { provider, ignoreChanges: ["bootDisk"] }
113
- );
114
- var publicIp = await toPromise(
115
- instance.networkInterfaces.apply((ni) => {
116
- const firstInterface = ni[0];
117
- return args.network.assignPublicIp ? firstInterface?.natIpAddress : firstInterface?.ipAddress;
118
- })
119
- );
96
+ bootDisk: {
97
+ diskId: disk.id
98
+ },
99
+ networkInterfaces: [
100
+ {
101
+ subnetId,
102
+ nat: args.network.assignPublicIp,
103
+ natIpAddress: publicAddress ? publicAddress.externalIpv4Address.apply((a) => a.address) : undefined
104
+ }
105
+ ],
106
+ metadata: {
107
+ "user-data": userData
108
+ }
109
+ }, { provider, ignoreChanges: ["bootDisk"] });
110
+ var publicIp = await toPromise(instance.networkInterfaces.apply((ni) => {
111
+ const firstInterface = ni[0];
112
+ return args.network.assignPublicIp ? firstInterface?.natIpAddress : firstInterface?.ipAddress;
113
+ }));
120
114
  if (!publicIp) {
121
115
  throw new Error("No IP address assigned to instance");
122
116
  }
@@ -137,7 +131,6 @@ var virtual_machine_default = outputs({
137
131
  },
138
132
  $terminals: [terminal]
139
133
  });
140
-
141
- export { virtual_machine_default as default };
142
- //# sourceMappingURL=index.js.map
143
- //# sourceMappingURL=index.js.map
134
+ export {
135
+ virtual_machine_default as default
136
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@highstate/yandex",
3
- "version": "0.20.0",
3
+ "version": "0.21.1",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
@@ -20,27 +20,27 @@
20
20
  "stdlib"
21
21
  ]
22
22
  },
23
+ "scripts": {
24
+ "build": "highstate build",
25
+ "typecheck": "tsgo --noEmit --skipLibCheck",
26
+ "biome": "biome check --write --unsafe --error-on-warnings",
27
+ "biome:check": "biome check --error-on-warnings",
28
+ "generate-sdks": "./scripts/generate-sdks.sh"
29
+ },
23
30
  "dependencies": {
24
- "@pulumi/pulumi": "3.220.0",
25
- "@highstate/contract": "0.20.0",
26
31
  "@highstate/common": "0.20.0",
32
+ "@highstate/contract": "0.20.0",
27
33
  "@highstate/library": "0.20.0",
34
+ "@highstate/pulumi": "0.20.0",
28
35
  "@highstate/yandex-sdk": "0.19.1",
29
- "@highstate/pulumi": "0.20.0"
36
+ "@pulumi/pulumi": "3.232.0"
30
37
  },
31
38
  "devDependencies": {
32
39
  "@biomejs/biome": "2.2.0",
33
- "@typescript/native-preview": "^7.0.0-dev.20250920.1",
34
- "@highstate/cli": "0.20.0"
40
+ "@highstate/cli": "0.20.0",
41
+ "@typescript/native-preview": "^7.0.0-dev.20250920.1"
35
42
  },
36
43
  "repository": {
37
44
  "url": "https://github.com/highstate-io/highstate"
38
- },
39
- "scripts": {
40
- "build": "highstate build",
41
- "typecheck": "tsgo --noEmit --skipLibCheck",
42
- "biome": "biome check --write --unsafe --error-on-warnings",
43
- "biome:check": "biome check --error-on-warnings",
44
- "generate-sdks": "./scripts/generate-sdks.sh"
45
45
  }
46
- }
46
+ }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Exeteres
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
@@ -1,21 +0,0 @@
1
- import { toPromise, output } from '@highstate/pulumi';
2
- import { Provider } from '@highstate/yandex-sdk';
3
-
4
- // src/provider.ts
5
- async function createProvider(connection, cloudId) {
6
- return await toPromise(
7
- output(connection).apply((connection2) => {
8
- return new Provider(connection2.cloudId, {
9
- serviceAccountKeyFile: connection2.authorizedKeyJson.value,
10
- cloudId: cloudId ?? connection2.cloudId,
11
- folderId: connection2.defaultFolderId,
12
- zone: connection2.defaultZone,
13
- regionId: connection2.regionId
14
- });
15
- })
16
- );
17
- }
18
-
19
- export { createProvider };
20
- //# sourceMappingURL=chunk-ISIWD2MZ.js.map
21
- //# sourceMappingURL=chunk-ISIWD2MZ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/provider.ts"],"names":["connection"],"mappings":";;;;AAKA,eAAsB,cAAA,CACpB,YACA,OAAA,EACmB;AACnB,EAAA,OAAO,MAAM,SAAA;AAAA,IACX,MAAA,CAAO,UAAU,CAAA,CAAE,KAAA,CAAM,CAAAA,WAAAA,KAAc;AACrC,MAAA,OAAO,IAAI,QAAA,CAASA,WAAAA,CAAW,OAAA,EAAS;AAAA,QACtC,qBAAA,EAAuBA,YAAW,iBAAA,CAAkB,KAAA;AAAA,QACpD,OAAA,EAAS,WAAWA,WAAAA,CAAW,OAAA;AAAA,QAC/B,UAAUA,WAAAA,CAAW,eAAA;AAAA,QACrB,MAAMA,WAAAA,CAAW,WAAA;AAAA,QACjB,UAAUA,WAAAA,CAAW;AAAA,OACtB,CAAA;AAAA,IACH,CAAC;AAAA,GACH;AACF","file":"chunk-ISIWD2MZ.js","sourcesContent":["import type { yandex } from \"@highstate/library\"\nimport type { Input } from \"@highstate/pulumi\"\nimport { output, toPromise } from \"@highstate/pulumi\"\nimport { Provider } from \"@highstate/yandex-sdk\"\n\nexport async function createProvider(\n connection: yandex.Connection,\n cloudId?: Input<string>,\n): Promise<Provider> {\n return await toPromise(\n output(connection).apply(connection => {\n return new Provider(connection.cloudId, {\n serviceAccountKeyFile: connection.authorizedKeyJson.value,\n cloudId: cloudId ?? connection.cloudId,\n folderId: connection.defaultFolderId,\n zone: connection.defaultZone,\n regionId: connection.regionId,\n })\n }),\n )\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/connection/index.ts"],"names":[],"mappings":";;;;;AAIA,IAAM,EAAE,IAAA,EAAM,OAAA,EAAS,SAAQ,GAAI,OAAA,CAAQ,OAAO,UAAU,CAAA;AAO5D,IAAM,2BAAA,GAA8B,MAAM,SAAA,CAAU,OAAA,CAAQ,iBAAiB,CAAA;AAC7E,IAAM,WAAA,GAAqC,IAAA,CAAK,KAAA,CAAM,2BAA2B,CAAA;AACjF,IAAM,mBAAmB,WAAA,CAAY,kBAAA;AAGrC,IAAM,QAAA,GAAW,IAAI,QAAA,CAAS,QAAA,EAAU;AAAA,EACtC,qBAAA,EAAuB,2BAAA;AAAA,EACvB,IAAA,EAAM,KAAK,MAAA,CAAO,WAAA;AAAA,EAClB,QAAA,EAAU,KAAK,MAAA,CAAO;AACxB,CAAC,CAAA;AAGD,IAAM,iBAAiB,MAAM,oBAAA;AAAA,EAC3B,EAAE,gBAAA,EAAmC;AAAA,EACrC,EAAE,QAAA;AACJ,CAAA;AAGA,IAAM,MAAA,GAAS,MAAM,wBAAA,CAAyB,EAAE,QAAA,EAAU,eAAe,QAAA,EAAS,EAAG,EAAE,QAAA,EAAU,CAAA;AACjG,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,EAAA,MAAM,IAAI,MAAM,0CAA0C,CAAA;AAC5D;AAEA,IAAM,aAAa,gBAAA,CAAiB;AAAA,EAClC,QAAQ,MAAA,CAAO,gBAAA;AAAA,EACf,UAAU,WAAA,CAAY,kBAAA;AAAA,EACtB,IAAA,EAAM;AAAA,IACJ,OAAO,cAAA,CAAe,IAAA;AAAA,IACtB,WAAA,EAAa,CAAA,kBAAA,EAAqB,cAAA,CAAe,IAAI,CAAA,OAAA,EAAU,cAAA,CAAe,EAAE,CAAA,aAAA,EAAgB,MAAA,CAAO,IAAI,CAAA,OAAA,EAAU,MAAA,CAAO,EAAE,CAAA,CAAA;AAAA,GAChI;AAAA,EACA,KAAA,EAAO;AAAA,IACL,mBAAmB,OAAA,CAAQ,iBAAA;AAAA,IAC3B,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,iBAAiB,cAAA,CAAe,QAAA;AAAA,IAChC,WAAA,EAAa,KAAK,MAAA,CAAO,WAAA;AAAA,IACzB,QAAA,EAAU,KAAK,MAAA,CAAO,EAAA;AAAA,IACtB,kBAAkB,cAAA,CAAe;AAAA;AAErC,CAAC,CAAA;AAED,IAAO,qBAAQ,OAAA,CAAQ;AAAA,EACrB,UAAA;AAAA,EAEA,aAAA,EAAe;AAAA,IACb,cAAA,EAAgB;AAAA,MACd,IAAA,EAAM;AAAA,QACJ,IAAA,EAAM;AAAA,OACR;AAAA,MACA,OAAO,UAAA,CAAW;AAAA,KACpB;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,IAAA,EAAM;AAAA,QACJ,IAAA,EAAM;AAAA,OACR;AAAA,MACA,OAAO,UAAA,CAAW;AAAA;AACpB;AAEJ,CAAC","file":"index.js","sourcesContent":["import { yandex } from \"@highstate/library\"\nimport { forUnit, makeEntityOutput, toPromise } from \"@highstate/pulumi\"\nimport { getIamServiceAccount, getResourcemanagerFolder, Provider } from \"@highstate/yandex-sdk\"\n\nconst { args, secrets, outputs } = forUnit(yandex.connection)\n\n// parse service account key file to extract service account ID\ntype ServiceAccountKeyFile = {\n service_account_id: string\n}\n\nconst serviceAccountKeyFileString = await toPromise(secrets.authorizedKeyJson)\nconst keyFileData: ServiceAccountKeyFile = JSON.parse(serviceAccountKeyFileString)\nconst serviceAccountId = keyFileData.service_account_id\n\n// create provider for auto-discovery\nconst provider = new Provider(\"yandex\", {\n serviceAccountKeyFile: serviceAccountKeyFileString,\n zone: args.region.defaultZone,\n regionId: args.region.id,\n})\n\n// auto-discover service account details to get folder and cloud\nconst serviceAccount = await getIamServiceAccount(\n { serviceAccountId: serviceAccountId },\n { provider },\n)\n\n// auto-discover cloud ID from folder\nconst folder = await getResourcemanagerFolder({ folderId: serviceAccount.folderId }, { provider })\nif (!folder.cloudId) {\n throw new Error(\"Could not determine cloud ID from folder\")\n}\n\nconst connection = makeEntityOutput({\n entity: yandex.connectionEntity,\n identity: keyFileData.service_account_id,\n meta: {\n title: serviceAccount.name,\n description: `Authorized as SA \"${serviceAccount.name}\" (ID: ${serviceAccount.id}) in folder \"${folder.name}\" (ID: ${folder.id})`,\n },\n value: {\n authorizedKeyJson: secrets.authorizedKeyJson,\n cloudId: folder.cloudId,\n defaultFolderId: serviceAccount.folderId,\n defaultZone: args.region.defaultZone,\n regionId: args.region.id,\n serviceAccountId: serviceAccount.id,\n },\n})\n\nexport default outputs({\n connection,\n\n $statusFields: {\n defaultCloudId: {\n meta: {\n icon: \"mdi:cloud\",\n },\n value: connection.cloudId,\n },\n defaultFolderId: {\n meta: {\n icon: \"mdi:folder\",\n },\n value: connection.defaultFolderId,\n },\n },\n})\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/disk/index.ts"],"names":[],"mappings":";;;;;AAKA,IAAM,EAAE,MAAM,IAAA,EAAM,MAAA,EAAQ,SAAQ,GAAI,OAAA,CAAQ,OAAO,IAAI,CAAA;AAE3D,IAAM,QAAA,GAAW,MAAM,cAAA,CAAe,MAAA,CAAO,UAAU,CAAA;AAEvD,IAAM,QAAA,GAAW,KAAK,QAAA,IAAY,IAAA;AAElC,IAAM,OAAO,IAAI,WAAA;AAAA,EACf,MAAA;AAAA,EACA;AAAA,IACE,IAAA,EAAM,QAAA;AAAA,IACN,aAAa,kBAAA,EAAmB;AAAA,IAChC,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,aAAA,EAAe;AAAA,GACjB;AAAA,EACA,EAAE,QAAA,EAAU,OAAA,EAAS,IAAA;AACvB,CAAA;AAEA,IAAO,eAAQ,OAAA,CAAQ;AAAA,EACrB,MAAM,gBAAA,CAAiB;AAAA,IACrB,QAAQ,MAAA,CAAO,UAAA;AAAA,IACf,UAAU,IAAA,CAAK,EAAA;AAAA,IACf,KAAA,EAAO;AAAA,MACL,IAAI,IAAA,CAAK;AAAA;AACX,GACD,CAAA;AAAA,EAED,aAAA,EAAe;AAAA,IACb,IAAI,IAAA,CAAK;AAAA;AAEb,CAAC","file":"index.js","sourcesContent":["import { yandex } from \"@highstate/library\"\nimport { forUnit, getResourceComment, makeEntityOutput } from \"@highstate/pulumi\"\nimport { ComputeDisk } from \"@highstate/yandex-sdk\"\nimport { createProvider } from \"../provider\"\n\nconst { name, args, inputs, outputs } = forUnit(yandex.disk)\n\nconst provider = await createProvider(inputs.connection)\n\nconst diskName = args.diskName ?? name\n\nconst disk = new ComputeDisk(\n \"disk\",\n {\n name: diskName,\n description: getResourceComment(),\n type: args.type,\n size: args.size,\n allowRecreate: false,\n },\n { provider, protect: true },\n)\n\nexport default outputs({\n disk: makeEntityOutput({\n entity: yandex.diskEntity,\n identity: disk.id,\n value: {\n id: disk.id,\n },\n }),\n\n $statusFields: {\n id: disk.id,\n },\n})\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/existing-image/index.ts"],"names":[],"mappings":";;;;;AAKA,IAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAQ,GAAI,OAAA,CAAQ,OAAO,aAAa,CAAA;AAE9D,IAAM,QAAA,GAAW,MAAM,cAAA,CAAe,MAAA,CAAO,UAAU,CAAA;AAEvD,IAAM,OAAA,GAAU,MAAM,eAAA,CAAgB,EAAE,OAAA,EAAS,KAAK,EAAA,EAAG,EAAG,EAAE,QAAA,EAAU,CAAA;AAExE,IAAM,QAAQ,gBAAA,CAAiB;AAAA,EAC7B,QAAQ,MAAA,CAAO,WAAA;AAAA,EACf,UAAU,OAAA,CAAQ,EAAA;AAAA,EAClB,IAAA,EAAM;AAAA,IACJ,OAAO,OAAA,CAAQ;AAAA,GACjB;AAAA,EACA,KAAA,EAAO;AAAA,IACL,IAAI,OAAA,CAAQ;AAAA;AAEhB,CAAC,CAAA;AAED,IAAO,yBAAQ,OAAA,CAAQ;AAAA,EACrB,KAAA;AAAA,EACA,aAAA,EAAe;AAAA,IACb,MAAM,OAAA,CAAQ;AAAA;AAElB,CAAC","file":"index.js","sourcesContent":["import { yandex } from \"@highstate/library\"\nimport { forUnit, makeEntityOutput } from \"@highstate/pulumi\"\nimport { getComputeImage } from \"@highstate/yandex-sdk\"\nimport { createProvider } from \"../provider\"\n\nconst { args, inputs, outputs } = forUnit(yandex.existingImage)\n\nconst provider = await createProvider(inputs.connection)\n\nconst ycImage = await getComputeImage({ imageId: args.id }, { provider })\n\nconst image = makeEntityOutput({\n entity: yandex.imageEntity,\n identity: ycImage.id,\n meta: {\n title: ycImage.name,\n },\n value: {\n id: ycImage.id,\n },\n})\n\nexport default outputs({\n image,\n $statusFields: {\n name: ycImage.name,\n },\n})\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/instance-group/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import {\n createServerBundle,\n generatePassword,\n generateSshPrivateKey,\n l3EndpointToString,\n parseEndpoint,\n sshPrivateKeyToKeyPair,\n} from \"@highstate/common\"\nimport { trimIndentation, type UnitTerminal } from \"@highstate/contract\"\nimport { yandex } from \"@highstate/library\"\nimport { forUnit, getResourceComment, interpolate, type Output, toPromise } from \"@highstate/pulumi\"\nimport {\n ComputeDisk,\n ComputeInstanceGroup,\n getVpcSubnet,\n KmsSymmetricKey,\n VpcAddress,\n} from \"@highstate/yandex-sdk\"\nimport { createProvider } from \"../provider\"\n\nconst { name, args, getSecret, inputs, outputs } = forUnit(yandex.instanceGroup)\n\nconst groupName = args.groupName ?? name\n\nconst provider = await createProvider(inputs.connection, args.cloudId)\n\nconst sshKeyPair =\n inputs.sshKeyPair ??\n getSecret(\"sshPrivateKey\", generateSshPrivateKey).apply(sshPrivateKeyToKeyPair)\n\nconst rootPassword = getSecret(\"rootPassword\", generatePassword)\n\n// auto-discover subnet if not specified\nlet subnetId = args.network.subnetId\nif (!subnetId) {\n const defaultSubnetName = await toPromise(interpolate`default-${inputs.connection.defaultZone}`)\n const subnet = await getVpcSubnet(\n {\n folderId: await toPromise(inputs.connection.defaultFolderId),\n name: defaultSubnetName,\n },\n { provider },\n )\n\n if (!subnet.id) {\n throw new Error(\n `Could not find default subnet '${defaultSubnetName}' in zone ${inputs.connection.defaultZone}`,\n )\n }\n\n subnetId = subnet.id\n}\n\n// create single key for all disks in the group\nlet encryptionKeyId: Output<string> | undefined\nif (args.bootDisk.encrypted) {\n const encryptionKey = new KmsSymmetricKey(\n \"encryption-key\",\n {\n name: groupName,\n description: getResourceComment(),\n folderId: args.folderId ?? inputs.connection.defaultFolderId,\n },\n { provider },\n )\n\n encryptionKeyId = encryptionKey.id\n}\n\n// create the disk for each instance in the group\nconst disks = Array.from({ length: args.size }, (_, i) => {\n return new ComputeDisk(\n `disk-${i + 1}`,\n {\n name: `${groupName}-${i + 1}`,\n type: args.bootDisk.type,\n size: args.bootDisk.size,\n imageId: inputs.image.id,\n allowRecreate: false,\n folderId: args.folderId ?? inputs.connection.defaultFolderId,\n zone: inputs.connection.defaultZone,\n kmsKeyId: encryptionKeyId,\n },\n { provider, ignoreChanges: [\"imageId\"] },\n )\n})\n\n// create internal IPs for each instance in the group\nconst internalAddresses = Array.from({ length: args.size }, (_, i) => {\n return new VpcAddress(\n `internal-address-${i + 1}`,\n {\n name: `${groupName}-internal-${i + 1}`,\n folderId: args.folderId ?? inputs.connection.defaultFolderId,\n description: getResourceComment(),\n internalIpv4Address: {\n subnetId,\n },\n },\n { provider },\n )\n})\n\n// create public IPs if needed\nlet publicAddresses: VpcAddress[] | undefined\n\nif (args.network.assignPublicIp && args.network.reservePublicIp) {\n publicAddresses = Array.from({ length: args.size }, (_, i) => {\n return new VpcAddress(\n `address-${i + 1}`,\n {\n name: `${groupName}-${i + 1}`,\n folderId: args.folderId ?? inputs.connection.defaultFolderId,\n description: getResourceComment(),\n externalIpv4Address: {\n zoneId: inputs.connection.defaultZone,\n },\n },\n { provider },\n )\n })\n}\n\n// create cloud-init user data\nconst userData = interpolate`\n #cloud-config\n hostname: ${groupName}-{instance.index}\n users:\n - name: root\n ssh-authorized-keys:\n - ${sshKeyPair.publicKey}\n sudo: ALL=(ALL) NOPASSWD:ALL\n`.apply(trimIndentation)\n\nconst instanceGroup = new ComputeInstanceGroup(\n \"instance-group\",\n {\n name: groupName,\n description: getResourceComment(),\n folderId: args.folderId ?? inputs.connection.defaultFolderId,\n\n allocationPolicy: {\n zones: [inputs.connection.defaultZone],\n },\n\n deployPolicy: {\n maxExpansion: 0,\n maxUnavailable: 1,\n },\n\n scalePolicy: {\n fixedScale: {\n size: args.size,\n },\n },\n\n instanceTemplate: {\n name: `${groupName}-{instance.index}`,\n description: getResourceComment(),\n platformId: args.platformId,\n\n resources: {\n cores: args.resources.cores,\n memory: args.resources.memory,\n coreFraction: args.resources.coreFraction,\n },\n\n schedulingPolicy: {\n preemptible: args.preemptible,\n },\n\n bootDisk: {\n diskId: `{disk_{instance.index}}`,\n },\n\n networkInterfaces: [\n {\n subnetIds: [subnetId],\n ipAddress: `{internal_address_{instance.index}}`,\n nat: args.network.assignPublicIp,\n natIpAddress: publicAddresses ? `{address_{instance.index}}` : undefined,\n },\n ],\n\n metadata: {\n \"user-data\": userData,\n },\n },\n\n variables: {\n ...Object.fromEntries(disks.map((_, i) => [`disk_${i + 1}`, disks[i].id])),\n ...Object.fromEntries(\n internalAddresses.map((_, i) => [\n `internal_address_${i + 1}`,\n internalAddresses[i].internalIpv4Address.apply(a => a!.address),\n ]),\n ),\n ...(publicAddresses\n ? Object.fromEntries(\n publicAddresses.map((_, i) => [\n `address_${i + 1}`,\n publicAddresses[i].externalIpv4Address.apply(a => a!.address),\n ]),\n )\n : {}),\n },\n\n serviceAccountId: inputs.connection.serviceAccountId,\n },\n { provider },\n)\n\nconst terminals: UnitTerminal[] = []\nconst instances = await toPromise(instanceGroup.instances)\n\nconst servers = await toPromise(\n instances.map(async (instance, i) => {\n // get the IP address\n const firstInterface = instance.networkInterfaces[0]\n const publicIp = args.network.assignPublicIp\n ? firstInterface?.natIpAddress\n : firstInterface?.ipAddress\n\n if (!publicIp) {\n throw new Error(\"No IP address assigned to instance\")\n }\n\n const endpoint = parseEndpoint(publicIp, 3)\n\n const { server, terminal } = await createServerBundle({\n name: `${groupName}-${i + 1}`,\n endpoints: [endpoint],\n sshArgs: args.ssh,\n sshPassword: rootPassword,\n sshKeyPair,\n })\n\n if (terminal) {\n const rawTerminal = await toPromise(terminal)\n\n terminals.push({\n ...rawTerminal,\n name: `ssh-${i + 1}`,\n meta: {\n title: `Shell (${i + 1})`,\n },\n })\n }\n\n return server\n }),\n)\n\nexport default outputs({\n servers,\n\n $statusFields: {\n id: instanceGroup.id,\n endpoints: servers.flatMap(server => server.endpoints).map(l3EndpointToString),\n },\n\n $terminals: terminals,\n})\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/virtual-machine/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import {\n createServerBundle,\n generatePassword,\n generateSshPrivateKey,\n l3EndpointToString,\n parseEndpoint,\n sshPrivateKeyToKeyPair,\n} from \"@highstate/common\"\nimport { trimIndentation } from \"@highstate/contract\"\nimport { yandex } from \"@highstate/library\"\nimport { forUnit, getResourceComment, interpolate, type Output, toPromise } from \"@highstate/pulumi\"\nimport {\n ComputeDisk,\n ComputeInstance,\n getVpcSubnet,\n KmsSymmetricKey,\n VpcAddress,\n} from \"@highstate/yandex-sdk\"\nimport { createProvider } from \"../provider\"\n\nconst { name, args, getSecret, inputs, outputs } = forUnit(yandex.virtualMachine)\n\nconst vmName = args.vmName ?? name\n\nconst provider = await createProvider(inputs.connection, args.cloudId)\n\nconst sshKeyPair =\n inputs.sshKeyPair ??\n getSecret(\"sshPrivateKey\", generateSshPrivateKey).apply(sshPrivateKeyToKeyPair)\n\nconst rootPassword = getSecret(\"rootPassword\", generatePassword)\n\n// auto-discover subnet if not specified\nlet subnetId = args.network.subnetId\nif (!subnetId) {\n const defaultSubnetName = await toPromise(interpolate`default-${inputs.connection.defaultZone}`)\n const subnet = await getVpcSubnet(\n {\n folderId: await toPromise(inputs.connection.defaultFolderId),\n name: defaultSubnetName,\n },\n { provider },\n )\n\n if (!subnet.id) {\n throw new Error(\n `Could not find default subnet '${defaultSubnetName}' in zone ${inputs.connection.defaultZone}`,\n )\n }\n\n subnetId = subnet.id\n}\n\n// create key for disk\nlet encryptionKeyId: Output<string> | undefined\nif (args.bootDisk.encrypted) {\n const encryptionKey = new KmsSymmetricKey(\n \"encryption-key\",\n {\n name: vmName,\n description: getResourceComment(),\n folderId: args.folderId ?? inputs.connection.defaultFolderId,\n },\n { provider },\n )\n\n encryptionKeyId = encryptionKey.id\n}\n\n// create the disk\nconst disk = new ComputeDisk(\n \"disk\",\n {\n name: vmName,\n type: args.bootDisk.type,\n size: args.bootDisk.size,\n imageId: inputs.image.id,\n allowRecreate: false,\n folderId: args.folderId ?? inputs.connection.defaultFolderId,\n zone: inputs.connection.defaultZone,\n kmsKeyId: encryptionKeyId,\n },\n { provider, ignoreChanges: [\"imageId\"] },\n)\n\n// create cloud-init user data\nconst userData = interpolate`\n #cloud-config\n hostname: ${vmName}\n users:\n - name: root\n ssh-authorized-keys:\n - ${sshKeyPair.publicKey}\n sudo: ALL=(ALL) NOPASSWD:ALL\n`.apply(trimIndentation)\n\nlet publicAddress: VpcAddress | undefined\n\nif (args.network.assignPublicIp && args.network.reservePublicIp) {\n publicAddress = new VpcAddress(\n \"address\",\n {\n name: vmName,\n folderId: args.folderId ?? inputs.connection.defaultFolderId,\n description: getResourceComment(),\n externalIpv4Address: {\n zoneId: inputs.connection.defaultZone,\n },\n },\n { provider },\n )\n}\n\n// create the instance\nconst instance = new ComputeInstance(\n \"virtual-machine\",\n {\n name: vmName,\n description: getResourceComment(),\n folderId: args.folderId ?? inputs.connection.defaultFolderId,\n zone: inputs.connection.defaultZone,\n platformId: args.platformId,\n allowStoppingForUpdate: true,\n\n resources: {\n cores: args.resources.cores,\n memory: args.resources.memory,\n coreFraction: args.resources.coreFraction,\n },\n\n schedulingPolicy: {\n preemptible: args.preemptible,\n },\n\n bootDisk: {\n diskId: disk.id,\n },\n\n networkInterfaces: [\n {\n subnetId: subnetId,\n nat: args.network.assignPublicIp,\n natIpAddress: publicAddress\n ? publicAddress.externalIpv4Address.apply(a => a!.address)\n : undefined,\n },\n ],\n\n metadata: {\n \"user-data\": userData,\n },\n },\n { provider, ignoreChanges: [\"bootDisk\"] },\n)\n\n// get the IP address\nconst publicIp = await toPromise(\n instance.networkInterfaces.apply(ni => {\n const firstInterface = ni[0]\n return args.network.assignPublicIp ? firstInterface?.natIpAddress : firstInterface?.ipAddress\n }),\n)\n\nif (!publicIp) {\n throw new Error(\"No IP address assigned to instance\")\n}\n\nconst endpoint = parseEndpoint(publicIp, 3)\n\nconst { server, terminal } = await createServerBundle({\n name: vmName,\n endpoints: [endpoint],\n sshArgs: args.ssh,\n sshPassword: rootPassword,\n sshKeyPair,\n})\n\nexport default outputs({\n server,\n\n $statusFields: {\n id: instance.id,\n endpoints: [l3EndpointToString(endpoint)],\n hostname: server.hostname,\n },\n\n $terminals: [terminal],\n})\n"]}