@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(
|
|
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.
|
|
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.
|
|
15
|
-
"@friggframework/test": "2.0.0--canary.461.
|
|
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.
|
|
38
|
-
"@friggframework/prettier-config": "2.0.0--canary.461.
|
|
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": "
|
|
73
|
+
"gitHead": "8f65f96aa1317fa9ab104de69b229e751dea2694"
|
|
74
74
|
}
|