@friggframework/devtools 2.0.0--canary.461.4f3c330.0 → 2.0.0--canary.461.8f65f96.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.
@@ -377,7 +377,7 @@ exports.handler = async (event, context) => {
377
377
  })
378
378
  );
379
379
 
380
- console.log(\`Successfully rotated password for cluster: \${ClusterIdentifier}\`);
380
+ console.log('Successfully rotated password for cluster: ' + ClusterIdentifier);
381
381
  await sendResponse('SUCCESS', {
382
382
  Message: 'Password rotated successfully',
383
383
  ClusterIdentifier,
@@ -343,6 +343,161 @@ describe('AuroraBuilder', () => {
343
343
  expect(result.resources.FriggAuroraIngressRule.Properties.ToPort).toBe(5432);
344
344
  expect(result.resources.FriggAuroraIngressRule.Properties.SourceSecurityGroupId).toEqual({ Ref: 'FriggLambdaSecurityGroup' });
345
345
  });
346
+
347
+ describe('autoCreateCredentials', () => {
348
+ it('should create Secrets Manager secret and password rotator when autoCreateCredentials is enabled', async () => {
349
+ const appDefinition = {
350
+ database: {
351
+ postgres: {
352
+ enable: true,
353
+ management: 'discover',
354
+ autoCreateCredentials: true,
355
+ username: 'postgres',
356
+ database: 'frigg',
357
+ },
358
+ },
359
+ };
360
+
361
+ const discoveredResources = {
362
+ auroraClusterEndpoint: 'quo-aurora-cluster.cluster-abc123.us-east-1.rds.amazonaws.com',
363
+ auroraPort: 5432,
364
+ };
365
+
366
+ const result = await auroraBuilder.build(appDefinition, discoveredResources);
367
+
368
+ // Check secret creation
369
+ expect(result.resources.FriggDBSecret).toBeDefined();
370
+ expect(result.resources.FriggDBSecret.Type).toBe('AWS::SecretsManager::Secret');
371
+ expect(result.resources.FriggDBSecret.Properties.GenerateSecretString.SecretStringTemplate).toContain('postgres');
372
+ expect(result.resources.FriggDBSecret.Properties.GenerateSecretString.PasswordLength).toBe(32);
373
+
374
+ // Check password rotator Lambda
375
+ expect(result.resources.PasswordRotatorLambda).toBeDefined();
376
+ expect(result.resources.PasswordRotatorLambda.Type).toBe('AWS::Lambda::Function');
377
+ expect(result.resources.PasswordRotatorLambda.Properties.Runtime).toBe('nodejs22.x');
378
+
379
+ // Check custom resource
380
+ expect(result.resources.FriggAuroraPasswordRotator).toBeDefined();
381
+ expect(result.resources.FriggAuroraPasswordRotator.Type).toBe('Custom::AuroraPasswordRotator');
382
+ expect(result.resources.FriggAuroraPasswordRotator.Properties.ClusterIdentifier).toBe('quo-aurora-cluster');
383
+
384
+ // Check IAM role
385
+ expect(result.resources.PasswordRotatorRole).toBeDefined();
386
+ expect(result.resources.PasswordRotatorRole.Type).toBe('AWS::IAM::Role');
387
+
388
+ // Check DATABASE_URL uses the secret
389
+ expect(result.environment.DATABASE_URL).toBeDefined();
390
+ expect(result.environment.DATABASE_URL['Fn::Sub']).toBeDefined();
391
+ expect(result.environment.DATABASE_URL['Fn::Sub'][1].Username).toContain('resolve:secretsmanager');
392
+ expect(result.environment.DATABASE_URL['Fn::Sub'][1].Password).toContain('resolve:secretsmanager');
393
+
394
+ // Check IAM permissions for secret access
395
+ const secretPermission = result.iamStatements.find(stmt =>
396
+ stmt.Action.includes('secretsmanager:GetSecretValue')
397
+ );
398
+ expect(secretPermission).toBeDefined();
399
+ });
400
+
401
+ it('should not create credentials when autoCreateCredentials is false', async () => {
402
+ const appDefinition = {
403
+ database: {
404
+ postgres: {
405
+ enable: true,
406
+ management: 'discover',
407
+ autoCreateCredentials: false,
408
+ },
409
+ },
410
+ };
411
+
412
+ const discoveredResources = {
413
+ auroraClusterEndpoint: 'cluster.abc.us-east-1.rds.amazonaws.com',
414
+ auroraPort: 5432,
415
+ };
416
+
417
+ const result = await auroraBuilder.build(appDefinition, discoveredResources);
418
+
419
+ // Should not create secret or rotator
420
+ expect(result.resources.FriggDBSecret).toBeUndefined();
421
+ expect(result.resources.PasswordRotatorLambda).toBeUndefined();
422
+ expect(result.resources.FriggAuroraPasswordRotator).toBeUndefined();
423
+ expect(result.resources.PasswordRotatorRole).toBeUndefined();
424
+
425
+ // DATABASE_URL should use env variables
426
+ expect(result.environment.DATABASE_URL).toBeDefined();
427
+ expect(result.environment.DATABASE_URL['Fn::Sub']).toBeDefined();
428
+ expect(result.environment.DATABASE_URL['Fn::Sub'][1].DatabaseUser).toContain('env:DATABASE_USER');
429
+ expect(result.environment.DATABASE_URL['Fn::Sub'][1].DatabasePassword).toContain('env:DATABASE_PASSWORD');
430
+ });
431
+
432
+ it('should not create credentials when secret is already discovered', async () => {
433
+ const appDefinition = {
434
+ database: {
435
+ postgres: {
436
+ enable: true,
437
+ management: 'discover',
438
+ autoCreateCredentials: true, // Enabled, but secret already exists
439
+ },
440
+ },
441
+ };
442
+
443
+ const discoveredResources = {
444
+ auroraClusterEndpoint: 'cluster.abc.us-east-1.rds.amazonaws.com',
445
+ auroraPort: 5432,
446
+ databaseSecretArn: 'arn:aws:secretsmanager:us-east-1:123:secret:existing-secret',
447
+ };
448
+
449
+ const result = await auroraBuilder.build(appDefinition, discoveredResources);
450
+
451
+ // Should use existing secret, not create new one
452
+ expect(result.resources.FriggDBSecret).toBeUndefined();
453
+ expect(result.resources.PasswordRotatorLambda).toBeUndefined();
454
+ expect(result.environment.DATABASE_SECRET_ARN).toBe('arn:aws:secretsmanager:us-east-1:123:secret:existing-secret');
455
+ });
456
+
457
+ it('should extract correct cluster identifier from endpoint', async () => {
458
+ const appDefinition = {
459
+ database: {
460
+ postgres: {
461
+ enable: true,
462
+ management: 'discover',
463
+ autoCreateCredentials: true,
464
+ },
465
+ },
466
+ };
467
+
468
+ const discoveredResources = {
469
+ auroraClusterEndpoint: 'my-cluster-name.cluster-xyz123.us-west-2.rds.amazonaws.com',
470
+ auroraPort: 5432,
471
+ };
472
+
473
+ const result = await auroraBuilder.build(appDefinition, discoveredResources);
474
+
475
+ expect(result.resources.FriggAuroraPasswordRotator.Properties.ClusterIdentifier).toBe('my-cluster-name');
476
+ });
477
+
478
+ it('should set DATABASE_HOST, DATABASE_PORT, DATABASE_NAME when autoCreateCredentials is enabled', async () => {
479
+ const appDefinition = {
480
+ database: {
481
+ postgres: {
482
+ enable: true,
483
+ management: 'discover',
484
+ autoCreateCredentials: true,
485
+ database: 'mydb',
486
+ },
487
+ },
488
+ };
489
+
490
+ const discoveredResources = {
491
+ auroraClusterEndpoint: 'cluster.abc.us-east-1.rds.amazonaws.com',
492
+ auroraPort: 5432,
493
+ };
494
+
495
+ const result = await auroraBuilder.build(appDefinition, discoveredResources);
496
+
497
+ expect(result.environment.DATABASE_HOST).toBe('cluster.abc.us-east-1.rds.amazonaws.com');
498
+ expect(result.environment.DATABASE_PORT).toBe('5432');
499
+ });
500
+ });
346
501
  });
347
502
 
348
503
  describe('build() - create-new mode', () => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@friggframework/devtools",
3
3
  "prettier": "@friggframework/prettier-config",
4
- "version": "2.0.0--canary.461.4f3c330.0",
4
+ "version": "2.0.0--canary.461.8f65f96.0",
5
5
  "dependencies": {
6
6
  "@aws-sdk/client-ec2": "^3.835.0",
7
7
  "@aws-sdk/client-kms": "^3.835.0",
@@ -11,8 +11,8 @@
11
11
  "@babel/eslint-parser": "^7.18.9",
12
12
  "@babel/parser": "^7.25.3",
13
13
  "@babel/traverse": "^7.25.3",
14
- "@friggframework/schemas": "2.0.0--canary.461.4f3c330.0",
15
- "@friggframework/test": "2.0.0--canary.461.4f3c330.0",
14
+ "@friggframework/schemas": "2.0.0--canary.461.8f65f96.0",
15
+ "@friggframework/test": "2.0.0--canary.461.8f65f96.0",
16
16
  "@hapi/boom": "^10.0.1",
17
17
  "@inquirer/prompts": "^5.3.8",
18
18
  "axios": "^1.7.2",
@@ -34,8 +34,8 @@
34
34
  "serverless-http": "^2.7.0"
35
35
  },
36
36
  "devDependencies": {
37
- "@friggframework/eslint-config": "2.0.0--canary.461.4f3c330.0",
38
- "@friggframework/prettier-config": "2.0.0--canary.461.4f3c330.0",
37
+ "@friggframework/eslint-config": "2.0.0--canary.461.8f65f96.0",
38
+ "@friggframework/prettier-config": "2.0.0--canary.461.8f65f96.0",
39
39
  "aws-sdk-client-mock": "^4.1.0",
40
40
  "aws-sdk-client-mock-jest": "^4.1.0",
41
41
  "jest": "^30.1.3",
@@ -70,5 +70,5 @@
70
70
  "publishConfig": {
71
71
  "access": "public"
72
72
  },
73
- "gitHead": "4f3c33010ab48c11f66a630ea72f75afc2e21762"
73
+ "gitHead": "8f65f96aa1317fa9ab104de69b229e751dea2694"
74
74
  }