diff --git a/local-app/python-tools/gfl-resource-actions/discovery.py b/local-app/python-tools/gfl-resource-actions/discovery.py index ec191280..4ce7cc4e 100644 --- a/local-app/python-tools/gfl-resource-actions/discovery.py +++ b/local-app/python-tools/gfl-resource-actions/discovery.py @@ -219,9 +219,242 @@ def get_rds_instances(credentials, region, account_id=None, account_name=None): return [] -# Similarly implement get_eks_clusters() and get_emr_clusters()... +def get_eks_clusters(credentials, region, account_id=None, account_name=None): + """Get EKS clusters in a region.""" + try: + eks_client = create_boto3_client('eks', credentials, region) + clusters = [] + + # List all clusters + response = eks_client.list_clusters() + cluster_names = response.get('clusters', []) + + # Get detailed info for each cluster + for cluster_name in cluster_names: + try: + cluster_info = eks_client.describe_cluster(name=cluster_name)['cluster'] + + # Get tags + tags = cluster_info.get('tags', {}) + + cluster_data = { + "name": cluster_name, + "id": cluster_name, # Using name as ID for consistency + "status": cluster_info.get('status', 'UNKNOWN'), + "region": region, + "endpoint": cluster_info.get('endpoint', ''), + "version": cluster_info.get('version', ''), + "tags": tags + } + + clusters.append(cluster_data) + + # Log the discovery + if account_id: + log_action_to_csv( + account_id=account_id, + account_name=account_name or "Unknown", + resource_type="eks", + resource_id=cluster_name, + resource_name=cluster_name, + action="discover", + region=region, + status="success", + details=f"Status: {cluster_data['status']}, Version: {cluster_data['version']}" + ) + + except Exception as e: + logger.warning(f"Error getting details for EKS cluster {cluster_name} in region {region}: {e}") + + # Handle pagination + while 'nextToken' in response: + response = eks_client.list_clusters(nextToken=response['nextToken']) + cluster_names = response.get('clusters', []) + + for cluster_name in cluster_names: + try: + cluster_info = eks_client.describe_cluster(name=cluster_name)['cluster'] + + # Get tags + tags = cluster_info.get('tags', {}) + + cluster_data = { + "name": cluster_name, + "id": cluster_name, # Using name as ID for consistency + "status": cluster_info.get('status', 'UNKNOWN'), + "region": region, + "endpoint": cluster_info.get('endpoint', ''), + "version": cluster_info.get('version', ''), + "tags": tags + } + + clusters.append(cluster_data) + + # Log the discovery + if account_id: + log_action_to_csv( + account_id=account_id, + account_name=account_name or "Unknown", + resource_type="eks", + resource_id=cluster_name, + resource_name=cluster_name, + action="discover", + region=region, + status="success", + details=f"Status: {cluster_data['status']}, Version: {cluster_data['version']}" + ) + + except Exception as e: + logger.warning(f"Error getting details for EKS cluster {cluster_name} in region {region}: {e}") + + logger.info(f"Found {len(clusters)} EKS clusters in region {region}") + return clusters + + except Exception as e: + error_msg = f"Error getting EKS clusters in region {region}: {e}" + logger.error(error_msg) + + # Log the error to CSV + if account_id: + log_action_to_csv( + account_id=account_id, + account_name=account_name or "Unknown", + resource_type="eks", + resource_id="N/A", + resource_name="N/A", + action="discover", + region=region, + status="failed", + details=error_msg + ) + + return [] + +def get_emr_clusters(credentials, region, account_id=None, account_name=None): + """Get EMR clusters in a region.""" + try: + emr_client = create_boto3_client('emr', credentials, region) + clusters = [] + + # List active clusters (RUNNING, WAITING, STARTING, BOOTSTRAPPING, TERMINATING) + response = emr_client.list_clusters( + ClusterStates=['RUNNING', 'WAITING', 'STARTING', 'BOOTSTRAPPING', 'TERMINATING', 'TERMINATED_WITH_ERRORS'] + ) + + # Process the clusters + for cluster in response.get('Clusters', []): + try: + # Get detailed cluster info + detail = emr_client.describe_cluster(ClusterId=cluster['Id']) + cluster_info = detail.get('Cluster', {}) + + # Extract tags + tags = {} + if 'Tags' in cluster_info: + for tag in cluster_info['Tags']: + tags[tag.get('Key', '')] = tag.get('Value', '') + + # Build the cluster data structure + cluster_data = { + "id": cluster['Id'], + "name": cluster.get('Name', 'Unnamed cluster'), + "status": cluster.get('Status', {}).get('State', 'UNKNOWN'), + "region": region, + "type": cluster_info.get('InstanceCollectionType', 'UNKNOWN'), + "creation_time": str(cluster.get('Status', {}).get('Timeline', {}).get('CreationDateTime', '')), + "tags": tags + } + + clusters.append(cluster_data) + + # Log the discovery action to CSV + if account_id: + log_action_to_csv( + account_id=account_id, + account_name=account_name or "Unknown", + resource_type="emr", + resource_id=cluster['Id'], + resource_name=cluster.get('Name', 'Unnamed cluster'), + action="discover", + region=region, + status="success", + details=f"Status: {cluster_data['status']}, Type: {cluster_data['type']}" + ) + except Exception as e: + logger.warning(f"Error getting details for EMR cluster {cluster['Id']} in region {region}: {e}") + + # Handle pagination + while 'Marker' in response: + response = emr_client.list_clusters( + ClusterStates=['RUNNING', 'WAITING', 'STARTING', 'BOOTSTRAPPING', 'TERMINATING', 'TERMINATED_WITH_ERRORS'], + Marker=response['Marker'] + ) + + for cluster in response.get('Clusters', []): + try: + # Get detailed cluster info + detail = emr_client.describe_cluster(ClusterId=cluster['Id']) + cluster_info = detail.get('Cluster', {}) + + # Extract tags + tags = {} + if 'Tags' in cluster_info: + for tag in cluster_info['Tags']: + tags[tag.get('Key', '')] = tag.get('Value', '') + + # Build the cluster data structure + cluster_data = { + "id": cluster['Id'], + "name": cluster.get('Name', 'Unnamed cluster'), + "status": cluster.get('Status', {}).get('State', 'UNKNOWN'), + "region": region, + "type": cluster_info.get('InstanceCollectionType', 'UNKNOWN'), + "creation_time": str(cluster.get('Status', {}).get('Timeline', {}).get('CreationDateTime', '')), + "tags": tags + } + + clusters.append(cluster_data) + + # Log the discovery action to CSV + if account_id: + log_action_to_csv( + account_id=account_id, + account_name=account_name or "Unknown", + resource_type="emr", + resource_id=cluster['Id'], + resource_name=cluster.get('Name', 'Unnamed cluster'), + action="discover", + region=region, + status="success", + details=f"Status: {cluster_data['status']}, Type: {cluster_data['type']}" + ) + except Exception as e: + logger.warning(f"Error getting details for EMR cluster {cluster['Id']} in region {region}: {e}") + + logger.info(f"Found {len(clusters)} EMR clusters in region {region}") + return clusters + + except Exception as e: + error_msg = f"Error getting EMR clusters in region {region}: {e}" + logger.error(error_msg) + + # Log the error to CSV + if account_id: + log_action_to_csv( + account_id=account_id, + account_name=account_name or "Unknown", + resource_type="emr", + resource_id="N/A", + resource_name="N/A", + action="discover", + region=region, + status="failed", + details=error_msg + ) + + return [] -def get_account_resources(credentials, regions, account_id=None, account_name=None, exclude_resources=None): +def get_account_resources(credentials, regions, exclude_resources=None, account_id=None, account_name=None): """Get all resources from an account across specified regions.""" if exclude_resources is None: exclude_resources = [] @@ -244,12 +477,10 @@ def get_account_resources(credentials, regions, account_id=None, account_name=No # Get EKS clusters if "eks" not in exclude_resources: - # Implementation would go here - pass + resources["eks_clusters"].extend(get_eks_clusters(credentials, region, account_id, account_name)) # Get EMR clusters if "emr" not in exclude_resources: - # Implementation would go here - pass + resources["emr_clusters"].extend(get_emr_clusters(credentials, region, account_id, account_name)) return resources