-
Notifications
You must be signed in to change notification settings - Fork 83
Add support for collecting deletable OCPs from AWS #481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
4cdfe79
19b920a
ade36a5
6f7a1bd
7625225
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ | |
""" | ||
|
||
CACHED_PROPERTY_TTL = 1 | ||
EC2_INSTANCE = "ec2:instance" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,15 @@ | ||
import base64 | ||
import os | ||
import re | ||
from datetime import datetime | ||
|
||
import boto3 | ||
from boto3 import client as boto3client | ||
from boto3 import resource as boto3resource | ||
from botocore.config import Config | ||
from botocore.exceptions import ClientError | ||
|
||
from wrapanapi.const import EC2_INSTANCE | ||
from wrapanapi.entities import ( | ||
Instance, | ||
Network, | ||
|
@@ -113,10 +115,17 @@ def __init__(self, system, raw=None, **kwargs): | |
|
||
self._api = self.system.ec2_connection | ||
|
||
def __repr__(self): | ||
return f"{type(self)} Id: {self.id}, Name: {self.name}" | ||
|
||
@property | ||
def id(self): | ||
oharan2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return self.raw.id | ||
|
||
@property | ||
def name(self): | ||
tag_value = self.get_tag_value("Name") | ||
return getattr(self.raw, "name", None) or tag_value if tag_value else self.raw.id | ||
return getattr(self.raw, "name", None) or tag_value if tag_value else self.id | ||
|
||
def _get_state(self): | ||
self.refresh() | ||
|
@@ -487,13 +496,26 @@ class ResourceExplorerResource: | |
This class represents a resource returned by Resource Explorer. | ||
""" | ||
|
||
def __init__(self, arn, region, resource_type, service, properties=[]): | ||
def __init__(self, arn, region, resource_type, service, properties, **kwargs): | ||
self.arn = arn | ||
self.region = region | ||
self.resource_type = resource_type | ||
self.service = service | ||
self.properties = properties | ||
|
||
if self.resource_type == EC2_INSTANCE: | ||
if kwargs: | ||
oharan2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
system = kwargs.get("system") | ||
if system: | ||
oharan2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
kwargs["raw"] = system.ec2_resource.Instance(self.id) | ||
kwargs["uuid"] = self.id | ||
# When Calling the raw ec2_instance with non-matching AWS Client Region, | ||
# the API call fails with a 'ClientError' (InvalidInstanceID.NotFound) | ||
self.ec2_instance = EC2Instance(**kwargs) | ||
|
||
def __repr__(self): | ||
return f"{type(self)} Id: {self.id}, Type: {self.resource_type}" | ||
|
||
def get_tag_value(self, key) -> str: | ||
""" | ||
Returns a tag value for a given tag key. | ||
|
@@ -531,7 +553,7 @@ def id(self) -> str: | |
This part is used as id in aws cli. | ||
""" | ||
if self.arn: | ||
return self.arn.split(":")[-1] | ||
return self.arn.split(":")[-1].split("/")[-1] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. looking at the docs here https://docs.aws.amazon.com/quicksight/latest/APIReference/qs-arn-format.html it could be three formats
it will fail for others ? I think you need to handle that ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Resolved in latest commit |
||
return None | ||
|
||
@property | ||
|
@@ -545,6 +567,23 @@ def name(self) -> str: | |
name = self.id | ||
return name | ||
|
||
@property | ||
def date_modified(self) -> datetime: | ||
""" | ||
Returns the time reference of the "LastReportedAt" tag, by the latest value. | ||
If the tag doesn't exist, returns the current time. | ||
Used for filtering resources by the latest modified time recorded. | ||
|
||
Example: | ||
datetime.datetime(2019, 3, 13, 14, 45, 33, tzinfo=tzutc()) | ||
""" | ||
modified_date = None | ||
if self.properties: | ||
modified_date = max(self.properties, key=lambda x: x == "LastReportedAt").get( | ||
"LastReportedAt" | ||
) | ||
return modified_date | ||
|
||
|
||
class EC2System(System, VmMixin, TemplateMixin, StackMixin, NetworkMixin): | ||
"""EC2 Management System, powered by boto | ||
|
@@ -667,9 +706,10 @@ def _get_instances(self, **kwargs): | |
instances = list() | ||
for reservation in reservations: | ||
for instance in reservation.get("Instances"): | ||
instance_id = instance.get("InstanceId") | ||
instances.append( | ||
EC2Instance( | ||
system=self, raw=self.ec2_resource.Instance(instance.get("InstanceId")) | ||
system=self, raw=self.ec2_resource.Instance(instance_id), uuid=instance_id | ||
) | ||
) | ||
return instances | ||
|
@@ -1814,28 +1854,43 @@ def list_resources(self, query="", view="") -> list[ResourceExplorerResource]: | |
Args: | ||
query: keywords and filters for resources; default is "" (all) | ||
view: arn of the view to use for the query; default is "" (default view) | ||
|
||
Return: | ||
a list of resources satisfying the query | ||
|
||
Examples: | ||
Use query "tag.key:kubernetes.io/cluster/*" to list OCP resources | ||
""" | ||
resource_list = [] | ||
kwargs = {"system": self} | ||
args = {"QueryString": query} | ||
if view: | ||
args["ViewArn"] = view | ||
list = [] | ||
|
||
paginator = self.resource_explorer_connection.get_paginator("search") | ||
page_iterator = paginator.paginate(**args) | ||
for page in page_iterator: | ||
resources = page.get("Resources") | ||
for r in resources: | ||
resource = ResourceExplorerResource( | ||
arn=r.get("Arn"), | ||
region=r.get("Region"), | ||
service=r.get("Service"), | ||
properties=r.get("Properties"), | ||
resource_type=r.get("ResourceType"), | ||
|
||
try: | ||
for page in page_iterator: | ||
resources = page.get("Resources") | ||
for r in resources: | ||
resource = ResourceExplorerResource( | ||
arn=r.get("Arn"), | ||
region=r.get("Region"), | ||
service=r.get("Service"), | ||
properties=r.get("Properties"), | ||
resource_type=r.get("ResourceType"), | ||
**kwargs, | ||
) | ||
resource_list.append(resource) | ||
except ClientError as error: | ||
if error.response["Error"]["Code"] == "UnauthorizedException": | ||
# Raised when the client uses a region that is not defined as an | ||
# Index Aggregator in the Resource Explorer. Official docs: | ||
# https://docs.aws.amazon.com/resource-explorer/latest/userguide/manage-aggregator-region.html | ||
self.logger.info( | ||
f"Region {self._region_name} is not an Index Aggregator. " | ||
f"Cannot fetch resources with current client." | ||
) | ||
list.append(resource) | ||
return list | ||
else: | ||
raise error | ||
return resource_list |
Uh oh!
There was an error while loading. Please reload this page.