Skip to content

Commit 50ec1d3

Browse files
1101-1aquamatthias
andauthored
[aws][feat] Bedrock resources collection (#2190)
Co-authored-by: Matthias Veit <aquamatthias@users.noreply.github.com> Co-authored-by: Matthias Veit <matthias_veit@yahoo.de>
1 parent 21ddc09 commit 50ec1d3

32 files changed

+2555
-30
lines changed

fixlib/fixlib/baseresources.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,6 +1513,31 @@ class BaseManagedKubernetesClusterProvider(BaseResource):
15131513
endpoint: Optional[str] = field(default=None, metadata={"description": "The kubernetes API endpoint"})
15141514

15151515

1516+
@define(eq=False, slots=False)
1517+
class BaseAIResource(BaseResource):
1518+
kind: ClassVar[str] = "ai_resource"
1519+
kind_display: ClassVar[str] = "AI resource"
1520+
kind_description: ClassVar[str] = "An AI Resource."
1521+
metadata: ClassVar[Dict[str, Any]] = {"icon": "resource", "group": "ai"}
1522+
_categories: ClassVar[List[Category]] = [Category.ai, Category.compute]
1523+
1524+
1525+
@define(eq=False, slots=False)
1526+
class BaseAIJob(BaseAIResource):
1527+
kind: ClassVar[str] = "ai_job"
1528+
kind_display: ClassVar[str] = "AI Job"
1529+
kind_description: ClassVar[str] = "An AI Job resource."
1530+
metadata: ClassVar[Dict[str, Any]] = {"icon": "job", "group": "ai"}
1531+
1532+
1533+
@define(eq=False, slots=False)
1534+
class BaseAIModel(BaseAIResource):
1535+
kind: ClassVar[str] = "ai_model"
1536+
kind_display: ClassVar[str] = "AI Model"
1537+
kind_description: ClassVar[str] = "An AI Model resource."
1538+
metadata: ClassVar[Dict[str, Any]] = {"icon": "resource", "group": "ai"}
1539+
1540+
15161541
@define(eq=False, slots=False)
15171542
class UnknownCloud(BaseCloud):
15181543
kind: ClassVar[str] = "unknown_cloud"

plugins/aws/fix_plugin_aws/collector.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
acm,
4949
waf,
5050
backup,
51+
bedrock,
5152
)
5253
from fix_plugin_aws.resource.base import AwsAccount, AwsApiSpec, AwsRegion, AwsResource, GraphBuilder
5354
from fixlib.baseresources import Cloud, EdgeType, BaseOrganizationalRoot, BaseOrganizationalUnit
@@ -107,6 +108,7 @@
107108
+ redshift.resources
108109
+ backup.resources
109110
+ amazonq.resources
111+
+ bedrock.resources
110112
)
111113
all_resources: List[Type[AwsResource]] = global_resources + regional_resources
112114

@@ -259,6 +261,8 @@ def get_last_run() -> Optional[datetime]:
259261

260262
# wait for all futures to finish
261263
shared_queue.wait_for_submitted_work()
264+
# remove unused nodes
265+
self.remove_unused()
262266
self.core_feedback.progress_done(self.account.dname, 1, 1, context=[self.cloud.id])
263267
self.error_accumulator.report_all(global_builder.core_feedback)
264268

