env-secrets 0.1.3 → 0.1.8
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/.cm/gitstream.cm +57 -0
- package/.eslintrc +5 -2
- package/.github/dependabot.yml +19 -8
- package/.github/workflows/build-main.yml +48 -0
- package/.github/workflows/gitstream.yaml +49 -0
- package/.github/workflows/lint.yaml +31 -0
- package/.github/workflows/release.yml +54 -0
- package/.github/workflows/snyk.yaml +24 -0
- package/.github/workflows/unittests.yaml +46 -0
- package/.husky/pre-commit +4 -0
- package/.lintstagedrc +9 -0
- package/.nvmrc +1 -1
- package/.prettierignore +1 -0
- package/.release-it.json +12 -0
- package/README.md +108 -3
- package/__tests__/index.test.ts +37 -0
- package/dist/index.js +3 -1
- package/dist/vaults/secretsmanager.js +10 -6
- package/generate-release-notes.sh +28 -0
- package/jest.config.js +6 -0
- package/package.json +38 -16
- package/src/index.ts +3 -1
- package/src/tsconfig.json +1 -3
- package/src/vaults/secretsmanager.ts +9 -6
- package/tsconfig.json +2 -3
package/.cm/gitstream.cm
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# -*- mode: yaml -*-
|
|
2
|
+
# This example configuration for provides basic automations to get started with gitStream.
|
|
3
|
+
# View the gitStream quickstart for more examples: https://docs.gitstream.cm/quick-start/
|
|
4
|
+
manifest:
|
|
5
|
+
version: 1.0
|
|
6
|
+
automations:
|
|
7
|
+
# Add a label that indicates how many minutes it will take to review the PR.
|
|
8
|
+
estimated_time_to_review:
|
|
9
|
+
if:
|
|
10
|
+
- true
|
|
11
|
+
run:
|
|
12
|
+
- action: add-label@v1
|
|
13
|
+
# etr is defined in the last section of this example
|
|
14
|
+
args:
|
|
15
|
+
label: "{{ calc.etr }} min review"
|
|
16
|
+
color: {{ 'E94637' if (calc.etr >= 20) else ('FBBD10' if (calc.etr >= 5) else '36A853') }}
|
|
17
|
+
# Post a comment that lists the best experts for the files that were modified.
|
|
18
|
+
code_experts:
|
|
19
|
+
if:
|
|
20
|
+
- true
|
|
21
|
+
run:
|
|
22
|
+
- action: add-comment@v1
|
|
23
|
+
# More info about explainCodeExperts: https://docs.gitstream.cm/filter-functions/#explaincodeexperts
|
|
24
|
+
args:
|
|
25
|
+
comment: |
|
|
26
|
+
{{ repo | explainCodeExperts(gt=10) }}
|
|
27
|
+
# approve changes to docs, formatting, tests or assets
|
|
28
|
+
safe_changes:
|
|
29
|
+
if:
|
|
30
|
+
- {{ is.docs or is.tests or is.asset or is.formatting }}
|
|
31
|
+
run:
|
|
32
|
+
- action: add-label@v1
|
|
33
|
+
args:
|
|
34
|
+
label: 'safe-changes'
|
|
35
|
+
- action: approve@v1
|
|
36
|
+
# approve dependabot
|
|
37
|
+
dependabot:
|
|
38
|
+
if:
|
|
39
|
+
- {{ branch.name | includes(term="dependabot") }}
|
|
40
|
+
- {{ branch.author | includes(term="dependabot") }}
|
|
41
|
+
run:
|
|
42
|
+
- action: approve@v1
|
|
43
|
+
- action: add-label@v1
|
|
44
|
+
args:
|
|
45
|
+
label: "approved-dependabot"
|
|
46
|
+
- action: merge@v1
|
|
47
|
+
args:
|
|
48
|
+
wait_for_all_checks: true
|
|
49
|
+
squash_on_merge: true
|
|
50
|
+
# The next function calculates the estimated time to review and makes it available in the automation above.
|
|
51
|
+
calc:
|
|
52
|
+
etr: {{ branch | estimatedReviewTime }}
|
|
53
|
+
is:
|
|
54
|
+
docs: {{ files | allDocs }}
|
|
55
|
+
tests: {{ files | allTests }}
|
|
56
|
+
asset: {{ files | match(regex=r/\.(png|svg|gif|css)$/) | every }}
|
|
57
|
+
formatting: {{ source.diff.files | isFormattingChange }}
|
package/.eslintrc
CHANGED
package/.github/dependabot.yml
CHANGED
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
version: 2
|
|
2
2
|
updates:
|
|
3
|
-
- package-ecosystem:
|
|
3
|
+
- package-ecosystem: 'npm'
|
|
4
4
|
versioning-strategy: increase
|
|
5
|
-
directory:
|
|
5
|
+
directory: '/'
|
|
6
6
|
schedule:
|
|
7
|
-
interval:
|
|
7
|
+
interval: 'weekly'
|
|
8
8
|
labels:
|
|
9
|
-
-
|
|
9
|
+
- 'dependencies'
|
|
10
10
|
open-pull-requests-limit: 100
|
|
11
11
|
pull-request-branch-name:
|
|
12
|
-
separator:
|
|
12
|
+
separator: '-'
|
|
13
13
|
ignore:
|
|
14
|
-
- dependency-name:
|
|
15
|
-
- dependency-name:
|
|
16
|
-
update-types: [
|
|
14
|
+
- dependency-name: 'fs-extra'
|
|
15
|
+
- dependency-name: '*'
|
|
16
|
+
update-types: ['version-update:semver-major']
|
|
17
|
+
|
|
18
|
+
# Maintain dependencies for GitHub Actions
|
|
19
|
+
- package-ecosystem: 'github-actions'
|
|
20
|
+
directory: '/'
|
|
21
|
+
schedule:
|
|
22
|
+
interval: 'weekly'
|
|
23
|
+
pull-request-branch-name:
|
|
24
|
+
separator: '-'
|
|
25
|
+
labels:
|
|
26
|
+
- 'github-actions'
|
|
27
|
+
- 'dependencies'
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Build
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
with:
|
|
15
|
+
fetch-depth: 0
|
|
16
|
+
|
|
17
|
+
- name: Set up Node.js
|
|
18
|
+
uses: actions/setup-node@v4
|
|
19
|
+
with:
|
|
20
|
+
node-version: 20.18.3
|
|
21
|
+
|
|
22
|
+
- name: Install Node.js dependencies
|
|
23
|
+
run: yarn
|
|
24
|
+
|
|
25
|
+
- name: Slack Notification
|
|
26
|
+
uses: rtCamp/action-slack-notify@v2
|
|
27
|
+
env:
|
|
28
|
+
SLACK_CHANNEL: feed-github
|
|
29
|
+
SLACK_COLOR: ${{ job.status }}
|
|
30
|
+
SLACK_ICON: https://avatars.githubusercontent.com/u/82425418?s=200&v=4
|
|
31
|
+
SLACK_TITLE: 'env-secrets to dev :rocket:'
|
|
32
|
+
SLACK_USERNAME: env-secrets-bot
|
|
33
|
+
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
|
34
|
+
|
|
35
|
+
- name: Notify failures
|
|
36
|
+
if: failure()
|
|
37
|
+
uses: rtCamp/action-slack-notify@v2
|
|
38
|
+
env:
|
|
39
|
+
SLACK_LINK_NAMES: true
|
|
40
|
+
SLACK_MESSAGE:
|
|
41
|
+
# prettier-ignore
|
|
42
|
+
"hey @${{ github.actor }}, @mark, sorry to let you know you broke the build"
|
|
43
|
+
SLACK_CHANNEL: feed-github
|
|
44
|
+
SLACK_COLOR: ${{ job.status }}
|
|
45
|
+
SLACK_ICON: https://avatars.githubusercontent.com/u/82425418?s=200&v=4
|
|
46
|
+
SLACK_TITLE: 'Failed: env-secrets to dev :fire:'
|
|
47
|
+
SLACK_USERNAME: env-secrets-bot
|
|
48
|
+
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Code generated by gitStream GitHub app - DO NOT EDIT
|
|
2
|
+
|
|
3
|
+
name: gitStream workflow automation
|
|
4
|
+
run-name: |
|
|
5
|
+
/:\ gitStream: PR #${{ fromJSON(fromJSON(github.event.inputs.client_payload)).pullRequestNumber }} from ${{ github.event.inputs.full_repository }}
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
inputs:
|
|
10
|
+
client_payload:
|
|
11
|
+
description: The Client payload
|
|
12
|
+
required: true
|
|
13
|
+
full_repository:
|
|
14
|
+
description: the repository name include the owner in `owner/repo_name` format
|
|
15
|
+
required: true
|
|
16
|
+
head_ref:
|
|
17
|
+
description: the head sha
|
|
18
|
+
required: true
|
|
19
|
+
base_ref:
|
|
20
|
+
description: the base ref
|
|
21
|
+
required: true
|
|
22
|
+
installation_id:
|
|
23
|
+
description: the installation id
|
|
24
|
+
required: false
|
|
25
|
+
resolver_url:
|
|
26
|
+
description: the resolver url to pass results to
|
|
27
|
+
required: true
|
|
28
|
+
resolver_token:
|
|
29
|
+
description: Optional resolver token for resolver service
|
|
30
|
+
required: false
|
|
31
|
+
default: ''
|
|
32
|
+
|
|
33
|
+
jobs:
|
|
34
|
+
gitStream:
|
|
35
|
+
timeout-minutes: 5
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
name: gitStream workflow automation
|
|
38
|
+
steps:
|
|
39
|
+
- name: Evaluate Rules
|
|
40
|
+
uses: linear-b/gitstream-github-action@v2
|
|
41
|
+
id: rules-engine
|
|
42
|
+
with:
|
|
43
|
+
full_repository: ${{ github.event.inputs.full_repository }}
|
|
44
|
+
head_ref: ${{ github.event.inputs.head_ref }}
|
|
45
|
+
base_ref: ${{ github.event.inputs.base_ref }}
|
|
46
|
+
client_payload: ${{ github.event.inputs.client_payload }}
|
|
47
|
+
installation_id: ${{ github.event.inputs.installation_id }}
|
|
48
|
+
resolver_url: ${{ github.event.inputs.resolver_url }}
|
|
49
|
+
resolver_token: ${{ github.event.inputs.resolver_token }}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Lint
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
run-linters:
|
|
10
|
+
name: Run linters
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Check out Git repository
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Set up Node.js
|
|
18
|
+
uses: actions/setup-node@v4
|
|
19
|
+
with:
|
|
20
|
+
node-version: 20.18.3
|
|
21
|
+
|
|
22
|
+
# ESLint and Prettier must be in `package.json`
|
|
23
|
+
- name: Install Node.js dependencies
|
|
24
|
+
run: yarn --frozen-lockfile
|
|
25
|
+
|
|
26
|
+
- name: Run linters
|
|
27
|
+
uses: wearerequired/lint-action@v2
|
|
28
|
+
with:
|
|
29
|
+
eslint: true
|
|
30
|
+
eslint_extensions: js,ts
|
|
31
|
+
prettier: true
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Release and Publish
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
release:
|
|
9
|
+
if: ${{ github.ref == 'refs/heads/main' }}
|
|
10
|
+
name: Create Github Release
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- name: Clone Repository
|
|
14
|
+
uses: actions/checkout@v4
|
|
15
|
+
with:
|
|
16
|
+
fetch-depth: 0
|
|
17
|
+
|
|
18
|
+
- name: git config
|
|
19
|
+
run: |
|
|
20
|
+
git config user.name "${GITHUB_ACTOR}"
|
|
21
|
+
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
|
|
22
|
+
|
|
23
|
+
- name: Set up Node.js
|
|
24
|
+
uses: actions/setup-node@v4
|
|
25
|
+
with:
|
|
26
|
+
node-version: 20.18.3
|
|
27
|
+
registry-url: 'https://registry.npmjs.org'
|
|
28
|
+
|
|
29
|
+
- name: Install Node.js dependencies
|
|
30
|
+
run: yarn
|
|
31
|
+
|
|
32
|
+
- name: Install Node.js dependencies
|
|
33
|
+
run: yarn build
|
|
34
|
+
|
|
35
|
+
- name: Github release
|
|
36
|
+
run: yarn release patch --ci
|
|
37
|
+
env:
|
|
38
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
39
|
+
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
|
40
|
+
|
|
41
|
+
- name: Notify failures
|
|
42
|
+
if: failure()
|
|
43
|
+
uses: rtCamp/action-slack-notify@v2
|
|
44
|
+
env:
|
|
45
|
+
SLACK_LINK_NAMES: true
|
|
46
|
+
SLACK_MESSAGE:
|
|
47
|
+
# prettier-ignore
|
|
48
|
+
"hey @${{ github.actor }}, @mark, sorry to let you know you broke the build"
|
|
49
|
+
SLACK_CHANNEL: feed-github
|
|
50
|
+
SLACK_COLOR: ${{ job.status }}
|
|
51
|
+
SLACK_ICON: https://avatars.githubusercontent.com/u/82425418?s=200&v=4
|
|
52
|
+
SLACK_TITLE: 'Failed: cld-cli to dev :fire:'
|
|
53
|
+
SLACK_USERNAME: cld-cli-bot
|
|
54
|
+
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Synk analysis
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request_target:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
security:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- name: Run Snyk to check for vulnerabilities
|
|
15
|
+
uses: snyk/actions/node@master
|
|
16
|
+
continue-on-error: true # To make sure that SARIF upload gets called
|
|
17
|
+
env:
|
|
18
|
+
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
|
19
|
+
with:
|
|
20
|
+
args: --sarif-file-output=snyk.sarif
|
|
21
|
+
- name: Upload result to GitHub Code Scanning
|
|
22
|
+
uses: github/codeql-action/upload-sarif@v3
|
|
23
|
+
with:
|
|
24
|
+
sarif_file: snyk.sarif
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: Unit Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
push:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
|
|
15
|
+
strategy:
|
|
16
|
+
matrix:
|
|
17
|
+
node-version: [16.x, 18.x, 20.x]
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout repository
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Set up Node.js ${{ matrix.node-version }}
|
|
24
|
+
uses: actions/setup-node@v4
|
|
25
|
+
with:
|
|
26
|
+
node-version: ${{ matrix.node-version }}
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: yarn
|
|
30
|
+
|
|
31
|
+
- name: Build
|
|
32
|
+
run: yarn build
|
|
33
|
+
|
|
34
|
+
- name: Run the tests
|
|
35
|
+
run: yarn test --coverage
|
|
36
|
+
|
|
37
|
+
- name: Notify failures
|
|
38
|
+
if: failure()
|
|
39
|
+
uses: rtCamp/action-slack-notify@v2
|
|
40
|
+
env:
|
|
41
|
+
SLACK_LINK_NAMES: true
|
|
42
|
+
SLACK_MESSAGE:
|
|
43
|
+
# prettier-ignore
|
|
44
|
+
"hey @${{ github.actor }}, @mark, sorry to let you know you broke the build"
|
|
45
|
+
SLACK_CHANNEL: feed-github
|
|
46
|
+
SLACK_COLOR: ${{ job.status }}
|
package/.lintstagedrc
ADDED
package/.nvmrc
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
v20.18.3
|
package/.prettierignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
dist/
|
package/.release-it.json
ADDED
package/README.md
CHANGED
|
@@ -2,16 +2,111 @@
|
|
|
2
2
|
|
|
3
3
|
Get secrets from a vault and inject them as environment variables
|
|
4
4
|
|
|
5
|
+
[](https://npmjs.org/package/env-secrets)
|
|
6
|
+
[](https://github.com/markcallen/env-secrets/tree/main)
|
|
7
|
+
[](https://github.com/markcallen/env-secrets/tree/main)
|
|
8
|
+

|
|
9
|
+
[](https://npmjs.org/package/env-secrets)
|
|
10
|
+
[](https://github.com/markcallen/env-secrets/blob/main/LICENSE)
|
|
11
|
+
|
|
5
12
|
## Setup
|
|
6
13
|
|
|
7
14
|
Install node
|
|
8
15
|
|
|
9
|
-
##
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
Globally
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
npm install -g env-secrets
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Project specific
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
npm install env-secrets
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
when using project specific run using npx
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
npx env-secrets ...
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
AWS
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
env-secrets aws -s <secret name> -r <region> -p <profile> -- <program to run>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`<secret name>` is the name of the secret in Secrets Manager
|
|
45
|
+
|
|
46
|
+
`<region>` is the region where the secret to stored. It is optional, the AWS_DEFAULT_REGION environment variable will be used instead.
|
|
47
|
+
|
|
48
|
+
`<profile>` is the local aws profile to use. It is optional, the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables will be used instead.
|
|
49
|
+
|
|
50
|
+
example:
|
|
51
|
+
|
|
52
|
+
Create a Secret using AWS cli
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
aws secretsmanager create-secret \
|
|
56
|
+
--region us-east-1 \
|
|
57
|
+
--profile marka \
|
|
58
|
+
--name local/sample \
|
|
59
|
+
--description "local/sample secret" \
|
|
60
|
+
--secret-string "{\"user\":\"marka\",\"password\":\"mypassword\"}"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
List the secret using AWS cli
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
aws secretsmanager get-secret-value \
|
|
67
|
+
--region us-east-1 \
|
|
68
|
+
--profile marka \
|
|
69
|
+
--secret-id local/sample \
|
|
70
|
+
--query SecretString
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
env-secrets aws -s local/sample -r us-east-1 -p marka -- echo \${user}/\${password}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Development
|
|
78
|
+
|
|
79
|
+
Setup node using [nvm](https://github.com/nvm-sh/nvm). Or use node 20 (LTS).
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
nvm use
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Install yarn
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
npm install -y yarn
|
|
89
|
+
```
|
|
10
90
|
|
|
11
|
-
|
|
91
|
+
Setup
|
|
12
92
|
|
|
13
93
|
```
|
|
14
|
-
|
|
94
|
+
yarn
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Run
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
npx ts-node src/index.ts aws -s local/sample -r us-east-1 -p marka -- env
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Debug
|
|
104
|
+
|
|
105
|
+
Uses debug-js to show debug logs by passing in env-secrets for the main application
|
|
106
|
+
and env-secrets:{vault} for vault specific debugging
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
DEBUG=env-secrets,env-secrets:secretsmanager npx ts-node src/index.ts aws -s local/sample -r us-east-1 -p marka -- env
|
|
15
110
|
```
|
|
16
111
|
|
|
17
112
|
## Publishing
|
|
@@ -33,3 +128,13 @@ Run:
|
|
|
33
128
|
```
|
|
34
129
|
npm run release -- patch
|
|
35
130
|
```
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
Distributed under the MIT License. See `LICENSE` for more information.
|
|
135
|
+
|
|
136
|
+
## Contact
|
|
137
|
+
|
|
138
|
+
Mark C Allen - [@markcallen](https://www.linkedin.com/in/markcallen/)
|
|
139
|
+
|
|
140
|
+
Project Link: [https://github.com/markcallen/env-secrets](https://github.com/markcallen/env-secrets)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import { exec } from 'child_process';
|
|
3
|
+
|
|
4
|
+
type Cli = {
|
|
5
|
+
code: number;
|
|
6
|
+
error: Error;
|
|
7
|
+
stdout: any;
|
|
8
|
+
stderr: any;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
describe('CLI tests', () => {
|
|
12
|
+
test('general help', async () => {
|
|
13
|
+
const result = await cli(['-h'], '.');
|
|
14
|
+
expect(result.code).toBe(0);
|
|
15
|
+
});
|
|
16
|
+
test('aws help', async () => {
|
|
17
|
+
const result = await cli(['aws -h'], '.');
|
|
18
|
+
expect(result.code).toBe(0);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
function cli(args, cwd): Promise<Cli> {
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
exec(
|
|
25
|
+
`node ${path.resolve('./dist/index')} ${args.join(' ')}`,
|
|
26
|
+
{ cwd },
|
|
27
|
+
(error, stdout, stderr) => {
|
|
28
|
+
resolve({
|
|
29
|
+
code: error && error.code ? error.code : 0,
|
|
30
|
+
error,
|
|
31
|
+
stdout,
|
|
32
|
+
stderr
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -20,10 +20,12 @@ const version_1 = require("./version");
|
|
|
20
20
|
const secretsmanager_1 = require("./vaults/secretsmanager");
|
|
21
21
|
const debug = (0, debug_1.default)('env-secrets');
|
|
22
22
|
const program = new commander_1.Command();
|
|
23
|
+
// main program
|
|
23
24
|
program
|
|
24
25
|
.name('env-secrets')
|
|
25
26
|
.description('pull secrets from vaults and inject them into the running environment')
|
|
26
27
|
.version(version_1.LIB_VERSION);
|
|
28
|
+
// aws secretsmanager
|
|
27
29
|
program
|
|
28
30
|
.command('aws')
|
|
29
31
|
.description('get secrets from AWS secrets manager')
|
|
@@ -35,7 +37,7 @@ program
|
|
|
35
37
|
let env = yield (0, secretsmanager_1.secretsmanager)(options);
|
|
36
38
|
env = Object.assign({}, process.env, env);
|
|
37
39
|
debug(env);
|
|
38
|
-
if (program) {
|
|
40
|
+
if (program && program.length > 0) {
|
|
39
41
|
debug(`${program[0]} ${program.slice(1)}`);
|
|
40
42
|
(0, node_child_process_1.spawn)(program[0], program.slice(1), {
|
|
41
43
|
stdio: 'inherit',
|
|
@@ -18,7 +18,7 @@ const debug_1 = __importDefault(require("debug"));
|
|
|
18
18
|
const debug = (0, debug_1.default)('env-secrets:secretsmanager');
|
|
19
19
|
const checkConnection = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
20
|
const sts = new aws_sdk_1.default.STS();
|
|
21
|
-
const
|
|
21
|
+
const getCallerPromise = new Promise((resolve, reject) => {
|
|
22
22
|
sts.getCallerIdentity({}, (err, data) => {
|
|
23
23
|
if (err)
|
|
24
24
|
reject(err);
|
|
@@ -29,7 +29,7 @@ const checkConnection = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
29
29
|
});
|
|
30
30
|
let value;
|
|
31
31
|
let err;
|
|
32
|
-
yield
|
|
32
|
+
yield getCallerPromise
|
|
33
33
|
.then((v) => {
|
|
34
34
|
value = v;
|
|
35
35
|
})
|
|
@@ -38,6 +38,7 @@ const checkConnection = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
38
38
|
});
|
|
39
39
|
if (err) {
|
|
40
40
|
console.error(err);
|
|
41
|
+
return false;
|
|
41
42
|
}
|
|
42
43
|
debug(value);
|
|
43
44
|
return !!value;
|
|
@@ -46,23 +47,23 @@ const secretsmanager = (options) => __awaiter(void 0, void 0, void 0, function*
|
|
|
46
47
|
const { secret, profile, region } = options;
|
|
47
48
|
const { AWS_ACCESS_KEY_ID: awsAccessKeyId, AWS_SECRET_ACCESS_KEY: awsSecretAccessKey } = process.env;
|
|
48
49
|
if (profile) {
|
|
49
|
-
|
|
50
|
+
debug(`Using profile: ${profile}`);
|
|
50
51
|
const credentials = new aws_sdk_1.default.SharedIniFileCredentials({
|
|
51
52
|
profile
|
|
52
53
|
});
|
|
53
54
|
aws_sdk_1.default.config.credentials = credentials;
|
|
54
55
|
}
|
|
55
56
|
else if (awsAccessKeyId && awsSecretAccessKey) {
|
|
56
|
-
|
|
57
|
+
debug('Using environment variables');
|
|
57
58
|
}
|
|
58
59
|
else {
|
|
59
|
-
|
|
60
|
+
debug('Using profile: default');
|
|
60
61
|
}
|
|
61
62
|
if (region) {
|
|
62
63
|
aws_sdk_1.default.config.update({ region });
|
|
63
64
|
}
|
|
64
65
|
if (!aws_sdk_1.default.config.region) {
|
|
65
|
-
|
|
66
|
+
debug('no region set');
|
|
66
67
|
}
|
|
67
68
|
const connected = yield checkConnection();
|
|
68
69
|
if (connected) {
|
|
@@ -96,5 +97,8 @@ const secretsmanager = (options) => __awaiter(void 0, void 0, void 0, function*
|
|
|
96
97
|
}
|
|
97
98
|
return {};
|
|
98
99
|
}
|
|
100
|
+
else {
|
|
101
|
+
console.error('Unable to connect to AWS');
|
|
102
|
+
}
|
|
99
103
|
});
|
|
100
104
|
exports.secretsmanager = secretsmanager;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
|
|
4
|
+
url=$(git config --get remote.origin.url)
|
|
5
|
+
|
|
6
|
+
re="^(https|git)(:\/\/|@)([^\/:]+)[\/:]([^\/:]+)\/(.+)(\.git)?$"
|
|
7
|
+
|
|
8
|
+
if [[ $url =~ $re ]]; then
|
|
9
|
+
protocol=${BASH_REMATCH[1]}
|
|
10
|
+
separator=${BASH_REMATCH[2]}
|
|
11
|
+
hostname=${BASH_REMATCH[3]}
|
|
12
|
+
user=${BASH_REMATCH[4]}
|
|
13
|
+
repo=$(basename ${BASH_REMATCH[5]} .git)
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
REPO=$user/$repo
|
|
17
|
+
|
|
18
|
+
LAST=$(curl -s -L \
|
|
19
|
+
-H "Accept: application/vnd.github+json" \
|
|
20
|
+
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
|
|
21
|
+
-H "X-GitHub-Api-Version: 2022-11-28" \
|
|
22
|
+
https://api.github.com/repos/${REPO}/releases | jq -r .[0].tag_name)
|
|
23
|
+
|
|
24
|
+
LATEST=$1
|
|
25
|
+
|
|
26
|
+
echo **Full Changelog**: https://github.com/${REPO}/compare/${LAST}...${LATEST}
|
|
27
|
+
|
|
28
|
+
git log --pretty="- %s" ${LAST}..HEAD
|
package/jest.config.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "env-secrets",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
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)",
|
|
@@ -9,33 +9,55 @@
|
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"private": false,
|
|
11
11
|
"scripts": {
|
|
12
|
+
"prepare": "husky install",
|
|
12
13
|
"build": "rimraf ./dist && tsc -b src",
|
|
13
14
|
"postbuild": "chmod 755 ./dist/index.js",
|
|
14
|
-
"lint": "eslint . --ext .ts",
|
|
15
|
+
"lint": "eslint . --ext .ts,.js",
|
|
15
16
|
"release": "release-it",
|
|
16
17
|
"prettier:fix": "npx prettier --write .",
|
|
17
|
-
"prettier:check": "npx prettier --check ."
|
|
18
|
+
"prettier:check": "npx prettier --check .",
|
|
19
|
+
"test": "jest"
|
|
18
20
|
},
|
|
19
21
|
"devDependencies": {
|
|
20
|
-
"@types/debug": "^4.1.
|
|
21
|
-
"@types/
|
|
22
|
-
"@
|
|
23
|
-
"@typescript-eslint/
|
|
24
|
-
"eslint": "^
|
|
25
|
-
"eslint
|
|
22
|
+
"@types/debug": "^4.1.12",
|
|
23
|
+
"@types/jest": "^29.5.14",
|
|
24
|
+
"@types/node": "^18.19.80",
|
|
25
|
+
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
|
26
|
+
"@typescript-eslint/parser": "^5.62.0",
|
|
27
|
+
"eslint": "^8.57.1",
|
|
28
|
+
"eslint-config-prettier": "^8.10.0",
|
|
26
29
|
"eslint-plugin-prettier": "^4.2.1",
|
|
27
|
-
"
|
|
28
|
-
"
|
|
30
|
+
"husky": "^8.0.3",
|
|
31
|
+
"jest": "^29.7.0",
|
|
32
|
+
"lint-staged": "13.3.0",
|
|
33
|
+
"prettier": "^2.8.8",
|
|
34
|
+
"release-it": "^15.11.0",
|
|
29
35
|
"rimraf": "^3.0.2",
|
|
30
|
-
"ts-
|
|
31
|
-
"
|
|
36
|
+
"ts-jest": "^29.2.6",
|
|
37
|
+
"ts-node": "^10.9.2",
|
|
38
|
+
"typescript": "^4.9.5"
|
|
32
39
|
},
|
|
33
40
|
"dependencies": {
|
|
34
|
-
"aws-sdk": "^2.
|
|
35
|
-
"commander": "^9.
|
|
36
|
-
"debug": "^4.
|
|
41
|
+
"aws-sdk": "^2.1692.0",
|
|
42
|
+
"commander": "^9.5.0",
|
|
43
|
+
"debug": "^4.4.0"
|
|
44
|
+
},
|
|
45
|
+
"lint-staged": {
|
|
46
|
+
"*.{ts,js}": [
|
|
47
|
+
"prettier --write .",
|
|
48
|
+
"eslint --fix ."
|
|
49
|
+
],
|
|
50
|
+
"*.{json,md,yaml}": [
|
|
51
|
+
"prettier --write ."
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"publishConfig": {
|
|
55
|
+
"registry": "https://registry.npmjs.org/"
|
|
37
56
|
},
|
|
38
57
|
"bin": {
|
|
39
58
|
"env-secrets": "./dist/index.js"
|
|
59
|
+
},
|
|
60
|
+
"engines": {
|
|
61
|
+
"node": "^16.14.0 || >=18.0.0"
|
|
40
62
|
}
|
|
41
63
|
}
|
package/src/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ const debug = Debug('env-secrets');
|
|
|
11
11
|
|
|
12
12
|
const program = new Command();
|
|
13
13
|
|
|
14
|
+
// main program
|
|
14
15
|
program
|
|
15
16
|
.name('env-secrets')
|
|
16
17
|
.description(
|
|
@@ -18,6 +19,7 @@ program
|
|
|
18
19
|
)
|
|
19
20
|
.version(LIB_VERSION);
|
|
20
21
|
|
|
22
|
+
// aws secretsmanager
|
|
21
23
|
program
|
|
22
24
|
.command('aws')
|
|
23
25
|
.description('get secrets from AWS secrets manager')
|
|
@@ -29,7 +31,7 @@ program
|
|
|
29
31
|
let env = await secretsmanager(options);
|
|
30
32
|
env = Object.assign({}, process.env, env);
|
|
31
33
|
debug(env);
|
|
32
|
-
if (program) {
|
|
34
|
+
if (program && program.length > 0) {
|
|
33
35
|
debug(`${program[0]} ${program.slice(1)}`);
|
|
34
36
|
spawn(program[0], program.slice(1), {
|
|
35
37
|
stdio: 'inherit',
|
package/src/tsconfig.json
CHANGED
|
@@ -12,7 +12,7 @@ interface secretsmanagerType {
|
|
|
12
12
|
const checkConnection = async () => {
|
|
13
13
|
const sts = new AWS.STS();
|
|
14
14
|
|
|
15
|
-
const
|
|
15
|
+
const getCallerPromise = new Promise((resolve, reject) => {
|
|
16
16
|
sts.getCallerIdentity({}, (err, data) => {
|
|
17
17
|
if (err) reject(err);
|
|
18
18
|
else {
|
|
@@ -24,7 +24,7 @@ const checkConnection = async () => {
|
|
|
24
24
|
let value;
|
|
25
25
|
let err;
|
|
26
26
|
|
|
27
|
-
await
|
|
27
|
+
await getCallerPromise
|
|
28
28
|
.then((v) => {
|
|
29
29
|
value = v;
|
|
30
30
|
})
|
|
@@ -34,6 +34,7 @@ const checkConnection = async () => {
|
|
|
34
34
|
|
|
35
35
|
if (err) {
|
|
36
36
|
console.error(err);
|
|
37
|
+
return false;
|
|
37
38
|
}
|
|
38
39
|
debug(value);
|
|
39
40
|
|
|
@@ -47,22 +48,22 @@ export const secretsmanager = async (options: secretsmanagerType) => {
|
|
|
47
48
|
AWS_SECRET_ACCESS_KEY: awsSecretAccessKey
|
|
48
49
|
} = process.env;
|
|
49
50
|
if (profile) {
|
|
50
|
-
|
|
51
|
+
debug(`Using profile: ${profile}`);
|
|
51
52
|
const credentials = new AWS.SharedIniFileCredentials({
|
|
52
53
|
profile
|
|
53
54
|
});
|
|
54
55
|
AWS.config.credentials = credentials;
|
|
55
56
|
} else if (awsAccessKeyId && awsSecretAccessKey) {
|
|
56
|
-
|
|
57
|
+
debug('Using environment variables');
|
|
57
58
|
} else {
|
|
58
|
-
|
|
59
|
+
debug('Using profile: default');
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
if (region) {
|
|
62
63
|
AWS.config.update({ region });
|
|
63
64
|
}
|
|
64
65
|
if (!AWS.config.region) {
|
|
65
|
-
|
|
66
|
+
debug('no region set');
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
const connected = await checkConnection();
|
|
@@ -97,5 +98,7 @@ export const secretsmanager = async (options: secretsmanagerType) => {
|
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
return {};
|
|
101
|
+
} else {
|
|
102
|
+
console.error('Unable to connect to AWS');
|
|
100
103
|
}
|
|
101
104
|
};
|