env-secrets 0.1.9 → 0.2.0
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/.devcontainer/devcontainer.json +29 -0
- package/.github/workflows/release.yml +12 -2
- package/.github/workflows/unittests.yaml +73 -4
- package/README.md +195 -43
- package/__e2e__/index.test.ts +37 -0
- package/__tests__/index.test.ts +316 -31
- package/__tests__/vaults/utils.test.ts +183 -0
- package/__tests__/version.test.ts +8 -0
- package/dist/vaults/secretsmanager.js +29 -40
- package/jest.config.js +2 -1
- package/package.json +14 -9
- package/src/vaults/secretsmanager.ts +34 -45
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "env-secrets",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "get secrets from a secrets vault and inject them into the running environment",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "Mark C Allen (@markcallen)",
|
|
@@ -16,31 +16,36 @@
|
|
|
16
16
|
"release": "release-it",
|
|
17
17
|
"prettier:fix": "npx prettier --write .",
|
|
18
18
|
"prettier:check": "npx prettier --check .",
|
|
19
|
-
"test": "
|
|
19
|
+
"test": "npm run test:unit && npm run test:e2e",
|
|
20
|
+
"test:unit": "jest __tests__",
|
|
21
|
+
"test:unit:coverage": "jest __tests__ --coverage",
|
|
22
|
+
"test:e2e": "npm run build && jest __e2e__"
|
|
20
23
|
},
|
|
21
24
|
"devDependencies": {
|
|
22
25
|
"@types/debug": "^4.1.12",
|
|
23
26
|
"@types/jest": "^29.5.14",
|
|
24
|
-
"@types/node": "^18.19.
|
|
27
|
+
"@types/node": "^18.19.121",
|
|
25
28
|
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
|
26
29
|
"@typescript-eslint/parser": "^5.62.0",
|
|
27
30
|
"eslint": "^8.57.1",
|
|
28
|
-
"eslint-config-prettier": "^8.10.
|
|
29
|
-
"eslint-plugin-prettier": "^4.2.
|
|
31
|
+
"eslint-config-prettier": "^8.10.2",
|
|
32
|
+
"eslint-plugin-prettier": "^4.2.5",
|
|
30
33
|
"husky": "^8.0.3",
|
|
31
34
|
"jest": "^29.7.0",
|
|
32
35
|
"lint-staged": "13.3.0",
|
|
33
36
|
"prettier": "^2.8.8",
|
|
34
37
|
"release-it": "^15.11.0",
|
|
35
38
|
"rimraf": "^3.0.2",
|
|
36
|
-
"ts-jest": "^29.
|
|
39
|
+
"ts-jest": "^29.4.1",
|
|
37
40
|
"ts-node": "^10.9.2",
|
|
38
41
|
"typescript": "^4.9.5"
|
|
39
42
|
},
|
|
40
43
|
"dependencies": {
|
|
41
|
-
"aws-sdk": "^
|
|
44
|
+
"@aws-sdk/client-secrets-manager": "^3.525.0",
|
|
45
|
+
"@aws-sdk/client-sts": "^3.525.0",
|
|
46
|
+
"@aws-sdk/credential-providers": "^3.525.0",
|
|
42
47
|
"commander": "^9.5.0",
|
|
43
|
-
"debug": "^4.4.
|
|
48
|
+
"debug": "^4.4.1"
|
|
44
49
|
},
|
|
45
50
|
"lint-staged": {
|
|
46
51
|
"*.{ts,js}": [
|
|
@@ -58,6 +63,6 @@
|
|
|
58
63
|
"env-secrets": "./dist/index.js"
|
|
59
64
|
},
|
|
60
65
|
"engines": {
|
|
61
|
-
"node": "
|
|
66
|
+
"node": ">=18.0.0"
|
|
62
67
|
}
|
|
63
68
|
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
SecretsManagerClient,
|
|
3
|
+
GetSecretValueCommand
|
|
4
|
+
} from '@aws-sdk/client-secrets-manager';
|
|
5
|
+
import { STSClient, GetCallerIdentityCommand } from '@aws-sdk/client-sts';
|
|
6
|
+
import { fromIni } from '@aws-sdk/credential-providers';
|
|
2
7
|
import Debug from 'debug';
|
|
3
8
|
|
|
4
9
|
const debug = Debug('env-secrets:secretsmanager');
|
|
@@ -9,36 +14,18 @@ interface secretsmanagerType {
|
|
|
9
14
|
region?: string;
|
|
10
15
|
}
|
|
11
16
|
|
|
12
|
-
const checkConnection = async () => {
|
|
13
|
-
const
|
|
17
|
+
const checkConnection = async (region?: string) => {
|
|
18
|
+
const stsClient = new STSClient({ region });
|
|
19
|
+
const command = new GetCallerIdentityCommand({});
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
let value;
|
|
25
|
-
let err;
|
|
26
|
-
|
|
27
|
-
await getCallerPromise
|
|
28
|
-
.then((v) => {
|
|
29
|
-
value = v;
|
|
30
|
-
})
|
|
31
|
-
.catch((e) => {
|
|
32
|
-
err = e;
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
if (err) {
|
|
21
|
+
try {
|
|
22
|
+
const data = await stsClient.send(command);
|
|
23
|
+
debug(data);
|
|
24
|
+
return true;
|
|
25
|
+
} catch (err) {
|
|
36
26
|
console.error(err);
|
|
37
27
|
return false;
|
|
38
28
|
}
|
|
39
|
-
debug(value);
|
|
40
|
-
|
|
41
|
-
return !!value;
|
|
42
29
|
};
|
|
43
30
|
|
|
44
31
|
export const secretsmanager = async (options: secretsmanagerType) => {
|
|
@@ -47,37 +34,38 @@ export const secretsmanager = async (options: secretsmanagerType) => {
|
|
|
47
34
|
AWS_ACCESS_KEY_ID: awsAccessKeyId,
|
|
48
35
|
AWS_SECRET_ACCESS_KEY: awsSecretAccessKey
|
|
49
36
|
} = process.env;
|
|
37
|
+
|
|
38
|
+
let credentials;
|
|
50
39
|
if (profile) {
|
|
51
40
|
debug(`Using profile: ${profile}`);
|
|
52
|
-
|
|
53
|
-
profile
|
|
54
|
-
});
|
|
55
|
-
AWS.config.credentials = credentials;
|
|
41
|
+
credentials = fromIni({ profile });
|
|
56
42
|
} else if (awsAccessKeyId && awsSecretAccessKey) {
|
|
57
43
|
debug('Using environment variables');
|
|
44
|
+
credentials = undefined; // Will use environment variables automatically
|
|
58
45
|
} else {
|
|
59
46
|
debug('Using profile: default');
|
|
47
|
+
credentials = fromIni({ profile: 'default' });
|
|
60
48
|
}
|
|
61
49
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
50
|
+
const config = {
|
|
51
|
+
region,
|
|
52
|
+
credentials
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
if (!config.region) {
|
|
66
56
|
debug('no region set');
|
|
67
57
|
}
|
|
68
58
|
|
|
69
|
-
const connected = await checkConnection();
|
|
59
|
+
const connected = await checkConnection(region);
|
|
70
60
|
|
|
71
61
|
if (connected) {
|
|
72
|
-
const
|
|
62
|
+
const client = new SecretsManagerClient(config);
|
|
73
63
|
|
|
74
64
|
try {
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
.promise();
|
|
80
|
-
|
|
65
|
+
const command = new GetSecretValueCommand({
|
|
66
|
+
SecretId: secret
|
|
67
|
+
});
|
|
68
|
+
const response = await client.send(command);
|
|
81
69
|
const secretvalue = response.SecretString;
|
|
82
70
|
|
|
83
71
|
try {
|
|
@@ -88,9 +76,9 @@ export const secretsmanager = async (options: secretsmanagerType) => {
|
|
|
88
76
|
console.error(err);
|
|
89
77
|
}
|
|
90
78
|
} catch (err: any) {
|
|
91
|
-
if (err && err.
|
|
79
|
+
if (err && err.name === 'ResourceNotFoundException') {
|
|
92
80
|
console.error(`${secret} not found`);
|
|
93
|
-
} else if (err && err.
|
|
81
|
+
} else if (err && err.name === 'ConfigError') {
|
|
94
82
|
console.error(err.message);
|
|
95
83
|
} else {
|
|
96
84
|
console.error(err);
|
|
@@ -100,5 +88,6 @@ export const secretsmanager = async (options: secretsmanagerType) => {
|
|
|
100
88
|
return {};
|
|
101
89
|
} else {
|
|
102
90
|
console.error('Unable to connect to AWS');
|
|
91
|
+
return {};
|
|
103
92
|
}
|
|
104
93
|
};
|