@@ -330,6 +334,32 @@ def collect_and_set_metrics(
330334

331335
builder.submit_work("cloudwatch", collect_and_set_metrics, start, region, queries)
332336

337+
def remove_unused(self) -> None:
338+
remove_nodes = []
339+
340+
def rm_nodes(cls, ignore_kinds: Optional[Type[Any]] = None, check_pred: bool = True) -> None: # type: ignore
341+
for node in self.graph.nodes:
342+
if not isinstance(node, cls):
343+
continue
344+
if check_pred:
345+
nodes = list(self.graph.predecessors(node))
346+
else:
347+
nodes = list(self.graph.successors(node))
348+
if ignore_kinds is not None:
349+
nodes = [n for n in nodes if not isinstance(n, ignore_kinds)]
350+
if not nodes:
351+
remove_nodes.append(node)
352+
log.debug(f"Removing {len(remove_nodes)} unreferenced nodes of type {cls}")
353+
removed = set()
354+
for node in remove_nodes:
355+
if node in removed:
356+
continue
357+
removed.add(node)
358+
self.graph.remove_node(node)
359+
remove_nodes.clear()
360+
361+
rm_nodes(bedrock.AwsBedrockFoundationModel, check_pred=False)
362+
333363
# TODO: move into separate AwsAccountSettings
334364
def update_account(self) -> None:
335365
log.info(f"Collecting AWS IAM Account Summary in account {self.account.dname}")

plugins/aws/fix_plugin_aws/resource/amazonq.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ def add_tags(tag_resource: AwsResource) -> None:
143143
resourceARN=tag_resource.arn,
144144
)
145145
if tags:
146-
tag_resource.tags.update(tags)
146+
tag_resource.tags.update(tags[0])
147147
else:
148148
tags = builder.client.list(
149149
service_name,
@@ -356,9 +356,9 @@ class AwsQBusinessDataSource(AmazonQTaggable, AwsResource):
356356
metadata: ClassVar[Dict[str, Any]] = {"icon": "bucket", "group": "ai"}
357357
# Collected via AwsQBusinessApplication()
358358
aws_metadata: ClassVar[Dict[str, Any]] = {
359-
"provider_link_tpl": "https://{region_id}.console.aws.amazon.com/amazonq/business/applications/{app_id}/indices/{indice_id}/datasources/{id}/details?region={region}", # fmt: skip
359+
"provider_link_tpl": "https://{region_id}.console.aws.amazon.com/amazonq/business/applications/{application_id}/indices/{indice_id}/datasources/{id}/details?region={region}", # fmt: skip
360360
"arn_tpl": "arn:{partition}:qbusiness:{region}:{account}:application/{application_id}/index/{indice_id}/data-source/{id}",
361-
"extra_args": ["application_id", "indice_id"],
361+
"extra_args_for_arn": ["application_id", "indice_id"],
362362
}
363363
mapping: ClassVar[Dict[str, Bender]] = {
364364
"id": S("dataSourceId"),
@@ -528,7 +528,7 @@ class AwsQBusinessIndice(AmazonQTaggable, AwsResource):
528528
metadata: ClassVar[Dict[str, Any]] = {"icon": "config", "group": "ai"}
529529
aws_metadata: ClassVar[Dict[str, Any]] = {
530530
"arn_tpl": "arn:{partition}:qbusiness:{region}:{account}:application/{application_id}/index/{id}",
531-
"extra_args": ["application_id"],
531+
"extra_args_for_arn": ["application_id"],
532532
}
533533
# Collected via AwsQBusinessApplication()
534534
mapping: ClassVar[Dict[str, Bender]] = {
@@ -753,7 +753,7 @@ class AwsQBusinessPlugin(AmazonQTaggable, AwsResource):
753753
metadata: ClassVar[Dict[str, Any]] = {"icon": "resource", "group": "ai"}
754754
aws_metadata: ClassVar[Dict[str, Any]] = {
755755
"arn_tpl": "arn:{partition}:qbusiness:{region}:{account}:application/{application_id}/plugin/{id}",
756-
"extra_args": ["application_id"],
756+
"extra_args_for_arn": ["application_id"],
757757
}
758758
# Collected via AwsQBusinessApplication()
759759
mapping: ClassVar[Dict[str, Bender]] = {
@@ -819,7 +819,7 @@ class AwsQBusinessRetriever(AmazonQTaggable, AwsResource):
819819
metadata: ClassVar[Dict[str, Any]] = {"icon": "application", "group": "ai"}
820820
aws_metadata: ClassVar[Dict[str, Any]] = {
821821
"arn_tpl": "arn:{partition}:qbusiness:{region}:{account}:application/{application_id}/retriever/{id}",
822-
"extra_args": ["application_id"],
822+
"extra_args_for_arn": ["application_id"],
823823
}
824824
# Collected via AwsQBusinessApplication()
825825
mapping: ClassVar[Dict[str, Bender]] = {
@@ -876,7 +876,7 @@ class AwsQBusinessWebExperience(AmazonQTaggable, AwsResource):
876876
metadata: ClassVar[Dict[str, Any]] = {"icon": "application", "group": "ai"}
877877
aws_metadata: ClassVar[Dict[str, Any]] = {
878878
"arn_tpl": "arn:{partition}:qbusiness:{region}:{account}:application/{application_id}/web-experience/{id}",
879-
"extra_args": ["application_id"],
879+
"extra_args_for_arn": ["application_id"],
880880
}
881881
# Collected via AwsQBusinessApplication()
882882
mapping: ClassVar[Dict[str, Bender]] = {

plugins/aws/fix_plugin_aws/resource/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ def add_node(
520520
}
521521

522522
# Add any additional dynamic arguments from the metadata (if they exist)
523-
if extra_args := meta.get("extra_args"):
523+
if extra_args := meta.get("extra_args_for_arn"):
524524
for extra_arg in extra_args:
525525
args[extra_arg] = getattr(node, extra_arg)
526526

0 commit comments

Comments
 (0)