Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

POC - Seed Secrets #2361

Draft
wants to merge 37 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
5f94dda
set up for seed secrets
Dec 17, 2024
37eb2c9
tsconfig update
Dec 17, 2024
9b90d77
most things but backendId
Dec 17, 2024
ade05b9
new files
Dec 18, 2024
c1f7455
temp sandbox Id resovler
Dec 18, 2024
38f50b4
tsconfig update
Dec 18, 2024
7c307dc
updating package.locks
Dec 18, 2024
521192d
exporting seed secret export
Dec 18, 2024
3a87856
more package.lock changes
Dec 18, 2024
1a3f6ce
export seed secret
Dec 18, 2024
d599a9d
updated API
Dec 18, 2024
460423f
added types file
Dec 18, 2024
7325c65
removed comments
Dec 18, 2024
9ba0894
sandbox seed command
Dec 18, 2024
e2bf43d
signal that seed command is running
Dec 19, 2024
6f347d6
add seed command to sandbox
Dec 19, 2024
20284b1
update seed console message
Dec 19, 2024
964ed6e
explict undefined check
Dec 19, 2024
c38fb30
adjustments
Dec 19, 2024
7930f5c
testing
Dec 19, 2024
8f8c9a5
testing
Dec 19, 2024
2e9d02b
adjusting env vars
Dec 19, 2024
146a91e
testing env vars stuff
Dec 19, 2024
6268d54
trying to use generators
Dec 19, 2024
12d2162
stole some seed command stuff from the first POC
Dec 19, 2024
cb8bf83
stole some seed command stuff from the first POC
Dec 19, 2024
0b715e9
removed useless import
Dec 19, 2024
dcc0bed
removed console.logs - it works :D
Dec 19, 2024
fb48d38
file clean up
Dec 19, 2024
d4a5658
move seed script out of Amplify folder
Dec 20, 2024
ecc470c
change to package-lock
Dec 20, 2024
827e02c
adjusted comments and error message
Dec 20, 2024
a4cbf95
removed section that is no longer needed
Dec 20, 2024
a92defc
update for package.json in seed package
Dec 20, 2024
cbaf469
added changeset
Dec 20, 2024
79dfb1c
changed name of secert getter
Dec 20, 2024
f8a9649
update api
Dec 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .changeset/green-melons-jump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
63 changes: 54 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions packages/backend-seed/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Be very careful editing this file. It is crafted to work around [this issue](https://github.com/npm/npm/issues/4479)

# First ignore everything
**/*

# Then add back in transpiled js and ts declaration files
!lib/**/*.js
!lib/**/*.d.ts

# Then ignore test js and ts declaration files
*.test.js
*.test.d.ts

# This leaves us with including only js and ts declaration files of functional code
12 changes: 12 additions & 0 deletions packages/backend-seed/API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## API Report File for "@aws-amplify/backend-seed"

> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).

```ts

// @public (undocumented)
export const GetSeedSecret: (secretName: string) => Promise<string>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd just call it getSecret .

Other option we could consider is

type SeedSecretClient {
  getSecret: () => Promise<string>;
}

// factory returns implementation
getSeedSecretClient = () => SeedSecretClient

We should think about packaging of this because APIs to deal with secrets will grow over time.
We'll also have AuthSeedClient or so or set of auth related APIs. it would be good to group secrets and auth.

An alternative would be to develop namespaces:
@aws-amplify/backend-seed/secret and @aws-amplify/backend-seed/auth .

We should capture these alternatives in API review.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially called it getSecret, but I got some errors since it conflicted with getSecret from the backend-secret package -- I'll probably experiment with it again

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be helpful syntax to resolve that problem

import { authOutputSchema as authOutputSchemaV1 } from './v1.js';
.

or import * as backendSecret from 'backend-secret' and then backendSecret.getSecret .


// (No @packageDocumentation comment for this package)

```
3 changes: 3 additions & 0 deletions packages/backend-seed/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Description

Replace with a description of this package
3 changes: 3 additions & 0 deletions packages/backend-seed/api-extractor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../../api-extractor.base.json"
}
26 changes: 26 additions & 0 deletions packages/backend-seed/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "@aws-amplify/backend-seed",
"version": "0.1.0",
"type": "module",
"publishConfig": {
"access": "public"
},
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./lib/index.js",
"require": "./lib/index.js"
}
},
"main": "lib/index.js",
"types": "lib/index.d.ts",
"scripts": {
"update:api": "api-extractor run --local"
},
"license": "Apache-2.0",
"dependencies": {
"@aws-amplify/backend-secret": "^1.1.5",
"@aws-amplify/platform-core": "^1.3.0",
"@aws-amplify/plugin-types": "^1.6.0"
}
}
19 changes: 19 additions & 0 deletions packages/backend-seed/src/get_secret_seed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { getSecretClientWithAmplifyErrorHandling } from '@aws-amplify/backend-secret';
import { BackendIdentifier } from '@aws-amplify/plugin-types';

//eslint-disable-next-line jsdoc/require-description
/**
*
*/
export const GetSeedSecret = async (secretName: string): Promise<string> => {
if (!process.env.AMPLIFY_SANDBOX_IDENTIFIER) {
throw new Error('SANDBOX_IDENTIFIER is undefined.');
}
const backendId: BackendIdentifier = JSON.parse(
process.env.AMPLIFY_SANDBOX_IDENTIFIER
);

const secretClient = getSecretClientWithAmplifyErrorHandling();
const secret = await secretClient.getSecret(backendId, { name: secretName });
return secret.value;
};
3 changes: 3 additions & 0 deletions packages/backend-seed/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { GetSeedSecret } from './get_secret_seed.js';

