fg-tracker-mcp 0.4.0 → 0.6.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.
- package/CHANGELOG.md +13 -0
- package/README.md +2 -0
- package/dist/docs.d.ts +1 -1
- package/dist/docs.js +12 -1
- package/dist/docs.js.map +1 -1
- package/dist/infra/aws.d.ts +97 -0
- package/dist/infra/aws.js +557 -0
- package/dist/infra/aws.js.map +1 -0
- package/dist/infra/diff.d.ts +15 -0
- package/dist/infra/diff.js +108 -0
- package/dist/infra/diff.js.map +1 -0
- package/dist/infra/files.d.ts +16 -0
- package/dist/infra/files.js +115 -0
- package/dist/infra/files.js.map +1 -0
- package/dist/infra/handover.d.ts +47 -0
- package/dist/infra/handover.js +437 -0
- package/dist/infra/handover.js.map +1 -0
- package/dist/infra/iac.d.ts +56 -0
- package/dist/infra/iac.js +378 -0
- package/dist/infra/iac.js.map +1 -0
- package/dist/infra/instrument.d.ts +6 -0
- package/dist/infra/instrument.js +140 -0
- package/dist/infra/instrument.js.map +1 -0
- package/dist/infra/tools.d.ts +10 -0
- package/dist/infra/tools.js +700 -0
- package/dist/infra/tools.js.map +1 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.js +5 -1
- package/dist/server.js.map +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,557 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Descoberta local de recursos AWS com as credenciais do usuário (CONTRATO.md §27.3, §27.9).
|
|
3
|
+
* Somente chamadas de LEITURA: sts:GetCallerIdentity, resource-explorer-2:GetIndex/Search,
|
|
4
|
+
* resource-explorer-2:ListIndexes, tag:GetResources, cloudformation:ListStacks/ListStackResources/DescribeStacks.
|
|
5
|
+
*/
|
|
6
|
+
import { CloudFormationClient, DescribeStacksCommand, ListStackResourcesCommand, ListStacksCommand } from '@aws-sdk/client-cloudformation';
|
|
7
|
+
import { GetIndexCommand, ListIndexesCommand, ResourceExplorer2Client, SearchCommand } from '@aws-sdk/client-resource-explorer-2';
|
|
8
|
+
import { GetResourcesCommand, ResourceGroupsTaggingAPIClient } from '@aws-sdk/client-resource-groups-tagging-api';
|
|
9
|
+
import { GetCallerIdentityCommand, STSClient } from '@aws-sdk/client-sts';
|
|
10
|
+
import { fromIni, fromNodeProviderChain } from '@aws-sdk/credential-providers';
|
|
11
|
+
import { readFile } from 'node:fs/promises';
|
|
12
|
+
import { homedir } from 'node:os';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
const EXPLORER_CAP = 2000;
|
|
15
|
+
const TAGGING_CAP = 10_000;
|
|
16
|
+
const STACK_RESOURCES_CAP = 5000;
|
|
17
|
+
function awsCredentials(profile) {
|
|
18
|
+
return profile ? fromIni({ profile }) : fromNodeProviderChain();
|
|
19
|
+
}
|
|
20
|
+
/** Mensagem amigável para erros do AWS SDK (credenciais ausentes/expiradas, acesso negado). */
|
|
21
|
+
export function describeAwsError(err) {
|
|
22
|
+
const e = err;
|
|
23
|
+
const name = e?.name ?? e?.Code ?? 'Error';
|
|
24
|
+
const msg = e?.message ?? String(err);
|
|
25
|
+
if (/CredentialsProviderError|Could not load credentials|ExpiredToken|InvalidClientTokenId|UnrecognizedClient|SSO.*(expired|session)/i.test(`${name} ${msg}`)) {
|
|
26
|
+
return `Credenciais AWS locais indisponíveis ou expiradas (${name}: ${msg}). Rode \`aws sso login --profile <perfil>\` ou \`aws configure\`, ou passe \`profile\`.`;
|
|
27
|
+
}
|
|
28
|
+
if (/AccessDenied|UnauthorizedOperation|not authorized/i.test(`${name} ${msg}`)) {
|
|
29
|
+
return `Acesso negado (${name}): ${msg}`;
|
|
30
|
+
}
|
|
31
|
+
return `${name}: ${msg}`;
|
|
32
|
+
}
|
|
33
|
+
export function parseArn(arn) {
|
|
34
|
+
const parts = arn.split(':');
|
|
35
|
+
if (parts.length < 6 || parts[0] !== 'arn')
|
|
36
|
+
return null;
|
|
37
|
+
const [, partition = '', service = '', region = '', account = ''] = parts;
|
|
38
|
+
const resource = parts.slice(5).join(':');
|
|
39
|
+
let resourceType = '';
|
|
40
|
+
let resourceId = resource;
|
|
41
|
+
const slash = resource.indexOf('/');
|
|
42
|
+
const colon = resource.indexOf(':');
|
|
43
|
+
if (service === 'apigateway') {
|
|
44
|
+
const m = /^\/(restapis|apis|domainnames|usageplans|apikeys)\/([^/]+)/.exec(resource);
|
|
45
|
+
if (m) {
|
|
46
|
+
resourceType = m[1] ?? '';
|
|
47
|
+
resourceId = m[2] ?? resource;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else if (slash >= 0 && (colon < 0 || slash < colon)) {
|
|
51
|
+
resourceType = resource.slice(0, slash);
|
|
52
|
+
resourceId = resource.slice(slash + 1);
|
|
53
|
+
}
|
|
54
|
+
else if (colon >= 0) {
|
|
55
|
+
resourceType = resource.slice(0, colon);
|
|
56
|
+
resourceId = resource.slice(colon + 1);
|
|
57
|
+
}
|
|
58
|
+
return { partition, service, region, account, resource, resourceType, resourceId };
|
|
59
|
+
}
|
|
60
|
+
const TYPE_MAP = {
|
|
61
|
+
'lambda:function': 'AWS::Lambda::Function',
|
|
62
|
+
'lambda:layer': 'AWS::Lambda::LayerVersion',
|
|
63
|
+
'lambda:event-source-mapping': 'AWS::Lambda::EventSourceMapping',
|
|
64
|
+
'dynamodb:table': 'AWS::DynamoDB::Table',
|
|
65
|
+
'ecs:cluster': 'AWS::ECS::Cluster',
|
|
66
|
+
'ecs:service': 'AWS::ECS::Service',
|
|
67
|
+
'ecs:task-definition': 'AWS::ECS::TaskDefinition',
|
|
68
|
+
'ec2:instance': 'AWS::EC2::Instance',
|
|
69
|
+
'ec2:vpc': 'AWS::EC2::VPC',
|
|
70
|
+
'ec2:subnet': 'AWS::EC2::Subnet',
|
|
71
|
+
'ec2:security-group': 'AWS::EC2::SecurityGroup',
|
|
72
|
+
'ec2:natgateway': 'AWS::EC2::NatGateway',
|
|
73
|
+
'ec2:internet-gateway': 'AWS::EC2::InternetGateway',
|
|
74
|
+
'ec2:route-table': 'AWS::EC2::RouteTable',
|
|
75
|
+
'ec2:volume': 'AWS::EC2::Volume',
|
|
76
|
+
'ec2:elastic-ip': 'AWS::EC2::EIP',
|
|
77
|
+
'ec2:launch-template': 'AWS::EC2::LaunchTemplate',
|
|
78
|
+
'ec2:vpc-endpoint': 'AWS::EC2::VPCEndpoint',
|
|
79
|
+
'rds:db': 'AWS::RDS::DBInstance',
|
|
80
|
+
'rds:cluster': 'AWS::RDS::DBCluster',
|
|
81
|
+
'rds:subgrp': 'AWS::RDS::DBSubnetGroup',
|
|
82
|
+
'rds:pg': 'AWS::RDS::DBParameterGroup',
|
|
83
|
+
'rds:cluster-pg': 'AWS::RDS::DBClusterParameterGroup',
|
|
84
|
+
'apigateway:restapis': 'AWS::ApiGateway::RestApi',
|
|
85
|
+
'apigateway:apis': 'AWS::ApiGatewayV2::Api',
|
|
86
|
+
'apigateway:domainnames': 'AWS::ApiGateway::DomainName',
|
|
87
|
+
'elasticloadbalancing:loadbalancer': 'AWS::ElasticLoadBalancingV2::LoadBalancer',
|
|
88
|
+
'elasticloadbalancing:targetgroup': 'AWS::ElasticLoadBalancingV2::TargetGroup',
|
|
89
|
+
'elasticloadbalancing:listener': 'AWS::ElasticLoadBalancingV2::Listener',
|
|
90
|
+
'elasticloadbalancing:listener-rule': 'AWS::ElasticLoadBalancingV2::ListenerRule',
|
|
91
|
+
'cloudfront:distribution': 'AWS::CloudFront::Distribution',
|
|
92
|
+
'events:rule': 'AWS::Events::Rule',
|
|
93
|
+
'events:event-bus': 'AWS::Events::EventBus',
|
|
94
|
+
'scheduler:schedule': 'AWS::Scheduler::Schedule',
|
|
95
|
+
'states:stateMachine': 'AWS::StepFunctions::StateMachine',
|
|
96
|
+
'ecr:repository': 'AWS::ECR::Repository',
|
|
97
|
+
'kinesis:stream': 'AWS::Kinesis::Stream',
|
|
98
|
+
'firehose:deliverystream': 'AWS::KinesisFirehose::DeliveryStream',
|
|
99
|
+
'codebuild:project': 'AWS::CodeBuild::Project',
|
|
100
|
+
'cloudformation:stack': 'AWS::CloudFormation::Stack',
|
|
101
|
+
'logs:log-group': 'AWS::Logs::LogGroup',
|
|
102
|
+
'iam:role': 'AWS::IAM::Role',
|
|
103
|
+
'iam:policy': 'AWS::IAM::ManagedPolicy',
|
|
104
|
+
'iam:user': 'AWS::IAM::User',
|
|
105
|
+
'secretsmanager:secret': 'AWS::SecretsManager::Secret',
|
|
106
|
+
'ssm:parameter': 'AWS::SSM::Parameter',
|
|
107
|
+
'kms:key': 'AWS::KMS::Key',
|
|
108
|
+
'autoscaling:autoScalingGroup': 'AWS::AutoScaling::AutoScalingGroup',
|
|
109
|
+
'elasticache:cluster': 'AWS::ElastiCache::CacheCluster',
|
|
110
|
+
'elasticache:replicationgroup': 'AWS::ElastiCache::ReplicationGroup',
|
|
111
|
+
'cognito-idp:userpool': 'AWS::Cognito::UserPool',
|
|
112
|
+
'acm:certificate': 'AWS::CertificateManager::Certificate',
|
|
113
|
+
'route53:hostedzone': 'AWS::Route53::HostedZone',
|
|
114
|
+
'cloudwatch:alarm': 'AWS::CloudWatch::Alarm',
|
|
115
|
+
'appsync:apis': 'AWS::AppSync::GraphQLApi',
|
|
116
|
+
'wafv2:regional': 'AWS::WAFv2::WebACL',
|
|
117
|
+
'wafv2:global': 'AWS::WAFv2::WebACL',
|
|
118
|
+
'efs:file-system': 'AWS::EFS::FileSystem',
|
|
119
|
+
};
|
|
120
|
+
/** ARN → tipo CloudFormation (melhor esforço; null quando desconhecido). */
|
|
121
|
+
export function arnToResourceType(arn) {
|
|
122
|
+
const p = parseArn(arn);
|
|
123
|
+
if (!p)
|
|
124
|
+
return null;
|
|
125
|
+
if (p.service === 's3' && !p.resourceType && !p.resource.includes('/'))
|
|
126
|
+
return 'AWS::S3::Bucket';
|
|
127
|
+
if (p.service === 'sqs')
|
|
128
|
+
return 'AWS::SQS::Queue';
|
|
129
|
+
if (p.service === 'sns')
|
|
130
|
+
return p.resource.includes(':') ? 'AWS::SNS::Subscription' : 'AWS::SNS::Topic';
|
|
131
|
+
if (p.service === 'codepipeline')
|
|
132
|
+
return 'AWS::CodePipeline::Pipeline';
|
|
133
|
+
if (p.service === 'states' && p.resourceType === 'stateMachine')
|
|
134
|
+
return 'AWS::StepFunctions::StateMachine';
|
|
135
|
+
if (p.service === 'autoscaling' && p.resource.startsWith('autoScalingGroup'))
|
|
136
|
+
return 'AWS::AutoScaling::AutoScalingGroup';
|
|
137
|
+
return TYPE_MAP[`${p.service}:${p.resourceType}`] ?? null;
|
|
138
|
+
}
|
|
139
|
+
/** Nome legível a partir do ARN. */
|
|
140
|
+
export function nameFromArn(arn) {
|
|
141
|
+
const p = parseArn(arn);
|
|
142
|
+
if (!p)
|
|
143
|
+
return arn;
|
|
144
|
+
if (p.service === 'cloudformation' && p.resourceType === 'stack')
|
|
145
|
+
return p.resourceId.split('/')[0] ?? p.resourceId;
|
|
146
|
+
if (p.service === 'elasticloadbalancing') {
|
|
147
|
+
const segs = p.resourceId.split('/');
|
|
148
|
+
return (p.resourceType === 'loadbalancer' ? segs[1] : segs[0]) ?? p.resourceId;
|
|
149
|
+
}
|
|
150
|
+
if (p.service === 'autoscaling')
|
|
151
|
+
return /autoScalingGroupName\/(.+)$/.exec(p.resource)?.[1] ?? p.resource;
|
|
152
|
+
if (p.service === 'lambda' && p.resourceType === 'function')
|
|
153
|
+
return p.resourceId.split(':')[0] ?? p.resourceId;
|
|
154
|
+
if (p.service === 'logs' && p.resourceType === 'log-group')
|
|
155
|
+
return p.resourceId.replace(/:\*$/, '');
|
|
156
|
+
if (p.service === 'states')
|
|
157
|
+
return p.resourceId.split(':')[0] ?? p.resourceId;
|
|
158
|
+
const segs = p.resourceId.split(/[/:]/).filter(Boolean);
|
|
159
|
+
return segs[segs.length - 1] ?? p.resourceId;
|
|
160
|
+
}
|
|
161
|
+
/** Serviço amigável (`lambda`, `ecs.service`…) só para o resumo. */
|
|
162
|
+
export function serviceLabel(resourceType, arn) {
|
|
163
|
+
if (resourceType) {
|
|
164
|
+
const [, svc = 'generic', kind = ''] = resourceType.split('::');
|
|
165
|
+
return `${svc.toLowerCase()}${kind ? '.' + kind.toLowerCase() : ''}`;
|
|
166
|
+
}
|
|
167
|
+
return parseArn(arn)?.service ?? 'generic';
|
|
168
|
+
}
|
|
169
|
+
/* ---------------- descoberta ---------------- */
|
|
170
|
+
function tagsFromExplorer(properties) {
|
|
171
|
+
const tagProp = properties?.find((p) => p.Name === 'tags' || p.Name === 'Tags');
|
|
172
|
+
if (!tagProp || !Array.isArray(tagProp.Data))
|
|
173
|
+
return undefined;
|
|
174
|
+
const out = {};
|
|
175
|
+
for (const t of tagProp.Data)
|
|
176
|
+
if (t?.Key)
|
|
177
|
+
out[t.Key] = t.Value ?? '';
|
|
178
|
+
return Object.keys(out).length ? out : undefined;
|
|
179
|
+
}
|
|
180
|
+
async function explorerSearch(region, credentials, budget) {
|
|
181
|
+
const rex = new ResourceExplorer2Client({ region, credentials });
|
|
182
|
+
try {
|
|
183
|
+
const idx = await rex.send(new GetIndexCommand({}));
|
|
184
|
+
if (idx.State !== 'ACTIVE')
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
return null; // sem índice nesta região
|
|
189
|
+
}
|
|
190
|
+
const resources = [];
|
|
191
|
+
let nextToken;
|
|
192
|
+
let complete = true;
|
|
193
|
+
try {
|
|
194
|
+
do {
|
|
195
|
+
const res = await rex.send(new SearchCommand({ QueryString: '*', MaxResults: 1000, NextToken: nextToken }));
|
|
196
|
+
for (const r of res.Resources ?? []) {
|
|
197
|
+
if (!r.Arn)
|
|
198
|
+
continue;
|
|
199
|
+
resources.push({
|
|
200
|
+
arn: r.Arn,
|
|
201
|
+
resourceType: r.CfnResourceType || arnToResourceType(r.Arn),
|
|
202
|
+
region: r.Region || region,
|
|
203
|
+
name: nameFromArn(r.Arn),
|
|
204
|
+
tags: tagsFromExplorer(r.Properties),
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
if (res.Count && res.Count.Complete === false)
|
|
208
|
+
complete = false;
|
|
209
|
+
nextToken = res.NextToken;
|
|
210
|
+
} while (nextToken && resources.length < budget);
|
|
211
|
+
if (nextToken)
|
|
212
|
+
complete = false;
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
const name = err.name ?? '';
|
|
216
|
+
// Sem view padrão: não dá para buscar; cai para o Tagging API.
|
|
217
|
+
if (/UnauthorizedException|ResourceNotFound|ValidationException|AccessDenied/i.test(name))
|
|
218
|
+
return null;
|
|
219
|
+
throw err;
|
|
220
|
+
}
|
|
221
|
+
return { resources: resources.slice(0, budget), complete };
|
|
222
|
+
}
|
|
223
|
+
async function taggingResources(region, credentials) {
|
|
224
|
+
const tagging = new ResourceGroupsTaggingAPIClient({ region, credentials });
|
|
225
|
+
const out = [];
|
|
226
|
+
let token;
|
|
227
|
+
do {
|
|
228
|
+
const res = await tagging.send(new GetResourcesCommand({ PaginationToken: token, ResourcesPerPage: 100 }));
|
|
229
|
+
for (const m of res.ResourceTagMappingList ?? []) {
|
|
230
|
+
if (!m.ResourceARN)
|
|
231
|
+
continue;
|
|
232
|
+
const tags = {};
|
|
233
|
+
for (const t of m.Tags ?? [])
|
|
234
|
+
if (t.Key)
|
|
235
|
+
tags[t.Key] = t.Value ?? '';
|
|
236
|
+
out.push({ arn: m.ResourceARN, resourceType: arnToResourceType(m.ResourceARN), region: parseArn(m.ResourceARN)?.region || region, name: nameFromArn(m.ResourceARN), tags: Object.keys(tags).length ? tags : undefined });
|
|
237
|
+
}
|
|
238
|
+
token = res.PaginationToken || undefined;
|
|
239
|
+
} while (token && out.length < TAGGING_CAP);
|
|
240
|
+
return out;
|
|
241
|
+
}
|
|
242
|
+
const ACTIVE_STACK_STATUSES = [
|
|
243
|
+
'CREATE_IN_PROGRESS', 'CREATE_COMPLETE', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_FAILED', 'ROLLBACK_COMPLETE', 'DELETE_FAILED',
|
|
244
|
+
'UPDATE_IN_PROGRESS', 'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS', 'UPDATE_COMPLETE', 'UPDATE_FAILED', 'UPDATE_ROLLBACK_IN_PROGRESS',
|
|
245
|
+
'UPDATE_ROLLBACK_FAILED', 'UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS', 'UPDATE_ROLLBACK_COMPLETE', 'REVIEW_IN_PROGRESS',
|
|
246
|
+
'IMPORT_IN_PROGRESS', 'IMPORT_COMPLETE', 'IMPORT_ROLLBACK_IN_PROGRESS', 'IMPORT_ROLLBACK_FAILED', 'IMPORT_ROLLBACK_COMPLETE',
|
|
247
|
+
];
|
|
248
|
+
/** Constrói o ARN a partir do physical id para os tipos em que isso é determinístico. */
|
|
249
|
+
function arnFromPhysicalId(type, physicalId, region, account, partition = 'aws') {
|
|
250
|
+
if (physicalId.startsWith('arn:'))
|
|
251
|
+
return physicalId;
|
|
252
|
+
switch (type) {
|
|
253
|
+
case 'AWS::Lambda::Function': return `arn:${partition}:lambda:${region}:${account}:function:${physicalId}`;
|
|
254
|
+
case 'AWS::SQS::Queue': {
|
|
255
|
+
const name = physicalId.split('/').pop();
|
|
256
|
+
return name ? `arn:${partition}:sqs:${region}:${account}:${name}` : null;
|
|
257
|
+
}
|
|
258
|
+
case 'AWS::DynamoDB::Table': return `arn:${partition}:dynamodb:${region}:${account}:table/${physicalId}`;
|
|
259
|
+
case 'AWS::S3::Bucket': return `arn:${partition}:s3:::${physicalId}`;
|
|
260
|
+
case 'AWS::ECS::Cluster': return `arn:${partition}:ecs:${region}:${account}:cluster/${physicalId}`;
|
|
261
|
+
case 'AWS::Logs::LogGroup': return `arn:${partition}:logs:${region}:${account}:log-group:${physicalId}`;
|
|
262
|
+
case 'AWS::Kinesis::Stream': return `arn:${partition}:kinesis:${region}:${account}:stream/${physicalId}`;
|
|
263
|
+
case 'AWS::ECR::Repository': return `arn:${partition}:ecr:${region}:${account}:repository/${physicalId}`;
|
|
264
|
+
case 'AWS::RDS::DBInstance': return `arn:${partition}:rds:${region}:${account}:db:${physicalId}`;
|
|
265
|
+
case 'AWS::RDS::DBCluster': return `arn:${partition}:rds:${region}:${account}:cluster:${physicalId}`;
|
|
266
|
+
case 'AWS::CodePipeline::Pipeline': return `arn:${partition}:codepipeline:${region}:${account}:${physicalId}`;
|
|
267
|
+
case 'AWS::CodeBuild::Project': return `arn:${partition}:codebuild:${region}:${account}:project/${physicalId}`;
|
|
268
|
+
case 'AWS::Events::Rule': return `arn:${partition}:events:${region}:${account}:rule/${physicalId}`;
|
|
269
|
+
case 'AWS::EC2::VPC': return `arn:${partition}:ec2:${region}:${account}:vpc/${physicalId}`;
|
|
270
|
+
case 'AWS::EC2::Subnet': return `arn:${partition}:ec2:${region}:${account}:subnet/${physicalId}`;
|
|
271
|
+
case 'AWS::EC2::SecurityGroup': return `arn:${partition}:ec2:${region}:${account}:security-group/${physicalId}`;
|
|
272
|
+
case 'AWS::EC2::Instance': return `arn:${partition}:ec2:${region}:${account}:instance/${physicalId}`;
|
|
273
|
+
case 'AWS::EC2::NatGateway': return `arn:${partition}:ec2:${region}:${account}:natgateway/${physicalId}`;
|
|
274
|
+
case 'AWS::CloudFront::Distribution': return `arn:${partition}:cloudfront::${account}:distribution/${physicalId}`;
|
|
275
|
+
case 'AWS::ApiGateway::RestApi': return `arn:${partition}:apigateway:${region}::/restapis/${physicalId}`;
|
|
276
|
+
case 'AWS::ApiGatewayV2::Api': return `arn:${partition}:apigateway:${region}::/apis/${physicalId}`;
|
|
277
|
+
case 'AWS::IAM::Role': return `arn:${partition}:iam::${account}:role/${physicalId}`;
|
|
278
|
+
default: return null;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
export async function discoverAws(options) {
|
|
282
|
+
const credentials = awsCredentials(options.profile);
|
|
283
|
+
const regions = [...new Set(options.regions)];
|
|
284
|
+
const sts = new STSClient({ region: regions[0] ?? 'us-east-1', credentials });
|
|
285
|
+
const identity = await sts.send(new GetCallerIdentityCommand({}));
|
|
286
|
+
const accountId = identity.Account ?? '';
|
|
287
|
+
const partition = parseArn(identity.Arn ?? '')?.partition || 'aws';
|
|
288
|
+
const byArn = new Map();
|
|
289
|
+
const sources = {};
|
|
290
|
+
const stacks = [];
|
|
291
|
+
const warnings = [];
|
|
292
|
+
const add = (r) => {
|
|
293
|
+
const prev = byArn.get(r.arn);
|
|
294
|
+
if (!prev)
|
|
295
|
+
byArn.set(r.arn, r);
|
|
296
|
+
else
|
|
297
|
+
byArn.set(r.arn, { ...prev, ...Object.fromEntries(Object.entries(r).filter(([, v]) => v !== undefined && v !== null)), tags: { ...(prev.tags ?? {}), ...(r.tags ?? {}) } });
|
|
298
|
+
};
|
|
299
|
+
const regionSet = new Set(regions);
|
|
300
|
+
for (const region of regions) {
|
|
301
|
+
options.onProgress?.(`região ${region}`);
|
|
302
|
+
try {
|
|
303
|
+
const budget = Math.max(0, EXPLORER_CAP - byArn.size);
|
|
304
|
+
const explorer = budget > 0 ? await explorerSearch(region, credentials, budget) : null;
|
|
305
|
+
if (explorer) {
|
|
306
|
+
// Índice agregador devolve outras regiões: mantém só as pedidas + globais.
|
|
307
|
+
for (const r of explorer.resources)
|
|
308
|
+
if (!r.region || r.region === 'global' || regionSet.has(r.region))
|
|
309
|
+
add({ ...r, region: r.region && r.region !== 'global' ? r.region : region });
|
|
310
|
+
sources[region] = 'resource-explorer';
|
|
311
|
+
if (!explorer.complete) {
|
|
312
|
+
for (const r of await taggingResources(region, credentials))
|
|
313
|
+
add(r);
|
|
314
|
+
sources[region] = 'resource-explorer+tagging-api';
|
|
315
|
+
warnings.push(`${region}: Resource Explorer devolveu resultado parcial (limite de ${EXPLORER_CAP}); complementado com o Tagging API.`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
for (const r of await taggingResources(region, credentials))
|
|
320
|
+
add({ ...r, region: r.region || region });
|
|
321
|
+
sources[region] = 'tagging-api';
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
catch (err) {
|
|
325
|
+
sources[region] = 'error';
|
|
326
|
+
warnings.push(`${region}: inventário falhou — ${describeAwsError(err)}`);
|
|
327
|
+
}
|
|
328
|
+
// CloudFormation: stacks e logical ids.
|
|
329
|
+
try {
|
|
330
|
+
const cfn = new CloudFormationClient({ region, credentials });
|
|
331
|
+
const index = new Map(); // `${type}|${name}` → arn
|
|
332
|
+
for (const r of byArn.values())
|
|
333
|
+
if (r.resourceType && r.name)
|
|
334
|
+
index.set(`${r.resourceType}|${r.name}`, r.arn);
|
|
335
|
+
let token;
|
|
336
|
+
const summaries = [];
|
|
337
|
+
do {
|
|
338
|
+
const res = await cfn.send(new ListStacksCommand({ NextToken: token, StackStatusFilter: ACTIVE_STACK_STATUSES }));
|
|
339
|
+
summaries.push(...(res.StackSummaries ?? []));
|
|
340
|
+
token = res.NextToken;
|
|
341
|
+
} while (token);
|
|
342
|
+
let totalStackResources = 0;
|
|
343
|
+
for (const s of summaries) {
|
|
344
|
+
if (!s.StackName || !s.StackId)
|
|
345
|
+
continue;
|
|
346
|
+
add({ arn: s.StackId, resourceType: 'AWS::CloudFormation::Stack', region, name: s.StackName });
|
|
347
|
+
let rtoken;
|
|
348
|
+
let count = 0;
|
|
349
|
+
let mapped = 0;
|
|
350
|
+
do {
|
|
351
|
+
const res = await cfn.send(new ListStackResourcesCommand({ StackName: s.StackName, NextToken: rtoken }));
|
|
352
|
+
for (const sr of res.StackResourceSummaries ?? []) {
|
|
353
|
+
count++;
|
|
354
|
+
totalStackResources++;
|
|
355
|
+
const type = sr.ResourceType ?? '';
|
|
356
|
+
const physical = sr.PhysicalResourceId ?? '';
|
|
357
|
+
if (!physical || type.startsWith('Custom::') || type === 'AWS::CDK::Metadata')
|
|
358
|
+
continue;
|
|
359
|
+
let arn = physical.startsWith('arn:') ? physical : undefined;
|
|
360
|
+
if (!arn) {
|
|
361
|
+
const name = type === 'AWS::SQS::Queue' ? physical.split('/').pop() ?? physical : physical;
|
|
362
|
+
arn = index.get(`${type}|${name}`);
|
|
363
|
+
}
|
|
364
|
+
if (!arn)
|
|
365
|
+
arn = arnFromPhysicalId(type, physical, region, accountId, partition) ?? undefined;
|
|
366
|
+
if (!arn)
|
|
367
|
+
continue;
|
|
368
|
+
mapped++;
|
|
369
|
+
add({ arn, resourceType: type || arnToResourceType(arn), region, name: nameFromArn(arn), stackName: s.StackName, stackLogicalId: sr.LogicalResourceId });
|
|
370
|
+
}
|
|
371
|
+
rtoken = res.NextToken;
|
|
372
|
+
} while (rtoken && totalStackResources < STACK_RESOURCES_CAP);
|
|
373
|
+
stacks.push({ name: s.StackName, region, status: s.StackStatus ?? '', resources: count, mapped, stackId: s.StackId });
|
|
374
|
+
if (totalStackResources >= STACK_RESOURCES_CAP) {
|
|
375
|
+
warnings.push(`${region}: limite de ${STACK_RESOURCES_CAP} recursos de stacks atingido; stacks restantes sem logical ids.`);
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
catch (err) {
|
|
381
|
+
warnings.push(`${region}: CloudFormation falhou — ${describeAwsError(err)}`);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return { accountId, callerArn: identity.Arn ?? '', regions, resources: [...byArn.values()], sources, stacks, warnings };
|
|
385
|
+
}
|
|
386
|
+
/** Lê os outputs de um stack (DescribeStacks, somente leitura). */
|
|
387
|
+
export async function readStackOutputs(stackName, region, profile) {
|
|
388
|
+
const cfn = new CloudFormationClient({ region, credentials: awsCredentials(profile) });
|
|
389
|
+
const res = await cfn.send(new DescribeStacksCommand({ StackName: stackName }));
|
|
390
|
+
const out = {};
|
|
391
|
+
for (const o of res.Stacks?.[0]?.Outputs ?? [])
|
|
392
|
+
if (o.OutputKey && o.OutputValue)
|
|
393
|
+
out[o.OutputKey] = o.OutputValue;
|
|
394
|
+
return out;
|
|
395
|
+
}
|
|
396
|
+
export const CANDIDATE_REGIONS = ['us-east-1', 'us-east-2', 'us-west-1', 'us-west-2', 'sa-east-1', 'eu-west-1', 'eu-central-1', 'ap-southeast-1', 'ap-northeast-1'];
|
|
397
|
+
const PROBE_TIMEOUT_MS = 6000;
|
|
398
|
+
const PROFILE_CAP = 10;
|
|
399
|
+
function iniSections(content) {
|
|
400
|
+
const out = [];
|
|
401
|
+
for (const line of content.split(/\r?\n/)) {
|
|
402
|
+
const m = /^\s*\[([^\]]+)\]\s*$/.exec(line);
|
|
403
|
+
if (m?.[1])
|
|
404
|
+
out.push(m[1].trim());
|
|
405
|
+
}
|
|
406
|
+
return out;
|
|
407
|
+
}
|
|
408
|
+
/** Perfis de ~/.aws/config e ~/.aws/credentials (respeita AWS_CONFIG_FILE / AWS_SHARED_CREDENTIALS_FILE) + AWS_PROFILE. */
|
|
409
|
+
export async function listAwsProfiles(env = process.env) {
|
|
410
|
+
const configFile = env.AWS_CONFIG_FILE || join(homedir(), '.aws', 'config');
|
|
411
|
+
const credentialsFile = env.AWS_SHARED_CREDENTIALS_FILE || join(homedir(), '.aws', 'credentials');
|
|
412
|
+
const names = new Set();
|
|
413
|
+
if (env.AWS_PROFILE?.trim())
|
|
414
|
+
names.add(env.AWS_PROFILE.trim());
|
|
415
|
+
const config = await readFile(configFile, 'utf8').catch(() => '');
|
|
416
|
+
for (const section of iniSections(config)) {
|
|
417
|
+
if (section === 'default')
|
|
418
|
+
names.add('default');
|
|
419
|
+
else if (section.startsWith('profile '))
|
|
420
|
+
names.add(section.slice('profile '.length).trim());
|
|
421
|
+
// [sso-session x] e [services x] não são perfis.
|
|
422
|
+
}
|
|
423
|
+
const credentials = await readFile(credentialsFile, 'utf8').catch(() => '');
|
|
424
|
+
for (const section of iniSections(credentials))
|
|
425
|
+
names.add(section);
|
|
426
|
+
return [...names].filter(Boolean);
|
|
427
|
+
}
|
|
428
|
+
/** Classifica o ambiente por dicas no nome do perfil/ARN; null = perguntar ao usuário. */
|
|
429
|
+
export function classifyEnvironment(...hints) {
|
|
430
|
+
for (const hint of hints) {
|
|
431
|
+
if (!hint)
|
|
432
|
+
continue;
|
|
433
|
+
const tokens = hint.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
|
|
434
|
+
if (tokens.some((t) => /^(prod|production|prd|prod\d+|prd\d+)$/.test(t)))
|
|
435
|
+
return 'production';
|
|
436
|
+
if (tokens.some((t) => /^(stag\w*|stage|stg|hml\w*|homolog\w*|qa\d*|uat)$/.test(t)))
|
|
437
|
+
return 'staging';
|
|
438
|
+
if (tokens.some((t) => /^(dev\w*|sandbox\w*|test\w*|tst)$/.test(t)))
|
|
439
|
+
return 'development';
|
|
440
|
+
}
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
443
|
+
export const ENVIRONMENT_LABEL = { production: 'Produção', staging: 'Staging', development: 'Desenvolvimento' };
|
|
444
|
+
function withTimeout(fn, ms = PROBE_TIMEOUT_MS) {
|
|
445
|
+
const controller = new AbortController();
|
|
446
|
+
const timer = setTimeout(() => controller.abort(), ms);
|
|
447
|
+
return Promise.race([
|
|
448
|
+
fn(controller.signal),
|
|
449
|
+
new Promise((_, reject) => controller.signal.addEventListener('abort', () => reject(new Error(`timeout de ${ms}ms`)), { once: true })),
|
|
450
|
+
]).finally(() => clearTimeout(timer));
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Regiões em uso na conta: índices do Resource Explorer (ListIndexes) quando existem; senão sonda
|
|
454
|
+
* as regiões candidatas com CloudFormation ListStacks (1ª página) e Tagging GetResources (1 recurso).
|
|
455
|
+
*/
|
|
456
|
+
export async function detectRegionsInUse(options) {
|
|
457
|
+
const credentials = awsCredentials(options.profile);
|
|
458
|
+
const include = [...new Set(options.includeRegions ?? [])];
|
|
459
|
+
const warnings = [];
|
|
460
|
+
let explorerRegions = [];
|
|
461
|
+
try {
|
|
462
|
+
const rex = new ResourceExplorer2Client({ region: 'us-east-1', credentials, maxAttempts: 1 });
|
|
463
|
+
let token;
|
|
464
|
+
do {
|
|
465
|
+
const res = await withTimeout((abortSignal) => rex.send(new ListIndexesCommand({ NextToken: token, MaxResults: 100 }), { abortSignal }));
|
|
466
|
+
for (const idx of res.Indexes ?? [])
|
|
467
|
+
if (idx.Region)
|
|
468
|
+
explorerRegions.push(idx.Region);
|
|
469
|
+
token = res.NextToken;
|
|
470
|
+
} while (token);
|
|
471
|
+
explorerRegions = [...new Set(explorerRegions)];
|
|
472
|
+
}
|
|
473
|
+
catch (err) {
|
|
474
|
+
warnings.push(`Resource Explorer indisponível (${describeAwsError(err)}); sondando regiões candidatas.`);
|
|
475
|
+
explorerRegions = [];
|
|
476
|
+
}
|
|
477
|
+
const useExplorer = explorerRegions.length > 0;
|
|
478
|
+
const candidates = useExplorer ? [...new Set([...explorerRegions, ...include])] : [...new Set([...CANDIDATE_REGIONS, ...include])];
|
|
479
|
+
const stacksPerRegion = {};
|
|
480
|
+
const inUse = [];
|
|
481
|
+
await Promise.all(candidates.map(async (region) => {
|
|
482
|
+
const cfn = new CloudFormationClient({ region, credentials, maxAttempts: 1 });
|
|
483
|
+
const tagging = new ResourceGroupsTaggingAPIClient({ region, credentials, maxAttempts: 1 });
|
|
484
|
+
const [stacks, tagged] = await Promise.allSettled([
|
|
485
|
+
withTimeout((abortSignal) => cfn.send(new ListStacksCommand({ StackStatusFilter: ACTIVE_STACK_STATUSES }), { abortSignal })),
|
|
486
|
+
withTimeout((abortSignal) => tagging.send(new GetResourcesCommand({ ResourcesPerPage: 1 }), { abortSignal })),
|
|
487
|
+
]);
|
|
488
|
+
const stackCount = stacks.status === 'fulfilled' ? (stacks.value.StackSummaries ?? []).length : 0;
|
|
489
|
+
const hasResources = tagged.status === 'fulfilled' && (tagged.value.ResourceTagMappingList ?? []).length > 0;
|
|
490
|
+
stacksPerRegion[region] = stackCount;
|
|
491
|
+
if (stacks.status === 'rejected' && tagged.status === 'rejected')
|
|
492
|
+
warnings.push(`${region}: sondagem falhou — ${describeAwsError(stacks.reason)}`);
|
|
493
|
+
if (useExplorer || include.includes(region) || stackCount > 0 || hasResources)
|
|
494
|
+
inUse.push(region);
|
|
495
|
+
}));
|
|
496
|
+
const order = (r) => {
|
|
497
|
+
const i = candidates.indexOf(r);
|
|
498
|
+
return i < 0 ? 999 : i;
|
|
499
|
+
};
|
|
500
|
+
const regionsInUse = inUse.sort((a, b) => (stacksPerRegion[b] ?? 0) - (stacksPerRegion[a] ?? 0) || order(a) - order(b));
|
|
501
|
+
if (!regionsInUse.length)
|
|
502
|
+
warnings.push('Nenhuma região com stacks ou recursos marcados nas candidatas; pergunte ao usuário as regiões ou passe includeRegions.');
|
|
503
|
+
return { regionsInUse, stacksPerRegion, source: useExplorer ? 'resource-explorer' : 'probe', warnings };
|
|
504
|
+
}
|
|
505
|
+
/** GetCallerIdentity por perfil (até 10), deduplica por conta, classifica ambiente e detecta regiões. */
|
|
506
|
+
export async function detectEnvironments(options) {
|
|
507
|
+
const found = options.profiles?.length ? [...new Set(options.profiles)] : await listAwsProfiles();
|
|
508
|
+
const targets = found.slice(0, PROFILE_CAP);
|
|
509
|
+
const skipped = [];
|
|
510
|
+
for (const p of found.slice(PROFILE_CAP))
|
|
511
|
+
skipped.push({ profile: p, reason: `limite de ${PROFILE_CAP} perfis por chamada — passe \`profiles\`` });
|
|
512
|
+
// Cadeia padrão (variáveis de ambiente, SSO/IMDS) quando não há perfis ou há credenciais no ambiente.
|
|
513
|
+
if (!options.profiles?.length && (!targets.length || process.env.AWS_ACCESS_KEY_ID))
|
|
514
|
+
targets.unshift(null);
|
|
515
|
+
const identities = await Promise.all(targets.map(async (profile) => {
|
|
516
|
+
try {
|
|
517
|
+
const sts = new STSClient({ region: 'us-east-1', credentials: awsCredentials(profile ?? undefined), maxAttempts: 1 });
|
|
518
|
+
const id = await withTimeout((abortSignal) => sts.send(new GetCallerIdentityCommand({}), { abortSignal }), 10_000);
|
|
519
|
+
return { profile, accountId: id.Account ?? '', arn: id.Arn ?? '' };
|
|
520
|
+
}
|
|
521
|
+
catch (err) {
|
|
522
|
+
skipped.push({ profile, reason: describeAwsError(err) });
|
|
523
|
+
return null;
|
|
524
|
+
}
|
|
525
|
+
}));
|
|
526
|
+
const byAccount = new Map();
|
|
527
|
+
for (const id of identities) {
|
|
528
|
+
if (!id?.accountId)
|
|
529
|
+
continue;
|
|
530
|
+
const entry = byAccount.get(id.accountId);
|
|
531
|
+
if (entry)
|
|
532
|
+
entry.profiles.push(id.profile);
|
|
533
|
+
else
|
|
534
|
+
byAccount.set(id.accountId, { profiles: [id.profile], arn: id.arn });
|
|
535
|
+
}
|
|
536
|
+
const accounts = await Promise.all([...byAccount].map(async ([accountId, { profiles, arn }]) => {
|
|
537
|
+
// Prefere um perfil nomeado (o comando de deploy precisa de --profile).
|
|
538
|
+
const named = profiles.filter((p) => !!p);
|
|
539
|
+
const profile = named[0] ?? null;
|
|
540
|
+
const environment = classifyEnvironment(...named, arn);
|
|
541
|
+
const regions = await detectRegionsInUse({ profile: profile ?? undefined, includeRegions: options.includeRegions });
|
|
542
|
+
return {
|
|
543
|
+
profile,
|
|
544
|
+
otherProfiles: named.slice(1),
|
|
545
|
+
accountId,
|
|
546
|
+
arn,
|
|
547
|
+
environment,
|
|
548
|
+
regionsInUse: regions.regionsInUse,
|
|
549
|
+
stacksPerRegion: Object.fromEntries(Object.entries(regions.stacksPerRegion).filter(([, n]) => n > 0)),
|
|
550
|
+
regionSource: regions.source,
|
|
551
|
+
suggestedConnectionName: environment ? ENVIRONMENT_LABEL[environment] : `AWS ${accountId}`,
|
|
552
|
+
warnings: regions.warnings,
|
|
553
|
+
};
|
|
554
|
+
}));
|
|
555
|
+
return { accounts, skipped, profilesFound: found };
|
|
556
|
+
}
|
|
557
|
+
//# sourceMappingURL=aws.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aws.js","sourceRoot":"","sources":["../../src/infra/aws.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Gerador de unified diff (compatível com `git apply`) a partir de edições por linha. */
|
|
2
|
+
export interface LineEdit {
|
|
3
|
+
/** Índice 0-based da primeira linha afetada no arquivo original. */
|
|
4
|
+
start: number;
|
|
5
|
+
deleteCount: number;
|
|
6
|
+
insert: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function splitLines(content: string): {
|
|
9
|
+
lines: string[];
|
|
10
|
+
trailingNewline: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare function applyEdits(lines: string[], edits: LineEdit[]): string[];
|
|
13
|
+
/** Remove sobreposições (mantém a primeira edição de cada região). */
|
|
14
|
+
export declare function normalizeEdits(edits: LineEdit[]): LineEdit[];
|
|
15
|
+
export declare function unifiedDiff(path: string, content: string | null, rawEdits: LineEdit[], context?: number): string;
|