-
Notifications
You must be signed in to change notification settings - Fork 1
feat: DB v2 test default db #94
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
Open
mandryllo
wants to merge
78
commits into
master
Choose a base branch
from
feat/db-v2-tests
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
78 commits
Select commit
Hold shift + click to select a range
7b8bac4
Create db v2 component
mandryllo 396e648
Remove ability to create custom parameter group
mandryllo b295e28
Cleanup
mandryllo 35bc5cb
Fix kms key id type
mandryllo 19c3ece
Cleanup
mandryllo ce83def
Cleanup vpc parameters
mandryllo 292b549
Cleanup types
mandryllo d4120ce
Fix formatting
mandryllo b09a6c0
Cleanup
mandryllo 53061fe
Create db builder component
mandryllo c32427b
Fix typo
mandryllo cb12a13
Remove custom parameter group args
mandryllo 784af7f
Cleanup private props
mandryllo 4df9363
Remove parameter group name from builder
mandryllo b439523
Cleanup naming
mandryllo 0195797
Fix formatting
mandryllo 2d399cf
Cleanup
mandryllo b17a54f
Expose db v2 components
mandryllo def9885
Add type tests
mandryllo 9cc3856
Add default db tests
mandryllo bb298bc
Cleanup database types
mandryllo 6af2d1b
Cleanup
mandryllo 950fe1a
Revert allocatedStorage type to number
mandryllo ff389f9
Remove withKms method from builder
mandryllo 817f100
Update type tests
mandryllo 0605888
Update integration tests
mandryllo 15927fe
fix tags
mandryllo f72366f
Fix snapshot id
mandryllo 3b4d3e5
Remove export
mandryllo ef9fea4
Fix imports in tests
mandryllo c826e12
Fix wrong condition
mandryllo 20a59e3
Cleanup final snapshots
mandryllo 3648874
Fix getting snapshots
mandryllo 3bba784
Update database builder
mandryllo 3602506
Cleanup
mandryllo 7822894
Fix type tests
mandryllo 3107de3
Create db v2 component
mandryllo e0cae9b
Remove ability to create custom parameter group
mandryllo 117e798
Cleanup
mandryllo 7c2b479
Fix kms key id type
mandryllo 06fe2d8
Cleanup
mandryllo 17f5e9e
Cleanup vpc parameters
mandryllo f491332
Cleanup types
mandryllo 9056cf8
Fix formatting
mandryllo 75308bc
Cleanup
mandryllo 3ba47f5
Create db builder component
mandryllo 6b0648f
Fix typo
mandryllo 65f030a
Remove custom parameter group args
mandryllo bfec1fc
Cleanup private props
mandryllo a48d054
Remove parameter group name from builder
mandryllo 379dc30
Cleanup naming
mandryllo 14d208b
Fix formatting
mandryllo c629546
Cleanup
mandryllo 6906eb4
Cleanup database types
mandryllo 8f5939e
Cleanup
mandryllo 80804be
Revert allocatedStorage type to number
mandryllo 98fb66b
Remove withKms method from builder
mandryllo 5cfb8f9
fix tags
mandryllo 823598e
Fix snapshot id
mandryllo 9d7d045
Fix wrong condition
mandryllo 1937146
Update database builder
mandryllo 311d792
Cleanup
mandryllo b43859c
Move applyImmediately to instance config
mandryllo 62b03d9
Update builder methods
mandryllo e8a017b
Update tests
mandryllo f9fdc02
Move kms key from storage type
mandryllo 6467dff
Update builder
mandryllo 3375e86
Cleanup default tests
mandryllo dce0103
Fix allocated storage type
mandryllo a783195
Revert "Fix allocated storage type"
mandryllo 41783a5
Update after merge
mandryllo 54ca753
Merge branch 'master' into feat/db-v2-tests
mandryllo b70eb78
Cleanup
mandryllo b3e2bc8
Merge branch 'master' into feat/db-v2-tests
mandryllo dd0efc7
Merge branch 'master' into feat/db-v2-tests
mandryllo d760f4e
Resolve comments
mandryllo 242e60f
Merge branch 'master' into feat/db-v2-tests
mandryllo 44df91e
Update dependecies
mandryllo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,205 @@ | ||
| import { describe, before, after } from 'node:test'; | ||
| import { | ||
| DescribeDBInstancesCommand, | ||
| DescribeDBSubnetGroupsCommand, | ||
| } from '@aws-sdk/client-rds'; | ||
| import { | ||
| DescribeKeyCommand, | ||
| GetKeyRotationStatusCommand, | ||
| } from '@aws-sdk/client-kms'; | ||
| import { | ||
| DescribeSecurityGroupsCommand, | ||
| IpPermission, | ||
| } from '@aws-sdk/client-ec2'; | ||
| import * as assert from 'node:assert'; | ||
| import * as automation from '../automation'; | ||
| import { cleanupSnapshots } from './util'; | ||
| import * as config from './infrastructure/config'; | ||
| import { DatabaseTestContext } from './test-context'; | ||
| import { EC2Client } from '@aws-sdk/client-ec2'; | ||
| import { InlineProgramArgs } from '@pulumi/pulumi/automation'; | ||
| import { it } from 'node:test'; | ||
| import { KMSClient } from '@aws-sdk/client-kms'; | ||
| import { RDSClient } from '@aws-sdk/client-rds'; | ||
| import { requireEnv } from '../util'; | ||
|
|
||
| const programArgs: InlineProgramArgs = { | ||
| stackName: 'dev', | ||
| projectName: 'icb-test-database', | ||
| program: () => import('./infrastructure'), | ||
| }; | ||
|
|
||
| const region = requireEnv('AWS_REGION'); | ||
| const ctx: DatabaseTestContext = { | ||
| outputs: {}, | ||
| config, | ||
| clients: { | ||
| rds: new RDSClient({ region }), | ||
| ec2: new EC2Client({ region }), | ||
| kms: new KMSClient({ region }), | ||
| }, | ||
| }; | ||
|
|
||
| describe('Database component deployment', () => { | ||
| before(async () => { | ||
| ctx.outputs = await automation.deploy(programArgs); | ||
| }); | ||
|
|
||
| after(async () => { | ||
| await automation.destroy(programArgs); | ||
| await cleanupSnapshots(ctx); | ||
| }); | ||
|
|
||
| it('should create a database', async () => { | ||
| const database = ctx.outputs.defaultDb.value; | ||
|
|
||
| assert.ok(database, 'Database should be defined'); | ||
| assert.strictEqual( | ||
| database.name, | ||
| `${ctx.config.appName}-default-db`, | ||
| 'Database should have correct name', | ||
| ); | ||
| assert.ok(database.instance, 'Database instance should be defined'); | ||
|
|
||
| const command = new DescribeDBInstancesCommand({ | ||
| DBInstanceIdentifier: database.instance.dbInstanceIdentifier, | ||
| }); | ||
|
|
||
| const { DBInstances } = await ctx.clients.rds.send(command); | ||
| assert.ok( | ||
| DBInstances && DBInstances.length === 1, | ||
| 'Database instance should be created', | ||
| ); | ||
| const [DBInstance] = DBInstances; | ||
| assert.strictEqual( | ||
| DBInstance.DBInstanceIdentifier, | ||
| database.instance.dbInstanceIdentifier, | ||
| 'Database instance identifier should match', | ||
| ); | ||
| }); | ||
|
|
||
| it('should create other resources', () => { | ||
| const database = ctx.outputs.defaultDb.value; | ||
|
|
||
| assert.ok(database.dbSecurityGroup, 'Db security group should be defined'); | ||
| assert.ok(database.dbSubnetGroup, 'Db subnet group should be defined'); | ||
| assert.ok(database.kmsKeyId, 'Kms key id should be defined'); | ||
| assert.ok(database.password, 'Password should be defined'); | ||
| }); | ||
|
|
||
| it('should configure database instance with correct defaults', () => { | ||
| const instance = ctx.outputs.defaultDb.value.instance; | ||
|
|
||
| assert.partialDeepStrictEqual( | ||
| instance, | ||
| { | ||
| dbName: ctx.config.dbName, | ||
| masterUsername: ctx.config.dbUsername, | ||
| multiAz: false, | ||
| applyImmediately: false, | ||
| allocatedStorage: '20', | ||
| maxAllocatedStorage: 100, | ||
| dbInstanceClass: 'db.t4g.micro', | ||
| enablePerformanceInsights: false, | ||
| allowMajorVersionUpgrade: false, | ||
| autoMinorVersionUpgrade: true, | ||
| engineVersion: '17.2', | ||
| engine: 'postgres', | ||
| storageEncrypted: true, | ||
| publiclyAccessible: false, | ||
| }, | ||
| 'Database instance should be configured correctly', | ||
| ); | ||
| }); | ||
|
|
||
| it('should create subnet group in the correct VPC', async () => { | ||
| const database = ctx.outputs.defaultDb.value; | ||
| const vpc = ctx.outputs.vpc.value; | ||
| const dbSubnetGroupName = database.dbSubnetGroup.name; | ||
|
|
||
| const command = new DescribeDBSubnetGroupsCommand({ | ||
| DBSubnetGroupName: dbSubnetGroupName, | ||
| }); | ||
|
|
||
| const { DBSubnetGroups } = await ctx.clients.rds.send(command); | ||
| assert.ok( | ||
| DBSubnetGroups && DBSubnetGroups.length > 0, | ||
| 'DB subnet groups should exist', | ||
| ); | ||
| const [subnetGroup] = DBSubnetGroups; | ||
| assert.strictEqual( | ||
| subnetGroup.VpcId, | ||
| vpc.vpc.vpcId, | ||
| 'DB subnet group should be in the correct VPC', | ||
| ); | ||
| assert.ok( | ||
| subnetGroup.Subnets && subnetGroup.Subnets.length > 0, | ||
| 'DB subnet group should have subnets', | ||
| ); | ||
| }); | ||
|
|
||
| it('should create a security group with correct ingress rules', async () => { | ||
| const database = ctx.outputs.defaultDb.value; | ||
| const vpc = ctx.outputs.vpc.value; | ||
| const dbSecurityGroupId = database.dbSecurityGroup.id; | ||
|
|
||
| const command = new DescribeSecurityGroupsCommand({ | ||
| GroupIds: [dbSecurityGroupId], | ||
| }); | ||
| const { SecurityGroups } = await ctx.clients.ec2.send(command); | ||
| assert.ok( | ||
| SecurityGroups && SecurityGroups.length > 0, | ||
| 'DB security groups should exist', | ||
| ); | ||
| const [securityGroup] = SecurityGroups; | ||
| assert.strictEqual( | ||
| securityGroup.VpcId, | ||
| vpc.vpc.vpcId, | ||
| 'DB security group should be in the correct VPC', | ||
| ); | ||
|
|
||
| const postgresRule = securityGroup.IpPermissions?.find( | ||
| (rule: IpPermission) => rule.FromPort === 5432 && rule.ToPort === 5432, | ||
| ); | ||
| assert.ok(postgresRule, 'Should have postgres port 5432 ingress rule'); | ||
| assert.strictEqual( | ||
| postgresRule.IpProtocol, | ||
| 'tcp', | ||
| 'Should allow TCP protocol', | ||
| ); | ||
| }); | ||
|
|
||
| it('should create a correctly configured RDS KMS key', async () => { | ||
| const database = ctx.outputs.defaultDb.value; | ||
| const kmsKeyId = database.kmsKeyId; | ||
|
|
||
| const describeCommand = new DescribeKeyCommand({ | ||
| KeyId: kmsKeyId, | ||
| }); | ||
| const { KeyMetadata } = await ctx.clients.kms.send(describeCommand); | ||
| assert.strictEqual( | ||
| KeyMetadata?.KeySpec, | ||
| 'SYMMETRIC_DEFAULT', | ||
| 'KMS key should use SYMMETRIC_DEFAULT spec', | ||
| ); | ||
| assert.strictEqual( | ||
| KeyMetadata.KeyUsage, | ||
| 'ENCRYPT_DECRYPT', | ||
| 'KMS key should be used for encryption/decryption', | ||
| ); | ||
| assert.strictEqual(KeyMetadata.Enabled, true, 'KMS key should be enabled'); | ||
| assert.strictEqual( | ||
| KeyMetadata.MultiRegion, | ||
| false, | ||
| 'KMS key should not be multi-region', | ||
| ); | ||
|
|
||
| const rotationCmd = new GetKeyRotationStatusCommand({ KeyId: kmsKeyId }); | ||
| const { KeyRotationEnabled } = await ctx.clients.kms.send(rotationCmd); | ||
| assert.strictEqual( | ||
| KeyRotationEnabled, | ||
| true, | ||
| 'KMS key rotation should be enabled', | ||
| ); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export const appName = 'db-test'; | ||
| export const dbName = 'dbname'; | ||
| export const dbUsername = 'dbusername'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import { appName, dbName, dbUsername } from './config'; | ||
| import { next as studion } from '@studion/infra-code-blocks'; | ||
| import { DatabaseBuilder } from '../../../dist/v2/components/database/builder'; | ||
|
|
||
| const vpc = new studion.Vpc(`${appName}-vpc`, {}); | ||
|
|
||
| const defaultDb = new DatabaseBuilder(`${appName}-default-db`) | ||
| .withInstance({ | ||
| dbName, | ||
| }) | ||
| .withCredentials({ | ||
| username: dbUsername, | ||
| }) | ||
| .withVpc(vpc.vpc) | ||
| .build(); | ||
|
|
||
| export { vpc, defaultDb }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import { EC2Client } from '@aws-sdk/client-ec2'; | ||
| import { KMSClient } from '@aws-sdk/client-kms'; | ||
| import { OutputMap } from '@pulumi/pulumi/automation'; | ||
| import { RDSClient } from '@aws-sdk/client-rds'; | ||
|
|
||
| interface ConfigContext { | ||
| config: DatabaseTestConfig; | ||
| } | ||
|
|
||
| interface DatabaseTestConfig { | ||
| appName: string; | ||
| dbName: string; | ||
| dbUsername: string; | ||
| } | ||
|
|
||
| interface PulumiProgramContext { | ||
| outputs: OutputMap; | ||
| } | ||
|
|
||
| interface AwsContext { | ||
| clients: { | ||
| rds: RDSClient; | ||
| ec2: EC2Client; | ||
| kms: KMSClient; | ||
| }; | ||
| } | ||
|
|
||
| export interface DatabaseTestContext | ||
| extends ConfigContext, | ||
| PulumiProgramContext, | ||
| AwsContext {} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.