export { GetSeedSecret };
35 changes: 35 additions & 0 deletions packages/backend-seed/src/namespace_resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {
AmplifyUserError,
PackageJsonReader,
} from '@aws-amplify/platform-core';
import { EOL } from 'os';

//not using this anymore
//stole this from ../packages/cli/src/backend-identifier/local_namespace_resolver.ts for the POC
Comment on lines +7 to +8
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these will probably go to cli-core .


export type NamespaceResolver = {
resolve: () => Promise<string>;
};

/**
* Reads the local app name from package.json#name in the current directory
*/
export class LocalNamespaceResolver implements NamespaceResolver {
/**
* packageJsonReader is assigned to an instance member for testing.
* resolve is bound to this so that it can be passed as a function reference
*/
constructor(private readonly packageJsonReader: PackageJsonReader) {}

/**
* Returns the value of package.json#name from the current working directory
*/
resolve = async () => {
const name = this.packageJsonReader.readFromCwd().name;
if (name) return name;
throw new AmplifyUserError('InvalidPackageJsonError', {
message: 'Cannot load name from the package.json',
resolution: `Ensure you are running ampx commands in root of your project (i.e. in the parent of the 'amplify' directory).${EOL}Also ensure that your root package.json file has a "name" field.`,
});
};
}
33 changes: 33 additions & 0 deletions packages/backend-seed/src/sandbox_id_resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { userInfo as _userInfo } from 'os';
import { NamespaceResolver } from './namespace_resolver.js';
import { BackendIdentifier } from '@aws-amplify/plugin-types';

//not using this anymore
//stole this from ../packages/cli/src/commands/sandbox/sandbox_id_resolver.ts for the POC

/**
* Resolves an ID that can be used to uniquely identify sandbox environments
*/
export class SandboxBackendIdResolver {
/**
* Initialize with an appName resolver
*/
constructor(
private readonly namespaceResolver: NamespaceResolver,
private readonly userInfo = _userInfo
) {}

/**
* Returns a concatenation of the resolved appName and the current username
*/
resolve = async (identifier?: string): Promise<BackendIdentifier> => {
const namespace = await this.namespaceResolver.resolve();
const name = identifier || this.userInfo().username;

return {
namespace,
name,
type: 'sandbox',
};
};
}
Empty file.
9 changes: 9 additions & 0 deletions packages/backend-seed/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": { "rootDir": "src", "outDir": "lib" },
"references": [
{ "path": "../backend-secret" },
{ "path": "../platform-core" },
{ "path": "../plugin-types" }
]
}
3 changes: 3 additions & 0 deletions packages/backend-seed/typedoc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"entryPoints": ["src/index.ts"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Argv, CommandModule } from 'yargs';
import path from 'path';
import { existsSync } from 'fs';
import { execa } from 'execa';
import { SandboxBackendIdResolver } from '../sandbox_id_resolver.js';
import { PackageJsonReader } from '@aws-amplify/platform-core';
import { LocalNamespaceResolver } from '../../../backend-identifier/local_namespace_resolver.js';

/**
*
*/
export class SandboxSeedCommand implements CommandModule<object> {
/**
* @inheritDoc
*/
readonly command: string;

/**
* @inheritDoc
*/
readonly describe: string;

/**
* Seeds sandbox environment.
*/
constructor() {
this.command = 'seed';
this.describe = 'Seeds sandbox environment';
}

/**
* @inheritDoc
*/
handler = async (): Promise<void> => {
const sandboxID = await new SandboxBackendIdResolver(
new LocalNamespaceResolver(new PackageJsonReader())
).resolve();

//most of this comes from the initial POC for seed, changed filepath to be more inline with discussions that have happened since then
const seedPath = path.join('seed.ts');
await execa('tsx', [seedPath], {
cwd: process.cwd(),
stdio: 'inherit',
env: {
AMPLIFY_SANDBOX_IDENTIFIER: JSON.stringify(sandboxID),
},
});
};

/**
* @inheritDoc
*/
//this section also comes from the initial POC for seed
builder = (yargs: Argv) => {
return yargs.check(() => {
const seedPath = path.join(process.cwd(), 'seed.ts');
if (!existsSync(seedPath)) {
throw new Error(`${seedPath} must exist`);
}
return true;
});
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { SandboxBackendIdResolver } from './sandbox_id_resolver.js';
import { ClientConfigGeneratorAdapter } from '../../client-config/client_config_generator_adapter.js';
import { LocalNamespaceResolver } from '../../backend-identifier/local_namespace_resolver.js';
import { createSandboxSecretCommand } from './sandbox-secret/sandbox_secret_command_factory.js';
import { SandboxSeedCommand } from './sandbox-seed/sandbox_seed_command.js';
import {
PackageJsonReader,
UsageDataEmitterFactory,
Expand Down Expand Up @@ -63,7 +64,11 @@ export const createSandboxCommand = (): CommandModule<
const commandMiddleWare = new CommandMiddleware(printer);
return new SandboxCommand(
sandboxFactory,
[new SandboxDeleteCommand(sandboxFactory), createSandboxSecretCommand()],
[
new SandboxDeleteCommand(sandboxFactory),
createSandboxSecretCommand(),
new SandboxSeedCommand(),
],
clientConfigGeneratorAdapter,
commandMiddleWare,
eventHandlerFactory.getSandboxEventHandlers
Expand Down
Loading