@highstate/yandex 0.19.1 → 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.
- package/dist/chunk-09r4wmhq.js +17 -0
- package/dist/connection/index.js +25 -20
- package/dist/disk/index.js +25 -22
- package/dist/existing-image/index.js +24 -13
- package/dist/highstate.manifest.json +5 -4
- package/dist/instance-group/index.js +189 -0
- package/dist/virtual-machine/index.js +90 -79
- package/package.json +19 -18
- package/LICENSE +0 -21
- package/dist/chunk-MK37EG4O.js +0 -21
- package/dist/chunk-MK37EG4O.js.map +0 -1
- package/dist/connection/index.js.map +0 -1
- package/dist/disk/index.js.map +0 -1
- package/dist/existing-image/index.js.map +0 -1
- package/dist/virtual-machine/index.js.map +0 -1
|
@@ -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 };
|
package/dist/connection/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
import { forUnit, toPromise, output } 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
|
-
var serviceAccountKeyFileString = await toPromise(secrets.
|
|
7
|
+
var serviceAccountKeyFileString = await toPromise(secrets.authorizedKeyJson);
|
|
8
8
|
var keyFileData = JSON.parse(serviceAccountKeyFileString);
|
|
9
9
|
var serviceAccountId = keyFileData.service_account_id;
|
|
10
10
|
var provider = new Provider("yandex", {
|
|
@@ -12,25 +12,31 @@ 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");
|
|
22
19
|
}
|
|
23
|
-
var connection =
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
var connection = makeEntityOutput({
|
|
21
|
+
entity: yandex.connectionEntity,
|
|
22
|
+
identity: keyFileData.service_account_id,
|
|
23
|
+
meta: {
|
|
24
|
+
title: serviceAccount.name,
|
|
25
|
+
description: `Authorized as SA "${serviceAccount.name}" (ID: ${serviceAccount.id}) in folder "${folder.name}" (ID: ${folder.id})`
|
|
26
|
+
},
|
|
27
|
+
value: {
|
|
28
|
+
authorizedKeyJson: secrets.authorizedKeyJson,
|
|
29
|
+
cloudId: folder.cloudId,
|
|
30
|
+
defaultFolderId: serviceAccount.folderId,
|
|
31
|
+
defaultZone: args.region.defaultZone,
|
|
32
|
+
regionId: args.region.id,
|
|
33
|
+
serviceAccountId: serviceAccount.id
|
|
34
|
+
}
|
|
29
35
|
});
|
|
30
36
|
var connection_default = outputs({
|
|
31
37
|
connection,
|
|
32
38
|
$statusFields: {
|
|
33
|
-
|
|
39
|
+
defaultCloudId: {
|
|
34
40
|
meta: {
|
|
35
41
|
icon: "mdi:cloud"
|
|
36
42
|
},
|
|
@@ -44,7 +50,6 @@ var connection_default = outputs({
|
|
|
44
50
|
}
|
|
45
51
|
}
|
|
46
52
|
});
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
//# sourceMappingURL=index.js.map
|
|
53
|
+
export {
|
|
54
|
+
connection_default as default
|
|
55
|
+
};
|
package/dist/disk/index.js
CHANGED
|
@@ -1,31 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
disk: {
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
disk: makeEntityOutput({
|
|
22
|
+
entity: yandex.diskEntity,
|
|
23
|
+
identity: disk.id,
|
|
24
|
+
value: {
|
|
25
|
+
id: disk.id
|
|
26
|
+
}
|
|
27
|
+
}),
|
|
24
28
|
$statusFields: {
|
|
25
29
|
id: disk.id
|
|
26
30
|
}
|
|
27
31
|
});
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
//# sourceMappingURL=index.js.map
|
|
32
|
+
export {
|
|
33
|
+
disk_default as default
|
|
34
|
+
};
|
|
@@ -1,20 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
var
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
var ycImage = await getComputeImage({ imageId: args.id }, { provider });
|
|
13
|
+
var image = makeEntityOutput({
|
|
14
|
+
entity: yandex.imageEntity,
|
|
15
|
+
identity: ycImage.id,
|
|
16
|
+
meta: {
|
|
17
|
+
title: ycImage.name
|
|
12
18
|
},
|
|
19
|
+
value: {
|
|
20
|
+
id: ycImage.id
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
var existing_image_default = outputs({
|
|
24
|
+
image,
|
|
13
25
|
$statusFields: {
|
|
14
|
-
name:
|
|
26
|
+
name: ycImage.name
|
|
15
27
|
}
|
|
16
28
|
});
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
//# sourceMappingURL=index.js.map
|
|
29
|
+
export {
|
|
30
|
+
existing_image_default as default
|
|
31
|
+
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"sourceHashes": {
|
|
3
|
-
"./dist/connection/index.js":
|
|
4
|
-
"./dist/disk/index.js":
|
|
5
|
-
"./dist/existing-image/index.js":
|
|
6
|
-
"./dist/virtual-machine/index.js":
|
|
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
|
|
7
8
|
}
|
|
8
9
|
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
createProvider
|
|
4
|
+
} from "../chunk-09r4wmhq.js";
|
|
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";
|
|
25
|
+
var { name, args, getSecret, inputs, outputs } = forUnit(yandex.instanceGroup);
|
|
26
|
+
var groupName = args.groupName ?? name;
|
|
27
|
+
var provider = await createProvider(inputs.connection, args.cloudId);
|
|
28
|
+
var sshKeyPair = inputs.sshKeyPair ?? getSecret("sshPrivateKey", generateSshPrivateKey).apply(sshPrivateKeyToKeyPair);
|
|
29
|
+
var rootPassword = getSecret("rootPassword", generatePassword);
|
|
30
|
+
var subnetId = args.network.subnetId;
|
|
31
|
+
if (!subnetId) {
|
|
32
|
+
const defaultSubnetName = await toPromise(interpolate`default-${inputs.connection.defaultZone}`);
|
|
33
|
+
const subnet = await getVpcSubnet({
|
|
34
|
+
folderId: await toPromise(inputs.connection.defaultFolderId),
|
|
35
|
+
name: defaultSubnetName
|
|
36
|
+
}, { provider });
|
|
37
|
+
if (!subnet.id) {
|
|
38
|
+
throw new Error(`Could not find default subnet '${defaultSubnetName}' in zone ${inputs.connection.defaultZone}`);
|
|
39
|
+
}
|
|
40
|
+
subnetId = subnet.id;
|
|
41
|
+
}
|
|
42
|
+
var encryptionKeyId;
|
|
43
|
+
if (args.bootDisk.encrypted) {
|
|
44
|
+
const encryptionKey = new KmsSymmetricKey("encryption-key", {
|
|
45
|
+
name: groupName,
|
|
46
|
+
description: getResourceComment(),
|
|
47
|
+
folderId: args.folderId ?? inputs.connection.defaultFolderId
|
|
48
|
+
}, { provider });
|
|
49
|
+
encryptionKeyId = encryptionKey.id;
|
|
50
|
+
}
|
|
51
|
+
var disks = Array.from({ length: args.size }, (_, i) => {
|
|
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"] });
|
|
62
|
+
});
|
|
63
|
+
var internalAddresses = Array.from({ length: args.size }, (_, i) => {
|
|
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
|
+
});
|
|
73
|
+
var publicAddresses;
|
|
74
|
+
if (args.network.assignPublicIp && args.network.reservePublicIp) {
|
|
75
|
+
publicAddresses = Array.from({ length: args.size }, (_, i) => {
|
|
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 });
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
var userData = interpolate`
|
|
87
|
+
#cloud-config
|
|
88
|
+
hostname: ${groupName}-{instance.index}
|
|
89
|
+
users:
|
|
90
|
+
- name: root
|
|
91
|
+
ssh-authorized-keys:
|
|
92
|
+
- ${sshKeyPair.publicKey}
|
|
93
|
+
sudo: ALL=(ALL) NOPASSWD:ALL
|
|
94
|
+
`.apply(trimIndentation);
|
|
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}`,
|
|
113
|
+
description: getResourceComment(),
|
|
114
|
+
platformId: args.platformId,
|
|
115
|
+
resources: {
|
|
116
|
+
cores: args.resources.cores,
|
|
117
|
+
memory: args.resources.memory,
|
|
118
|
+
coreFraction: args.resources.coreFraction
|
|
119
|
+
},
|
|
120
|
+
schedulingPolicy: {
|
|
121
|
+
preemptible: args.preemptible
|
|
122
|
+
},
|
|
123
|
+
bootDisk: {
|
|
124
|
+
diskId: `{disk_{instance.index}}`
|
|
125
|
+
},
|
|
126
|
+
networkInterfaces: [
|
|
127
|
+
{
|
|
128
|
+
subnetIds: [subnetId],
|
|
129
|
+
ipAddress: `{internal_address_{instance.index}}`,
|
|
130
|
+
nat: args.network.assignPublicIp,
|
|
131
|
+
natIpAddress: publicAddresses ? `{address_{instance.index}}` : undefined
|
|
132
|
+
}
|
|
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
|
+
])) : {}
|
|
148
|
+
},
|
|
149
|
+
serviceAccountId: inputs.connection.serviceAccountId
|
|
150
|
+
}, { provider });
|
|
151
|
+
var terminals = [];
|
|
152
|
+
var instances = await toPromise(instanceGroup.instances);
|
|
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
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
return server;
|
|
178
|
+
}));
|
|
179
|
+
var instance_group_default = outputs({
|
|
180
|
+
servers,
|
|
181
|
+
$statusFields: {
|
|
182
|
+
id: instanceGroup.id,
|
|
183
|
+
endpoints: servers.flatMap((server) => server.endpoints).map(l3EndpointToString)
|
|
184
|
+
},
|
|
185
|
+
$terminals: terminals
|
|
186
|
+
});
|
|
187
|
+
export {
|
|
188
|
+
instance_group_default as default
|
|
189
|
+
};
|
|
@@ -1,45 +1,63 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import { forUnit, toPromise, interpolate, getResourceComment } from '@highstate/pulumi';
|
|
6
|
-
import { getVpcSubnet, 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
|
-
var provider = await createProvider(inputs.connection);
|
|
11
|
-
var sshKeyPair = inputs.sshKeyPair ??
|
|
27
|
+
var provider = await createProvider(inputs.connection, args.cloudId);
|
|
28
|
+
var sshKeyPair = inputs.sshKeyPair ?? getSecret("sshPrivateKey", generateSshPrivateKey).apply(sshPrivateKeyToKeyPair);
|
|
12
29
|
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
|
-
|
|
19
|
-
|
|
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
|
-
var
|
|
31
|
-
|
|
32
|
-
{
|
|
42
|
+
var encryptionKeyId;
|
|
43
|
+
if (args.bootDisk.encrypted) {
|
|
44
|
+
const encryptionKey = new KmsSymmetricKey("encryption-key", {
|
|
33
45
|
name: vmName,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
description: getResourceComment(),
|
|
47
|
+
folderId: args.folderId ?? inputs.connection.defaultFolderId
|
|
48
|
+
}, { provider });
|
|
49
|
+
encryptionKeyId = encryptionKey.id;
|
|
50
|
+
}
|
|
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"] });
|
|
43
61
|
var userData = interpolate`
|
|
44
62
|
#cloud-config
|
|
45
63
|
hostname: ${vmName}
|
|
@@ -49,56 +67,50 @@ var userData = interpolate`
|
|
|
49
67
|
- ${sshKeyPair.publicKey}
|
|
50
68
|
sudo: ALL=(ALL) NOPASSWD:ALL
|
|
51
69
|
`.apply(trimIndentation);
|
|
52
|
-
var
|
|
70
|
+
var publicAddress;
|
|
53
71
|
if (args.network.assignPublicIp && args.network.reservePublicIp) {
|
|
54
|
-
|
|
55
|
-
"address",
|
|
56
|
-
{
|
|
57
|
-
name: vmName,
|
|
58
|
-
description: getResourceComment(),
|
|
59
|
-
externalIpv4Address: {
|
|
60
|
-
zoneId: inputs.connection.defaultZone
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
{ provider }
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
var instance = new ComputeInstance(
|
|
67
|
-
"virtual-machine",
|
|
68
|
-
{
|
|
72
|
+
publicAddress = new VpcAddress("address", {
|
|
69
73
|
name: vmName,
|
|
74
|
+
folderId: args.folderId ?? inputs.connection.defaultFolderId,
|
|
70
75
|
description: getResourceComment(),
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
platformId: args.platformId,
|
|
74
|
-
allowStoppingForUpdate: true,
|
|
75
|
-
resources: {
|
|
76
|
-
cores: args.resources.cores,
|
|
77
|
-
memory: args.resources.memory,
|
|
78
|
-
coreFraction: args.resources.coreFraction
|
|
79
|
-
},
|
|
80
|
-
bootDisk: {
|
|
81
|
-
diskId: disk.id
|
|
82
|
-
},
|
|
83
|
-
networkInterfaces: [
|
|
84
|
-
{
|
|
85
|
-
subnetId,
|
|
86
|
-
nat: args.network.assignPublicIp,
|
|
87
|
-
natIpAddress: address ? address.externalIpv4Address.apply((a) => a.address) : void 0
|
|
88
|
-
}
|
|
89
|
-
],
|
|
90
|
-
metadata: {
|
|
91
|
-
"user-data": userData
|
|
76
|
+
externalIpv4Address: {
|
|
77
|
+
zoneId: inputs.connection.defaultZone
|
|
92
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
|
|
93
95
|
},
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
)
|
|
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
|
+
}));
|
|
102
114
|
if (!publicIp) {
|
|
103
115
|
throw new Error("No IP address assigned to instance");
|
|
104
116
|
}
|
|
@@ -119,7 +131,6 @@ var virtual_machine_default = outputs({
|
|
|
119
131
|
},
|
|
120
132
|
$terminals: [terminal]
|
|
121
133
|
});
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
//# 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.
|
|
3
|
+
"version": "0.21.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"./connection": "./dist/connection/index.js",
|
|
10
10
|
"./disk": "./dist/disk/index.js",
|
|
11
11
|
"./existing-image": "./dist/existing-image/index.js",
|
|
12
|
-
"./virtual-machine": "./dist/virtual-machine/index.js"
|
|
12
|
+
"./virtual-machine": "./dist/virtual-machine/index.js",
|
|
13
|
+
"./instance-group": "./dist/instance-group/index.js"
|
|
13
14
|
},
|
|
14
15
|
"publishConfig": {
|
|
15
16
|
"access": "public"
|
|
@@ -19,27 +20,27 @@
|
|
|
19
20
|
"stdlib"
|
|
20
21
|
]
|
|
21
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
|
+
},
|
|
22
30
|
"dependencies": {
|
|
23
|
-
"@
|
|
24
|
-
"@highstate/
|
|
25
|
-
"@highstate/
|
|
26
|
-
"@highstate/
|
|
27
|
-
"@highstate/
|
|
28
|
-
"@
|
|
31
|
+
"@highstate/common": "0.20.0",
|
|
32
|
+
"@highstate/contract": "0.20.0",
|
|
33
|
+
"@highstate/library": "0.20.0",
|
|
34
|
+
"@highstate/pulumi": "0.20.0",
|
|
35
|
+
"@highstate/yandex-sdk": "0.19.1",
|
|
36
|
+
"@pulumi/pulumi": "3.232.0"
|
|
29
37
|
},
|
|
30
38
|
"devDependencies": {
|
|
31
39
|
"@biomejs/biome": "2.2.0",
|
|
32
|
-
"@
|
|
33
|
-
"@
|
|
40
|
+
"@highstate/cli": "0.20.0",
|
|
41
|
+
"@typescript/native-preview": "^7.0.0-dev.20250920.1"
|
|
34
42
|
},
|
|
35
43
|
"repository": {
|
|
36
44
|
"url": "https://github.com/highstate-io/highstate"
|
|
37
|
-
},
|
|
38
|
-
"scripts": {
|
|
39
|
-
"build": "highstate build",
|
|
40
|
-
"typecheck": "tsgo --noEmit --skipLibCheck",
|
|
41
|
-
"biome": "biome check --write --unsafe --error-on-warnings",
|
|
42
|
-
"biome:check": "biome check --error-on-warnings",
|
|
43
|
-
"generate-sdks": "./scripts/generate-sdks.sh"
|
|
44
45
|
}
|
|
45
|
-
}
|
|
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.
|
package/dist/chunk-MK37EG4O.js
DELETED
|
@@ -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) {
|
|
6
|
-
return await toPromise(
|
|
7
|
-
output(connection).apply((connection2) => {
|
|
8
|
-
return new Provider(connection2.cloudId, {
|
|
9
|
-
serviceAccountKeyFile: connection2.serviceAccountKeyFile,
|
|
10
|
-
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-MK37EG4O.js.map
|
|
21
|
-
//# sourceMappingURL=chunk-MK37EG4O.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider.ts"],"names":["connection"],"mappings":";;;;AAKA,eAAsB,eAAe,UAAA,EAAyD;AAC5F,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,uBAAuBA,WAAAA,CAAW,qBAAA;AAAA,QAClC,SAASA,WAAAA,CAAW,OAAA;AAAA,QACpB,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-MK37EG4O.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(connection: Input<yandex.Connection>): Promise<Provider> {\n return await toPromise(\n output(connection).apply(connection => {\n return new Provider(connection.cloudId, {\n serviceAccountKeyFile: connection.serviceAccountKeyFile,\n 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":";;;;;AAKA,IAAM,EAAE,IAAA,EAAM,OAAA,EAAS,SAAQ,GAAI,OAAA,CAAQ,OAAO,UAAU,CAAA;AAO5D,IAAM,2BAAA,GAA8B,MAAM,SAAA,CAAU,OAAA,CAAQ,qBAAqB,CAAA;AACjF,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,aAAwC,MAAA,CAAO;AAAA,EACnD,uBAAuB,OAAA,CAAQ,qBAAA;AAAA,EAC/B,SAAS,MAAA,CAAO,OAAA;AAAA,EAChB,iBAAiB,cAAA,CAAe,QAAA;AAAA,EAChC,WAAA,EAAa,KAAK,MAAA,CAAO,WAAA;AAAA,EACzB,QAAA,EAAU,KAAK,MAAA,CAAO;AACxB,CAAC,CAAA;AAED,IAAO,qBAAQ,OAAA,CAAQ;AAAA,EACrB,UAAA;AAAA,EAEA,aAAA,EAAe;AAAA,IACb,OAAA,EAAS;AAAA,MACP,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 type { Output } from \"@highstate/pulumi\"\nimport { yandex } from \"@highstate/library\"\nimport { forUnit, output, 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.serviceAccountKeyFile)\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: Output<yandex.Connection> = output({\n serviceAccountKeyFile: secrets.serviceAccountKeyFile,\n cloudId: folder.cloudId,\n defaultFolderId: serviceAccount.folderId,\n defaultZone: args.region.defaultZone,\n regionId: args.region.id,\n})\n\nexport default outputs({\n connection,\n\n $statusFields: {\n cloudId: {\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"]}
|
package/dist/disk/index.js.map
DELETED
|
@@ -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,IAAA,EAAM;AAAA,IACJ,IAAI,IAAA,CAAK;AAAA,GACX;AAAA,EACA,aAAA,EAAe;AAAA,IACb,IAAI,IAAA,CAAK;AAAA;AAEb,CAAC","file":"index.js","sourcesContent":["import { yandex } from \"@highstate/library\"\nimport { forUnit, getResourceComment } 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: {\n id: disk.id,\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,KAAA,GAAQ,MAAM,eAAA,CAAgB,EAAE,OAAA,EAAS,KAAK,EAAA,EAAG,EAAG,EAAE,QAAA,EAAU,CAAA;AAEtE,IAAO,yBAAQ,OAAA,CAAQ;AAAA,EACrB,KAAA,EAAO;AAAA,IACL,IAAI,KAAA,CAAM;AAAA,GACZ;AAAA,EACA,aAAA,EAAe;AAAA,IACb,MAAM,KAAA,CAAM;AAAA;AAEhB,CAAC","file":"index.js","sourcesContent":["import { yandex } from \"@highstate/library\"\nimport { forUnit } 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 image = await getComputeImage({ imageId: args.id }, { provider })\n\nexport default outputs({\n image: {\n id: image.id,\n },\n $statusFields: {\n name: image.name,\n },\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, toPromise } from \"@highstate/pulumi\"\nimport { ComputeDisk, ComputeInstance, getVpcSubnet, VpcAddress } 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)\n\nconst sshKeyPair =\n inputs.sshKeyPair ?? sshPrivateKeyToKeyPair(getSecret(\"sshPrivateKey\", generateSshPrivateKey))\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 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: inputs.connection.defaultFolderId,\n zone: inputs.connection.defaultZone,\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 address: VpcAddress | undefined\n\nif (args.network.assignPublicIp && args.network.reservePublicIp) {\n address = new VpcAddress(\n \"address\",\n {\n name: vmName,\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: 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 bootDisk: {\n diskId: disk.id,\n },\n\n networkInterfaces: [\n {\n subnetId: subnetId,\n nat: args.network.assignPublicIp,\n natIpAddress: address ? address.externalIpv4Address.apply(a => a!.address) : 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"]}
|