@goldstack/template-hetzner-vps-cli 0.1.2
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/README.md +5 -0
- package/bin/template +12 -0
- package/dist/src/awsCredentials.d.ts +13 -0
- package/dist/src/awsCredentials.d.ts.map +1 -0
- package/dist/src/awsCredentials.js +211 -0
- package/dist/src/awsCredentials.js.map +1 -0
- package/dist/src/createZip.d.ts +2 -0
- package/dist/src/createZip.d.ts.map +1 -0
- package/dist/src/createZip.js +27 -0
- package/dist/src/createZip.js.map +1 -0
- package/dist/src/deploymentsS3Bucket.d.ts +13 -0
- package/dist/src/deploymentsS3Bucket.d.ts.map +1 -0
- package/dist/src/deploymentsS3Bucket.js +103 -0
- package/dist/src/deploymentsS3Bucket.js.map +1 -0
- package/dist/src/initScriptUpdate.d.ts +3 -0
- package/dist/src/initScriptUpdate.d.ts.map +1 -0
- package/dist/src/initScriptUpdate.js +19 -0
- package/dist/src/initScriptUpdate.js.map +1 -0
- package/dist/src/templateHetznerVPSCli.d.ts +3 -0
- package/dist/src/templateHetznerVPSCli.d.ts.map +1 -0
- package/dist/src/templateHetznerVPSCli.js +118 -0
- package/dist/src/templateHetznerVPSCli.js.map +1 -0
- package/dist/src/uploadCredentials.d.ts +7 -0
- package/dist/src/uploadCredentials.d.ts.map +1 -0
- package/dist/src/uploadCredentials.js +45 -0
- package/dist/src/uploadCredentials.js.map +1 -0
- package/dist/src/uploadZip.d.ts +6 -0
- package/dist/src/uploadZip.d.ts.map +1 -0
- package/dist/src/uploadZip.js +21 -0
- package/dist/src/uploadZip.js.map +1 -0
- package/package.json +76 -0
package/README.md
ADDED
package/bin/template
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
4
|
+
require('source-map-support').install();
|
|
5
|
+
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
7
|
+
require('./../dist/src/templateHetznerVPSCli')
|
|
8
|
+
.run(process.argv)
|
|
9
|
+
.catch((e) => {
|
|
10
|
+
console.log(e);
|
|
11
|
+
process.exit(1);
|
|
12
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { HetznerVPSDeployment } from '@goldstack/template-hetzner-vps';
|
|
2
|
+
export declare function assertAWSCredentials(params: {
|
|
3
|
+
deployment: HetznerVPSDeployment;
|
|
4
|
+
}): Promise<void>;
|
|
5
|
+
export declare function assertUserWithReadOnlyS3Access(params: {
|
|
6
|
+
deployment: HetznerVPSDeployment;
|
|
7
|
+
bucketName: string;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
export declare function deleteUserAndResources(params: {
|
|
10
|
+
deployment: HetznerVPSDeployment;
|
|
11
|
+
vpsUserName: string;
|
|
12
|
+
}): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=awsCredentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"awsCredentials.d.ts","sourceRoot":"","sources":["../../src/awsCredentials.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAyFvE,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,UAAU,EAAE,oBAAoB,CAAC;CAClC,GAAG,OAAO,CAAC,IAAI,CAAC,CA6ChB;AAED,wBAAsB,8BAA8B,CAAC,MAAM,EAAE;IAC3D,UAAU,EAAE,oBAAoB,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0ChB;AAED,wBAAsB,sBAAsB,CAAC,MAAM,EAAE;IACnD,UAAU,EAAE,oBAAoB,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;CACrB,iBAkEA"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.deleteUserAndResources = exports.assertUserWithReadOnlyS3Access = exports.assertAWSCredentials = void 0;
|
|
7
|
+
const client_iam_1 = require("@aws-sdk/client-iam");
|
|
8
|
+
const infra_aws_1 = require("@goldstack/infra-aws");
|
|
9
|
+
const utils_cli_1 = require("@goldstack/utils-cli");
|
|
10
|
+
const utils_sh_1 = require("@goldstack/utils-sh");
|
|
11
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
12
|
+
const fs_1 = require("fs");
|
|
13
|
+
async function checkIfUserExists(iamClient, userName) {
|
|
14
|
+
try {
|
|
15
|
+
const getUserCommand = new client_iam_1.GetUserCommand({ UserName: userName });
|
|
16
|
+
await iamClient.send(getUserCommand);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
if (error.name === 'NoSuchEntityException') {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function createUser(iamClient, userName) {
|
|
27
|
+
(0, utils_cli_1.logger)().info(`Creating user ${userName}...`);
|
|
28
|
+
const createUserCommand = new client_iam_1.CreateUserCommand({ UserName: userName });
|
|
29
|
+
const createUserResponse = await iamClient.send(createUserCommand);
|
|
30
|
+
if (!createUserResponse.User) {
|
|
31
|
+
throw new Error('User could not be created.');
|
|
32
|
+
}
|
|
33
|
+
(0, utils_cli_1.logger)().info(`User ${userName} created.`);
|
|
34
|
+
}
|
|
35
|
+
async function createAccessKey(iamClient, userName) {
|
|
36
|
+
(0, utils_cli_1.logger)().info(`Creating access key for user ${userName}...`);
|
|
37
|
+
const createAccessKeyCommand = new client_iam_1.CreateAccessKeyCommand({
|
|
38
|
+
UserName: userName,
|
|
39
|
+
});
|
|
40
|
+
const createAccessKeyResponse = await iamClient.send(createAccessKeyCommand);
|
|
41
|
+
if (!createAccessKeyResponse.AccessKey) {
|
|
42
|
+
throw new Error('Cannot create new access key for user.');
|
|
43
|
+
}
|
|
44
|
+
(0, utils_cli_1.logger)().info(`Access key created for user ${userName}.`);
|
|
45
|
+
return {
|
|
46
|
+
accessKeyId: createAccessKeyResponse.AccessKey.AccessKeyId,
|
|
47
|
+
secretAccessKey: createAccessKeyResponse.AccessKey.SecretAccessKey,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async function attachPolicyToUser(iamClient, userName, bucketName) {
|
|
51
|
+
var _a, _b;
|
|
52
|
+
(0, utils_cli_1.logger)().info(`Attaching policy to user ${userName} for bucket ${bucketName}...`);
|
|
53
|
+
const policy = {
|
|
54
|
+
Version: '2012-10-17',
|
|
55
|
+
Statement: [
|
|
56
|
+
{
|
|
57
|
+
Effect: 'Allow',
|
|
58
|
+
Action: ['s3:ListBucket', 's3:GetObject'],
|
|
59
|
+
Resource: [
|
|
60
|
+
`arn:aws:s3:::${bucketName}`,
|
|
61
|
+
`arn:aws:s3:::${bucketName}/*`,
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
const createPolicyCommand = new client_iam_1.CreatePolicyCommand({
|
|
67
|
+
PolicyName: `bucket-access-${bucketName}-${userName}`,
|
|
68
|
+
PolicyDocument: JSON.stringify(policy),
|
|
69
|
+
});
|
|
70
|
+
const createPolicyResponse = await iamClient.send(createPolicyCommand);
|
|
71
|
+
(0, utils_cli_1.logger)().info(`Policy created successfully: ${(_a = createPolicyResponse.Policy) === null || _a === void 0 ? void 0 : _a.Arn}`);
|
|
72
|
+
const attachPolicyCommand = new client_iam_1.AttachUserPolicyCommand({
|
|
73
|
+
PolicyArn: (_b = createPolicyResponse.Policy) === null || _b === void 0 ? void 0 : _b.Arn,
|
|
74
|
+
UserName: userName,
|
|
75
|
+
});
|
|
76
|
+
await iamClient.send(attachPolicyCommand);
|
|
77
|
+
(0, utils_cli_1.logger)().info(`Policy attached to user ${userName}.`);
|
|
78
|
+
}
|
|
79
|
+
async function assertAWSCredentials(params) {
|
|
80
|
+
if ((0, fs_1.existsSync)('./dist/credentials/credentials')) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
(0, utils_cli_1.logger)().info('AWS credentials for deployment access not found. Creating deleting all existing access keys and creating new access key.');
|
|
84
|
+
const { deployment } = params;
|
|
85
|
+
const userName = deployment.configuration.vpsIAMUserName;
|
|
86
|
+
if (!userName) {
|
|
87
|
+
throw new Error(`IAM user name for bucket access not defined ${userName}`);
|
|
88
|
+
}
|
|
89
|
+
const awsUser = await (0, infra_aws_1.getAWSUser)(deployment.awsUser);
|
|
90
|
+
const credentials = await (0, infra_aws_1.getAWSCredentials)(awsUser);
|
|
91
|
+
const iamClient = new client_iam_1.IAMClient({
|
|
92
|
+
credentials: credentials,
|
|
93
|
+
region: deployment.awsRegion,
|
|
94
|
+
});
|
|
95
|
+
// before creating our new access key, we first delete all existing ones
|
|
96
|
+
await deleteAllAccessKeys(userName, iamClient);
|
|
97
|
+
const accessKeys = await createAccessKey(iamClient, userName);
|
|
98
|
+
(0, utils_cli_1.logger)().info(`Access key created: ${accessKeys.accessKeyId}`);
|
|
99
|
+
let existingSecrets = {};
|
|
100
|
+
if ((0, fs_1.existsSync)('./dist/credentials/credentials')) {
|
|
101
|
+
existingSecrets = JSON.parse((0, utils_sh_1.read)('./dist/credentials/credentials'));
|
|
102
|
+
}
|
|
103
|
+
const vpsCredentials = {
|
|
104
|
+
...existingSecrets,
|
|
105
|
+
...accessKeys,
|
|
106
|
+
awsRegion: deployment.awsRegion,
|
|
107
|
+
};
|
|
108
|
+
(0, utils_sh_1.mkdir)('-p', './dist/credentials');
|
|
109
|
+
(0, utils_sh_1.write)(JSON.stringify(vpsCredentials, null, 2), './dist/credentials/credentials');
|
|
110
|
+
}
|
|
111
|
+
exports.assertAWSCredentials = assertAWSCredentials;
|
|
112
|
+
async function assertUserWithReadOnlyS3Access(params) {
|
|
113
|
+
if (!params.deployment.configuration.vpsIAMUserName) {
|
|
114
|
+
const userHash = crypto_1.default.randomBytes(6).toString('hex');
|
|
115
|
+
params.deployment.configuration.vpsIAMUserName = `vps-${params.deployment.name}-${params.deployment.configuration.serverName}-${userHash}`;
|
|
116
|
+
(0, utils_cli_1.logger)().info({
|
|
117
|
+
userName: params.deployment.configuration.vpsIAMUserName,
|
|
118
|
+
}, 'No AWS IAM user name defined for deployments bucket access. Generated user name');
|
|
119
|
+
}
|
|
120
|
+
const userName = params.deployment.configuration.vpsIAMUserName;
|
|
121
|
+
const { bucketName, deployment } = params;
|
|
122
|
+
const awsUser = await (0, infra_aws_1.getAWSUser)(deployment.awsUser);
|
|
123
|
+
const credentials = await (0, infra_aws_1.getAWSCredentials)(awsUser);
|
|
124
|
+
const iamClient = new client_iam_1.IAMClient({
|
|
125
|
+
credentials: credentials,
|
|
126
|
+
region: deployment.awsRegion,
|
|
127
|
+
});
|
|
128
|
+
try {
|
|
129
|
+
const userExists = await checkIfUserExists(iamClient, userName);
|
|
130
|
+
if (!userExists) {
|
|
131
|
+
(0, utils_cli_1.logger)().info('AWS IAM user for deployment bucket access does not exist. Creating user.', { userName });
|
|
132
|
+
await createUser(iamClient, userName);
|
|
133
|
+
await attachPolicyToUser(iamClient, userName, bucketName);
|
|
134
|
+
(0, utils_cli_1.logger)().info('AWS IAM user created.');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
(0, utils_cli_1.logger)().error(`Error creating user or attaching policy: ${error.message}`);
|
|
139
|
+
throw new Error(`Error creating user or attaching policy: ${error.message}`);
|
|
140
|
+
}
|
|
141
|
+
(0, utils_cli_1.logger)().info(`IAM user used for deployments via S3 bucket: ${userName}`);
|
|
142
|
+
}
|
|
143
|
+
exports.assertUserWithReadOnlyS3Access = assertUserWithReadOnlyS3Access;
|
|
144
|
+
async function deleteUserAndResources(params) {
|
|
145
|
+
const userName = params.vpsUserName;
|
|
146
|
+
const awsUser = await (0, infra_aws_1.getAWSUser)(params.deployment.awsUser);
|
|
147
|
+
const credentials = await (0, infra_aws_1.getAWSCredentials)(awsUser);
|
|
148
|
+
const iamClient = new client_iam_1.IAMClient({
|
|
149
|
+
credentials: credentials,
|
|
150
|
+
region: params.deployment.awsRegion,
|
|
151
|
+
});
|
|
152
|
+
(0, utils_cli_1.logger)().info(`Deleting user ${userName} and all associated resources.`);
|
|
153
|
+
try {
|
|
154
|
+
// Step 1: List and delete all access keys for the user
|
|
155
|
+
(0, utils_cli_1.logger)().info('Deleting access keys');
|
|
156
|
+
await deleteAllAccessKeys(userName, iamClient);
|
|
157
|
+
// Step 2: List and detach all policies attached to the user
|
|
158
|
+
const listAttachedUserPoliciesCommand = new client_iam_1.ListAttachedUserPoliciesCommand({
|
|
159
|
+
UserName: userName,
|
|
160
|
+
});
|
|
161
|
+
const listAttachedUserPoliciesResponse = await iamClient.send(listAttachedUserPoliciesCommand);
|
|
162
|
+
if (!listAttachedUserPoliciesResponse.AttachedPolicies) {
|
|
163
|
+
throw new Error('Cannot read attached policies');
|
|
164
|
+
}
|
|
165
|
+
for (const policy of listAttachedUserPoliciesResponse.AttachedPolicies) {
|
|
166
|
+
const detachUserPolicyCommand = new client_iam_1.DetachUserPolicyCommand({
|
|
167
|
+
UserName: userName,
|
|
168
|
+
PolicyArn: policy.PolicyArn,
|
|
169
|
+
});
|
|
170
|
+
await iamClient.send(detachUserPolicyCommand);
|
|
171
|
+
if (!policy.PolicyName) {
|
|
172
|
+
throw new Error('Could not load policy for detaching it ' + policy.PolicyName);
|
|
173
|
+
}
|
|
174
|
+
// Step 3: Delete the policy if it was created by the create function
|
|
175
|
+
if (policy.PolicyName.startsWith('bucket-access-')) {
|
|
176
|
+
(0, utils_cli_1.logger)().info(`Deleting policy ${policy.PolicyName}`);
|
|
177
|
+
const deletePolicyCommand = new client_iam_1.DeletePolicyCommand({
|
|
178
|
+
PolicyArn: policy.PolicyArn,
|
|
179
|
+
});
|
|
180
|
+
await iamClient.send(deletePolicyCommand);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Step 4: Delete the user
|
|
184
|
+
const deleteUserCommand = new client_iam_1.DeleteUserCommand({ UserName: userName });
|
|
185
|
+
(0, utils_cli_1.logger)().info('Deleting user');
|
|
186
|
+
await iamClient.send(deleteUserCommand);
|
|
187
|
+
(0, utils_cli_1.logger)().info(`User ${userName} and all associated resources have been deleted.`);
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
(0, utils_cli_1.logger)().error(`Error deleting user or resources: ${error.message}`);
|
|
191
|
+
throw new Error(`Error deleting user or resources: ${error.message}`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
exports.deleteUserAndResources = deleteUserAndResources;
|
|
195
|
+
async function deleteAllAccessKeys(userName, iamClient) {
|
|
196
|
+
const listAccessKeysCommand = new client_iam_1.ListAccessKeysCommand({
|
|
197
|
+
UserName: userName,
|
|
198
|
+
});
|
|
199
|
+
const listAccessKeysResponse = await iamClient.send(listAccessKeysCommand);
|
|
200
|
+
if (!listAccessKeysResponse.AccessKeyMetadata) {
|
|
201
|
+
throw new Error('Cannot read access key metadata');
|
|
202
|
+
}
|
|
203
|
+
for (const accessKey of listAccessKeysResponse.AccessKeyMetadata) {
|
|
204
|
+
const deleteAccessKeyCommand = new client_iam_1.DeleteAccessKeyCommand({
|
|
205
|
+
UserName: userName,
|
|
206
|
+
AccessKeyId: accessKey.AccessKeyId,
|
|
207
|
+
});
|
|
208
|
+
await iamClient.send(deleteAccessKeyCommand);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=awsCredentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"awsCredentials.js","sourceRoot":"","sources":["../../src/awsCredentials.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createZip.d.ts","sourceRoot":"","sources":["../../src/createZip.ts"],"names":[],"mappings":"AAIA,wBAAsB,SAAS,kBAwB9B"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createZip = void 0;
|
|
4
|
+
const utils_sh_1 = require("@goldstack/utils-sh");
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
6
|
+
const fs_1 = require("fs");
|
|
7
|
+
async function createZip() {
|
|
8
|
+
(0, utils_sh_1.mkdir)('-p', './dist/app');
|
|
9
|
+
(0, utils_sh_1.rm)('-f', './dist/app/server.zip');
|
|
10
|
+
await (0, utils_sh_1.zip)({
|
|
11
|
+
directory: './server',
|
|
12
|
+
target: './dist/app/server.zip',
|
|
13
|
+
});
|
|
14
|
+
const hash = (0, crypto_1.createHash)('sha256');
|
|
15
|
+
const zipFilePath = './dist/app/server.zip';
|
|
16
|
+
const zipFileContent = (0, fs_1.readFileSync)(zipFilePath);
|
|
17
|
+
hash.update(zipFileContent);
|
|
18
|
+
let hashValue = hash.digest('hex');
|
|
19
|
+
const credentialsHash = (0, crypto_1.createHash)('sha256');
|
|
20
|
+
const credentialsFilePath = './dist/credentials/credentials';
|
|
21
|
+
const credentialsFileContent = (0, fs_1.readFileSync)(credentialsFilePath);
|
|
22
|
+
credentialsHash.update(credentialsFileContent);
|
|
23
|
+
hashValue += credentialsHash.digest('hex');
|
|
24
|
+
(0, fs_1.writeFileSync)('./dist/app/current', hashValue);
|
|
25
|
+
}
|
|
26
|
+
exports.createZip = createZip;
|
|
27
|
+
//# sourceMappingURL=createZip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createZip.js","sourceRoot":"","sources":["../../src/createZip.ts"],"names":[],"mappings":";;;AAAA,kDAA2D;AAC3D,mCAAoC;AACpC,2BAAiD;AAE1C,KAAK,UAAU,SAAS;IAC7B,IAAA,gBAAK,EAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAE1B,IAAA,aAAE,EAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC;IAElC,MAAM,IAAA,cAAG,EAAC;QACR,SAAS,EAAE,UAAU;QACrB,MAAM,EAAE,uBAAuB;KAChC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,WAAW,GAAG,uBAAuB,CAAC;IAC5C,MAAM,cAAc,GAAG,IAAA,iBAAY,EAAC,WAAW,CAAC,CAAC;IACjD,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAE5B,IAAI,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEnC,MAAM,eAAe,GAAG,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,mBAAmB,GAAG,gCAAgC,CAAC;IAC7D,MAAM,sBAAsB,GAAG,IAAA,iBAAY,EAAC,mBAAmB,CAAC,CAAC;IACjE,eAAe,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAC/C,SAAS,IAAI,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAE3C,IAAA,kBAAa,EAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;AACjD,CAAC;AAxBD,8BAwBC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { HetznerVPSDeployment, HetznerVPSPackage } from '@goldstack/template-hetzner-vps';
|
|
2
|
+
import { PackageConfig } from '@goldstack/utils-package-config';
|
|
3
|
+
export interface DeploymentsS3BucketParams {
|
|
4
|
+
deployment: string;
|
|
5
|
+
packageConfig: PackageConfig<HetznerVPSPackage, HetznerVPSDeployment>;
|
|
6
|
+
}
|
|
7
|
+
export declare function assertDeploymentsS3Bucket(params: DeploymentsS3BucketParams): Promise<void>;
|
|
8
|
+
export interface DeleteDeploymentsS3BucketParams {
|
|
9
|
+
deployment: string;
|
|
10
|
+
packageConfig: PackageConfig<HetznerVPSPackage, HetznerVPSDeployment>;
|
|
11
|
+
}
|
|
12
|
+
export declare function deleteDeploymentsS3Bucket(params: DeleteDeploymentsS3BucketParams): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=deploymentsS3Bucket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploymentsS3Bucket.d.ts","sourceRoot":"","sources":["../../src/deploymentsS3Bucket.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAchE,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,aAAa,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,CAAC;CACvE;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,yBAAyB,iBAgClC;AAED,MAAM,WAAW,+BAA+B;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,aAAa,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,CAAC;CACvE;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,+BAA+B,iBAyBxC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.deleteDeploymentsS3Bucket = exports.assertDeploymentsS3Bucket = void 0;
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
+
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
9
|
+
const infra_aws_1 = require("@goldstack/infra-aws");
|
|
10
|
+
const utils_cli_1 = require("@goldstack/utils-cli");
|
|
11
|
+
async function assertDeploymentsS3Bucket(params) {
|
|
12
|
+
const deployment = params.packageConfig.getDeployment(params.deployment);
|
|
13
|
+
const awsUser = await (0, infra_aws_1.getAWSUser)(deployment.awsUser);
|
|
14
|
+
const credentials = await (0, infra_aws_1.getAWSCredentials)(awsUser);
|
|
15
|
+
const s3Client = new client_s3_1.S3Client({
|
|
16
|
+
credentials: credentials,
|
|
17
|
+
region: deployment.awsRegion,
|
|
18
|
+
});
|
|
19
|
+
if (!deployment.configuration.deploymentsS3Bucket) {
|
|
20
|
+
const projectHash = crypto_1.default.randomBytes(6).toString('hex');
|
|
21
|
+
deployment.configuration.deploymentsS3Bucket = `goldstack-deployments-${deployment.name}-${deployment.configuration.serverName}-${projectHash}`;
|
|
22
|
+
(0, utils_cli_1.logger)().info('Deployments bucket does not exist. Generating bucket name.', {
|
|
23
|
+
bucketName: deployment.configuration.deploymentsS3Bucket,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
await assertS3Bucket({
|
|
27
|
+
s3: s3Client,
|
|
28
|
+
bucketName: deployment.configuration.deploymentsS3Bucket,
|
|
29
|
+
});
|
|
30
|
+
(0, utils_cli_1.logger)().info(`S3 bucket used for deployments: ${deployment.configuration.deploymentsS3Bucket}`);
|
|
31
|
+
}
|
|
32
|
+
exports.assertDeploymentsS3Bucket = assertDeploymentsS3Bucket;
|
|
33
|
+
async function deleteDeploymentsS3Bucket(params) {
|
|
34
|
+
const deployment = params.packageConfig.getDeployment(params.deployment);
|
|
35
|
+
const awsUser = await (0, infra_aws_1.getAWSUser)(deployment.awsUser);
|
|
36
|
+
const credentials = await (0, infra_aws_1.getAWSCredentials)(awsUser);
|
|
37
|
+
const s3Client = new client_s3_1.S3Client({
|
|
38
|
+
credentials: credentials,
|
|
39
|
+
region: deployment.awsRegion,
|
|
40
|
+
});
|
|
41
|
+
if (!deployment.configuration.deploymentsS3Bucket) {
|
|
42
|
+
(0, utils_cli_1.logger)().warn('No deployments S3 bucket was destroyed since S3 bucket name not specified. This could be due to the S3 bucket not having been created yet.');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
(0, utils_cli_1.logger)().info(`Deleting S3 bucket: ${deployment.configuration.deploymentsS3Bucket}`);
|
|
46
|
+
await deleteS3Bucket({
|
|
47
|
+
s3: s3Client,
|
|
48
|
+
bucketName: deployment.configuration.deploymentsS3Bucket,
|
|
49
|
+
});
|
|
50
|
+
(0, utils_cli_1.logger)().info('S3 bucket deleted');
|
|
51
|
+
}
|
|
52
|
+
exports.deleteDeploymentsS3Bucket = deleteDeploymentsS3Bucket;
|
|
53
|
+
const assertS3Bucket = async (params) => {
|
|
54
|
+
const bucketParams = {
|
|
55
|
+
Bucket: params.bucketName,
|
|
56
|
+
};
|
|
57
|
+
try {
|
|
58
|
+
await params.s3.send(new client_s3_1.CreateBucketCommand(bucketParams));
|
|
59
|
+
(0, utils_cli_1.logger)().info('S3 bucket created', { bucketName: bucketParams.Bucket });
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
// if bucket already exists, ignore error
|
|
63
|
+
if (!(e instanceof client_s3_1.BucketAlreadyOwnedByYou)) {
|
|
64
|
+
(0, utils_cli_1.logger)().error('Cannot create bucket ', params.bucketName, ' error code', e.code);
|
|
65
|
+
throw new Error('Cannot create S3 state bucket: ' + e.message);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const deleteAllObjectsFromBucket = async (s3, bucketName) => {
|
|
70
|
+
let continuationToken = undefined;
|
|
71
|
+
do {
|
|
72
|
+
// List objects in the bucket
|
|
73
|
+
const listResponse = await s3.send(new client_s3_1.ListObjectsV2Command({
|
|
74
|
+
Bucket: bucketName,
|
|
75
|
+
ContinuationToken: continuationToken,
|
|
76
|
+
}));
|
|
77
|
+
// Check if there are any objects to delete
|
|
78
|
+
if (listResponse.Contents && listResponse.Contents.length > 0) {
|
|
79
|
+
// Delete listed objects
|
|
80
|
+
const deleteParams = {
|
|
81
|
+
Bucket: bucketName,
|
|
82
|
+
Delete: {
|
|
83
|
+
Objects: listResponse.Contents.map((object) => ({ Key: object.Key })),
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
await s3.send(new client_s3_1.DeleteObjectsCommand(deleteParams));
|
|
87
|
+
}
|
|
88
|
+
// Check if more objects are to be listed (pagination)
|
|
89
|
+
continuationToken = listResponse.NextContinuationToken;
|
|
90
|
+
} while (continuationToken);
|
|
91
|
+
};
|
|
92
|
+
const deleteS3Bucket = async (params) => {
|
|
93
|
+
try {
|
|
94
|
+
// First, delete all objects from the bucket
|
|
95
|
+
await deleteAllObjectsFromBucket(params.s3, params.bucketName);
|
|
96
|
+
// Then, delete the empty bucket
|
|
97
|
+
await params.s3.send(new client_s3_1.DeleteBucketCommand({ Bucket: params.bucketName }));
|
|
98
|
+
}
|
|
99
|
+
catch (e) {
|
|
100
|
+
throw e; // Rethrow the error to handle it in the calling code if necessary
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=deploymentsS3Bucket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploymentsS3Bucket.js","sourceRoot":"","sources":["../../src/deploymentsS3Bucket.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initScriptUpdate.d.ts","sourceRoot":"","sources":["../../src/initScriptUpdate.ts"],"names":[],"mappings":"AAEA,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAQzD;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAQtD"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updateS3Bucket = exports.updateCredentialsUrl = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
function updateCredentialsUrl(newUrl) {
|
|
6
|
+
const filePath = './infra/aws/cloud-init.yml';
|
|
7
|
+
const fileContent = (0, fs_1.readFileSync)(filePath, 'utf8');
|
|
8
|
+
const updatedContent = fileContent.replace(/CREDENTIALS_URL="[^"]*"/, `CREDENTIALS_URL="${newUrl}"`);
|
|
9
|
+
(0, fs_1.writeFileSync)(filePath, updatedContent, 'utf8');
|
|
10
|
+
}
|
|
11
|
+
exports.updateCredentialsUrl = updateCredentialsUrl;
|
|
12
|
+
function updateS3Bucket(newBucket) {
|
|
13
|
+
const filePath = './infra/aws/cloud-init.yml';
|
|
14
|
+
const fileContent = (0, fs_1.readFileSync)(filePath, 'utf8');
|
|
15
|
+
const updatedContent = fileContent.replace(/S3_BUCKET="[^"]*"/, `S3_BUCKET="${newBucket}"`);
|
|
16
|
+
(0, fs_1.writeFileSync)(filePath, updatedContent, 'utf8');
|
|
17
|
+
}
|
|
18
|
+
exports.updateS3Bucket = updateS3Bucket;
|
|
19
|
+
//# sourceMappingURL=initScriptUpdate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initScriptUpdate.js","sourceRoot":"","sources":["../../src/initScriptUpdate.ts"],"names":[],"mappings":";;;AAAA,2BAAiD;AAEjD,SAAgB,oBAAoB,CAAC,MAAc;IACjD,MAAM,QAAQ,GAAG,4BAA4B,CAAC;IAC9C,MAAM,WAAW,GAAG,IAAA,iBAAY,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACnD,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,CACxC,yBAAyB,EACzB,oBAAoB,MAAM,GAAG,CAC9B,CAAC;IACF,IAAA,kBAAa,EAAC,QAAQ,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AARD,oDAQC;AAED,SAAgB,cAAc,CAAC,SAAiB;IAC9C,MAAM,QAAQ,GAAG,4BAA4B,CAAC;IAC9C,MAAM,WAAW,GAAG,IAAA,iBAAY,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACnD,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,CACxC,mBAAmB,EACnB,cAAc,SAAS,GAAG,CAC3B,CAAC;IACF,IAAA,kBAAa,EAAC,QAAQ,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AARD,wCAQC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templateHetznerVPSCli.d.ts","sourceRoot":"","sources":["../../src/templateHetznerVPSCli.ts"],"names":[],"mappings":"AA+BA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAexC,eAAO,MAAM,GAAG,SAAgB,MAAM,EAAE,KAAG,QAAQ,IAAI,CA0HtD,CAAC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.run = exports.createZip = void 0;
|
|
7
|
+
const utils_package_1 = require("@goldstack/utils-package");
|
|
8
|
+
const utils_cli_1 = require("@goldstack/utils-cli");
|
|
9
|
+
const deploymentsS3Bucket_1 = require("./deploymentsS3Bucket");
|
|
10
|
+
const utils_terraform_1 = require("@goldstack/utils-terraform");
|
|
11
|
+
const utils_terraform_aws_1 = require("@goldstack/utils-terraform-aws");
|
|
12
|
+
const utils_terraform_hetzner_1 = require("@goldstack/utils-terraform-hetzner");
|
|
13
|
+
const utils_package_config_1 = require("@goldstack/utils-package-config");
|
|
14
|
+
const yargs_1 = __importDefault(require("yargs"));
|
|
15
|
+
const uploadZip_1 = require("./uploadZip");
|
|
16
|
+
const awsCredentials_1 = require("./awsCredentials");
|
|
17
|
+
var createZip_1 = require("./createZip");
|
|
18
|
+
Object.defineProperty(exports, "createZip", { enumerable: true, get: function () { return createZip_1.createZip; } });
|
|
19
|
+
const utils_sh_1 = require("@goldstack/utils-sh");
|
|
20
|
+
const uploadCredentials_1 = require("./uploadCredentials");
|
|
21
|
+
const initScriptUpdate_1 = require("./initScriptUpdate");
|
|
22
|
+
const createZip_2 = require("./createZip");
|
|
23
|
+
const utils_cli_2 = require("@goldstack/utils-cli");
|
|
24
|
+
const run = async (args) => {
|
|
25
|
+
await (0, utils_cli_1.wrapCli)(async () => {
|
|
26
|
+
const argv = await (0, utils_package_1.buildCli)({
|
|
27
|
+
yargs: yargs_1.default,
|
|
28
|
+
deployCommands: (0, utils_package_1.buildDeployCommands)(),
|
|
29
|
+
infraCommands: (0, utils_terraform_1.infraCommands)(),
|
|
30
|
+
})
|
|
31
|
+
.help()
|
|
32
|
+
.parse();
|
|
33
|
+
const packageConfig = new utils_package_config_1.PackageConfig({
|
|
34
|
+
packagePath: './',
|
|
35
|
+
});
|
|
36
|
+
const config = packageConfig.getConfig();
|
|
37
|
+
const command = argv._[0];
|
|
38
|
+
const [, , , ...opArgs] = args;
|
|
39
|
+
if (command === 'deploy') {
|
|
40
|
+
(0, utils_cli_2.logger)().info('Starting deployment to Hetzner VPS.');
|
|
41
|
+
const deployment = packageConfig.getDeployment(opArgs[0]);
|
|
42
|
+
await (0, createZip_2.createZip)();
|
|
43
|
+
await (0, uploadCredentials_1.uploadCredentials)({ deployment });
|
|
44
|
+
await (0, uploadZip_1.uploadZip)({
|
|
45
|
+
deployment,
|
|
46
|
+
});
|
|
47
|
+
(0, utils_cli_2.logger)().info('Deployment to Hetzner VPS completed. Server should restart in a few seconds.');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (command === 'infra') {
|
|
51
|
+
const deployment = packageConfig.getDeployment(opArgs[1]);
|
|
52
|
+
const infrastructureOp = opArgs[0];
|
|
53
|
+
(0, utils_cli_2.logger)().info(`Running infrastructure operation ${infrastructureOp} for ${deployment.name}`);
|
|
54
|
+
// use remote managed state from Terraform
|
|
55
|
+
await (0, utils_terraform_aws_1.terraformAwsCli)(['create-state', opArgs[1]]);
|
|
56
|
+
if (infrastructureOp === 'up' || infrastructureOp === 'apply') {
|
|
57
|
+
// Ensure S3 Bucket for deployments exist
|
|
58
|
+
await (0, deploymentsS3Bucket_1.assertDeploymentsS3Bucket)({
|
|
59
|
+
packageConfig,
|
|
60
|
+
deployment: opArgs[1],
|
|
61
|
+
});
|
|
62
|
+
if (!deployment.configuration.deploymentsS3Bucket) {
|
|
63
|
+
throw new Error('Expected bucket to have been created');
|
|
64
|
+
}
|
|
65
|
+
(0, utils_package_1.writePackageConfig)(config);
|
|
66
|
+
if (!deployment.configuration.deploymentsS3Bucket) {
|
|
67
|
+
throw new Error('Cannot define IAM user since bucket not created.');
|
|
68
|
+
}
|
|
69
|
+
await (0, awsCredentials_1.assertUserWithReadOnlyS3Access)({
|
|
70
|
+
bucketName: deployment.configuration.deploymentsS3Bucket,
|
|
71
|
+
deployment,
|
|
72
|
+
});
|
|
73
|
+
(0, utils_package_1.writePackageConfig)(config);
|
|
74
|
+
await (0, awsCredentials_1.assertAWSCredentials)({
|
|
75
|
+
deployment,
|
|
76
|
+
});
|
|
77
|
+
await (0, uploadCredentials_1.uploadCredentials)({ deployment });
|
|
78
|
+
const url = await (0, uploadCredentials_1.generateCredentialsReadOnlyUrl)(deployment);
|
|
79
|
+
(0, initScriptUpdate_1.updateCredentialsUrl)(url);
|
|
80
|
+
(0, initScriptUpdate_1.updateS3Bucket)(deployment.configuration.deploymentsS3Bucket);
|
|
81
|
+
(0, utils_package_1.writePackageConfig)(config);
|
|
82
|
+
}
|
|
83
|
+
(0, utils_package_1.writePackageConfig)(config);
|
|
84
|
+
if (infrastructureOp !== 'destroy') {
|
|
85
|
+
await (0, createZip_2.createZip)();
|
|
86
|
+
await (0, uploadCredentials_1.uploadCredentials)({ deployment });
|
|
87
|
+
await (0, uploadZip_1.uploadZip)({
|
|
88
|
+
deployment,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
const { awsProvider } = await (0, utils_terraform_aws_1.initTerraformEnvironment)(opArgs);
|
|
92
|
+
await (0, utils_terraform_hetzner_1.terraformHetznerCli)(opArgs, awsProvider);
|
|
93
|
+
(0, initScriptUpdate_1.updateCredentialsUrl)('https://injectedurl.com');
|
|
94
|
+
(0, initScriptUpdate_1.updateS3Bucket)('injected-s3-bucket');
|
|
95
|
+
if (infrastructureOp === 'destroy') {
|
|
96
|
+
if (deployment.configuration.vpsIAMUserName) {
|
|
97
|
+
await (0, awsCredentials_1.deleteUserAndResources)({
|
|
98
|
+
deployment,
|
|
99
|
+
vpsUserName: deployment.configuration.vpsIAMUserName,
|
|
100
|
+
});
|
|
101
|
+
deployment.configuration.vpsIAMUserName = undefined;
|
|
102
|
+
(0, utils_package_1.writePackageConfig)(config);
|
|
103
|
+
}
|
|
104
|
+
await (0, deploymentsS3Bucket_1.deleteDeploymentsS3Bucket)({
|
|
105
|
+
packageConfig,
|
|
106
|
+
deployment: opArgs[1],
|
|
107
|
+
});
|
|
108
|
+
deployment.configuration.deploymentsS3Bucket = undefined;
|
|
109
|
+
(0, utils_package_1.writePackageConfig)(config);
|
|
110
|
+
(0, utils_sh_1.rm)('-f', './dist/credentials/credentials');
|
|
111
|
+
}
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
throw new Error('Unknown command: ' + command);
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
exports.run = run;
|
|
118
|
+
//# sourceMappingURL=templateHetznerVPSCli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templateHetznerVPSCli.js","sourceRoot":"","sources":["../../src/templateHetznerVPSCli.ts"],"names":[],"mappings":";;;;;;AAAA,4DAIkC;AAClC,oDAA+C;AAE/C,+DAG+B;AAE/B,gEAA2D;AAC3D,wEAGwC;AACxC,gFAAyE;AACzE,0EAAgE;AAKhE,kDAA0B;AAC1B,2CAAwC;AACxC,qDAK0B;AAC1B,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAElB,kDAAuD;AACvD,2DAG6B;AAC7B,yDAG4B;AAC5B,2CAAwC;AAExC,oDAA8C;AAEvC,MAAM,GAAG,GAAG,KAAK,EAAE,IAAc,EAAiB,EAAE;IACzD,MAAM,IAAA,mBAAO,EAAC,KAAK,IAAI,EAAE;QACvB,MAAM,IAAI,GAAG,MAAM,IAAA,wBAAQ,EAAC;YAC1B,KAAK,EAAL,eAAK;YACL,cAAc,EAAE,IAAA,mCAAmB,GAAE;YACrC,aAAa,EAAE,IAAA,+BAAa,GAAE;SAC/B,CAAC;aACC,IAAI,EAAE;aACN,KAAK,EAAE,CAAC;QAEX,MAAM,aAAa,GAAG,IAAI,oCAAa,CAGrC;YACA,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,CAAC,EAAE,AAAD,EAAG,AAAD,EAAG,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC;QAE/B,IAAI,OAAO,KAAK,QAAQ,EAAE;YACxB,IAAA,kBAAM,GAAE,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;YACrD,MAAM,UAAU,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1D,MAAM,IAAA,qBAAS,GAAE,CAAC;YAElB,MAAM,IAAA,qCAAiB,EAAC,EAAE,UAAU,EAAE,CAAC,CAAC;YACxC,MAAM,IAAA,qBAAS,EAAC;gBACd,UAAU;aACX,CAAC,CAAC;YACH,IAAA,kBAAM,GAAE,CAAC,IAAI,CACX,8EAA8E,CAC/E,CAAC;YACF,OAAO;SACR;QAED,IAAI,OAAO,KAAK,OAAO,EAAE;YACvB,MAAM,UAAU,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1D,MAAM,gBAAgB,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACnC,IAAA,kBAAM,GAAE,CAAC,IAAI,CACX,oCAAoC,gBAAgB,QAAQ,UAAU,CAAC,IAAI,EAAE,CAC9E,CAAC;YACF,0CAA0C;YAC1C,MAAM,IAAA,qCAAe,EAAC,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAEnD,IAAI,gBAAgB,KAAK,IAAI,IAAI,gBAAgB,KAAK,OAAO,EAAE;gBAC7D,yCAAyC;gBAEzC,MAAM,IAAA,+CAAyB,EAAC;oBAC9B,aAAa;oBACb,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;iBACtB,CAAC,CAAC;gBAEH,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,mBAAmB,EAAE;oBACjD,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;iBACzD;gBAED,IAAA,kCAAkB,EAAC,MAAM,CAAC,CAAC;gBAE3B,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,mBAAmB,EAAE;oBACjD,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;iBACrE;gBAED,MAAM,IAAA,+CAA8B,EAAC;oBACnC,UAAU,EAAE,UAAU,CAAC,aAAa,CAAC,mBAAmB;oBACxD,UAAU;iBACX,CAAC,CAAC;gBAEH,IAAA,kCAAkB,EAAC,MAAM,CAAC,CAAC;gBAE3B,MAAM,IAAA,qCAAoB,EAAC;oBACzB,UAAU;iBACX,CAAC,CAAC;gBAEH,MAAM,IAAA,qCAAiB,EAAC,EAAE,UAAU,EAAE,CAAC,CAAC;gBAExC,MAAM,GAAG,GAAG,MAAM,IAAA,kDAA8B,EAAC,UAAU,CAAC,CAAC;gBAC7D,IAAA,uCAA+B,EAAC,GAAG,CAAC,CAAC;gBACrC,IAAA,iCAAyB,EAAC,UAAU,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;gBACxE,IAAA,kCAAkB,EAAC,MAAM,CAAC,CAAC;aAC5B;YAED,IAAA,kCAAkB,EAAC,MAAM,CAAC,CAAC;YAE3B,IAAI,gBAAgB,KAAK,SAAS,EAAE;gBAClC,MAAM,IAAA,qBAAS,GAAE,CAAC;gBAClB,MAAM,IAAA,qCAAiB,EAAC,EAAE,UAAU,EAAE,CAAC,CAAC;gBACxC,MAAM,IAAA,qBAAS,EAAC;oBACd,UAAU;iBACX,CAAC,CAAC;aACJ;YAED,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,IAAA,8CAAwB,EAAC,MAAM,CAAC,CAAC;YAC/D,MAAM,IAAA,6CAAmB,EAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YAE/C,IAAA,uCAA+B,EAAC,yBAAyB,CAAC,CAAC;YAC3D,IAAA,iCAAyB,EAAC,oBAAoB,CAAC,CAAC;YAEhD,IAAI,gBAAgB,KAAK,SAAS,EAAE;gBAClC,IAAI,UAAU,CAAC,aAAa,CAAC,cAAc,EAAE;oBAC3C,MAAM,IAAA,uCAAsB,EAAC;wBAC3B,UAAU;wBACV,WAAW,EAAE,UAAU,CAAC,aAAa,CAAC,cAAc;qBACrD,CAAC,CAAC;oBACH,UAAU,CAAC,aAAa,CAAC,cAAc,GAAG,SAAS,CAAC;oBACpD,IAAA,kCAAkB,EAAC,MAAM,CAAC,CAAC;iBAC5B;gBAED,MAAM,IAAA,+CAAyB,EAAC;oBAC9B,aAAa;oBACb,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;iBACtB,CAAC,CAAC;gBACH,UAAU,CAAC,aAAa,CAAC,mBAAmB,GAAG,SAAS,CAAC;gBACzD,IAAA,kCAAkB,EAAC,MAAM,CAAC,CAAC;gBAE3B,IAAA,aAAE,EAAC,IAAI,EAAE,gCAAgC,CAAC,CAAC;aAC5C;YAED,OAAO;SACR;QAED,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,OAAO,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AA1HW,QAAA,GAAG,OA0Hd"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { HetznerVPSDeployment } from '@goldstack/template-hetzner-vps';
|
|
2
|
+
export interface UploadCredentialsParams {
|
|
3
|
+
deployment: HetznerVPSDeployment;
|
|
4
|
+
}
|
|
5
|
+
export declare function uploadCredentials({ deployment, }: UploadCredentialsParams): Promise<void>;
|
|
6
|
+
export declare function generateCredentialsReadOnlyUrl(deployment: HetznerVPSDeployment): Promise<string>;
|
|
7
|
+
//# sourceMappingURL=uploadCredentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uploadCredentials.d.ts","sourceRoot":"","sources":["../../src/uploadCredentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAOvE,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,oBAAoB,CAAC;CAClC;AAED,wBAAsB,iBAAiB,CAAC,EACtC,UAAU,GACX,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBzC;AAED,wBAAsB,8BAA8B,CAClD,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAAC,MAAM,CAAC,CA2BjB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateCredentialsReadOnlyUrl = exports.uploadCredentials = void 0;
|
|
4
|
+
const utils_s3_deployment_1 = require("@goldstack/utils-s3-deployment");
|
|
5
|
+
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
6
|
+
const s3_request_presigner_1 = require("@aws-sdk/s3-request-presigner");
|
|
7
|
+
const infra_aws_1 = require("@goldstack/infra-aws");
|
|
8
|
+
const utils_cli_1 = require("@goldstack/utils-cli");
|
|
9
|
+
async function uploadCredentials({ deployment, }) {
|
|
10
|
+
const userName = deployment.awsUser;
|
|
11
|
+
if (!deployment.configuration.deploymentsS3Bucket) {
|
|
12
|
+
throw new Error('Cannot upload credentials files. Deployments S3 bucket is not defined.');
|
|
13
|
+
}
|
|
14
|
+
(0, utils_cli_1.logger)().info('Uploading credentials file to S3 bucket');
|
|
15
|
+
await (0, utils_s3_deployment_1.upload)({
|
|
16
|
+
userName,
|
|
17
|
+
bucketPath: '/credentials/',
|
|
18
|
+
region: deployment.awsRegion,
|
|
19
|
+
bucket: deployment.configuration.deploymentsS3Bucket,
|
|
20
|
+
localPath: './dist/credentials',
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
exports.uploadCredentials = uploadCredentials;
|
|
24
|
+
async function generateCredentialsReadOnlyUrl(deployment) {
|
|
25
|
+
if (!deployment.configuration.deploymentsS3Bucket) {
|
|
26
|
+
throw new Error('Cannot generate URL. Deployments S3 bucket is not defined.');
|
|
27
|
+
}
|
|
28
|
+
const awsUser = await (0, infra_aws_1.getAWSUser)(deployment.awsUser);
|
|
29
|
+
const credentials = await (0, infra_aws_1.getAWSCredentials)(awsUser);
|
|
30
|
+
const s3Client = new client_s3_1.S3Client({
|
|
31
|
+
credentials,
|
|
32
|
+
region: deployment.awsRegion,
|
|
33
|
+
});
|
|
34
|
+
const bucket = deployment.configuration.deploymentsS3Bucket;
|
|
35
|
+
const command = new client_s3_1.GetObjectCommand({
|
|
36
|
+
Bucket: bucket,
|
|
37
|
+
Key: 'credentials/credentials',
|
|
38
|
+
});
|
|
39
|
+
const credentialsUrl = await (0, s3_request_presigner_1.getSignedUrl)(s3Client, command, {
|
|
40
|
+
expiresIn: 60 * 60,
|
|
41
|
+
}); // 1 hour
|
|
42
|
+
return credentialsUrl;
|
|
43
|
+
}
|
|
44
|
+
exports.generateCredentialsReadOnlyUrl = generateCredentialsReadOnlyUrl;
|
|
45
|
+
//# sourceMappingURL=uploadCredentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uploadCredentials.js","sourceRoot":"","sources":["../../src/uploadCredentials.ts"],"names":[],"mappings":";;;AACA,wEAAwD;AACxD,kDAAgE;AAChE,wEAA6D;AAC7D,oDAAqE;AACrE,oDAA8C;AAMvC,KAAK,UAAU,iBAAiB,CAAC,EACtC,UAAU,GACc;IACxB,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC;IAEpC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,mBAAmB,EAAE;QACjD,MAAM,IAAI,KAAK,CACb,wEAAwE,CACzE,CAAC;KACH;IAED,IAAA,kBAAM,GAAE,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;IACzD,MAAM,IAAA,4BAAM,EAAC;QACX,QAAQ;QACR,UAAU,EAAE,eAAe;QAC3B,MAAM,EAAE,UAAU,CAAC,SAAS;QAC5B,MAAM,EAAE,UAAU,CAAC,aAAa,CAAC,mBAAmB;QACpD,SAAS,EAAE,oBAAoB;KAChC,CAAC,CAAC;AACL,CAAC;AAnBD,8CAmBC;AAEM,KAAK,UAAU,8BAA8B,CAClD,UAAgC;IAEhC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,mBAAmB,EAAE;QACjD,MAAM,IAAI,KAAK,CACb,4DAA4D,CAC7D,CAAC;KACH;IAED,MAAM,OAAO,GAAG,MAAM,IAAA,sBAAU,EAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,WAAW,GAAG,MAAM,IAAA,6BAAiB,EAAC,OAAO,CAAC,CAAC;IAErD,MAAM,QAAQ,GAAG,IAAI,oBAAQ,CAAC;QAC5B,WAAW;QACX,MAAM,EAAE,UAAU,CAAC,SAAS;KAC7B,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,UAAU,CAAC,aAAa,CAAC,mBAAmB,CAAC;IAE5D,MAAM,OAAO,GAAG,IAAI,4BAAgB,CAAC;QACnC,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,yBAAyB;KAC/B,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,MAAM,IAAA,mCAAY,EAAC,QAAQ,EAAE,OAAO,EAAE;QAC3D,SAAS,EAAE,EAAE,GAAG,EAAE;KACnB,CAAC,CAAC,CAAC,SAAS;IAEb,OAAO,cAAc,CAAC;AACxB,CAAC;AA7BD,wEA6BC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { HetznerVPSDeployment } from '@goldstack/template-hetzner-vps';
|
|
2
|
+
export interface UploadZipParams {
|
|
3
|
+
deployment: HetznerVPSDeployment;
|
|
4
|
+
}
|
|
5
|
+
export declare function uploadZip({ deployment }: UploadZipParams): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=uploadZip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uploadZip.d.ts","sourceRoot":"","sources":["../../src/uploadZip.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAIvE,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,oBAAoB,CAAC;CAClC;AAED,wBAAsB,SAAS,CAAC,EAAE,UAAU,EAAE,EAAE,eAAe,iBAkB9D"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.uploadZip = void 0;
|
|
4
|
+
const utils_cli_1 = require("@goldstack/utils-cli");
|
|
5
|
+
const utils_s3_deployment_1 = require("@goldstack/utils-s3-deployment");
|
|
6
|
+
async function uploadZip({ deployment }) {
|
|
7
|
+
const userName = deployment.awsUser;
|
|
8
|
+
if (!deployment.configuration.deploymentsS3Bucket) {
|
|
9
|
+
throw new Error('Cannot upload server files. Deployments S3 bucket is not defined.');
|
|
10
|
+
}
|
|
11
|
+
(0, utils_cli_1.logger)().info('Uploading application files to S3 bucket');
|
|
12
|
+
await (0, utils_s3_deployment_1.upload)({
|
|
13
|
+
userName,
|
|
14
|
+
bucketPath: '/server/',
|
|
15
|
+
region: deployment.awsRegion,
|
|
16
|
+
bucket: deployment.configuration.deploymentsS3Bucket,
|
|
17
|
+
localPath: './dist/app',
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
exports.uploadZip = uploadZip;
|
|
21
|
+
//# sourceMappingURL=uploadZip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uploadZip.js","sourceRoot":"","sources":["../../src/uploadZip.ts"],"names":[],"mappings":";;;AACA,oDAA8C;AAC9C,wEAAwD;AAMjD,KAAK,UAAU,SAAS,CAAC,EAAE,UAAU,EAAmB;IAC7D,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC;IAEpC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,mBAAmB,EAAE;QACjD,MAAM,IAAI,KAAK,CACb,mEAAmE,CACpE,CAAC;KACH;IAED,IAAA,kBAAM,GAAE,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IAE1D,MAAM,IAAA,4BAAM,EAAC;QACX,QAAQ;QACR,UAAU,EAAE,UAAU;QACtB,MAAM,EAAE,UAAU,CAAC,SAAS;QAC5B,MAAM,EAAE,UAAU,CAAC,aAAa,CAAC,mBAAmB;QACpD,SAAS,EAAE,YAAY;KACxB,CAAC,CAAC;AACL,CAAC;AAlBD,8BAkBC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@goldstack/template-hetzner-vps-cli",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Utilities for packages that allows provisioning a Hetzner server with Docker",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"goldstack",
|
|
7
|
+
"utility",
|
|
8
|
+
"infrastructure",
|
|
9
|
+
"IaC",
|
|
10
|
+
"aws",
|
|
11
|
+
"SES",
|
|
12
|
+
"email",
|
|
13
|
+
"configuration"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://goldstack.party",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/goldstack/goldstack/issues"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/goldstack/goldstack.git"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"author": "Max Rohde",
|
|
25
|
+
"sideEffects": false,
|
|
26
|
+
"main": "dist/src/templateHetznerVPSCli.js",
|
|
27
|
+
"bin": {
|
|
28
|
+
"template": "./bin/template",
|
|
29
|
+
"template-email-send": "./bin/template"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "yarn clean && yarn compile",
|
|
33
|
+
"clean": "rimraf ./dist",
|
|
34
|
+
"compile": "tsc -p tsconfig.json",
|
|
35
|
+
"coverage": "jest --collect-coverage --passWithNoTests --config=./jest.config.js --runInBand",
|
|
36
|
+
"prepublishOnly": "yarn run build",
|
|
37
|
+
"publish": "utils-git changed --exec \"yarn npm publish $@\"",
|
|
38
|
+
"test": "GOLDSTACK_DEPLOYMENT=local jest --watch --config=./jest.config.js --runInBand",
|
|
39
|
+
"test-ci": "GOLDSTACK_DEPLOYMENT=local jest --passWithNoTests --config=./jest.config.js --runInBand ",
|
|
40
|
+
"version:apply": "utils-git changed --exec \"yarn version $@ && yarn version apply\"",
|
|
41
|
+
"version:apply:force": "yarn version $@ && yarn version apply"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@aws-sdk/client-iam": "^3.645.0",
|
|
45
|
+
"@aws-sdk/client-s3": "3.620.0",
|
|
46
|
+
"@aws-sdk/s3-request-presigner": "^3.645.0",
|
|
47
|
+
"@goldstack/infra-aws": "0.4.18",
|
|
48
|
+
"@goldstack/template-hetzner-vps": "0.1.2",
|
|
49
|
+
"@goldstack/utils-cli": "0.3.10",
|
|
50
|
+
"@goldstack/utils-package": "0.4.10",
|
|
51
|
+
"@goldstack/utils-package-config": "0.4.10",
|
|
52
|
+
"@goldstack/utils-s3-deployment": "0.5.20",
|
|
53
|
+
"@goldstack/utils-sh": "0.5.9",
|
|
54
|
+
"@goldstack/utils-terraform": "0.4.20",
|
|
55
|
+
"@goldstack/utils-terraform-aws": "0.4.23",
|
|
56
|
+
"@goldstack/utils-terraform-hetzner": "0.1.2",
|
|
57
|
+
"source-map-support": "^0.5.21",
|
|
58
|
+
"yargs": "^17.5.1"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@goldstack/utils-git": "0.2.9",
|
|
62
|
+
"@goldstack/utils-package-config-generate": "0.3.9",
|
|
63
|
+
"@swc/core": "^1.3.74",
|
|
64
|
+
"@swc/jest": "^0.2.27",
|
|
65
|
+
"@types/jest": "^29.0.1",
|
|
66
|
+
"@types/node": "^18.7.13",
|
|
67
|
+
"@types/yargs": "^17.0.10",
|
|
68
|
+
"jest": "^29.3.1",
|
|
69
|
+
"rimraf": "^3.0.2",
|
|
70
|
+
"ts-node": "^10.9.1",
|
|
71
|
+
"typescript": "^4.8.4"
|
|
72
|
+
},
|
|
73
|
+
"publishConfig": {
|
|
74
|
+
"main": "dist/src/templateHetznerVPSCli.js"
|
|
75
|
+
}
|
|
76
|
+
}
|