sst 2.24.17 → 2.24.19
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/config.js +66 -47
- package/constructs/Service.js +3 -1
- package/package.json +1 -1
package/config.js
CHANGED
|
@@ -5,11 +5,24 @@ import { useProject } from "./project.js";
|
|
|
5
5
|
import { useAWSClient } from "./credentials.js";
|
|
6
6
|
import { useIOT } from "./iot.js";
|
|
7
7
|
import { Stacks } from "./stacks/index.js";
|
|
8
|
+
const ssm = useAWSClient(SSMClient);
|
|
9
|
+
const FALLBACK_STAGE = ".fallback";
|
|
10
|
+
const SECRET_UPDATED_AT_ENV = "SST_ADMIN_SECRET_UPDATED_AT";
|
|
11
|
+
const PREFIX = {
|
|
12
|
+
get STAGE() {
|
|
13
|
+
const project = useProject();
|
|
14
|
+
return project.config.ssmPrefix;
|
|
15
|
+
},
|
|
16
|
+
get FALLBACK() {
|
|
17
|
+
const project = useProject();
|
|
18
|
+
return `/sst/${project.config.name}/${FALLBACK_STAGE}/`;
|
|
19
|
+
},
|
|
20
|
+
};
|
|
8
21
|
export var Config;
|
|
9
22
|
(function (Config) {
|
|
10
23
|
async function parameters() {
|
|
11
24
|
const result = [];
|
|
12
|
-
for await (const p of
|
|
25
|
+
for await (const p of scanParameters(PREFIX.FALLBACK)) {
|
|
13
26
|
const parsed = parse(p.Name, PREFIX.FALLBACK);
|
|
14
27
|
if (parsed.type === "secrets")
|
|
15
28
|
continue;
|
|
@@ -18,7 +31,7 @@ export var Config;
|
|
|
18
31
|
value: p.Value,
|
|
19
32
|
});
|
|
20
33
|
}
|
|
21
|
-
for await (const p of
|
|
34
|
+
for await (const p of scanParameters(PREFIX.STAGE)) {
|
|
22
35
|
const parsed = parse(p.Name, PREFIX.STAGE);
|
|
23
36
|
if (parsed.type === "secrets")
|
|
24
37
|
continue;
|
|
@@ -44,13 +57,13 @@ export var Config;
|
|
|
44
57
|
Config.normalizeID = normalizeID;
|
|
45
58
|
async function secrets() {
|
|
46
59
|
const result = {};
|
|
47
|
-
for await (const p of
|
|
60
|
+
for await (const p of scanParameters(PREFIX.STAGE + "Secret")) {
|
|
48
61
|
const parsed = parse(p.Name, PREFIX.STAGE);
|
|
49
62
|
if (!result[parsed.id])
|
|
50
63
|
result[parsed.id] = {};
|
|
51
64
|
result[parsed.id].value = p.Value;
|
|
52
65
|
}
|
|
53
|
-
for await (const p of
|
|
66
|
+
for await (const p of scanParameters(PREFIX.FALLBACK + "Secret")) {
|
|
54
67
|
const parsed = parse(p.Name, PREFIX.FALLBACK);
|
|
55
68
|
if (!result[parsed.id])
|
|
56
69
|
result[parsed.id] = {};
|
|
@@ -71,18 +84,24 @@ export var Config;
|
|
|
71
84
|
}
|
|
72
85
|
Config.env = env;
|
|
73
86
|
async function setSecret(input) {
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
const paramName = pathFor({
|
|
88
|
+
id: input.key,
|
|
89
|
+
type: "Secret",
|
|
90
|
+
prop: "value",
|
|
91
|
+
fallback: input.fallback,
|
|
92
|
+
});
|
|
93
|
+
try {
|
|
94
|
+
await putParameter(paramName, input.value);
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
// If the parameter was previously ADVANCED, re-create it in STANDARD tier.
|
|
98
|
+
const wasAdvanced = e.name === "ValidationException" &&
|
|
99
|
+
e.message.startsWith("This parameter uses the advanced-parameter tier. You can't downgrade a parameter from the advanced-parameter tier to the standard-parameter tier.");
|
|
100
|
+
if (!wasAdvanced)
|
|
101
|
+
throw e;
|
|
102
|
+
await deleteParameter(paramName);
|
|
103
|
+
await putParameter(paramName, input.value);
|
|
104
|
+
}
|
|
86
105
|
// Publish event
|
|
87
106
|
const iot = await useIOT();
|
|
88
107
|
const topic = `${iot.prefix}/events`;
|
|
@@ -90,28 +109,21 @@ export var Config;
|
|
|
90
109
|
}
|
|
91
110
|
Config.setSecret = setSecret;
|
|
92
111
|
async function getSecret(input) {
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
type: "Secret",
|
|
99
|
-
fallback: input.fallback,
|
|
100
|
-
}),
|
|
101
|
-
WithDecryption: true,
|
|
112
|
+
const result = await getParameter(pathFor({
|
|
113
|
+
id: input.key,
|
|
114
|
+
prop: "value",
|
|
115
|
+
type: "Secret",
|
|
116
|
+
fallback: input.fallback,
|
|
102
117
|
}));
|
|
103
118
|
return result.Parameter?.Value;
|
|
104
119
|
}
|
|
105
120
|
Config.getSecret = getSecret;
|
|
106
121
|
async function removeSecret(input) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
prop: "value",
|
|
113
|
-
fallback: input.fallback,
|
|
114
|
-
}),
|
|
122
|
+
await deleteParameter(pathFor({
|
|
123
|
+
id: input.key,
|
|
124
|
+
type: "Secret",
|
|
125
|
+
prop: "value",
|
|
126
|
+
fallback: input.fallback,
|
|
115
127
|
}));
|
|
116
128
|
}
|
|
117
129
|
Config.removeSecret = removeSecret;
|
|
@@ -158,8 +170,7 @@ export var Config;
|
|
|
158
170
|
}
|
|
159
171
|
Config.restart = restart;
|
|
160
172
|
})(Config || (Config = {}));
|
|
161
|
-
async function*
|
|
162
|
-
const ssm = useAWSClient(SSMClient);
|
|
173
|
+
async function* scanParameters(prefix) {
|
|
163
174
|
let token;
|
|
164
175
|
while (true) {
|
|
165
176
|
const results = await ssm.send(new GetParametersByPathCommand({
|
|
@@ -174,18 +185,26 @@ async function* scan(prefix) {
|
|
|
174
185
|
token = results.NextToken;
|
|
175
186
|
}
|
|
176
187
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
188
|
+
function getParameter(name) {
|
|
189
|
+
return ssm.send(new GetParameterCommand({
|
|
190
|
+
Name: name,
|
|
191
|
+
WithDecryption: true,
|
|
192
|
+
}));
|
|
193
|
+
}
|
|
194
|
+
function putParameter(name, value) {
|
|
195
|
+
return ssm.send(new PutParameterCommand({
|
|
196
|
+
Name: name,
|
|
197
|
+
Value: value,
|
|
198
|
+
Type: "SecureString",
|
|
199
|
+
Overwrite: true,
|
|
200
|
+
Tier: value.length > 4096 ? "Advanced" : "Standard",
|
|
201
|
+
}));
|
|
202
|
+
}
|
|
203
|
+
function deleteParameter(name) {
|
|
204
|
+
return ssm.send(new DeleteParameterCommand({
|
|
205
|
+
Name: name,
|
|
206
|
+
}));
|
|
207
|
+
}
|
|
189
208
|
function parse(ssmName, prefix) {
|
|
190
209
|
const parts = ssmName.substring(prefix.length).split("/");
|
|
191
210
|
return {
|
package/constructs/Service.js
CHANGED
|
@@ -491,7 +491,7 @@ export class Service extends Construct {
|
|
|
491
491
|
assumedBy: new CompositePrincipal(new AccountPrincipal(app.account), new ServicePrincipal("lambda.amazonaws.com")),
|
|
492
492
|
maxSessionDuration: CdkDuration.hours(12),
|
|
493
493
|
});
|
|
494
|
-
|
|
494
|
+
const fn = new Function(this, `ServerFunction`, {
|
|
495
495
|
description: "Service dev function",
|
|
496
496
|
handler: path.join(__dirname, "../support/service-dev-function", "index.handler"),
|
|
497
497
|
runtime: "nodejs18.x",
|
|
@@ -502,6 +502,8 @@ export class Service extends Construct {
|
|
|
502
502
|
environment,
|
|
503
503
|
permissions,
|
|
504
504
|
});
|
|
505
|
+
fn._doNotAllowOthersToBind = true;
|
|
506
|
+
return fn;
|
|
505
507
|
}
|
|
506
508
|
bindForService(constructs) {
|
|
507
509
|
// Get referenced secrets
|