@go-to-k/cdkd 0.0.3 → 0.0.4
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/dist/cli.js +124 -1
- package/dist/cli.js.map +2 -2
- package/dist/go-to-k-cdkd-0.0.4.tgz +0 -0
- package/dist/index.js +123 -0
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.0.3.tgz +0 -0
package/dist/cli.js
CHANGED
|
@@ -3519,6 +3519,11 @@ var TemplateParser = class {
|
|
|
3519
3519
|
|
|
3520
3520
|
// src/analyzer/dag-builder.ts
|
|
3521
3521
|
var { Graph, alg } = graphlib;
|
|
3522
|
+
var IAM_ROLE_POLICY_TYPES = /* @__PURE__ */ new Set([
|
|
3523
|
+
"AWS::IAM::Policy",
|
|
3524
|
+
"AWS::IAM::RolePolicy",
|
|
3525
|
+
"AWS::IAM::ManagedPolicy"
|
|
3526
|
+
]);
|
|
3522
3527
|
var DagBuilder = class {
|
|
3523
3528
|
logger = getLogger().child("DagBuilder");
|
|
3524
3529
|
parser = new TemplateParser();
|
|
@@ -3559,6 +3564,7 @@ var DagBuilder = class {
|
|
|
3559
3564
|
}
|
|
3560
3565
|
}
|
|
3561
3566
|
this.logger.debug(`Dependency graph built: ${resourceIds.length} nodes, ${edgeCount} edges`);
|
|
3567
|
+
edgeCount += this.addCustomResourcePolicyEdges(graph, template);
|
|
3562
3568
|
if (!alg.isAcyclic(graph)) {
|
|
3563
3569
|
const cycles = this.findCycles(graph);
|
|
3564
3570
|
throw new DependencyError(
|
|
@@ -3701,6 +3707,123 @@ var DagBuilder = class {
|
|
|
3701
3707
|
const deps = this.getAllDependencies(graph, resourceA);
|
|
3702
3708
|
return deps.has(resourceB);
|
|
3703
3709
|
}
|
|
3710
|
+
/**
|
|
3711
|
+
* Add implicit edges from IAM::Policy resources to Custom Resources whose
|
|
3712
|
+
* ServiceToken Lambda's execution role those policies attach to.
|
|
3713
|
+
*
|
|
3714
|
+
* Returns the number of edges added.
|
|
3715
|
+
*/
|
|
3716
|
+
addCustomResourcePolicyEdges(graph, template) {
|
|
3717
|
+
const rolePolicies = this.buildRolePoliciesMap(template);
|
|
3718
|
+
if (rolePolicies.size === 0) {
|
|
3719
|
+
return 0;
|
|
3720
|
+
}
|
|
3721
|
+
let added = 0;
|
|
3722
|
+
for (const logicalId of this.parser.getResourceIds(template)) {
|
|
3723
|
+
const resource = this.parser.getResource(template, logicalId);
|
|
3724
|
+
if (!resource || !this.isCustomResourceType(resource.Type)) {
|
|
3725
|
+
continue;
|
|
3726
|
+
}
|
|
3727
|
+
const serviceToken = (resource.Properties ?? {})["ServiceToken"];
|
|
3728
|
+
const lambdaId = this.extractLogicalIdFromReference(serviceToken);
|
|
3729
|
+
if (!lambdaId)
|
|
3730
|
+
continue;
|
|
3731
|
+
const lambdaResource = this.parser.getResource(template, lambdaId);
|
|
3732
|
+
if (!lambdaResource || lambdaResource.Type !== "AWS::Lambda::Function") {
|
|
3733
|
+
continue;
|
|
3734
|
+
}
|
|
3735
|
+
const roleId = this.extractLogicalIdFromReference((lambdaResource.Properties ?? {})["Role"]);
|
|
3736
|
+
if (!roleId)
|
|
3737
|
+
continue;
|
|
3738
|
+
const policies = rolePolicies.get(roleId);
|
|
3739
|
+
if (!policies)
|
|
3740
|
+
continue;
|
|
3741
|
+
for (const policyId of policies) {
|
|
3742
|
+
if (policyId === logicalId)
|
|
3743
|
+
continue;
|
|
3744
|
+
if (!graph.hasNode(policyId))
|
|
3745
|
+
continue;
|
|
3746
|
+
if (graph.hasEdge(policyId, logicalId))
|
|
3747
|
+
continue;
|
|
3748
|
+
graph.setEdge(policyId, logicalId);
|
|
3749
|
+
added++;
|
|
3750
|
+
this.logger.debug(
|
|
3751
|
+
`Added implicit edge (custom resource policy): ${policyId} -> ${logicalId}`
|
|
3752
|
+
);
|
|
3753
|
+
}
|
|
3754
|
+
}
|
|
3755
|
+
if (added > 0) {
|
|
3756
|
+
this.logger.debug(`Added ${added} implicit edges for custom resource policies`);
|
|
3757
|
+
}
|
|
3758
|
+
return added;
|
|
3759
|
+
}
|
|
3760
|
+
isCustomResourceType(type) {
|
|
3761
|
+
return type === "AWS::CloudFormation::CustomResource" || type.startsWith("Custom::");
|
|
3762
|
+
}
|
|
3763
|
+
/**
|
|
3764
|
+
* Build a map of roleLogicalId -> Set<policyLogicalId> by scanning the
|
|
3765
|
+
* template for IAM::Policy / IAM::RolePolicy / IAM::ManagedPolicy resources
|
|
3766
|
+
* that attach to a role by Ref/GetAtt.
|
|
3767
|
+
*/
|
|
3768
|
+
buildRolePoliciesMap(template) {
|
|
3769
|
+
const map = /* @__PURE__ */ new Map();
|
|
3770
|
+
for (const [policyId, resource] of Object.entries(template.Resources)) {
|
|
3771
|
+
if (!IAM_ROLE_POLICY_TYPES.has(resource.Type))
|
|
3772
|
+
continue;
|
|
3773
|
+
for (const roleId of this.extractAttachedRoleIds(resource)) {
|
|
3774
|
+
let set = map.get(roleId);
|
|
3775
|
+
if (!set) {
|
|
3776
|
+
set = /* @__PURE__ */ new Set();
|
|
3777
|
+
map.set(roleId, set);
|
|
3778
|
+
}
|
|
3779
|
+
set.add(policyId);
|
|
3780
|
+
}
|
|
3781
|
+
}
|
|
3782
|
+
return map;
|
|
3783
|
+
}
|
|
3784
|
+
/**
|
|
3785
|
+
* Extract the logical IDs of IAM::Role resources that a policy resource
|
|
3786
|
+
* attaches to. Supports both `Roles: [Ref]` (IAM::Policy / IAM::ManagedPolicy)
|
|
3787
|
+
* and `RoleName: Ref` (IAM::RolePolicy) shapes.
|
|
3788
|
+
*/
|
|
3789
|
+
extractAttachedRoleIds(resource) {
|
|
3790
|
+
const ids = [];
|
|
3791
|
+
const props = resource.Properties ?? {};
|
|
3792
|
+
const roles = props["Roles"];
|
|
3793
|
+
if (Array.isArray(roles)) {
|
|
3794
|
+
for (const entry of roles) {
|
|
3795
|
+
const id = this.extractLogicalIdFromReference(entry);
|
|
3796
|
+
if (id)
|
|
3797
|
+
ids.push(id);
|
|
3798
|
+
}
|
|
3799
|
+
}
|
|
3800
|
+
const roleName = props["RoleName"];
|
|
3801
|
+
const roleNameId = this.extractLogicalIdFromReference(roleName);
|
|
3802
|
+
if (roleNameId)
|
|
3803
|
+
ids.push(roleNameId);
|
|
3804
|
+
return ids;
|
|
3805
|
+
}
|
|
3806
|
+
/**
|
|
3807
|
+
* Extract a resource logical ID from a direct Ref or Fn::GetAtt expression.
|
|
3808
|
+
* Returns undefined for literals or intrinsics we can't statically resolve
|
|
3809
|
+
* (Fn::Join, Fn::ImportValue, etc.) — callers should skip in that case.
|
|
3810
|
+
*/
|
|
3811
|
+
extractLogicalIdFromReference(value) {
|
|
3812
|
+
if (typeof value !== "object" || value === null)
|
|
3813
|
+
return void 0;
|
|
3814
|
+
const obj = value;
|
|
3815
|
+
if ("Ref" in obj && typeof obj["Ref"] === "string") {
|
|
3816
|
+
const ref = obj["Ref"];
|
|
3817
|
+
return ref.startsWith("AWS::") ? void 0 : ref;
|
|
3818
|
+
}
|
|
3819
|
+
if ("Fn::GetAtt" in obj) {
|
|
3820
|
+
const getAtt = obj["Fn::GetAtt"];
|
|
3821
|
+
if (Array.isArray(getAtt) && typeof getAtt[0] === "string") {
|
|
3822
|
+
return getAtt[0];
|
|
3823
|
+
}
|
|
3824
|
+
}
|
|
3825
|
+
return void 0;
|
|
3826
|
+
}
|
|
3704
3827
|
};
|
|
3705
3828
|
|
|
3706
3829
|
// src/analyzer/replacement-rules.ts
|
|
@@ -26890,7 +27013,7 @@ function reorderArgs(argv) {
|
|
|
26890
27013
|
}
|
|
26891
27014
|
async function main() {
|
|
26892
27015
|
const program = new Command8();
|
|
26893
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.0.
|
|
27016
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.0.4");
|
|
26894
27017
|
program.addCommand(createBootstrapCommand());
|
|
26895
27018
|
program.addCommand(createSynthCommand());
|
|
26896
27019
|
program.addCommand(createDeployCommand());
|