runbooks 0.2.3__py3-none-any.whl → 0.6.1__py3-none-any.whl
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.
- conftest.py +26 -0
- jupyter-agent/.env.template +2 -0
- jupyter-agent/.gitattributes +35 -0
- jupyter-agent/README.md +16 -0
- jupyter-agent/app.py +256 -0
- jupyter-agent/cloudops-agent.png +0 -0
- jupyter-agent/ds-system-prompt.txt +154 -0
- jupyter-agent/jupyter-agent.png +0 -0
- jupyter-agent/llama3_template.jinja +123 -0
- jupyter-agent/requirements.txt +9 -0
- jupyter-agent/utils.py +409 -0
- runbooks/__init__.py +71 -3
- runbooks/__main__.py +13 -0
- runbooks/aws/ec2_describe_instances.py +1 -1
- runbooks/aws/ec2_run_instances.py +8 -2
- runbooks/aws/ec2_start_stop_instances.py +17 -4
- runbooks/aws/ec2_unused_volumes.py +5 -1
- runbooks/aws/s3_create_bucket.py +4 -2
- runbooks/aws/s3_list_objects.py +6 -1
- runbooks/aws/tagging_lambda_handler.py +13 -2
- runbooks/aws/tags.json +12 -0
- runbooks/base.py +353 -0
- runbooks/cfat/README.md +49 -0
- runbooks/cfat/__init__.py +74 -0
- runbooks/cfat/app.ts +644 -0
- runbooks/cfat/assessment/__init__.py +40 -0
- runbooks/cfat/assessment/asana-import.csv +39 -0
- runbooks/cfat/assessment/cfat-checks.csv +31 -0
- runbooks/cfat/assessment/cfat.txt +520 -0
- runbooks/cfat/assessment/collectors.py +200 -0
- runbooks/cfat/assessment/jira-import.csv +39 -0
- runbooks/cfat/assessment/runner.py +387 -0
- runbooks/cfat/assessment/validators.py +290 -0
- runbooks/cfat/cli.py +103 -0
- runbooks/cfat/docs/asana-import.csv +24 -0
- runbooks/cfat/docs/cfat-checks.csv +31 -0
- runbooks/cfat/docs/cfat.txt +335 -0
- runbooks/cfat/docs/checks-output.png +0 -0
- runbooks/cfat/docs/cloudshell-console-run.png +0 -0
- runbooks/cfat/docs/cloudshell-download.png +0 -0
- runbooks/cfat/docs/cloudshell-output.png +0 -0
- runbooks/cfat/docs/downloadfile.png +0 -0
- runbooks/cfat/docs/jira-import.csv +24 -0
- runbooks/cfat/docs/open-cloudshell.png +0 -0
- runbooks/cfat/docs/report-header.png +0 -0
- runbooks/cfat/models.py +1026 -0
- runbooks/cfat/package-lock.json +5116 -0
- runbooks/cfat/package.json +38 -0
- runbooks/cfat/report.py +496 -0
- runbooks/cfat/reporting/__init__.py +46 -0
- runbooks/cfat/reporting/exporters.py +337 -0
- runbooks/cfat/reporting/formatters.py +496 -0
- runbooks/cfat/reporting/templates.py +135 -0
- runbooks/cfat/run-assessment.sh +23 -0
- runbooks/cfat/runner.py +69 -0
- runbooks/cfat/src/actions/check-cloudtrail-existence.ts +43 -0
- runbooks/cfat/src/actions/check-config-existence.ts +37 -0
- runbooks/cfat/src/actions/check-control-tower.ts +37 -0
- runbooks/cfat/src/actions/check-ec2-existence.ts +46 -0
- runbooks/cfat/src/actions/check-iam-users.ts +50 -0
- runbooks/cfat/src/actions/check-legacy-cur.ts +30 -0
- runbooks/cfat/src/actions/check-org-cloudformation.ts +30 -0
- runbooks/cfat/src/actions/check-vpc-existence.ts +43 -0
- runbooks/cfat/src/actions/create-asanaimport.ts +14 -0
- runbooks/cfat/src/actions/create-backlog.ts +372 -0
- runbooks/cfat/src/actions/create-jiraimport.ts +15 -0
- runbooks/cfat/src/actions/create-report.ts +616 -0
- runbooks/cfat/src/actions/define-account-type.ts +51 -0
- runbooks/cfat/src/actions/get-enabled-org-policy-types.ts +40 -0
- runbooks/cfat/src/actions/get-enabled-org-services.ts +26 -0
- runbooks/cfat/src/actions/get-idc-info.ts +34 -0
- runbooks/cfat/src/actions/get-org-da-accounts.ts +34 -0
- runbooks/cfat/src/actions/get-org-details.ts +35 -0
- runbooks/cfat/src/actions/get-org-member-accounts.ts +44 -0
- runbooks/cfat/src/actions/get-org-ous.ts +35 -0
- runbooks/cfat/src/actions/get-regions.ts +22 -0
- runbooks/cfat/src/actions/zip-assessment.ts +27 -0
- runbooks/cfat/src/types/index.d.ts +147 -0
- runbooks/cfat/tests/__init__.py +141 -0
- runbooks/cfat/tests/test_cli.py +340 -0
- runbooks/cfat/tests/test_integration.py +290 -0
- runbooks/cfat/tests/test_models.py +505 -0
- runbooks/cfat/tests/test_reporting.py +354 -0
- runbooks/cfat/tsconfig.json +16 -0
- runbooks/cfat/webpack.config.cjs +27 -0
- runbooks/config.py +260 -0
- runbooks/finops/__init__.py +88 -0
- runbooks/finops/aws_client.py +245 -0
- runbooks/finops/cli.py +151 -0
- runbooks/finops/cost_processor.py +410 -0
- runbooks/finops/dashboard_runner.py +448 -0
- runbooks/finops/helpers.py +355 -0
- runbooks/finops/main.py +14 -0
- runbooks/finops/profile_processor.py +174 -0
- runbooks/finops/types.py +66 -0
- runbooks/finops/visualisations.py +80 -0
- runbooks/inventory/.gitignore +354 -0
- runbooks/inventory/ArgumentsClass.py +261 -0
- runbooks/inventory/Inventory_Modules.py +6130 -0
- runbooks/inventory/LandingZone/delete_lz.py +1075 -0
- runbooks/inventory/README.md +1320 -0
- runbooks/inventory/__init__.py +62 -0
- runbooks/inventory/account_class.py +532 -0
- runbooks/inventory/all_my_instances_wrapper.py +123 -0
- runbooks/inventory/aws_decorators.py +201 -0
- runbooks/inventory/cfn_move_stack_instances.py +1526 -0
- runbooks/inventory/check_cloudtrail_compliance.py +614 -0
- runbooks/inventory/check_controltower_readiness.py +1107 -0
- runbooks/inventory/check_landingzone_readiness.py +711 -0
- runbooks/inventory/cloudtrail.md +727 -0
- runbooks/inventory/collectors/__init__.py +20 -0
- runbooks/inventory/collectors/aws_compute.py +518 -0
- runbooks/inventory/collectors/aws_networking.py +275 -0
- runbooks/inventory/collectors/base.py +222 -0
- runbooks/inventory/core/__init__.py +19 -0
- runbooks/inventory/core/collector.py +303 -0
- runbooks/inventory/core/formatter.py +296 -0
- runbooks/inventory/delete_s3_buckets_objects.py +169 -0
- runbooks/inventory/discovery.md +81 -0
- runbooks/inventory/draw_org_structure.py +748 -0
- runbooks/inventory/ec2_vpc_utils.py +341 -0
- runbooks/inventory/find_cfn_drift_detection.py +272 -0
- runbooks/inventory/find_cfn_orphaned_stacks.py +719 -0
- runbooks/inventory/find_cfn_stackset_drift.py +733 -0
- runbooks/inventory/find_ec2_security_groups.py +669 -0
- runbooks/inventory/find_landingzone_versions.py +201 -0
- runbooks/inventory/find_vpc_flow_logs.py +1221 -0
- runbooks/inventory/inventory.sh +659 -0
- runbooks/inventory/list_cfn_stacks.py +558 -0
- runbooks/inventory/list_cfn_stackset_operation_results.py +252 -0
- runbooks/inventory/list_cfn_stackset_operations.py +734 -0
- runbooks/inventory/list_cfn_stacksets.py +453 -0
- runbooks/inventory/list_config_recorders_delivery_channels.py +681 -0
- runbooks/inventory/list_ds_directories.py +354 -0
- runbooks/inventory/list_ec2_availability_zones.py +286 -0
- runbooks/inventory/list_ec2_ebs_volumes.py +244 -0
- runbooks/inventory/list_ec2_instances.py +425 -0
- runbooks/inventory/list_ecs_clusters_and_tasks.py +562 -0
- runbooks/inventory/list_elbs_load_balancers.py +411 -0
- runbooks/inventory/list_enis_network_interfaces.py +526 -0
- runbooks/inventory/list_guardduty_detectors.py +568 -0
- runbooks/inventory/list_iam_policies.py +404 -0
- runbooks/inventory/list_iam_roles.py +518 -0
- runbooks/inventory/list_iam_saml_providers.py +359 -0
- runbooks/inventory/list_lambda_functions.py +882 -0
- runbooks/inventory/list_org_accounts.py +446 -0
- runbooks/inventory/list_org_accounts_users.py +354 -0
- runbooks/inventory/list_rds_db_instances.py +406 -0
- runbooks/inventory/list_route53_hosted_zones.py +318 -0
- runbooks/inventory/list_servicecatalog_provisioned_products.py +575 -0
- runbooks/inventory/list_sns_topics.py +360 -0
- runbooks/inventory/list_ssm_parameters.py +402 -0
- runbooks/inventory/list_vpc_subnets.py +433 -0
- runbooks/inventory/list_vpcs.py +422 -0
- runbooks/inventory/lockdown_cfn_stackset_role.py +224 -0
- runbooks/inventory/models/__init__.py +24 -0
- runbooks/inventory/models/account.py +192 -0
- runbooks/inventory/models/inventory.py +309 -0
- runbooks/inventory/models/resource.py +247 -0
- runbooks/inventory/recover_cfn_stack_ids.py +205 -0
- runbooks/inventory/requirements.txt +12 -0
- runbooks/inventory/run_on_multi_accounts.py +211 -0
- runbooks/inventory/tests/common_test_data.py +3661 -0
- runbooks/inventory/tests/common_test_functions.py +204 -0
- runbooks/inventory/tests/script_test_data.py +0 -0
- runbooks/inventory/tests/setup.py +24 -0
- runbooks/inventory/tests/src.py +18 -0
- runbooks/inventory/tests/test_cfn_describe_stacks.py +208 -0
- runbooks/inventory/tests/test_ec2_describe_instances.py +162 -0
- runbooks/inventory/tests/test_inventory_modules.py +55 -0
- runbooks/inventory/tests/test_lambda_list_functions.py +86 -0
- runbooks/inventory/tests/test_moto_integration_example.py +273 -0
- runbooks/inventory/tests/test_org_list_accounts.py +49 -0
- runbooks/inventory/update_aws_actions.py +173 -0
- runbooks/inventory/update_cfn_stacksets.py +1215 -0
- runbooks/inventory/update_cloudwatch_logs_retention_policy.py +294 -0
- runbooks/inventory/update_iam_roles_cross_accounts.py +478 -0
- runbooks/inventory/update_s3_public_access_block.py +539 -0
- runbooks/inventory/utils/__init__.py +23 -0
- runbooks/inventory/utils/aws_helpers.py +510 -0
- runbooks/inventory/utils/threading_utils.py +493 -0
- runbooks/inventory/utils/validation.py +682 -0
- runbooks/inventory/verify_ec2_security_groups.py +1430 -0
- runbooks/main.py +785 -0
- runbooks/organizations/__init__.py +12 -0
- runbooks/organizations/manager.py +374 -0
- runbooks/security_baseline/README.md +324 -0
- runbooks/security_baseline/checklist/alternate_contacts.py +8 -1
- runbooks/security_baseline/checklist/bucket_public_access.py +4 -1
- runbooks/security_baseline/checklist/cloudwatch_alarm_configuration.py +9 -2
- runbooks/security_baseline/checklist/guardduty_enabled.py +9 -2
- runbooks/security_baseline/checklist/multi_region_instance_usage.py +5 -1
- runbooks/security_baseline/checklist/root_access_key.py +6 -1
- runbooks/security_baseline/config-origin.json +1 -1
- runbooks/security_baseline/config.json +1 -1
- runbooks/security_baseline/permission.json +1 -1
- runbooks/security_baseline/report_generator.py +10 -2
- runbooks/security_baseline/report_template_en.html +8 -8
- runbooks/security_baseline/report_template_jp.html +8 -8
- runbooks/security_baseline/report_template_kr.html +13 -13
- runbooks/security_baseline/report_template_vn.html +8 -8
- runbooks/security_baseline/requirements.txt +7 -0
- runbooks/security_baseline/run_script.py +8 -2
- runbooks/security_baseline/security_baseline_tester.py +10 -2
- runbooks/security_baseline/utils/common.py +5 -1
- runbooks/utils/__init__.py +204 -0
- runbooks-0.6.1.dist-info/METADATA +373 -0
- runbooks-0.6.1.dist-info/RECORD +237 -0
- {runbooks-0.2.3.dist-info → runbooks-0.6.1.dist-info}/WHEEL +1 -1
- runbooks-0.6.1.dist-info/entry_points.txt +7 -0
- runbooks-0.6.1.dist-info/licenses/LICENSE +201 -0
- runbooks-0.6.1.dist-info/top_level.txt +3 -0
- runbooks/python101/calculator.py +0 -34
- runbooks/python101/config.py +0 -1
- runbooks/python101/exceptions.py +0 -16
- runbooks/python101/file_manager.py +0 -218
- runbooks/python101/toolkit.py +0 -153
- runbooks-0.2.3.dist-info/METADATA +0 -435
- runbooks-0.2.3.dist-info/RECORD +0 -61
- runbooks-0.2.3.dist-info/entry_points.txt +0 -3
- runbooks-0.2.3.dist-info/top_level.txt +0 -1
runbooks/cfat/runner.py
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
"""
|
2
|
+
Cloud Foundations Assessment Tool - Backward Compatibility Module.
|
3
|
+
|
4
|
+
This module maintains backward compatibility for existing code
|
5
|
+
while providing access to the enhanced assessment engine.
|
6
|
+
|
7
|
+
For new implementations, consider using the enhanced assessment
|
8
|
+
module directly:
|
9
|
+
|
10
|
+
from runbooks.cfat.assessment import CloudFoundationsAssessment
|
11
|
+
|
12
|
+
This module will be deprecated in a future version.
|
13
|
+
"""
|
14
|
+
|
15
|
+
from typing import Optional
|
16
|
+
|
17
|
+
from loguru import logger
|
18
|
+
|
19
|
+
from runbooks.cfat.assessment.runner import CloudFoundationsAssessment
|
20
|
+
from runbooks.config import RunbooksConfig
|
21
|
+
|
22
|
+
|
23
|
+
class AssessmentRunner(CloudFoundationsAssessment):
|
24
|
+
"""
|
25
|
+
Backward Compatibility Wrapper for Cloud Foundations Assessment.
|
26
|
+
|
27
|
+
This class provides backward compatibility for existing code that
|
28
|
+
uses the original AssessmentRunner class. All functionality is
|
29
|
+
delegated to the enhanced CloudFoundationsAssessment engine.
|
30
|
+
|
31
|
+
**Deprecation Notice**: This class is deprecated and will be removed
|
32
|
+
in a future version. Please migrate to using CloudFoundationsAssessment
|
33
|
+
directly:
|
34
|
+
|
35
|
+
```python
|
36
|
+
# Old way (deprecated)
|
37
|
+
from runbooks.cfat.runner import AssessmentRunner
|
38
|
+
runner = AssessmentRunner()
|
39
|
+
|
40
|
+
# New way (recommended)
|
41
|
+
from runbooks.cfat.assessment import CloudFoundationsAssessment
|
42
|
+
assessment = CloudFoundationsAssessment()
|
43
|
+
```
|
44
|
+
|
45
|
+
Args:
|
46
|
+
profile: AWS CLI profile for authentication
|
47
|
+
region: AWS region for assessment
|
48
|
+
config: RunbooksConfig instance for configuration
|
49
|
+
"""
|
50
|
+
|
51
|
+
def __init__(
|
52
|
+
self, profile: Optional[str] = None, region: Optional[str] = None, config: Optional[RunbooksConfig] = None
|
53
|
+
):
|
54
|
+
"""
|
55
|
+
Initialize backward compatibility wrapper.
|
56
|
+
|
57
|
+
Args:
|
58
|
+
profile: AWS CLI profile to use
|
59
|
+
region: AWS region for assessment
|
60
|
+
config: Configuration object
|
61
|
+
"""
|
62
|
+
# Log deprecation warning
|
63
|
+
logger.warning(
|
64
|
+
"AssessmentRunner is deprecated. Please use CloudFoundationsAssessment "
|
65
|
+
"from runbooks.cfat.assessment instead."
|
66
|
+
)
|
67
|
+
|
68
|
+
# Initialize the enhanced assessment engine
|
69
|
+
super().__init__(profile=profile, region=region, config=config)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import { CloudTrailClient, DescribeTrailsCommand } from '@aws-sdk/client-cloudtrail';
|
2
|
+
import { CloudTrailInfo } from '../types';
|
3
|
+
|
4
|
+
async function checkCloudTrailExists(regions: string[]): Promise<CloudTrailInfo[]> {
|
5
|
+
let cloudTrailValidation: CloudTrailInfo[] = []
|
6
|
+
for (const region of regions){
|
7
|
+
const cloudTrailClient = new CloudTrailClient({ region });
|
8
|
+
const cloudTrailDescribeCommand = new DescribeTrailsCommand({});
|
9
|
+
|
10
|
+
try {
|
11
|
+
const cloudTrailResponse = await cloudTrailClient.send(cloudTrailDescribeCommand);
|
12
|
+
if(cloudTrailResponse.trailList){
|
13
|
+
for (const trail of cloudTrailResponse.trailList) {
|
14
|
+
let trailInfo: CloudTrailInfo = {}
|
15
|
+
if(trail.HomeRegion == region){
|
16
|
+
//console.log(`trail found in ${region}`)
|
17
|
+
trailInfo = {
|
18
|
+
region: region,
|
19
|
+
trailFound: true,
|
20
|
+
isOrgTrail: trail.IsMultiRegionTrail,
|
21
|
+
isMultiRegion: trail.IsMultiRegionTrail
|
22
|
+
}
|
23
|
+
}
|
24
|
+
else{
|
25
|
+
trailInfo = {
|
26
|
+
region: region,
|
27
|
+
trailFound: false
|
28
|
+
}
|
29
|
+
}
|
30
|
+
cloudTrailValidation.push(trailInfo)
|
31
|
+
}
|
32
|
+
}
|
33
|
+
} catch (error) {
|
34
|
+
console.log(`Error checking instance: ${error}`);
|
35
|
+
}
|
36
|
+
finally {
|
37
|
+
cloudTrailClient.destroy();
|
38
|
+
}
|
39
|
+
}// end for regions
|
40
|
+
return cloudTrailValidation;
|
41
|
+
};
|
42
|
+
|
43
|
+
export default checkCloudTrailExists;
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import { ConfigServiceClient, DescribeConfigurationRecorderStatusCommand, DescribeDeliveryChannelsCommand } from '@aws-sdk/client-config-service';
|
2
|
+
import { ConfigInfo } from '../types';
|
3
|
+
|
4
|
+
async function checkConfigExists(regions: string[]): Promise<ConfigInfo[]> {
|
5
|
+
let configDetails:ConfigInfo[] = [];
|
6
|
+
for (const region of regions) {
|
7
|
+
const configServiceClient = new ConfigServiceClient({ region });
|
8
|
+
let configDetail: ConfigInfo = {
|
9
|
+
region: region,
|
10
|
+
configRecorderFound: false,
|
11
|
+
configDeliveryChannelFound: false
|
12
|
+
}
|
13
|
+
try {
|
14
|
+
// Check if Config recorder exists
|
15
|
+
const recorderResponse = await configServiceClient.send(new DescribeConfigurationRecorderStatusCommand({}));
|
16
|
+
const recorderExists = recorderResponse.ConfigurationRecordersStatus?.length !== 0;
|
17
|
+
if(recorderExists){
|
18
|
+
configDetail.configRecorderFound = true
|
19
|
+
}
|
20
|
+
// Check if Config delivery channel exists
|
21
|
+
const channelResponse = await configServiceClient.send(new DescribeDeliveryChannelsCommand({}));
|
22
|
+
const channelExists = channelResponse.DeliveryChannels?.length !== 0;
|
23
|
+
if(channelExists){
|
24
|
+
configDetail.configDeliveryChannelFound = true
|
25
|
+
}
|
26
|
+
configDetails.push(configDetail)
|
27
|
+
} catch (error) {
|
28
|
+
console.error(`Error checking AWS Config in ${region}:`, error);
|
29
|
+
}
|
30
|
+
finally {
|
31
|
+
configServiceClient.destroy();
|
32
|
+
}
|
33
|
+
}
|
34
|
+
return configDetails;
|
35
|
+
}
|
36
|
+
|
37
|
+
export default checkConfigExists
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import { ControlTowerClient, ListLandingZonesCommand, GetLandingZoneCommand } from "@aws-sdk/client-controltower";
|
2
|
+
import { ControlTowerInfo } from '../types';
|
3
|
+
|
4
|
+
async function getControlTower(region: string): Promise<ControlTowerInfo> {
|
5
|
+
let controlTowerInfo:ControlTowerInfo = {}
|
6
|
+
const controlTowerClient = new ControlTowerClient({ region });
|
7
|
+
try {
|
8
|
+
const command = new ListLandingZonesCommand({});
|
9
|
+
const response = await controlTowerClient.send(command);
|
10
|
+
if(response.landingZones && response.landingZones.length > 0){
|
11
|
+
const input = {
|
12
|
+
landingZoneIdentifier: response.landingZones[0].arn,
|
13
|
+
};
|
14
|
+
const lzRegion:string = response.landingZones[0].arn?.toString().split(':')[3] ?? ""
|
15
|
+
if(lzRegion){
|
16
|
+
controlTowerInfo.controlTowerRegion = lzRegion
|
17
|
+
const controlTowerClientRegion = new ControlTowerClient({ region: lzRegion });
|
18
|
+
const command = new GetLandingZoneCommand(input);
|
19
|
+
const lzResponse = await controlTowerClientRegion.send(command);
|
20
|
+
if(lzResponse.landingZone){
|
21
|
+
controlTowerInfo.status= lzResponse.landingZone.status
|
22
|
+
controlTowerInfo.latestAvailableVersion = lzResponse.landingZone.latestAvailableVersion
|
23
|
+
controlTowerInfo.deployedVersion = lzResponse.landingZone.version
|
24
|
+
controlTowerInfo.driftStatus = lzResponse.landingZone.driftStatus?.status
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
28
|
+
} catch (error) {
|
29
|
+
console.error(`Error checking Control Tower in ${region}:`, error);
|
30
|
+
}
|
31
|
+
finally {
|
32
|
+
controlTowerClient.destroy();
|
33
|
+
}
|
34
|
+
return controlTowerInfo
|
35
|
+
}
|
36
|
+
|
37
|
+
export default getControlTower
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import { EC2Client, DescribeInstancesCommand, DescribeInstancesCommandOutput } from "@aws-sdk/client-ec2";
|
2
|
+
import { Ec2Check } from '../types';
|
3
|
+
|
4
|
+
async function checkEc2Exists(regions: string[]): Promise<Ec2Check[]> {
|
5
|
+
let ec2Validation: Ec2Check[] = []
|
6
|
+
for (const region of regions){
|
7
|
+
const ec2Client = new EC2Client({ region });
|
8
|
+
|
9
|
+
const command = new DescribeInstancesCommand({});
|
10
|
+
|
11
|
+
try {
|
12
|
+
const response = await ec2Client.send(command);
|
13
|
+
if(response.Reservations){
|
14
|
+
if (response.Reservations.length > 0) {
|
15
|
+
//console.log(`WARNING: Instance(s) exists in region: ${region}`);
|
16
|
+
const ec2Found: Ec2Check = {
|
17
|
+
region: region,
|
18
|
+
ec2Found: true
|
19
|
+
}
|
20
|
+
ec2Validation.push(ec2Found)
|
21
|
+
}
|
22
|
+
else{
|
23
|
+
const ec2Found: Ec2Check = {
|
24
|
+
region: region,
|
25
|
+
ec2Found: false
|
26
|
+
}
|
27
|
+
ec2Validation.push(ec2Found)
|
28
|
+
}
|
29
|
+
} else {
|
30
|
+
const ec2Found: Ec2Check = {
|
31
|
+
region: region,
|
32
|
+
ec2Found: false
|
33
|
+
}
|
34
|
+
ec2Validation.push(ec2Found)
|
35
|
+
}
|
36
|
+
} catch (error) {
|
37
|
+
console.log(`Error checking instance: ${error}`);
|
38
|
+
}
|
39
|
+
finally {
|
40
|
+
ec2Client.destroy();
|
41
|
+
}
|
42
|
+
}// end for
|
43
|
+
return ec2Validation;
|
44
|
+
};
|
45
|
+
|
46
|
+
export default checkEc2Exists;
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import { IamUserInfo } from '../types';
|
2
|
+
import { IAMClient, ListUsersCommand, ListAccessKeysCommand, GetAccessKeyLastUsedCommand } from "@aws-sdk/client-iam";
|
3
|
+
|
4
|
+
// function list all IAM users and if they have keys in the management account
|
5
|
+
const checkIamUsers = async (): Promise<IamUserInfo[]> => {
|
6
|
+
// Set to us-east-1 as IAM is global and region isn't a concern
|
7
|
+
const iamClient = new IAMClient({ region: 'us-east-1' });
|
8
|
+
const iamUserInfo: IamUserInfo[] = [];
|
9
|
+
try {
|
10
|
+
const listUsersCommand = new ListUsersCommand({});
|
11
|
+
const listUsersResponse = await iamClient.send(listUsersCommand);
|
12
|
+
for (const user of listUsersResponse.Users || []) {
|
13
|
+
const userName = user.UserName || "";
|
14
|
+
const listAccessKeysCommand = new ListAccessKeysCommand({
|
15
|
+
UserName: userName,
|
16
|
+
});
|
17
|
+
const listAccessKeysResponse = await iamClient.send(listAccessKeysCommand);
|
18
|
+
const accessKeys = listAccessKeysResponse.AccessKeyMetadata || [];
|
19
|
+
if (accessKeys.length > 0) {
|
20
|
+
for (const accessKey of accessKeys) {
|
21
|
+
const accessKeyId = accessKey.AccessKeyId || "";
|
22
|
+
const getLastUsedCommand = new GetAccessKeyLastUsedCommand({
|
23
|
+
AccessKeyId: accessKeyId,
|
24
|
+
});
|
25
|
+
const lastUsedResponse = await iamClient.send(getLastUsedCommand);
|
26
|
+
const foundUserInfo: IamUserInfo = {
|
27
|
+
userName,
|
28
|
+
accessKeyId,
|
29
|
+
lastUsed: lastUsedResponse && lastUsedResponse.AccessKeyLastUsed
|
30
|
+
? `${lastUsedResponse.AccessKeyLastUsed.LastUsedDate}` || "Not available"
|
31
|
+
: "Not available",
|
32
|
+
};
|
33
|
+
iamUserInfo.push(foundUserInfo);
|
34
|
+
}
|
35
|
+
} else {
|
36
|
+
const foundUserInfo: IamUserInfo = {
|
37
|
+
userName
|
38
|
+
};
|
39
|
+
iamUserInfo.push(foundUserInfo);
|
40
|
+
}
|
41
|
+
}
|
42
|
+
} catch (error) {
|
43
|
+
console.error("Error:", error);
|
44
|
+
} finally {
|
45
|
+
iamClient.destroy();
|
46
|
+
}
|
47
|
+
return iamUserInfo;
|
48
|
+
};
|
49
|
+
|
50
|
+
export default checkIamUsers;
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { CostAndUsageReportServiceClient, DescribeReportDefinitionsCommand } from "@aws-sdk/client-cost-and-usage-report-service";
|
2
|
+
import { LegacyCurInfo } from '../types';
|
3
|
+
|
4
|
+
const checkLegacyCur = async (region: string): Promise<LegacyCurInfo> => {
|
5
|
+
// Set up AWS SDK client for Cost Explorer
|
6
|
+
const curClient = new CostAndUsageReportServiceClient({ region });
|
7
|
+
let isLegacyCurSetup = false;
|
8
|
+
|
9
|
+
try {
|
10
|
+
// Check if Cost Explorer is set up
|
11
|
+
const input = {};
|
12
|
+
const command = new DescribeReportDefinitionsCommand(input);
|
13
|
+
const response = await curClient.send(command);
|
14
|
+
if (response.ReportDefinitions && response.ReportDefinitions.length > 0) {
|
15
|
+
isLegacyCurSetup = true;
|
16
|
+
}
|
17
|
+
|
18
|
+
return { isLegacyCurSetup };
|
19
|
+
} catch (error) {
|
20
|
+
// Check if the error is related to Cost Explorer setup
|
21
|
+
console.error(`Error: ${error}`);
|
22
|
+
isLegacyCurSetup = false;
|
23
|
+
return { isLegacyCurSetup };
|
24
|
+
} finally {
|
25
|
+
// Close the AWS SDK client
|
26
|
+
curClient.destroy();
|
27
|
+
}
|
28
|
+
};
|
29
|
+
|
30
|
+
export default checkLegacyCur;
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { CloudFormationClient,
|
2
|
+
DescribeOrganizationsAccessCommand,
|
3
|
+
DescribeOrganizationsAccessInput,
|
4
|
+
} from "@aws-sdk/client-cloudformation";
|
5
|
+
|
6
|
+
import {OrgCloudFormationStatus} from '../types'
|
7
|
+
|
8
|
+
async function getOrgCloudFormation(region: string): Promise<OrgCloudFormationStatus> {
|
9
|
+
let orgCfnStatus: OrgCloudFormationStatus = {
|
10
|
+
status: "disabled"
|
11
|
+
}
|
12
|
+
const cloudFormationClient = new CloudFormationClient({region});
|
13
|
+
try {
|
14
|
+
const describeOrgAccessInput: DescribeOrganizationsAccessInput = {};
|
15
|
+
const command = new DescribeOrganizationsAccessCommand(describeOrgAccessInput);
|
16
|
+
const cloudFormationOrgAccess = await cloudFormationClient.send(command);
|
17
|
+
//console.log("CloudFormation activation status: ", cloudFormationOrgAccess.Status)
|
18
|
+
orgCfnStatus.status = cloudFormationOrgAccess.Status ?? "disabled"
|
19
|
+
}
|
20
|
+
catch (error) {
|
21
|
+
console.log(`Error: ${error}`);
|
22
|
+
//throw new Error(`Error: ${error}`);
|
23
|
+
}
|
24
|
+
finally {
|
25
|
+
cloudFormationClient.destroy()
|
26
|
+
return orgCfnStatus
|
27
|
+
}
|
28
|
+
};
|
29
|
+
|
30
|
+
export default getOrgCloudFormation;
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import { EC2Client, DescribeVpcsCommand} from "@aws-sdk/client-ec2";
|
2
|
+
import { VpcCheck } from '../types';
|
3
|
+
|
4
|
+
async function checkVpcExists(regions: string[]): Promise<VpcCheck[]> {
|
5
|
+
let vpcValidation: VpcCheck[] = []
|
6
|
+
for (const region of regions){
|
7
|
+
const ec2Client = new EC2Client({ region });
|
8
|
+
const command = new DescribeVpcsCommand({});
|
9
|
+
try {
|
10
|
+
const response = await ec2Client.send(command);
|
11
|
+
if(response.Vpcs){
|
12
|
+
if (response.Vpcs.length > 0) {
|
13
|
+
const vpcFound: VpcCheck = {
|
14
|
+
region: region,
|
15
|
+
vpcFound: true
|
16
|
+
}
|
17
|
+
vpcValidation.push(vpcFound)
|
18
|
+
}
|
19
|
+
else{
|
20
|
+
const vpcFound: VpcCheck = {
|
21
|
+
region: region,
|
22
|
+
vpcFound: false
|
23
|
+
}
|
24
|
+
vpcValidation.push(vpcFound)
|
25
|
+
}
|
26
|
+
} else {
|
27
|
+
const vpcFound: VpcCheck = {
|
28
|
+
region: region,
|
29
|
+
vpcFound: false
|
30
|
+
}
|
31
|
+
vpcValidation.push(vpcFound)
|
32
|
+
}
|
33
|
+
} catch (error) {
|
34
|
+
console.log(`Error: ${error}`);
|
35
|
+
}
|
36
|
+
finally {
|
37
|
+
ec2Client.destroy();
|
38
|
+
}
|
39
|
+
}// end for
|
40
|
+
return vpcValidation;
|
41
|
+
};
|
42
|
+
|
43
|
+
export default checkVpcExists;
|
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
import { Task } from '../types';
|
3
|
+
import * as fs from 'fs';
|
4
|
+
|
5
|
+
async function createAsanaImport(tasks: Task[]): Promise<void> {
|
6
|
+
let csv:string = '"Task", "Description", "Status" \r\n'
|
7
|
+
for(const task of tasks){
|
8
|
+
csv += `"cfat - ${task.title}", "${task.detail} - Remediation Link: ${task.remediationLink}", "Not Started" \r\n`
|
9
|
+
}
|
10
|
+
fs.writeFileSync('./asana-import.csv', csv);
|
11
|
+
return
|
12
|
+
}
|
13
|
+
|
14
|
+
export default createAsanaImport;
|