diff --git a/internal/inventory/ASSETS.md b/internal/inventory/ASSETS.md index 93c92c12a2..c2a286d796 100644 --- a/internal/inventory/ASSETS.md +++ b/internal/inventory/ASSETS.md @@ -1,200 +1,236 @@ ## AWS Resources -**Progress: 25% (22/85)** -Identity: 33% (4/12) -Infrastructure: 24% (18/73) +**Progress: 24% (21/85)** +Access Management: 50% (1/2) +Database: 100% (1/1) +FaaS: 100% (3/3) +Firewall: 100% (1/1) +Gateway: 100% (4/4) +Host: 100% (1/1) +Identity: 11% (1/9) +Infrastructure: 0% (0/55) +Load Balancer: 100% (2/2) +Messaging Service: 100% (1/1) +Networking: 100% (4/4) +Service Account: 100% (1/1) +Storage Bucket: 100% (1/1)
Full table -| Category | SubCategory | Type | SubType | Implemented? | -|---|---|---|---|---| -| Identity | Authentication | Certificate | API Gateway Client Certificate | No ❌ | -| Identity | Authentication | Credential | Access Key | No ❌ | -| Identity | Authentication | Credential | EC2 Key Pair | No ❌ | -| Identity | Authorization | ACL | S3 Access Control List | Yes ✅ | -| Identity | Authorization | Grant | KMS Key Grant | No ❌ | -| Identity | Authorization | Policy | S3 Bucket Policy Statement | No ❌ | -| Identity | Digital Identity | Group | IAM Group | No ❌ | -| Identity | Digital Identity | Policy | IAM Policy | Yes ✅ | -| Identity | Digital Identity | Policy | IAM Policy Statement | No ❌ | -| Identity | Digital Identity | Principal | IAM Principal | No ❌ | -| Identity | Digital Identity | Role | IAM Role | Yes ✅ | -| Identity | Digital Identity | User | IAM User | Yes ✅ | -| Infrastructure | Analytics | Cluster | EMR Cluster | No ❌ | -| Infrastructure | Compute | Configuration | Launch Configuration | No ❌ | -| Infrastructure | Compute | Configuration | Launch Template | No ❌ | -| Infrastructure | Compute | Configuration | Launch Template Version | No ❌ | -| Infrastructure | Compute | Image | EC2 AMI | No ❌ | -| Infrastructure | Compute | Reservation | EC2 Reserved Instance | No ❌ | -| Infrastructure | Compute | Scaling | Auto Scaling Group | No ❌ | -| Infrastructure | Compute | Serverless | Lambda Function | Yes ✅ | -| Infrastructure | Compute | Serverless | Lambda Function Alias | No ❌ | -| Infrastructure | Compute | Serverless | Lambda Layer | Yes ✅ | -| Infrastructure | Compute | Virtual Machine | EC2 Instance | Yes ✅ | -| Infrastructure | Container | Compute | ECS Container | No ❌ | -| Infrastructure | Container | Compute | ECS Container Instance | No ❌ | -| Infrastructure | Container | Compute | ECS Task | No ❌ | -| Infrastructure | Container | Configuration | ECS Container Definition | No ❌ | -| Infrastructure | Container | Configuration | ECS Task Definition | No ❌ | -| Infrastructure | Container | Image | ECR Image | No ❌ | -| Infrastructure | Container | Image | ECR Repository Image | No ❌ | -| Infrastructure | Container | Orchestration | ECS Cluster | No ❌ | -| Infrastructure | Container | Orchestration | ECS Service | No ❌ | -| Infrastructure | Container | Orchestration | EKS Cluster | No ❌ | -| Infrastructure | Container | Registry | ECR Repository | No ❌ | -| Infrastructure | Database | Data Warehouse | Redshift Cluster | No ❌ | -| Infrastructure | Database | NoSQL | DynamoDB Table | No ❌ | -| Infrastructure | Database | Relational | RDS Cluster | No ❌ | -| Infrastructure | Database | Relational | RDS Instance | Yes ✅ | -| Infrastructure | Database | Search | Elasticsearch Domain | No ❌ | -| Infrastructure | Integration | API | API Gateway Resource | No ❌ | -| Infrastructure | Integration | API | API Gateway REST API | No ❌ | -| Infrastructure | Integration | API | API Gateway Stage | No ❌ | -| Infrastructure | Integration | Event Source | Lambda Event Source Mapping | Yes ✅ | -| Infrastructure | Integration | Message Queue | SQS Queue | No ❌ | -| Infrastructure | Management | Cloud Account | Cloud Service Provider Account | No ❌ | -| Infrastructure | Management | Configuration | Config Configuration Recorder | No ❌ | -| Infrastructure | Management | Configuration | Config Delivery Channel | No ❌ | -| Infrastructure | Management | Inventory | Systems Manager Instance | No ❌ | -| Infrastructure | Management | Patch | Systems Manager Instance Patch | No ❌ | -| Infrastructure | Messaging | Notification Service | SNS Topic | Yes ✅ | -| Infrastructure | Network | DNS | DNS Record | No ❌ | -| Infrastructure | Network | DNS | Nameserver | No ❌ | -| Infrastructure | Network | DNS | Route53 DNS Record | No ❌ | -| Infrastructure | Network | DNS | Route53 DNS Zone | No ❌ | -| Infrastructure | Network | Endpoint | Network Endpoint | No ❌ | -| Infrastructure | Network | Firewall Rule | Inbound IP Permission | No ❌ | -| Infrastructure | Network | Firewall Rule | IP Rule | No ❌ | -| Infrastructure | Network | Firewall | EC2 Security Group | Yes ✅ | -| Infrastructure | Network | Gateway | Internet Gateway | Yes ✅ | -| Infrastructure | Network | Gateway | NAT Gateway | Yes ✅ | -| Infrastructure | Network | Interface | EC2 Network Interface | Yes ✅ | -| Infrastructure | Network | IP Address Range | VPC CIDR Block | No ❌ | -| Infrastructure | Network | IP Address Range | VPC IPv4 CIDR Block | No ❌ | -| Infrastructure | Network | IP Address Range | VPC IPv6 CIDR Block | No ❌ | -| Infrastructure | Network | IP Address | EC2 Private IP | No ❌ | -| Infrastructure | Network | IP Address | Elastic IP | No ❌ | -| Infrastructure | Network | IP Address | IP Address | No ❌ | -| Infrastructure | Network | Load Balancer | ELBv2 Listener | No ❌ | -| Infrastructure | Network | Load Balancer | Elastic Load Balancer | Yes ✅ | -| Infrastructure | Network | Load Balancer | Elastic Load Balancer v2 | Yes ✅ | -| Infrastructure | Network | Load Balancer | ELB Listener | No ❌ | -| Infrastructure | Network | Peering | VPC Peering Connection | Yes ✅ | -| Infrastructure | Network | Subnet | DB Subnet Group | No ❌ | -| Infrastructure | Network | Subnet | EC2 Subnet | Yes ✅ | -| Infrastructure | Network | Virtual Network | Transit Gateway | Yes ✅ | -| Infrastructure | Network | Virtual Network | Transit Gateway Attachment | Yes ✅ | -| Infrastructure | Network | Virtual Network | VPC | Yes ✅ | -| Infrastructure | Security | Encryption | KMS Key | No ❌ | -| Infrastructure | Security | Encryption | KMS Key Alias | No ❌ | -| Infrastructure | Security | Secrets Management | Secrets Manager Secret | No ❌ | -| Infrastructure | Security | Security Management | Security Hub | No ❌ | -| Infrastructure | Storage | Disk | EBS Volume | No ❌ | -| Infrastructure | Storage | Object Storage | S3 Bucket | Yes ✅ | -| Infrastructure | Storage | Snapshot | EBS Snapshot | No ❌ | -| Infrastructure | Storage | Snapshot | RDS Snapshot | No ❌ | +| Category | Old Type | Type | Implemented? | +|---|---|---|---| +| Access Management | IAM Policy | AWS IAM Policy | Yes ✅ | +| Access Management | S3 Access Control List | AWS S3 Access Control List | No ❌ | +| Database | RDS Instance | AWS RDS Instance | Yes ✅ | +| FaaS | Lambda Event Source Mapping | AWS Lambda Event Source Mapping | Yes ✅ | +| FaaS | Lambda Function | AWS Lambda Function | Yes ✅ | +| FaaS | Lambda Layer | AWS Lambda Layer | Yes ✅ | +| Firewall | EC2 Security Group | AWS EC2 Security Group | Yes ✅ | +| Gateway | Internet Gateway | AWS Internet Gateway | Yes ✅ | +| Gateway | NAT Gateway | AWS NAT Gateway | Yes ✅ | +| Gateway | Transit Gateway | AWS Transit Gateway | Yes ✅ | +| Gateway | Transit Gateway Attachment | AWS Transit Gateway Attachment | Yes ✅ | +| Host | EC2 Instance | AWS EC2 Instance | Yes ✅ | +| Identity | Access Key | | No ❌ | +| Identity | API Gateway Client Certificate | | No ❌ | +| Identity | IAM User | AWS IAM User | Yes ✅ | +| Identity | EC2 Key Pair | | No ❌ | +| Identity | IAM Group | | No ❌ | +| Identity | IAM Policy Statement | | No ❌ | +| Identity | IAM Principal | | No ❌ | +| Identity | KMS Key Grant | | No ❌ | +| Identity | S3 Bucket Policy Statement | | No ❌ | +| Infrastructure | API Gateway Resource | | No ❌ | +| Infrastructure | API Gateway REST API | | No ❌ | +| Infrastructure | API Gateway Stage | | No ❌ | +| Infrastructure | Auto Scaling Group | | No ❌ | +| Infrastructure | Cloud Service Provider Account | | No ❌ | +| Infrastructure | Config Configuration Recorder | | No ❌ | +| Infrastructure | Config Delivery Channel | | No ❌ | +| Infrastructure | DB Subnet Group | | No ❌ | +| Infrastructure | DNS Record | | No ❌ | +| Infrastructure | DynamoDB Table | | No ❌ | +| Infrastructure | EBS Snapshot | | No ❌ | +| Infrastructure | EBS Volume | | No ❌ | +| Infrastructure | EC2 AMI | | No ❌ | +| Infrastructure | EC2 Private IP | | No ❌ | +| Infrastructure | EC2 Reserved Instance | | No ❌ | +| Infrastructure | ECR Image | | No ❌ | +| Infrastructure | ECR Repository | | No ❌ | +| Infrastructure | ECR Repository Image | | No ❌ | +| Infrastructure | ECS Cluster | | No ❌ | +| Infrastructure | ECS Container | | No ❌ | +| Infrastructure | ECS Container Definition | | No ❌ | +| Infrastructure | ECS Container Instance | | No ❌ | +| Infrastructure | ECS Service | | No ❌ | +| Infrastructure | ECS Task | | No ❌ | +| Infrastructure | ECS Task Definition | | No ❌ | +| Infrastructure | EKS Cluster | | No ❌ | +| Infrastructure | ELBv2 Listener | | No ❌ | +| Infrastructure | Elastic IP | | No ❌ | +| Infrastructure | Elasticsearch Domain | | No ❌ | +| Infrastructure | ELB Listener | | No ❌ | +| Infrastructure | EMR Cluster | | No ❌ | +| Infrastructure | Inbound IP Permission | | No ❌ | +| Infrastructure | IP Address | | No ❌ | +| Infrastructure | IP Rule | | No ❌ | +| Infrastructure | KMS Key | | No ❌ | +| Infrastructure | KMS Key Alias | | No ❌ | +| Infrastructure | Lambda Function Alias | | No ❌ | +| Infrastructure | Launch Configuration | | No ❌ | +| Infrastructure | Launch Template | | No ❌ | +| Infrastructure | Launch Template Version | | No ❌ | +| Infrastructure | Nameserver | | No ❌ | +| Infrastructure | Network Endpoint | | No ❌ | +| Infrastructure | RDS Cluster | | No ❌ | +| Infrastructure | RDS Snapshot | | No ❌ | +| Infrastructure | Redshift Cluster | | No ❌ | +| Infrastructure | Route53 DNS Record | | No ❌ | +| Infrastructure | Route53 DNS Zone | | No ❌ | +| Infrastructure | Secrets Manager Secret | | No ❌ | +| Infrastructure | Security Hub | | No ❌ | +| Infrastructure | SQS Queue | | No ❌ | +| Infrastructure | Systems Manager Instance | | No ❌ | +| Infrastructure | Systems Manager Instance Patch | | No ❌ | +| Infrastructure | VPC CIDR Block | | No ❌ | +| Infrastructure | VPC IPv4 CIDR Block | | No ❌ | +| Infrastructure | VPC IPv6 CIDR Block | | No ❌ | +| Load Balancer | Elastic Load Balancer | AWS Elastic Load Balancer | Yes ✅ | +| Load Balancer | Elastic Load Balancer v2 | AWS Elastic Load Balancer v2 | Yes ✅ | +| Messaging Service | SNS Topic | AWS SNS Topic | Yes ✅ | +| Networking | EC2 Network Interface | AWS EC2 Network Interface | Yes ✅ | +| Networking | EC2 Subnet | AWS EC2 Subnet | Yes ✅ | +| Networking | VPC | AWS VPC | Yes ✅ | +| Networking | VPC Peering Connection | AWS VPC Peering Connection | Yes ✅ | +| Service Account | IAM Role | AWS IAM Role | Yes ✅ | +| Storage Bucket | S3 Bucket | AWS S3 Bucket | Yes ✅ |
## AZURE Resources -**Progress: 31% (16/51)** -Identity: 12% (1/8) -Infrastructure: 34% (15/43) +**Progress: 33% (18/54)** +Access Management: 100% (3/3) +Container Registry: 100% (1/1) +Database: 100% (3/3) +Host: 100% (1/1) +Identity: 9% (1/11) +Infrastructure: 7% (2/28) +Messaging Service: 100% (2/2) +Private Endpoint: 100% (1/1) +Snapshot: 100% (1/1) +Storage Bucket: 100% (1/1) +Volume: 100% (1/1) +Web Service: 100% (1/1)
Full table -| Category | SubCategory | Type | SubType | Implemented? | -|---|---|---|---|---| -| Identity | Access Management | Role Assignment | Azure Role Assignment | No ❌ | -| Identity | Access Management | Role | Azure Role | No ❌ | -| Identity | Application | Application | Azure AD Application | No ❌ | -| Identity | Digital Identity | Administrator | Azure Server AD Administrator | No ❌ | -| Identity | Digital Identity | Principal | Azure Principal | Yes ✅ | -| Identity | Directory | Group | Azure AD Group | No ❌ | -| Identity | Directory | User | Azure AD User | No ❌ | -| Identity | Service Identity | Service Principal | Azure AD Service Principal | No ❌ | -| Infrastructure | Application Integration | Message Queue | Azure Storage Queue | Yes ✅ | -| Infrastructure | Application Integration | Message Queue | Azure Storage Queue Service | Yes ✅ | -| Infrastructure | Application | Web Application | Azure App Service | Yes ✅ | -| Infrastructure | Compute | Virtual Machine | Azure Virtual Machine | Yes ✅ | -| Infrastructure | Container | Registry | Azure Container Registry | Yes ✅ | -| Infrastructure | Database | Backup and Recovery | Azure Recoverable Database | No ❌ | -| Infrastructure | Database | Backup and Recovery | Azure Restorable Dropped Database | No ❌ | -| Infrastructure | Database | Backup and Recovery | Azure Restore Point | No ❌ | -| Infrastructure | Database | High Availability | Azure Cosmos DB Account Failover Policy | No ❌ | -| Infrastructure | Database | High Availability | Azure Failover Group | No ❌ | -| Infrastructure | Database | NoSQL Database | Azure Cosmos DB Account | No ❌ | -| Infrastructure | Database | NoSQL Database | Azure Cosmos DB Cassandra Keyspace | No ❌ | -| Infrastructure | Database | NoSQL Database | Azure Cosmos DB Cassandra Table | No ❌ | -| Infrastructure | Database | NoSQL Database | Azure Cosmos DB Location | No ❌ | -| Infrastructure | Database | NoSQL Database | Azure Cosmos DB MongoDB Collection | No ❌ | -| Infrastructure | Database | NoSQL Database | Azure Cosmos DB MongoDB Database | No ❌ | -| Infrastructure | Database | NoSQL Database | Azure Cosmos DB SQL Container | No ❌ | -| Infrastructure | Database | NoSQL Database | Azure Cosmos DB SQL Database | No ❌ | -| Infrastructure | Database | NoSQL Database | Azure Cosmos DB Table Resource | No ❌ | -| Infrastructure | Database | NoSQL Database | Azure Storage Table | No ❌ | -| Infrastructure | Database | NoSQL Database | Azure Storage Table Service | No ❌ | -| Infrastructure | Database | Relational | Azure SQL Database | Yes ✅ | -| Infrastructure | Database | Relational | Azure SQL Server | Yes ✅ | -| Infrastructure | Database | Replication | Azure Replication Link | No ❌ | -| Infrastructure | Database | Scalability | Azure Elastic Pool | Yes ✅ | -| Infrastructure | Management | Cloud Account | Azure Subscription | Yes ✅ | -| Infrastructure | Management | Cloud Account | Azure Tenant | Yes ✅ | -| Infrastructure | Management | Resource Group | Azure Resource Group | Yes ✅ | -| Infrastructure | Network | DNS | Azure Server DNS Alias | No ❌ | -| Infrastructure | Network | Network Security | Azure Cosmos DB Virtual Network Rule | No ❌ | -| Infrastructure | Network | Private Connectivity | Azure Cosmos DB Private Endpoint Connection | No ❌ | -| Infrastructure | Security | Cross-Origin Resource Sharing | Azure Cosmos DB CORS Policy | No ❌ | -| Infrastructure | Security | Encryption | Azure Transparent Data Encryption | No ❌ | -| Infrastructure | Security | Threat Detection | Azure Database Threat Detection Policy | No ❌ | -| Infrastructure | Serverless | Function | Azure Function | No ❌ | -| Infrastructure | Storage | Disk | Azure Data Disk | No ❌ | -| Infrastructure | Storage | Disk | Azure Disk | Yes ✅ | -| Infrastructure | Storage | File Storage | Azure Storage File Service | No ❌ | -| Infrastructure | Storage | File Storage | Azure Storage File Share | No ❌ | -| Infrastructure | Storage | Object Storage | Azure Storage Blob Container | No ❌ | -| Infrastructure | Storage | Object Storage | Azure Storage Blob Service | Yes ✅ | -| Infrastructure | Storage | Snapshot | Azure Snapshot | Yes ✅ | -| Infrastructure | Storage | Storage | Azure Storage Account | Yes ✅ | +| Category | Old Type | Type | Implemented? | +|---|---|---|---| +| Access Management | Azure Resource Group | Azure Resource Group | Yes ✅ | +| Access Management | Azure Subscription | Azure Subscription | Yes ✅ | +| Access Management | Azure Tenant | Azure Tenant | Yes ✅ | +| Container Registry | Azure Container Registry | Azure Container Registry | Yes ✅ | +| Database | Azure Elastic Pool | Azure Elastic Pool | Yes ✅ | +| Database | Azure SQL Database | Azure SQL Database | Yes ✅ | +| Database | Azure SQL Server | Azure SQL Server | Yes ✅ | +| Host | Azure Virtual Machine | Azure Virtual Machine | Yes ✅ | +| Identity | Access Key | | No ❌ | +| Identity | API Gateway Client Certificate | | No ❌ | +| Identity | Azure AD Application | | No ❌ | +| Identity | Azure AD Group | | No ❌ | +| Identity | Azure AD Service Principal | | No ❌ | +| Identity | Azure AD User | | No ❌ | +| Identity | Azure Principal | Azure Principal | Yes ✅ | +| Identity | Azure Role | | No ❌ | +| Identity | Azure Role Assignment | | No ❌ | +| Identity | Azure Server AD Administrator | | No ❌ | +| Identity | EC2 Key Pair | | No ❌ | +| Infrastructure | Azure Cosmos DB Account | Azure Cosmos DB Account | Yes ✅ | +| Infrastructure | Azure Cosmos DB Account Failover Policy | | No ❌ | +| Infrastructure | Azure Cosmos DB Cassandra Keyspace | | No ❌ | +| Infrastructure | Azure Cosmos DB Cassandra Table | | No ❌ | +| Infrastructure | Azure Cosmos DB CORS Policy | | No ❌ | +| Infrastructure | Azure Cosmos DB Location | | No ❌ | +| Infrastructure | Azure Cosmos DB MongoDB Collection | | No ❌ | +| Infrastructure | Azure Cosmos DB MongoDB Database | | No ❌ | +| Infrastructure | Azure Cosmos DB Private Endpoint Connection | | No ❌ | +| Infrastructure | Azure Cosmos DB SQL Container | | No ❌ | +| Infrastructure | Azure Cosmos DB SQL Database | Azure Cosmos DB SQL Database | Yes ✅ | +| Infrastructure | Azure Cosmos DB Table Resource | | No ❌ | +| Infrastructure | Azure Cosmos DB Virtual Network Rule | | No ❌ | +| Infrastructure | Azure Data Disk | | No ❌ | +| Infrastructure | Azure Database Threat Detection Policy | | No ❌ | +| Infrastructure | Azure Failover Group | | No ❌ | +| Infrastructure | Azure Function | | No ❌ | +| Infrastructure | Azure Recoverable Database | | No ❌ | +| Infrastructure | Azure Replication Link | | No ❌ | +| Infrastructure | Azure Restorable Dropped Database | | No ❌ | +| Infrastructure | Azure Restore Point | | No ❌ | +| Infrastructure | Azure Server DNS Alias | | No ❌ | +| Infrastructure | Azure Storage Blob Container | | No ❌ | +| Infrastructure | Azure Storage File Service | | No ❌ | +| Infrastructure | Azure Storage File Share | | No ❌ | +| Infrastructure | Azure Storage Table | | No ❌ | +| Infrastructure | Azure Storage Table Service | | No ❌ | +| Infrastructure | Azure Transparent Data Encryption | | No ❌ | +| Messaging Service | Azure Storage Queue | Azure Storage Queue | Yes ✅ | +| Messaging Service | Azure Storage Queue Service | Azure Storage Queue Service | Yes ✅ | +| Private Endpoint | Azure Storage Account | Azure Storage Account | Yes ✅ | +| Snapshot | Azure Snapshot | Azure Snapshot | Yes ✅ | +| Storage Bucket | Azure Storage Blob Service | Azure Storage Blob Service | Yes ✅ | +| Volume | Azure Disk | Azure Disk | Yes ✅ | +| Web Service | Azure App Service | Azure App Service | Yes ✅ |
## GCP Resources **Progress: 56% (14/25)** -Identity: 75% (3/4) -Infrastructure: 55% (11/20) +Access Management: 100% (2/2) +Account: 100% (1/1) +Container Service: 100% (1/1) +FaaS: 100% (1/1) +Firewall: 100% (1/1) +Host: 100% (1/1) +Identity: 0% (0/1) +Infrastructure: 0% (0/9) +Load Balancer: 100% (1/1) Management: 0% (0/1) +Orchestrator: 100% (1/1) +Organization: 100% (2/2) +Service Usage Technology: 100% (1/1) +Storage Bucket: 100% (1/1) +Subnet: 100% (1/1)
Full table -| Category | SubCategory | Type | SubType | Implemented? | -|---|---|---|---|---| -| Identity | Access Management | IAM Policy | GCP IAM Policy | No ❌ | -| Identity | Access Management | IAM Role | GCP IAM Role | Yes ✅ | -| Identity | Service Identity | Service Account Key | GCP Service Account Key | Yes ✅ | -| Identity | Service Identity | Service Account | GCP Service Account | Yes ✅ | -| Infrastructure | Compute | Virtual Machine | GCP Instance | Yes ✅ | -| Infrastructure | Container | Orchestration | GKE Cluster | Yes ✅ | -| Infrastructure | Container | Serverless | GCP Cloud Run Service | Yes ✅ | -| Infrastructure | Management | Cloud Account | GCP Organization | Yes ✅ | -| Infrastructure | Management | Cloud Account | GCP Project | Yes ✅ | -| Infrastructure | Management | Resource Hierarchy | GCP Folder | Yes ✅ | -| Infrastructure | Network | DNS | GCP DNS Record Set | No ❌ | -| Infrastructure | Network | DNS | GCP DNS Zone | No ❌ | -| Infrastructure | Network | Firewall Rule | GCP IP Rule | No ❌ | -| Infrastructure | Network | Firewall | GCP Firewall | Yes ✅ | -| Infrastructure | Network | Firewall | GCP Network Tag | No ❌ | -| Infrastructure | Network | IP Address Range | IP Range | No ❌ | -| Infrastructure | Network | Load Balancing | GCP Compute Target Pool | No ❌ | -| Infrastructure | Network | Load Balancing | GCP Forwarding Rule | Yes ✅ | -| Infrastructure | Network | Network Interface | GCP Network Interface | No ❌ | -| Infrastructure | Network | Network Interface | GCP Network Interface Access Config | No ❌ | -| Infrastructure | Network | Subnet | GCP Subnet | Yes ✅ | -| Infrastructure | Network | Virtual Network | GCP VPC | No ❌ | -| Infrastructure | Serverless | Function | GCP Cloud Function | Yes ✅ | -| Infrastructure | Storage | Object Storage | GCP Bucket | Yes ✅ | -| Management | Resource Management | Label | GCP Bucket Label | No ❌ | +| Category | Old Type | Type | Implemented? | +|---|---|---|---| +| Access Management | GCP Service Account | GCP Service Account | Yes ✅ | +| Access Management | GCP Service Account Key | GCP Service Account Key | Yes ✅ | +| Account | GCP Project | GCP Project | Yes ✅ | +| Container Service | GCP Cloud Run Service | GCP Cloud Run Service | Yes ✅ | +| FaaS | GCP Cloud Function | GCP Cloud Function | Yes ✅ | +| Firewall | GCP Firewall | GCP Firewall | Yes ✅ | +| Host | GCP Instance | GCP Compute Instance | Yes ✅ | +| Identity | GCP IAM Policy | | No ❌ | +| Infrastructure | GCP Compute Target Pool | | No ❌ | +| Infrastructure | GCP DNS Record Set | | No ❌ | +| Infrastructure | GCP DNS Zone | | No ❌ | +| Infrastructure | GCP IP Rule | | No ❌ | +| Infrastructure | GCP Network Interface | | No ❌ | +| Infrastructure | GCP Network Interface Access Config | | No ❌ | +| Infrastructure | GCP Network Tag | | No ❌ | +| Infrastructure | GCP VPC | | No ❌ | +| Infrastructure | IP Range | | No ❌ | +| Load Balancer | GCP Forwarding Rule | GCP Load Balancing Forwarding Rule | Yes ✅ | +| Management | GCP Bucket Label | | No ❌ | +| Orchestrator | GKE Cluster | GCP Kubernetes Engine (GKE) Cluster | Yes ✅ | +| Organization | GCP Folder | GCP Folder | Yes ✅ | +| Organization | GCP Organization | GCP Organization | Yes ✅ | +| Service Usage Technology | GCP IAM Role | GCP IAM Role | Yes ✅ | +| Storage Bucket | GCP Bucket | GCP Bucket | Yes ✅ | +| Subnet | GCP Subnet | GCP Subnet | Yes ✅ |
diff --git a/internal/inventory/asset.go b/internal/inventory/asset.go index 99604dee43..05fd3a7aa5 100644 --- a/internal/inventory/asset.go +++ b/internal/inventory/asset.go @@ -17,137 +17,41 @@ package inventory -// AssetCategory is used to build the document index. Use only numbers, letters and dashes (-) -type AssetCategory string +import "github.com/samber/lo" -const ( - CategoryIdentity AssetCategory = "identity" - CategoryInfrastructure AssetCategory = "infrastructure" -) - -// AssetSubCategory is used to build the document index. Use only numbers, letters and dashes (-) -type AssetSubCategory string +// AssetCategory is used to build the document index. +type AssetCategory string const ( - SubCategoryAccessManagement AssetSubCategory = "access-management" - SubCategoryApplication AssetSubCategory = "application" - SubCategoryApplicationIntegration AssetSubCategory = "application-integration" - SubCategoryAuthorization AssetSubCategory = "authorization" - SubCategoryCompute AssetSubCategory = "compute" - SubCategoryContainer AssetSubCategory = "container" - SubCategoryDatabase AssetSubCategory = "database" - SubCategoryDigitalIdentity AssetSubCategory = "digital-identity" - SubCategoryIntegration AssetSubCategory = "integration" - SubCategoryManagement AssetSubCategory = "management" - SubCategoryMessaging AssetSubCategory = "messaging" - SubCategoryNetwork AssetSubCategory = "network" - SubCategoryServerless AssetSubCategory = "serverless" - SubCategoryServiceIdentity AssetSubCategory = "service-identity" - SubCategoryStorage AssetSubCategory = "storage" + CategoryAccessManagement AssetCategory = "Access Management" + CategoryAccount AssetCategory = "Account" + CategoryContainerRegistry AssetCategory = "Container Registry" + CategoryContainerService AssetCategory = "Container Service" + CategoryDatabase AssetCategory = "Database" + CategoryFaaS AssetCategory = "FaaS" + CategoryFirewall AssetCategory = "Firewall" + CategoryGateway AssetCategory = "Gateway" + CategoryHost AssetCategory = "Host" + CategoryIdentity AssetCategory = "Identity" + CategoryInfrastructure AssetCategory = "Infrastructure" + CategoryLoadBalancer AssetCategory = "Load Balancer" + CategoryMessagingService AssetCategory = "Messaging Service" + CategoryNetworking AssetCategory = "Networking" + CategoryOrchestrator AssetCategory = "Orchestrator" + CategoryOrganization AssetCategory = "Organization" + CategoryPrivateEndpoint AssetCategory = "Private Endpoint" + CategoryServiceAccount AssetCategory = "Service Account" + CategoryServiceUsageTechnology AssetCategory = "Service Usage Technology" + CategorySnapshot AssetCategory = "Snapshot" + CategoryStorageBucket AssetCategory = "Storage Bucket" + CategorySubnet AssetCategory = "Subnet" + CategoryVolume AssetCategory = "Volume" + CategoryWebService AssetCategory = "Web Service" ) -// AssetType is used to build the document index. Use only numbers, letters and dashes (-) +// AssetType is used to build the document index. type AssetType string -const ( - TypeAcl AssetType = "acl" - TypeCloudAccount AssetType = "cloud-account" - TypeDisk AssetType = "disk" - TypeEventSource AssetType = "event-source" - TypeFirewall AssetType = "firewall" - TypeGateway AssetType = "gateway" - TypeInterface AssetType = "interface" - TypeLoadBalancer AssetType = "load-balancer" - TypeMessageQueue AssetType = "message-queue" - TypeNoSQLDatabase AssetType = "nosql-database" - TypeNotificationService AssetType = "notification-service" - TypeObjectStorage AssetType = "object-storage" - TypePeering AssetType = "peering" - TypePolicy AssetType = "policy" - TypePrincipal AssetType = "principal" - TypeRegistry AssetType = "registry" - TypeRelationalDatabase AssetType = "relational" - TypeResourceGroup AssetType = "resource-group" - TypeRole AssetType = "role" - TypeScalability AssetType = "scalability" - TypeServerless AssetType = "serverless" - TypeServiceAccount AssetType = "service-account" - TypeServiceAccountKey AssetType = "service-account-key" - TypeSnapshot AssetType = "snapshot" - TypeStorage AssetType = "storage" - TypeSubnet AssetType = "subnet" - TypeUser AssetType = "user" - TypeVirtualMachine AssetType = "virtual-machine" - TypeVirtualNetwork AssetType = "virtual-network" - TypeWebApplication AssetType = "web-application" - TypeResourceHierarchy AssetType = "resource-hierarchy" - TypeOrchestration AssetType = "orchestration" - TypeFunction AssetType = "function" - TypeLoadBalancing AssetType = "load-balancing" - TypeIamRole AssetType = "iam-role" -) - -// AssetSubType is used to build the document index. Use only numbers, letters and dashes (-) -type AssetSubType string - -const ( - SubTypeAzureAppService AssetSubType = "azure-app-service" - SubTypeAzureContainerRegistry AssetSubType = "azure-container-registry" - SubTypeAzureCosmosDBAccount AssetSubType = "azure-cosmos-db-account" - SubTypeAzureCosmosDBSQLDatabase AssetSubType = "azure-cosmos-db-sql-database" - SubTypeAzureDisk AssetSubType = "azure-disk" - SubTypeAzureElasticPool AssetSubType = "azure-elastic-pool" - SubTypeAzurePrincipal AssetSubType = "azure-principal" - SubTypeAzureResourceGroup AssetSubType = "azure-resource-group" - SubTypeAzureSQLDatabase AssetSubType = "azure-sql-database" - SubTypeAzureSQLServer AssetSubType = "azure-sql-server" - SubTypeAzureSnapshot AssetSubType = "azure-snapshot" - SubTypeAzureStorageAccount AssetSubType = "azure-storage-account" - SubTypeAzureStorageBlobService AssetSubType = "azure-storage-blob-service" - SubTypeAzureStorageQueue AssetSubType = "azure-storage-queue" - SubTypeAzureStorageQueueService AssetSubType = "azure-storage-queue-service" - SubTypeAzureSubscription AssetSubType = "azure-subscription" - SubTypeAzureTenant AssetSubType = "azure-tenant" - SubTypeAzureVirtualMachine AssetSubType = "azure-virtual-machine" - SubTypeEC2 AssetSubType = "ec2-instance" - SubTypeEC2NetworkInterface AssetSubType = "ec2-network-interface" - SubTypeEC2Subnet AssetSubType = "ec2-subnet" - SubTypeELBv1 AssetSubType = "elastic-load-balancer" - SubTypeELBv2 AssetSubType = "elastic-load-balancer-v2" - SubTypeIAMPolicy AssetSubType = "iam-policy" - SubTypeIAMRole AssetSubType = "iam-role" - SubTypeIAMUser AssetSubType = "iam-user" - SubTypeInternetGateway AssetSubType = "internet-gateway" - SubTypeLambdaAlias AssetSubType = "lambda-function-alias" - SubTypeLambdaEventSourceMapping AssetSubType = "lambda-event-source-mapping" - SubTypeLambdaFunction AssetSubType = "lambda-function" - SubTypeLambdaLayer AssetSubType = "lambda-layer" - SubTypeNatGateway AssetSubType = "nat-gateway" - SubTypeRDS AssetSubType = "rds-instance" - SubTypeS3 AssetSubType = "s3-bucket" - SubTypeSNSTopic AssetSubType = "sns-topic" - SubTypeSecurityGroup AssetSubType = "ec2-security-group" - SubTypeTransitGateway AssetSubType = "transit-gateway" - SubTypeTransitGatewayAttachment AssetSubType = "transit-gateway-attachment" - SubTypeVpc AssetSubType = "vpc" - SubTypeVpcAcl AssetSubType = "s3-access-control-list" - SubTypeVpcPeeringConnection AssetSubType = "vpc-peering-connection" - SubTypeGcpProject AssetSubType = "gcp-project" - SubTypeGcpInstance AssetSubType = "gcp-instance" - SubTypeGcpSubnet AssetSubType = "gcp-subnet" - SubTypeGcpFirewall AssetSubType = "gcp-firewall" - SubTypeGcpBucket AssetSubType = "gcp-bucket" - SubTypeGcpOrganization AssetSubType = "gcp-organization" - SubTypeGcpFolder AssetSubType = "gcp-folder" - SubTypeGcpServiceAccount AssetSubType = "gcp-service-account" - SubTypeGcpServiceAccountKey AssetSubType = "gcp-service-account-key" - SubTypeGcpGkeCluster AssetSubType = "gke-cluster" - SubTypeGcpForwardingRule AssetSubType = "gcp-forwarding-rule" - SubTypeGcpCloudFunction AssetSubType = "gcp-cloud-function" - SubTypeGcpCloudRunService AssetSubType = "gcp-cloud-run-service" - SubTypeGcpIamRole AssetSubType = "gcp-iam-role" -) - const ( AwsCloudProvider = "aws" AzureCloudProvider = "azure" @@ -156,190 +60,145 @@ const ( // AssetClassification holds the taxonomy of an asset type AssetClassification struct { - Category AssetCategory `json:"category"` - SubCategory AssetSubCategory `json:"sub_category"` - Type AssetType `json:"type"` - SubType AssetSubType `json:"sub_type"` + Category AssetCategory `json:"category"` + Type AssetType `json:"type"` } // AssetClassifications below are used to generate // 'internal/inventory/ASSETS.md'. Please keep formatting consistent. var ( // AWS - AssetClassificationAwsEc2Instance = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryCompute, Type: TypeVirtualMachine, SubType: SubTypeEC2} - AssetClassificationAwsElbV1 = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryNetwork, Type: TypeLoadBalancer, SubType: SubTypeELBv1} - AssetClassificationAwsElbV2 = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryNetwork, Type: TypeLoadBalancer, SubType: SubTypeELBv2} - AssetClassificationAwsIamPolicy = AssetClassification{Category: CategoryIdentity, SubCategory: SubCategoryDigitalIdentity, Type: TypePolicy, SubType: SubTypeIAMPolicy} - AssetClassificationAwsIamRole = AssetClassification{Category: CategoryIdentity, SubCategory: SubCategoryDigitalIdentity, Type: TypeRole, SubType: SubTypeIAMRole} - AssetClassificationAwsIamUser = AssetClassification{Category: CategoryIdentity, SubCategory: SubCategoryDigitalIdentity, Type: TypeUser, SubType: SubTypeIAMUser} - AssetClassificationAwsLambdaEventSourceMapping = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryIntegration, Type: TypeEventSource, SubType: SubTypeLambdaEventSourceMapping} - AssetClassificationAwsLambdaFunction = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryCompute, Type: TypeServerless, SubType: SubTypeLambdaFunction} - AssetClassificationAwsLambdaLayer = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryCompute, Type: TypeServerless, SubType: SubTypeLambdaLayer} - AssetClassificationAwsInternetGateway = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryNetwork, Type: TypeGateway, SubType: SubTypeInternetGateway} - AssetClassificationAwsNatGateway = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryNetwork, Type: TypeGateway, SubType: SubTypeNatGateway} - AssetClassificationAwsNetworkAcl = AssetClassification{Category: CategoryIdentity, SubCategory: SubCategoryAuthorization, Type: TypeAcl, SubType: SubTypeVpcAcl} - AssetClassificationAwsNetworkInterface = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryNetwork, Type: TypeInterface, SubType: SubTypeEC2NetworkInterface} - AssetClassificationAwsSecurityGroup = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryNetwork, Type: TypeFirewall, SubType: SubTypeSecurityGroup} - AssetClassificationAwsSubnet = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryNetwork, Type: TypeSubnet, SubType: SubTypeEC2Subnet} - AssetClassificationAwsTransitGateway = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryNetwork, Type: TypeVirtualNetwork, SubType: SubTypeTransitGateway} - AssetClassificationAwsTransitGatewayAttachment = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryNetwork, Type: TypeVirtualNetwork, SubType: SubTypeTransitGatewayAttachment} - AssetClassificationAwsVpcPeeringConnection = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryNetwork, Type: TypePeering, SubType: SubTypeVpcPeeringConnection} - AssetClassificationAwsVpc = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryNetwork, Type: TypeVirtualNetwork, SubType: SubTypeVpc} - AssetClassificationAwsRds = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryDatabase, Type: TypeRelationalDatabase, SubType: SubTypeRDS} - AssetClassificationAwsS3Bucket = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryStorage, Type: TypeObjectStorage, SubType: SubTypeS3} - AssetClassificationAwsSnsTopic = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryMessaging, Type: TypeNotificationService, SubType: SubTypeSNSTopic} + AssetClassificationAwsEc2Instance = AssetClassification{CategoryHost, "AWS EC2 Instance"} + AssetClassificationAwsElbV1 = AssetClassification{CategoryLoadBalancer, "AWS Elastic Load Balancer"} + AssetClassificationAwsElbV2 = AssetClassification{CategoryLoadBalancer, "AWS Elastic Load Balancer v2"} + AssetClassificationAwsIamPolicy = AssetClassification{CategoryAccessManagement, "AWS IAM Policy"} + AssetClassificationAwsIamRole = AssetClassification{CategoryServiceAccount, "AWS IAM Role"} + AssetClassificationAwsIamUser = AssetClassification{CategoryIdentity, "AWS IAM User"} + AssetClassificationAwsLambdaEventSourceMapping = AssetClassification{CategoryFaaS, "AWS Lambda Event Source Mapping"} + AssetClassificationAwsLambdaFunction = AssetClassification{CategoryFaaS, "AWS Lambda Function"} + AssetClassificationAwsLambdaLayer = AssetClassification{CategoryFaaS, "AWS Lambda Layer"} + AssetClassificationAwsInternetGateway = AssetClassification{CategoryGateway, "AWS Internet Gateway"} + AssetClassificationAwsNatGateway = AssetClassification{CategoryGateway, "AWS NAT Gateway"} + AssetClassificationAwsNetworkAcl = AssetClassification{CategoryNetworking, "AWS EC2 Network ACL"} + AssetClassificationAwsNetworkInterface = AssetClassification{CategoryNetworking, "AWS EC2 Network Interface"} + AssetClassificationAwsSecurityGroup = AssetClassification{CategoryFirewall, "AWS EC2 Security Group"} + AssetClassificationAwsSubnet = AssetClassification{CategoryNetworking, "AWS EC2 Subnet"} + AssetClassificationAwsTransitGateway = AssetClassification{CategoryGateway, "AWS Transit Gateway"} + AssetClassificationAwsTransitGatewayAttachment = AssetClassification{CategoryGateway, "AWS Transit Gateway Attachment"} + AssetClassificationAwsVpcPeeringConnection = AssetClassification{CategoryNetworking, "AWS VPC Peering Connection"} + AssetClassificationAwsVpc = AssetClassification{CategoryNetworking, "AWS VPC"} + AssetClassificationAwsRds = AssetClassification{CategoryDatabase, "AWS RDS Instance"} + AssetClassificationAwsS3Bucket = AssetClassification{CategoryStorageBucket, "AWS S3 Bucket"} + AssetClassificationAwsSnsTopic = AssetClassification{CategoryMessagingService, "AWS SNS Topic"} + // Azure - AssetClassificationAzureAppService = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryApplication, Type: TypeWebApplication, SubType: SubTypeAzureAppService} - AssetClassificationAzureContainerRegistry = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryContainer, Type: TypeRegistry, SubType: SubTypeAzureContainerRegistry} - AssetClassificationAzureCosmosDBAccount = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryDatabase, Type: TypeNoSQLDatabase, SubType: SubTypeAzureCosmosDBAccount} - AssetClassificationAzureCosmosDBSQLDatabase = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryDatabase, Type: TypeNoSQLDatabase, SubType: SubTypeAzureCosmosDBSQLDatabase} - AssetClassificationAzureDisk = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryStorage, Type: TypeDisk, SubType: SubTypeAzureDisk} - AssetClassificationAzureElasticPool = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryDatabase, Type: TypeScalability, SubType: SubTypeAzureElasticPool} - AssetClassificationAzureResourceGroup = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryManagement, Type: TypeResourceGroup, SubType: SubTypeAzureResourceGroup} - AssetClassificationAzureSQLDatabase = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryDatabase, Type: TypeRelationalDatabase, SubType: SubTypeAzureSQLDatabase} - AssetClassificationAzureSQLServer = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryDatabase, Type: TypeRelationalDatabase, SubType: SubTypeAzureSQLServer} - AssetClassificationAzureServicePrincipal = AssetClassification{Category: CategoryIdentity, SubCategory: SubCategoryDigitalIdentity, Type: TypePrincipal, SubType: SubTypeAzurePrincipal} - AssetClassificationAzureSnapshot = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryStorage, Type: TypeSnapshot, SubType: SubTypeAzureSnapshot} - AssetClassificationAzureStorageAccount = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryStorage, Type: TypeStorage, SubType: SubTypeAzureStorageAccount} - AssetClassificationAzureStorageBlobService = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryStorage, Type: TypeObjectStorage, SubType: SubTypeAzureStorageBlobService} - AssetClassificationAzureStorageQueue = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryApplicationIntegration, Type: TypeMessageQueue, SubType: SubTypeAzureStorageQueue} - AssetClassificationAzureStorageQueueService = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryApplicationIntegration, Type: TypeMessageQueue, SubType: SubTypeAzureStorageQueueService} - AssetClassificationAzureSubscription = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryManagement, Type: TypeCloudAccount, SubType: SubTypeAzureSubscription} - AssetClassificationAzureTenant = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryManagement, Type: TypeCloudAccount, SubType: SubTypeAzureTenant} - AssetClassificationAzureVirtualMachine = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryCompute, Type: TypeVirtualMachine, SubType: SubTypeAzureVirtualMachine} + AssetClassificationAzureAppService = AssetClassification{CategoryWebService, "Azure App Service"} + AssetClassificationAzureContainerRegistry = AssetClassification{CategoryContainerRegistry, "Azure Container Registry"} + AssetClassificationAzureCosmosDBAccount = AssetClassification{CategoryInfrastructure, "Azure Cosmos DB Account"} + AssetClassificationAzureCosmosDBSQLDatabase = AssetClassification{CategoryInfrastructure, "Azure Cosmos DB SQL Database"} + AssetClassificationAzureDisk = AssetClassification{CategoryVolume, "Azure Disk"} + AssetClassificationAzureElasticPool = AssetClassification{CategoryDatabase, "Azure Elastic Pool"} + AssetClassificationAzureResourceGroup = AssetClassification{CategoryAccessManagement, "Azure Resource Group"} + AssetClassificationAzureSQLDatabase = AssetClassification{CategoryDatabase, "Azure SQL Database"} + AssetClassificationAzureSQLServer = AssetClassification{CategoryDatabase, "Azure SQL Server"} + AssetClassificationAzureServicePrincipal = AssetClassification{CategoryIdentity, "Azure Principal"} + AssetClassificationAzureSnapshot = AssetClassification{CategorySnapshot, "Azure Snapshot"} + AssetClassificationAzureStorageAccount = AssetClassification{CategoryPrivateEndpoint, "Azure Storage Account"} + AssetClassificationAzureStorageBlobService = AssetClassification{CategoryStorageBucket, "Azure Storage Blob Service"} + AssetClassificationAzureStorageQueue = AssetClassification{CategoryMessagingService, "Azure Storage Queue"} + AssetClassificationAzureStorageQueueService = AssetClassification{CategoryMessagingService, "Azure Storage Queue Service"} + AssetClassificationAzureSubscription = AssetClassification{CategoryAccessManagement, "Azure Subscription"} + AssetClassificationAzureTenant = AssetClassification{CategoryAccessManagement, "Azure Tenant"} + AssetClassificationAzureVirtualMachine = AssetClassification{CategoryHost, "Azure Virtual Machine"} // GCP - AssetClassificationGcpProject = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryManagement, Type: TypeCloudAccount, SubType: SubTypeGcpProject} - AssetClassificationGcpOrganization = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryManagement, Type: TypeCloudAccount, SubType: SubTypeGcpOrganization} - AssetClassificationGcpFolder = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryManagement, Type: TypeResourceHierarchy, SubType: SubTypeGcpFolder} - AssetClassificationGcpInstance = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryCompute, Type: TypeVirtualMachine, SubType: SubTypeGcpInstance} - AssetClassificationGcpBucket = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryStorage, Type: TypeObjectStorage, SubType: SubTypeGcpBucket} - AssetClassificationGcpFirewall = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryNetwork, Type: TypeFirewall, SubType: SubTypeGcpFirewall} - AssetClassificationGcpSubnet = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryNetwork, Type: TypeSubnet, SubType: SubTypeGcpSubnet} - AssetClassificationGcpServiceAccount = AssetClassification{Category: CategoryIdentity, SubCategory: SubCategoryServiceIdentity, Type: TypeServiceAccount, SubType: SubTypeGcpServiceAccount} - AssetClassificationGcpServiceAccountKey = AssetClassification{Category: CategoryIdentity, SubCategory: SubCategoryServiceIdentity, Type: TypeServiceAccountKey, SubType: SubTypeGcpServiceAccountKey} - - AssetClassificationGcpGkeCluster = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryContainer, Type: TypeOrchestration, SubType: SubTypeGcpGkeCluster} - AssetClassificationGcpForwardingRule = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryNetwork, Type: TypeLoadBalancing, SubType: SubTypeGcpForwardingRule} - AssetClassificationGcpIamRole = AssetClassification{Category: CategoryIdentity, SubCategory: SubCategoryAccessManagement, Type: TypeIamRole, SubType: SubTypeGcpIamRole} - AssetClassificationGcpCloudFunction = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryServerless, Type: TypeFunction, SubType: SubTypeGcpCloudFunction} - AssetClassificationGcpCloudRunService = AssetClassification{Category: CategoryInfrastructure, SubCategory: SubCategoryContainer, Type: TypeServerless, SubType: SubTypeGcpCloudRunService} + AssetClassificationGcpProject = AssetClassification{CategoryAccount, "GCP Project"} + AssetClassificationGcpOrganization = AssetClassification{CategoryOrganization, "GCP Organization"} + AssetClassificationGcpFolder = AssetClassification{CategoryOrganization, "GCP Folder"} + AssetClassificationGcpInstance = AssetClassification{CategoryHost, "GCP Compute Instance"} + AssetClassificationGcpBucket = AssetClassification{CategoryStorageBucket, "GCP Bucket"} + AssetClassificationGcpFirewall = AssetClassification{CategoryFirewall, "GCP Firewall"} + AssetClassificationGcpSubnet = AssetClassification{CategorySubnet, "GCP Subnet"} + AssetClassificationGcpServiceAccount = AssetClassification{CategoryAccessManagement, "GCP Service Account"} + AssetClassificationGcpServiceAccountKey = AssetClassification{CategoryAccessManagement, "GCP Service Account Key"} + AssetClassificationGcpGkeCluster = AssetClassification{CategoryOrchestrator, "GCP Kubernetes Engine (GKE) Cluster"} + AssetClassificationGcpForwardingRule = AssetClassification{CategoryLoadBalancer, "GCP Load Balancing Forwarding Rule"} + AssetClassificationGcpIamRole = AssetClassification{CategoryServiceUsageTechnology, "GCP IAM Role"} + AssetClassificationGcpCloudFunction = AssetClassification{CategoryFaaS, "GCP Cloud Function"} + AssetClassificationGcpCloudRunService = AssetClassification{CategoryContainerService, "GCP Cloud Run Service"} ) // AssetEvent holds the whole asset type AssetEvent struct { - Asset Asset - Network *AssetNetwork - Cloud *AssetCloud - Host *AssetHost - IAM *AssetIAM - ResourcePolicies []AssetResourcePolicy + Entity Entity + Event Event + Network *Network + Cloud *Cloud + Host *Host + User *User + Labels map[string]string + RawAttributes *any } -// Asset contains the identifiers of the asset -type Asset struct { - Id []string `json:"id"` - RelatedEntityId []string `json:"related_entity_id"` - Name string `json:"name"` +// Entity contains the identifiers of the asset +type Entity struct { + Id string `json:"id"` + Name string `json:"name"` AssetClassification - Tags map[string]string `json:"tags"` - Raw any `json:"raw"` -} - -// AssetNetwork contains network information -type AssetNetwork struct { - Ipv6Address *string `json:"ipv6_address,omitempty"` - NetworkId *string `json:"network_id,omitempty"` - NetworkInterfaceIds []string `json:"network_interface_ids,omitempty"` - PrivateDnsName *string `json:"private_dns_name,omitempty"` - PrivateIpAddress *string `json:"private_ip_address,omitempty"` - PublicDnsName *string `json:"public_dns_name,omitempty"` - PublicIpAddress *string `json:"public_ip_address,omitempty"` - RouteTableIds []string `json:"route_table_ids,omitempty"` - SecurityGroupIds []string `json:"security_group_ids,omitempty"` - SubnetIds []string `json:"subnet_ids,omitempty"` - TransitGatewayIds []string `json:"transit_gateway_ids,omitempty"` - VpcIds []string `json:"vpc_ids,omitempty"` -} -// AssetCloud contains information about the cloud provider -type AssetCloud struct { - AvailabilityZone *string `json:"availability_zone,omitempty"` - Provider string `json:"provider,omitempty"` - Region string `json:"region,omitempty"` - Account AssetCloudAccount `json:"account"` - Organization AssetCloudOrganization `json:"organization,omitempty"` - Instance *AssetCloudInstance `json:"instance,omitempty"` - Machine *AssetCloudMachine `json:"machine,omitempty"` - Project *AssetCloudProject `json:"project,omitempty"` - Service *AssetCloudService `json:"service,omitempty"` + // non exported fields + relatedEntityId []string } -type AssetCloudAccount struct { - Id string `json:"id,omitempty"` - Name string `json:"name,omitempty"` +type Event struct { + Kind string `json:"kind"` } -type AssetCloudOrganization struct { - Id string `json:"id,omitempty"` +type Network struct { Name string `json:"name,omitempty"` } -type AssetCloudInstance struct { - Id string `json:"id,omitempty"` - Name string `json:"name,omitempty"` +type Cloud struct { + Provider string `json:"provider,omitempty"` + Region string `json:"region,omitempty"` + AvailabilityZone string `json:"availability_zone,omitempty"` + AccountID string `json:"account.id,omitempty"` + AccountName string `json:"account.name,omitempty"` + InstanceID string `json:"instance.id,omitempty"` + InstanceName string `json:"instance.name,omitempty"` + MachineType string `json:"machine.type,omitempty"` + ServiceName string `json:"service.name,omitempty"` + ProjectID string `json:"project.id,omitempty"` + ProjectName string `json:"project.name,omitempty"` } -type AssetCloudMachine struct { - MachineType string `json:"machine_type,omitempty"` +type Host struct { + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Architecture string `json:"architecture,omitempty"` + Type string `json:"type,omitempty"` + IP string `json:"ip,omitempty"` + MacAddress []string `json:"mac,omitempty"` } -type AssetCloudProject struct { - Id string `json:"id,omitempty"` +type User struct { + ID string `json:"id,omitempty"` Name string `json:"name,omitempty"` } -type AssetCloudService struct { - Name string `json:"name,omitempty"` -} - -// AssetHost contains information of the asset in case it is a host -type AssetHost struct { - Architecture string `json:"architecture"` - ImageId *string `json:"imageId"` - InstanceType string `json:"instance_type"` - Platform string `json:"platform"` - PlatformDetails *string `json:"platform_details"` -} - -type AssetIAM struct { - Id *string `json:"id"` - Arn *string `json:"arn"` -} - -// AssetResourcePolicy maps security policies applied directly on resources -type AssetResourcePolicy struct { - Version *string `json:"version,omitempty"` - Id *string `json:"id,omitempty"` - Effect string `json:"effect,omitempty"` - Principal map[string]any `json:"principal,omitempty"` - Action []string `json:"action,omitempty"` - NotAction []string `json:"notAction,omitempty"` - Resource []string `json:"resource,omitempty"` - NoResource []string `json:"noResource,omitempty"` - Condition map[string]any `json:"condition,omitempty"` -} - // AssetEnricher functional builder function type AssetEnricher func(asset *AssetEvent) -func NewAssetEvent(c AssetClassification, ids []string, name string, enrichers ...AssetEnricher) AssetEvent { +func NewAssetEvent(c AssetClassification, id string, name string, enrichers ...AssetEnricher) AssetEvent { a := AssetEvent{ - Asset: Asset{ - Id: removeEmpty(ids), + Entity: Entity{ + Id: id, Name: name, AssetClassification: c, }, + Event: Event{ + Kind: "asset", + }, } for _, enrich := range enrichers { @@ -351,57 +210,56 @@ func NewAssetEvent(c AssetClassification, ids []string, name string, enrichers . func WithRawAsset(raw any) AssetEnricher { return func(a *AssetEvent) { - a.Asset.Raw = &raw + a.RawAttributes = &raw } } func WithRelatedAssetIds(ids []string) AssetEnricher { return func(a *AssetEvent) { - a.Asset.RelatedEntityId = ids + ids = lo.Filter(ids, func(id string, _ int) bool { + return id != "" + }) + + if len(ids) == 0 { + a.Entity.relatedEntityId = nil + return + } + + a.Entity.relatedEntityId = lo.Uniq(ids) } } -func WithTags(tags map[string]string) AssetEnricher { +func WithLabels(labels map[string]string) AssetEnricher { return func(a *AssetEvent) { - if len(tags) == 0 { + if len(labels) == 0 { return } - a.Asset.Tags = tags + a.Labels = labels } } -func WithNetwork(network AssetNetwork) AssetEnricher { +func WithNetwork(network Network) AssetEnricher { return func(a *AssetEvent) { a.Network = &network } } -func WithCloud(cloud AssetCloud) AssetEnricher { +func WithCloud(cloud Cloud) AssetEnricher { return func(a *AssetEvent) { a.Cloud = &cloud } } -func WithHost(host AssetHost) AssetEnricher { +func WithHost(host Host) AssetEnricher { return func(a *AssetEvent) { a.Host = &host } } -func WithIAM(iam AssetIAM) AssetEnricher { +func WithUser(user User) AssetEnricher { return func(a *AssetEvent) { - a.IAM = &iam - } -} - -func WithResourcePolicies(policies ...AssetResourcePolicy) AssetEnricher { - return func(a *AssetEvent) { - if len(policies) == 0 { - return - } - - a.ResourcePolicies = policies + a.User = &user } } diff --git a/internal/inventory/awsfetcher/fetcher_ec2_instance.go b/internal/inventory/awsfetcher/fetcher_ec2_instance.go index 26c413c30f..a2b22adc11 100644 --- a/internal/inventory/awsfetcher/fetcher_ec2_instance.go +++ b/internal/inventory/awsfetcher/fetcher_ec2_instance.go @@ -58,66 +58,46 @@ func (e *ec2InstanceFetcher) Fetch(ctx context.Context, assetChannel chan<- inve return } - for _, instance := range instances { - if instance == nil { + for _, i := range instances { + if i == nil { continue } iamFetcher := inventory.EmptyEnricher() - if instance.IamInstanceProfile != nil { - iamFetcher = inventory.WithIAM(inventory.AssetIAM{ - Id: instance.IamInstanceProfile.Id, - Arn: instance.IamInstanceProfile.Arn, + if i.IamInstanceProfile != nil { + iamFetcher = inventory.WithUser(inventory.User{ + ID: pointers.Deref(i.IamInstanceProfile.Arn), }) } - subnetIds := []string{} - if id := pointers.Deref(instance.SubnetId); id != "" { - subnetIds = append(subnetIds, id) - } assetChannel <- inventory.NewAssetEvent( inventory.AssetClassificationAwsEc2Instance, - []string{instance.GetResourceArn(), pointers.Deref(instance.InstanceId)}, - instance.GetResourceName(), + i.GetResourceArn(), + pointers.Deref(i.PrivateDnsName), - inventory.WithRawAsset(instance), - inventory.WithTags(e.getTags(instance)), - inventory.WithCloud(inventory.AssetCloud{ + inventory.WithRelatedAssetIds([]string{pointers.Deref(i.InstanceId)}), + inventory.WithRawAsset(i), + inventory.WithLabels(e.getTags(i)), + inventory.WithCloud(inventory.Cloud{ Provider: inventory.AwsCloudProvider, - Region: instance.Region, - AvailabilityZone: e.getAvailabilityZone(instance), - Account: inventory.AssetCloudAccount{ - Id: e.AccountId, - Name: e.AccountName, - }, - Instance: &inventory.AssetCloudInstance{ - Id: pointers.Deref(instance.InstanceId), - Name: instance.GetResourceName(), - }, - Machine: &inventory.AssetCloudMachine{ - MachineType: string(instance.InstanceType), - }, - Service: &inventory.AssetCloudService{ - Name: "AWS EC2", - }, + Region: i.Region, + AvailabilityZone: e.getAvailabilityZone(i), + AccountID: e.AccountId, + AccountName: e.AccountName, + InstanceID: pointers.Deref(i.InstanceId), + InstanceName: i.GetResourceName(), + MachineType: string(i.InstanceType), + ServiceName: "AWS EC2", }), - inventory.WithHost(inventory.AssetHost{ - Architecture: string(instance.Architecture), - ImageId: instance.ImageId, - InstanceType: string(instance.InstanceType), - Platform: string(instance.Platform), - PlatformDetails: instance.PlatformDetails, + inventory.WithHost(inventory.Host{ + ID: pointers.Deref(i.InstanceId), + Name: pointers.Deref(i.PrivateDnsName), + Architecture: string(i.Architecture), + Type: string(i.InstanceType), + IP: pointers.Deref(i.PublicIpAddress), + MacAddress: i.GetResourceMacAddresses(), }), iamFetcher, - inventory.WithNetwork(inventory.AssetNetwork{ - NetworkId: instance.VpcId, - SubnetIds: subnetIds, - Ipv6Address: instance.Ipv6Address, - PublicIpAddress: instance.PublicIpAddress, - PrivateIpAddress: instance.PrivateIpAddress, - PublicDnsName: instance.PublicDnsName, - PrivateDnsName: instance.PrivateDnsName, - }), ) } } @@ -134,10 +114,10 @@ func (e *ec2InstanceFetcher) getTags(instance *ec2.Ec2Instance) map[string]strin return tags } -func (e *ec2InstanceFetcher) getAvailabilityZone(instance *ec2.Ec2Instance) *string { +func (e *ec2InstanceFetcher) getAvailabilityZone(instance *ec2.Ec2Instance) string { if instance.Placement == nil { - return nil + return "" } - return instance.Placement.AvailabilityZone + return pointers.Deref(instance.Placement.AvailabilityZone) } diff --git a/internal/inventory/awsfetcher/fetcher_ec2_instance_test.go b/internal/inventory/awsfetcher/fetcher_ec2_instance_test.go index 830203e94d..ca0e62c0e8 100644 --- a/internal/inventory/awsfetcher/fetcher_ec2_instance_test.go +++ b/internal/inventory/awsfetcher/fetcher_ec2_instance_test.go @@ -64,6 +64,14 @@ func TestEC2InstanceFetcher_Fetch(t *testing.T) { Placement: &types.Placement{ AvailabilityZone: pointers.Ref("1a"), }, + NetworkInterfaces: []types.InstanceNetworkInterface{ + { + MacAddress: pointers.Ref("mac1"), + }, + { + MacAddress: pointers.Ref("mac2"), + }, + }, }, Region: "us-east", } @@ -78,77 +86,55 @@ func TestEC2InstanceFetcher_Fetch(t *testing.T) { expected := []inventory.AssetEvent{ inventory.NewAssetEvent( inventory.AssetClassificationAwsEc2Instance, - []string{"arn:aws:ec2:us-east::ec2/234567890", "234567890"}, - "test-server", + "arn:aws:ec2:us-east::ec2/234567890", + "private-dns", + inventory.WithRelatedAssetIds([]string{"234567890"}), inventory.WithRawAsset(instance1), - inventory.WithTags(map[string]string{"Name": "test-server", "key": "value"}), - inventory.WithCloud(inventory.AssetCloud{ + inventory.WithLabels(map[string]string{"Name": "test-server", "key": "value"}), + inventory.WithCloud(inventory.Cloud{ Provider: inventory.AwsCloudProvider, Region: "us-east", - AvailabilityZone: pointers.Ref("1a"), - Account: inventory.AssetCloudAccount{ - Id: "123", - Name: "alias", - }, - Instance: &inventory.AssetCloudInstance{ - Id: "234567890", - Name: "test-server", - }, - Machine: &inventory.AssetCloudMachine{ - MachineType: "instance-type", - }, - Service: &inventory.AssetCloudService{ - Name: "AWS EC2", - }, + AvailabilityZone: "1a", + AccountID: "123", + AccountName: "alias", + InstanceID: "234567890", + InstanceName: "test-server", + MachineType: "instance-type", + ServiceName: "AWS EC2", }), - inventory.WithHost(inventory.AssetHost{ - Architecture: string(types.ArchitectureValuesX8664), - ImageId: pointers.Ref("image-id"), - InstanceType: "instance-type", - Platform: "linux", - PlatformDetails: pointers.Ref("ubuntu"), + inventory.WithHost(inventory.Host{ + ID: "234567890", + Name: "private-dns", + Architecture: string(types.ArchitectureValuesX8664), + Type: "instance-type", + IP: "public-ip-addr", + MacAddress: []string{"mac1", "mac2"}, }), - inventory.WithIAM(inventory.AssetIAM{ - Id: pointers.Ref("a123123"), - Arn: pointers.Ref("123123:123123:123123"), - }), - inventory.WithNetwork(inventory.AssetNetwork{ - NetworkId: pointers.Ref("vpc-id"), - SubnetIds: []string{"subnetId"}, - Ipv6Address: pointers.Ref("ipv6"), - PublicIpAddress: pointers.Ref("public-ip-addr"), - PrivateIpAddress: pointers.Ref("private-ip-addre"), - PublicDnsName: pointers.Ref("public-dns"), - PrivateDnsName: pointers.Ref("private-dns"), + inventory.WithUser(inventory.User{ + ID: "123123:123123:123123", }), ), inventory.NewAssetEvent( inventory.AssetClassificationAwsEc2Instance, - []string{}, + "", "", inventory.WithRawAsset(instance2), - inventory.WithTags(map[string]string{}), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: "us-east", - Account: inventory.AssetCloudAccount{ - Id: "123", - Name: "alias", - }, - Instance: &inventory.AssetCloudInstance{ - Id: "", - Name: "", - }, - Machine: &inventory.AssetCloudMachine{ - MachineType: "", - }, - Service: &inventory.AssetCloudService{ - Name: "AWS EC2", - }, + inventory.WithLabels(map[string]string{}), + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: "us-east", + AvailabilityZone: "", + AccountID: "123", + AccountName: "alias", + InstanceID: "", + InstanceName: "", + MachineType: "", + ServiceName: "AWS EC2", + }), + inventory.WithHost(inventory.Host{ + MacAddress: []string{}, }), - inventory.WithHost(inventory.AssetHost{}), - inventory.WithNetwork(inventory.AssetNetwork{SubnetIds: []string{}}), ), } diff --git a/internal/inventory/awsfetcher/fetcher_elb.go b/internal/inventory/awsfetcher/fetcher_elb.go index dc55532c58..10be3adf8f 100644 --- a/internal/inventory/awsfetcher/fetcher_elb.go +++ b/internal/inventory/awsfetcher/fetcher_elb.go @@ -81,19 +81,15 @@ func (f *elbFetcher) fetch(ctx context.Context, resourceName string, function el for _, item := range awsResources { assetChannel <- inventory.NewAssetEvent( classification, - []string{item.GetResourceArn()}, + item.GetResourceArn(), item.GetResourceName(), inventory.WithRawAsset(item), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: item.GetRegion(), - Account: inventory.AssetCloudAccount{ - Id: f.AccountId, - Name: f.AccountName, - }, - Service: &inventory.AssetCloudService{ - Name: "AWS Networking", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: item.GetRegion(), + AccountID: f.AccountId, + AccountName: f.AccountName, + ServiceName: "AWS Networking", }), ) } diff --git a/internal/inventory/awsfetcher/fetcher_elb_test.go b/internal/inventory/awsfetcher/fetcher_elb_test.go index a7c9c9702a..e97019e947 100644 --- a/internal/inventory/awsfetcher/fetcher_elb_test.go +++ b/internal/inventory/awsfetcher/fetcher_elb_test.go @@ -69,18 +69,14 @@ func TestELBv1Fetcher_Fetch(t *testing.T) { expected := []inventory.AssetEvent{ inventory.NewAssetEvent( inventory.AssetClassificationAwsElbV1, - []string{"arn:aws:elasticloadbalancing:::loadbalancer/my-elb-v1"}, + "arn:aws:elasticloadbalancing:::loadbalancer/my-elb-v1", "my-elb-v1", inventory.WithRawAsset(asset), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: "123", - Name: "alias", - }, - Service: &inventory.AssetCloudService{ - Name: "AWS Networking", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + AccountID: "123", + AccountName: "alias", + ServiceName: "AWS Networking", }), ), } @@ -119,18 +115,14 @@ func TestELBv2Fetcher_Fetch(t *testing.T) { expected := []inventory.AssetEvent{ inventory.NewAssetEvent( inventory.AssetClassificationAwsElbV2, - []string{"arn:aws:elasticloadbalancing:::loadbalancer/my-elb-v2"}, + "arn:aws:elasticloadbalancing:::loadbalancer/my-elb-v2", "my-elb-v2", inventory.WithRawAsset(asset), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: "123", - Name: "alias", - }, - Service: &inventory.AssetCloudService{ - Name: "AWS Networking", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + AccountID: "123", + AccountName: "alias", + ServiceName: "AWS Networking", }), ), } diff --git a/internal/inventory/awsfetcher/fetcher_iam_policy.go b/internal/inventory/awsfetcher/fetcher_iam_policy.go index da1a28a045..a54029cb29 100644 --- a/internal/inventory/awsfetcher/fetcher_iam_policy.go +++ b/internal/inventory/awsfetcher/fetcher_iam_policy.go @@ -74,22 +74,18 @@ func (i *iamPolicyFetcher) Fetch(ctx context.Context, assetChannel chan<- invent assetChannel <- inventory.NewAssetEvent( inventory.AssetClassificationAwsIamPolicy, - []string{policy.GetResourceArn(), pointers.Deref(policy.PolicyId)}, + policy.GetResourceArn(), resource.GetResourceName(), + inventory.WithRelatedAssetIds([]string{pointers.Deref(policy.PolicyId)}), inventory.WithRawAsset(policy), - inventory.WithResourcePolicies(convertPolicy(policy.Document)...), - inventory.WithTags(i.getTags(policy)), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: awslib.GlobalRegion, - Account: inventory.AssetCloudAccount{ - Id: i.AccountId, - Name: i.AccountName, - }, - Service: &inventory.AssetCloudService{ - Name: "AWS IAM", - }, + inventory.WithLabels(i.getTags(policy)), + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: awslib.GlobalRegion, + AccountID: i.AccountId, + AccountName: i.AccountName, + ServiceName: "AWS IAM", }), ) } @@ -104,95 +100,3 @@ func (i *iamPolicyFetcher) getTags(policy iam.Policy) map[string]string { return tags } - -func convertPolicy(policy map[string]any) []inventory.AssetResourcePolicy { - if len(policy) == 0 { - return nil - } - - version, hasVersion := policy["Version"].(string) - if !hasVersion { - version = "" - } - - switch statements := policy["Statement"].(type) { - case []map[string]any: - return convertStatements(statements, version) - case []any: - return convertAnyStatements(statements, version) - case map[string]any: - return []inventory.AssetResourcePolicy{convertStatement(statements, &version)} - } - return nil -} - -func convertAnyStatements(statements []any, version string) []inventory.AssetResourcePolicy { - policies := make([]inventory.AssetResourcePolicy, 0, len(statements)) - for _, statement := range statements { - policies = append(policies, convertStatement(statement.(map[string]any), &version)) - } - return policies -} - -func convertStatements(statements []map[string]any, version string) []inventory.AssetResourcePolicy { - policies := make([]inventory.AssetResourcePolicy, 0, len(statements)) - for _, statement := range statements { - policies = append(policies, convertStatement(statement, &version)) - } - return policies -} - -func convertStatement(statement map[string]any, version *string) inventory.AssetResourcePolicy { - p := inventory.AssetResourcePolicy{} - p.Version = version - - if sid, ok := statement["Sid"]; ok { - p.Id = pointers.Ref(sid.(string)) - } - - if effect, ok := statement["Effect"]; ok { - p.Effect = effect.(string) - } - - if anyPrincipal, ok := statement["Principal"]; ok { - switch principal := anyPrincipal.(type) { - case string: - p.Principal = map[string]any{principal: principal} - case map[string]any: - p.Principal = principal - } - } - - if action, ok := statement["Action"]; ok { - p.Action = anyToSliceString(action) - } - - if notAction, ok := statement["NotAction"]; ok { - p.NotAction = anyToSliceString(notAction) - } - - if resource, ok := statement["Resource"]; ok { - p.Resource = anyToSliceString(resource) - } - - if noResource, ok := statement["NoResource"]; ok { - p.NoResource = anyToSliceString(noResource) - } - - if condition, ok := statement["Condition"]; ok { - p.Condition = condition.(map[string]any) - } - - return p -} - -func anyToSliceString(anyString any) []string { - switch s := anyString.(type) { - case string: - return []string{s} - case []string: - return s - } - - return nil -} diff --git a/internal/inventory/awsfetcher/fetcher_iam_policy_test.go b/internal/inventory/awsfetcher/fetcher_iam_policy_test.go index b055c31a43..2157566f76 100644 --- a/internal/inventory/awsfetcher/fetcher_iam_policy_test.go +++ b/internal/inventory/awsfetcher/fetcher_iam_policy_test.go @@ -102,62 +102,42 @@ func TestIAMPolicyFetcher_Fetch(t *testing.T) { in := []awslib.AwsResource{policy1, nil, policy2, policy3} - cloudField := inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: "global", - Account: inventory.AssetCloudAccount{ - Id: "123", - Name: "alias", - }, - Service: &inventory.AssetCloudService{ - Name: "AWS IAM", - }, + cloudField := inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: "global", + AccountID: "123", + AccountName: "alias", + ServiceName: "AWS IAM", } expected := []inventory.AssetEvent{ inventory.NewAssetEvent( inventory.AssetClassificationAwsIamPolicy, - []string{"arn:aws:iam::0000:policy/policy-1", "178263"}, + "arn:aws:iam::0000:policy/policy-1", "policy-1", + inventory.WithRelatedAssetIds([]string{"178263"}), inventory.WithRawAsset(policy1), inventory.WithCloud(cloudField), - inventory.WithTags(map[string]string{ + inventory.WithLabels(map[string]string{ "key-1": "value-1", "key-2": "value-2", }), - inventory.WithResourcePolicies(inventory.AssetResourcePolicy{ - Version: pointers.Ref("2012-10-17"), - Effect: "Allow", - Action: []string{"read", "update", "delete"}, - Resource: []string{"s3/bucket", "s3/bucket/*"}, - }, inventory.AssetResourcePolicy{ - Version: pointers.Ref("2012-10-17"), - Effect: "Deny", - Action: []string{"delete"}, - Resource: []string{"s3/bucket"}, - }), ), inventory.NewAssetEvent( inventory.AssetClassificationAwsIamPolicy, - []string{"arn:aws:iam::0000:policy/policy-2"}, + "arn:aws:iam::0000:policy/policy-2", "policy-2", inventory.WithRawAsset(policy2), inventory.WithCloud(cloudField), - inventory.WithTags(map[string]string{ + inventory.WithLabels(map[string]string{ "key-1": "value-1", }), - inventory.WithResourcePolicies(inventory.AssetResourcePolicy{ - Version: pointers.Ref("2012-10-17"), - Effect: "Allow", - Action: []string{"read"}, - Resource: []string{"*"}, - }), ), inventory.NewAssetEvent( inventory.AssetClassificationAwsIamPolicy, - []string{"arn:aws:iam::0000:policy/policy-3"}, + "arn:aws:iam::0000:policy/policy-3", "policy-3", inventory.WithRawAsset(policy3), inventory.WithCloud(cloudField), diff --git a/internal/inventory/awsfetcher/fetcher_iam_role.go b/internal/inventory/awsfetcher/fetcher_iam_role.go index fbd700cfa9..32e9c09716 100644 --- a/internal/inventory/awsfetcher/fetcher_iam_role.go +++ b/internal/inventory/awsfetcher/fetcher_iam_role.go @@ -68,20 +68,21 @@ func (i *iamRoleFetcher) Fetch(ctx context.Context, assetChannel chan<- inventor assetChannel <- inventory.NewAssetEvent( inventory.AssetClassificationAwsIamRole, - []string{pointers.Deref(role.Arn), pointers.Deref(role.RoleId)}, + pointers.Deref(role.Arn), pointers.Deref(role.RoleName), + inventory.WithRelatedAssetIds([]string{pointers.Deref(role.RoleId)}), inventory.WithRawAsset(*role), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: awslib.GlobalRegion, - Account: inventory.AssetCloudAccount{ - Id: i.AccountId, - Name: i.AccountName, - }, - Service: &inventory.AssetCloudService{ - Name: "AWS IAM", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: awslib.GlobalRegion, + AccountID: i.AccountId, + AccountName: i.AccountName, + ServiceName: "AWS IAM", + }), + inventory.WithUser(inventory.User{ + ID: pointers.Deref(role.Arn), + Name: pointers.Deref(role.RoleName), }), ) } diff --git a/internal/inventory/awsfetcher/fetcher_iam_role_test.go b/internal/inventory/awsfetcher/fetcher_iam_role_test.go index 6d2fc5d364..2e26be1ece 100644 --- a/internal/inventory/awsfetcher/fetcher_iam_role_test.go +++ b/internal/inventory/awsfetcher/fetcher_iam_role_test.go @@ -63,7 +63,7 @@ func TestIAMRoleFetcher_Fetch(t *testing.T) { AssumeRolePolicyDocument: pointers.Ref("document"), Description: pointers.Ref("EKS managed node group IAM role"), Path: pointers.Ref("/"), - RoleId: pointers.Ref("17823618723"), + RoleId: pointers.Ref("17823618724"), }, } @@ -72,37 +72,39 @@ func TestIAMRoleFetcher_Fetch(t *testing.T) { expected := []inventory.AssetEvent{ inventory.NewAssetEvent( inventory.AssetClassificationAwsIamRole, - []string{"arn:aws:iam::0000:role/role-name-1", "17823618723"}, + "arn:aws:iam::0000:role/role-name-1", "role-name-1", + inventory.WithRelatedAssetIds([]string{"17823618723"}), inventory.WithRawAsset(role1), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: "global", - Account: inventory.AssetCloudAccount{ - Id: "123", - Name: "alias", - }, - Service: &inventory.AssetCloudService{ - Name: "AWS IAM", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: "global", + AccountID: "123", + AccountName: "alias", + ServiceName: "AWS IAM", + }), + inventory.WithUser(inventory.User{ + ID: "arn:aws:iam::0000:role/role-name-1", + Name: "role-name-1", }), ), inventory.NewAssetEvent( inventory.AssetClassificationAwsIamRole, - []string{"arn:aws:iam::0000:role/role-name-2", "17823618723"}, + "arn:aws:iam::0000:role/role-name-2", "role-name-2", + inventory.WithRelatedAssetIds([]string{"17823618724"}), inventory.WithRawAsset(role2), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: "global", - Account: inventory.AssetCloudAccount{ - Id: "123", - Name: "alias", - }, - Service: &inventory.AssetCloudService{ - Name: "AWS IAM", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: "global", + AccountID: "123", + AccountName: "alias", + ServiceName: "AWS IAM", + }), + inventory.WithUser(inventory.User{ + ID: "arn:aws:iam::0000:role/role-name-2", + Name: "role-name-2", }), ), } diff --git a/internal/inventory/awsfetcher/fetcher_iam_user.go b/internal/inventory/awsfetcher/fetcher_iam_user.go index ff992a8a74..75dfc6081c 100644 --- a/internal/inventory/awsfetcher/fetcher_iam_user.go +++ b/internal/inventory/awsfetcher/fetcher_iam_user.go @@ -73,20 +73,21 @@ func (i *iamUserFetcher) Fetch(ctx context.Context, assetChannel chan<- inventor assetChannel <- inventory.NewAssetEvent( inventory.AssetClassificationAwsIamUser, - []string{user.GetResourceArn(), user.UserId}, + user.GetResourceArn(), user.GetResourceName(), + inventory.WithRelatedAssetIds([]string{user.UserId}), inventory.WithRawAsset(user), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: user.GetRegion(), - Account: inventory.AssetCloudAccount{ - Id: i.AccountId, - Name: i.AccountName, - }, - Service: &inventory.AssetCloudService{ - Name: "AWS IAM", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: user.GetRegion(), + AccountID: i.AccountId, + AccountName: i.AccountName, + ServiceName: "AWS IAM", + }), + inventory.WithUser(inventory.User{ + ID: user.GetResourceArn(), + Name: user.GetResourceName(), }), ) } diff --git a/internal/inventory/awsfetcher/fetcher_iam_user_test.go b/internal/inventory/awsfetcher/fetcher_iam_user_test.go index c08c3014a2..c7f1246d78 100644 --- a/internal/inventory/awsfetcher/fetcher_iam_user_test.go +++ b/internal/inventory/awsfetcher/fetcher_iam_user_test.go @@ -87,37 +87,38 @@ func TestIAMUserFetcher_Fetch(t *testing.T) { expected := []inventory.AssetEvent{ inventory.NewAssetEvent( inventory.AssetClassificationAwsIamUser, - []string{"arn:aws:iam::000:user/user-1", "u-123123"}, + "arn:aws:iam::000:user/user-1", "user-1", + inventory.WithRelatedAssetIds([]string{"u-123123"}), inventory.WithRawAsset(user1), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: "global", - Account: inventory.AssetCloudAccount{ - Id: "123", - Name: "alias", - }, - Service: &inventory.AssetCloudService{ - Name: "AWS IAM", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: "global", + AccountID: "123", + AccountName: "alias", + ServiceName: "AWS IAM", + }), + inventory.WithUser(inventory.User{ + ID: "arn:aws:iam::000:user/user-1", + Name: "user-1", }), ), inventory.NewAssetEvent( inventory.AssetClassificationAwsIamUser, - []string{"arn:aws:iam::000:user/user-2"}, + "arn:aws:iam::000:user/user-2", "user-2", inventory.WithRawAsset(user2), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: "global", - Account: inventory.AssetCloudAccount{ - Id: "123", - Name: "alias", - }, - Service: &inventory.AssetCloudService{ - Name: "AWS IAM", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: "global", + AccountID: "123", + AccountName: "alias", + ServiceName: "AWS IAM", + }), + inventory.WithUser(inventory.User{ + ID: "arn:aws:iam::000:user/user-2", + Name: "user-2", }), ), } diff --git a/internal/inventory/awsfetcher/fetcher_lambda.go b/internal/inventory/awsfetcher/fetcher_lambda.go index 3c195078a8..25503b5804 100644 --- a/internal/inventory/awsfetcher/fetcher_lambda.go +++ b/internal/inventory/awsfetcher/fetcher_lambda.go @@ -85,19 +85,15 @@ func (s *lambdaFetcher) fetch(ctx context.Context, resourceName string, function } assetChannel <- inventory.NewAssetEvent( classification, - []string{id}, + id, item.GetResourceName(), inventory.WithRawAsset(item), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: item.GetRegion(), - Account: inventory.AssetCloudAccount{ - Id: s.AccountId, - Name: s.AccountName, - }, - Service: &inventory.AssetCloudService{ - Name: "AWS Lambda", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: item.GetRegion(), + AccountID: s.AccountId, + AccountName: s.AccountName, + ServiceName: "AWS Lambda", }), ) } diff --git a/internal/inventory/awsfetcher/fetcher_lambda_test.go b/internal/inventory/awsfetcher/fetcher_lambda_test.go index f0b4806ee2..f307d15c57 100644 --- a/internal/inventory/awsfetcher/fetcher_lambda_test.go +++ b/internal/inventory/awsfetcher/fetcher_lambda_test.go @@ -55,18 +55,14 @@ func TestLambdaFunction_Fetch(t *testing.T) { expected := []inventory.AssetEvent{ inventory.NewAssetEvent( inventory.AssetClassificationAwsLambdaFunction, - []string{"arn:aws:lambda:us-east-1:378890115541:function:kuba-test-func"}, + "arn:aws:lambda:us-east-1:378890115541:function:kuba-test-func", "kuba-test-func", inventory.WithRawAsset(function1), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: "123", - Name: "alias", - }, - Service: &inventory.AssetCloudService{ - Name: "AWS Lambda", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + AccountID: "123", + AccountName: "alias", + ServiceName: "AWS Lambda", }), ), } diff --git a/internal/inventory/awsfetcher/fetcher_networking.go b/internal/inventory/awsfetcher/fetcher_networking.go index af016d2479..e9e2db0319 100644 --- a/internal/inventory/awsfetcher/fetcher_networking.go +++ b/internal/inventory/awsfetcher/fetcher_networking.go @@ -96,111 +96,21 @@ func (s *networkingFetcher) fetch(ctx context.Context, resourceName string, func for _, item := range awsResources { assetChannel <- inventory.NewAssetEvent( classification, - []string{item.GetResourceArn(), pointers.Deref(s.retrieveId(item))}, + item.GetResourceArn(), item.GetResourceName(), + inventory.WithRelatedAssetIds([]string{pointers.Deref(s.retrieveId(item))}), inventory.WithRawAsset(item), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: item.GetRegion(), - Account: inventory.AssetCloudAccount{ - Id: s.AccountId, - Name: s.AccountName, - }, - Service: &inventory.AssetCloudService{ - Name: "AWS Networking", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: item.GetRegion(), + AccountID: s.AccountId, + AccountName: s.AccountName, + ServiceName: "AWS Networking", }), - s.networkEnricher(item), ) } } -//nolint:revive -func (s *networkingFetcher) networkEnricher(item awslib.AwsResource) inventory.AssetEnricher { - var enricher inventory.AssetEnricher - - switch obj := item.(type) { - case *ec2.InternetGatewayInfo: - vpcIds := []string{} - for _, attachment := range obj.InternetGateway.Attachments { - id := pointers.Deref(attachment.VpcId) - if id != "" { - vpcIds = append(vpcIds, id) - } - } - enricher = inventory.WithNetwork(inventory.AssetNetwork{ - VpcIds: vpcIds, - }) - case *ec2.NatGatewayInfo: - ifaceIds := []string{} - for _, iface := range obj.NatGateway.NatGatewayAddresses { - id := pointers.Deref(iface.NetworkInterfaceId) - if id != "" { - ifaceIds = append(ifaceIds, id) - } - } - enricher = inventory.WithNetwork(inventory.AssetNetwork{ - NetworkInterfaceIds: ifaceIds, - SubnetIds: []string{pointers.Deref(obj.NatGateway.SubnetId)}, - VpcIds: []string{pointers.Deref(obj.NatGateway.VpcId)}, - }) - case *ec2.NACLInfo: - subnetIds := []string{} - for _, association := range obj.NetworkAcl.Associations { - id := pointers.Deref(association.SubnetId) - if id != "" { - subnetIds = append(subnetIds, id) - } - } - enricher = inventory.WithNetwork(inventory.AssetNetwork{ - SubnetIds: subnetIds, - VpcIds: []string{pointers.Deref(obj.NetworkAcl.VpcId)}, - }) - case *ec2.NetworkInterfaceInfo: - secGroupIds := []string{} - for _, secGroup := range obj.NetworkInterface.Groups { - id := pointers.Deref(secGroup.GroupId) - secGroupIds = append(secGroupIds, id) - } - enricher = inventory.WithNetwork(inventory.AssetNetwork{ - SecurityGroupIds: secGroupIds, - SubnetIds: []string{pointers.Deref(obj.NetworkInterface.SubnetId)}, - VpcIds: []string{pointers.Deref(obj.NetworkInterface.VpcId)}, - }) - case *ec2.SecurityGroup: - enricher = inventory.WithNetwork(inventory.AssetNetwork{ - VpcIds: []string{pointers.Deref(obj.VpcId)}, - }) - case *ec2.SubnetInfo: - enricher = inventory.WithNetwork(inventory.AssetNetwork{ - VpcIds: []string{pointers.Deref(obj.Subnet.VpcId)}, - }) - case *ec2.TransitGatewayAttachmentInfo: - routeTableId := "" - if obj.TransitGatewayAttachment.Association != nil { - routeTableId = pointers.Deref(obj.TransitGatewayAttachment.Association.TransitGatewayRouteTableId) - } - enricher = inventory.WithNetwork(inventory.AssetNetwork{ - RouteTableIds: []string{routeTableId}, - TransitGatewayIds: []string{pointers.Deref(obj.TransitGatewayAttachment.TransitGatewayId)}, - }) - case *ec2.VpcPeeringConnectionInfo: - enricher = inventory.WithNetwork(inventory.AssetNetwork{ - VpcIds: []string{ - pointers.Deref(obj.VpcPeeringConnection.AccepterVpcInfo.VpcId), - pointers.Deref(obj.VpcPeeringConnection.RequesterVpcInfo.VpcId), - }, - }) - case *ec2.VpcInfo: - enricher = inventory.EmptyEnricher() - default: - s.logger.Warnf("Unsupported Networking Fetcher type %T (enricher)", obj) - enricher = inventory.EmptyEnricher() - } - - return enricher -} - func (s *networkingFetcher) retrieveId(awsResource awslib.AwsResource) *string { switch resource := awsResource.(type) { case *ec2.InternetGatewayInfo: diff --git a/internal/inventory/awsfetcher/fetcher_rds.go b/internal/inventory/awsfetcher/fetcher_rds.go index 590a6e812d..d9c21ccc71 100644 --- a/internal/inventory/awsfetcher/fetcher_rds.go +++ b/internal/inventory/awsfetcher/fetcher_rds.go @@ -68,19 +68,16 @@ func (s *rdsFetcher) Fetch(ctx context.Context, assetChannel chan<- inventory.As for _, item := range rdsInstances { assetChannel <- inventory.NewAssetEvent( inventory.AssetClassificationAwsRds, - []string{item.GetResourceArn(), item.Identifier}, + item.GetResourceArn(), item.GetResourceName(), + inventory.WithRelatedAssetIds([]string{item.Identifier}), inventory.WithRawAsset(item), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: item.GetRegion(), - Account: inventory.AssetCloudAccount{ - Id: s.AccountId, - Name: s.AccountName, - }, - Service: &inventory.AssetCloudService{ - Name: "RDS", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: item.GetRegion(), + AccountID: s.AccountId, + AccountName: s.AccountName, + ServiceName: "AWS RDS", }), ) } diff --git a/internal/inventory/awsfetcher/fetcher_rds_test.go b/internal/inventory/awsfetcher/fetcher_rds_test.go index dcca017e81..96426460b3 100644 --- a/internal/inventory/awsfetcher/fetcher_rds_test.go +++ b/internal/inventory/awsfetcher/fetcher_rds_test.go @@ -84,34 +84,28 @@ func TestRDSInstanceFetcher_Fetch(t *testing.T) { expected := []inventory.AssetEvent{ inventory.NewAssetEvent( inventory.AssetClassificationAwsRds, - []string{"arn:aws:rds:eu-west-1:123:db:db1", "db1"}, + "arn:aws:rds:eu-west-1:123:db:db1", "db1", + inventory.WithRelatedAssetIds([]string{"db1"}), inventory.WithRawAsset(instance1), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: "123", - Name: "alias", - }, - Service: &inventory.AssetCloudService{ - Name: "RDS", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + AccountID: "123", + AccountName: "alias", + ServiceName: "AWS RDS", }), ), inventory.NewAssetEvent( inventory.AssetClassificationAwsRds, - []string{"arn:aws:rds:eu-west-1:123:db:db2", "db2"}, + "arn:aws:rds:eu-west-1:123:db:db2", "db2", + inventory.WithRelatedAssetIds([]string{"db2"}), inventory.WithRawAsset(instance2), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: "123", - Name: "alias", - }, - Service: &inventory.AssetCloudService{ - Name: "RDS", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + AccountID: "123", + AccountName: "alias", + ServiceName: "AWS RDS", }), ), } diff --git a/internal/inventory/awsfetcher/fetcher_s3_bucket.go b/internal/inventory/awsfetcher/fetcher_s3_bucket.go index 7c6744da73..0b366a1fdb 100644 --- a/internal/inventory/awsfetcher/fetcher_s3_bucket.go +++ b/internal/inventory/awsfetcher/fetcher_s3_bucket.go @@ -36,13 +36,6 @@ type s3BucketFetcher struct { AccountName string } -var s3BucketClassification = inventory.AssetClassification{ - Category: inventory.CategoryInfrastructure, - SubCategory: inventory.SubCategoryStorage, - Type: inventory.TypeObjectStorage, - SubType: inventory.SubTypeS3, -} - type s3BucketProvider interface { DescribeBuckets(ctx context.Context) ([]awslib.AwsResource, error) } @@ -74,23 +67,18 @@ func (s *s3BucketFetcher) Fetch(ctx context.Context, assetChannel chan<- invento for _, bucket := range buckets { assetChannel <- inventory.NewAssetEvent( - s3BucketClassification, - []string{bucket.GetResourceArn()}, + inventory.AssetClassificationAwsS3Bucket, + bucket.GetResourceArn(), bucket.GetResourceName(), inventory.WithRawAsset(bucket), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: bucket.Region, - Account: inventory.AssetCloudAccount{ - Id: s.AccountId, - Name: s.AccountName, - }, - Service: &inventory.AssetCloudService{ - Name: "AWS S3", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: bucket.Region, + AccountID: s.AccountId, + AccountName: s.AccountName, + ServiceName: "AWS S3", }), - inventory.WithResourcePolicies(convertPolicy(bucket.BucketPolicy)...), ) } } diff --git a/internal/inventory/awsfetcher/fetcher_s3_bucket_test.go b/internal/inventory/awsfetcher/fetcher_s3_bucket_test.go index e9d7cb7529..e06f22872b 100644 --- a/internal/inventory/awsfetcher/fetcher_s3_bucket_test.go +++ b/internal/inventory/awsfetcher/fetcher_s3_bucket_test.go @@ -104,62 +104,28 @@ func TestS3BucketFetcher_Fetch(t *testing.T) { expected := []inventory.AssetEvent{ inventory.NewAssetEvent( inventory.AssetClassificationAwsS3Bucket, - []string{"arn:aws:s3:::bucket-1"}, + "arn:aws:s3:::bucket-1", "bucket-1", inventory.WithRawAsset(bucket1), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: "europe-west-1", - Account: inventory.AssetCloudAccount{ - Id: "123", - Name: "alias", - }, - Service: &inventory.AssetCloudService{ - Name: "AWS S3", - }, - }), - inventory.WithResourcePolicies(inventory.AssetResourcePolicy{ - Version: pointers.Ref("2012-10-17"), - Id: pointers.Ref("Test 1"), - Effect: "Allow", - Principal: map[string]any{ - "AWS": "dima", - "service": "aws.com", - }, - Action: []string{"read", "update", "delete"}, - Resource: []string{"s3/bucket", "s3/bucket/*"}, - }, inventory.AssetResourcePolicy{ - Version: pointers.Ref("2012-10-17"), - Id: pointers.Ref("Test 2"), - Effect: "Deny", - Principal: map[string]any{"AWS": "romulo"}, - Action: []string{"delete"}, - Resource: []string{"s3/bucket"}, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: "europe-west-1", + AccountID: "123", + AccountName: "alias", + ServiceName: "AWS S3", }), ), inventory.NewAssetEvent( inventory.AssetClassificationAwsS3Bucket, - []string{"arn:aws:s3:::bucket-2"}, + "arn:aws:s3:::bucket-2", "bucket-2", inventory.WithRawAsset(bucket2), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: "europe-west-1", - Account: inventory.AssetCloudAccount{ - Id: "123", - Name: "alias", - }, - Service: &inventory.AssetCloudService{ - Name: "AWS S3", - }, - }), - inventory.WithResourcePolicies(inventory.AssetResourcePolicy{ - Version: pointers.Ref("2012-10-17"), - Id: pointers.Ref("Test 1"), - Effect: "Allow", - Principal: map[string]any{"*": "*"}, - Action: []string{"read"}, - Resource: []string{"s3/bucket"}, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: "europe-west-1", + AccountID: "123", + AccountName: "alias", + ServiceName: "AWS S3", }), ), } diff --git a/internal/inventory/awsfetcher/fetcher_sns.go b/internal/inventory/awsfetcher/fetcher_sns.go index 86c082d531..d81b357f80 100644 --- a/internal/inventory/awsfetcher/fetcher_sns.go +++ b/internal/inventory/awsfetcher/fetcher_sns.go @@ -60,19 +60,15 @@ func (s *snsFetcher) Fetch(ctx context.Context, assetChannel chan<- inventory.As for _, item := range awsResources { assetChannel <- inventory.NewAssetEvent( inventory.AssetClassificationAwsSnsTopic, - []string{item.GetResourceArn()}, + item.GetResourceArn(), item.GetResourceName(), inventory.WithRawAsset(item), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Region: item.GetRegion(), - Account: inventory.AssetCloudAccount{ - Id: s.AccountId, - Name: s.AccountName, - }, - Service: &inventory.AssetCloudService{ - Name: "AWS SNS", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + Region: item.GetRegion(), + AccountID: s.AccountId, + AccountName: s.AccountName, + ServiceName: "AWS SNS", }), ) } diff --git a/internal/inventory/awsfetcher/fetcher_sns_test.go b/internal/inventory/awsfetcher/fetcher_sns_test.go index 5ab22226cb..8c6a490b8e 100644 --- a/internal/inventory/awsfetcher/fetcher_sns_test.go +++ b/internal/inventory/awsfetcher/fetcher_sns_test.go @@ -45,18 +45,14 @@ func TestSNSFetcher_Fetch(t *testing.T) { expected := []inventory.AssetEvent{ inventory.NewAssetEvent( inventory.AssetClassificationAwsSnsTopic, - []string{"topic:arn:test-topic"}, + "topic:arn:test-topic", "test-topic", inventory.WithRawAsset(awsResource), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AwsCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: "123", - Name: "alias", - }, - Service: &inventory.AssetCloudService{ - Name: "AWS SNS", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AwsCloudProvider, + AccountID: "123", + AccountName: "alias", + ServiceName: "AWS SNS", }), ), } diff --git a/internal/inventory/azurefetcher/fetcher_account.go b/internal/inventory/azurefetcher/fetcher_account.go index f30244586b..e5568e8e3a 100644 --- a/internal/inventory/azurefetcher/fetcher_account.go +++ b/internal/inventory/azurefetcher/fetcher_account.go @@ -73,17 +73,13 @@ func (f *accountFetcher) fetch(ctx context.Context, resourceName string, functio for _, item := range azureAssets { assetChan <- inventory.NewAssetEvent( classification, - []string{item.Id}, + item.Id, item.DisplayName, inventory.WithRawAsset(item), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AzureCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: item.TenantId, - }, - Service: &inventory.AssetCloudService{ - Name: "Azure", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AzureCloudProvider, + AccountID: item.TenantId, + ServiceName: "Azure", }), ) } diff --git a/internal/inventory/azurefetcher/fetcher_account_test.go b/internal/inventory/azurefetcher/fetcher_account_test.go index 514b8107be..20b7519647 100644 --- a/internal/inventory/azurefetcher/fetcher_account_test.go +++ b/internal/inventory/azurefetcher/fetcher_account_test.go @@ -40,17 +40,13 @@ func TestAccountFetcher_Fetch_Tenants(t *testing.T) { expected := []inventory.AssetEvent{ inventory.NewAssetEvent( inventory.AssetClassificationAzureTenant, - []string{"/tenants/"}, + "/tenants/", "Mario", inventory.WithRawAsset(azureAssets[0]), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AzureCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: "", - }, - Service: &inventory.AssetCloudService{ - Name: "Azure", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AzureCloudProvider, + AccountID: "", + ServiceName: "Azure", }), ), } @@ -77,17 +73,13 @@ func TestAccountFetcher_Fetch_Subscriptions(t *testing.T) { expected := []inventory.AssetEvent{ inventory.NewAssetEvent( inventory.AssetClassificationAzureSubscription, - []string{"/subscriptions/"}, + "/subscriptions/", "Luigi", inventory.WithRawAsset(azureAssets[0]), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AzureCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: "", - }, - Service: &inventory.AssetCloudService{ - Name: "Azure", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AzureCloudProvider, + AccountID: "", + ServiceName: "Azure", }), ), } diff --git a/internal/inventory/azurefetcher/fetcher_activedirectory.go b/internal/inventory/azurefetcher/fetcher_activedirectory.go index fb121dc68a..a2352fdc00 100644 --- a/internal/inventory/azurefetcher/fetcher_activedirectory.go +++ b/internal/inventory/azurefetcher/fetcher_activedirectory.go @@ -65,19 +65,15 @@ func (f *activedirectoryFetcher) fetchServicePrincipals(ctx context.Context, ass } assetChan <- inventory.NewAssetEvent( inventory.AssetClassificationAzureServicePrincipal, - []string{pointers.Deref(item.GetId())}, + pointers.Deref(item.GetId()), pointers.Deref(item.GetDisplayName()), inventory.WithRawAsset( item.GetBackingStore().Enumerate(), ), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AzureCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: tenantId, - }, - Service: &inventory.AssetCloudService{ - Name: "Azure", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AzureCloudProvider, + AccountID: tenantId, + ServiceName: "Azure", }), ) } diff --git a/internal/inventory/azurefetcher/fetcher_activedirectory_test.go b/internal/inventory/azurefetcher/fetcher_activedirectory_test.go index bb142da58f..6c427511fb 100644 --- a/internal/inventory/azurefetcher/fetcher_activedirectory_test.go +++ b/internal/inventory/azurefetcher/fetcher_activedirectory_test.go @@ -59,17 +59,13 @@ func TestActiveDirectoryFetcher_Fetch(t *testing.T) { expected := []inventory.AssetEvent{ inventory.NewAssetEvent( inventory.AssetClassificationAzureServicePrincipal, - []string{"id"}, + "id", "dn", inventory.WithRawAsset(values), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AzureCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: appOwnerOrganizationId.String(), - }, - Service: &inventory.AssetCloudService{ - Name: "Azure", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AzureCloudProvider, + AccountID: appOwnerOrganizationId.String(), + ServiceName: "Azure", }), ), } diff --git a/internal/inventory/azurefetcher/fetcher_resource_graph.go b/internal/inventory/azurefetcher/fetcher_resource_graph.go index 2cb877cd04..8e65e7e2bd 100644 --- a/internal/inventory/azurefetcher/fetcher_resource_graph.go +++ b/internal/inventory/azurefetcher/fetcher_resource_graph.go @@ -86,17 +86,13 @@ func (f *resourceGraphFetcher) fetch(ctx context.Context, resourceName, resource } assetChan <- inventory.NewAssetEvent( classification, - []string{item.Id}, + item.Id, name, inventory.WithRawAsset(item), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AzureCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: item.TenantId, - }, - Service: &inventory.AssetCloudService{ - Name: "Azure", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AzureCloudProvider, + AccountID: item.TenantId, + ServiceName: "Azure", }), ) } diff --git a/internal/inventory/azurefetcher/fetcher_resource_graph_test.go b/internal/inventory/azurefetcher/fetcher_resource_graph_test.go index bdf7118339..f3d92ab5f8 100644 --- a/internal/inventory/azurefetcher/fetcher_resource_graph_test.go +++ b/internal/inventory/azurefetcher/fetcher_resource_graph_test.go @@ -45,32 +45,24 @@ func TestResourceGraphFetcher_Fetch(t *testing.T) { expected := []inventory.AssetEvent{ inventory.NewAssetEvent( inventory.AssetClassificationAzureAppService, - []string{appService.Id}, + appService.Id, appService.Name, inventory.WithRawAsset(appService), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AzureCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: "", - }, - Service: &inventory.AssetCloudService{ - Name: "Azure", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AzureCloudProvider, + AccountID: "", + ServiceName: "Azure", }), ), inventory.NewAssetEvent( inventory.AssetClassificationAzureDisk, - []string{disk.Id}, + disk.Id, disk.Name, inventory.WithRawAsset(disk), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AzureCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: "", - }, - Service: &inventory.AssetCloudService{ - Name: "Azure", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AzureCloudProvider, + AccountID: "", + ServiceName: "Azure", }), ), } diff --git a/internal/inventory/azurefetcher/fetcher_storage.go b/internal/inventory/azurefetcher/fetcher_storage.go index 8676f8c662..d06d8c80f9 100644 --- a/internal/inventory/azurefetcher/fetcher_storage.go +++ b/internal/inventory/azurefetcher/fetcher_storage.go @@ -104,17 +104,13 @@ func (f *storageFetcher) fetch(ctx context.Context, storageAccounts []azurelib.A for _, item := range azureAssets { assetChan <- inventory.NewAssetEvent( classification, - []string{item.Id}, + item.Id, item.DisplayName, inventory.WithRawAsset(item), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AzureCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: item.TenantId, - }, - Service: &inventory.AssetCloudService{ - Name: "Azure", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AzureCloudProvider, + AccountID: item.TenantId, + ServiceName: "Azure", }), ) } diff --git a/internal/inventory/azurefetcher/fetcher_storage_test.go b/internal/inventory/azurefetcher/fetcher_storage_test.go index 05a6fdb7cf..078ff94641 100644 --- a/internal/inventory/azurefetcher/fetcher_storage_test.go +++ b/internal/inventory/azurefetcher/fetcher_storage_test.go @@ -55,38 +55,32 @@ func TestStorageFetcher_Fetch(t *testing.T) { expected := []inventory.AssetEvent{ inventory.NewAssetEvent( inventory.AssetClassificationAzureStorageBlobService, - []string{azureBlobService.Id}, + azureBlobService.Id, azureBlobService.Name, inventory.WithRawAsset(azureBlobService), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AzureCloudProvider, - Service: &inventory.AssetCloudService{ - Name: "Azure", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AzureCloudProvider, + ServiceName: "Azure", }), ), inventory.NewAssetEvent( inventory.AssetClassificationAzureStorageQueueService, - []string{azureQueueService.Id}, + azureQueueService.Id, azureQueueService.Name, inventory.WithRawAsset(azureQueueService), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AzureCloudProvider, - Service: &inventory.AssetCloudService{ - Name: "Azure", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AzureCloudProvider, + ServiceName: "Azure", }), ), inventory.NewAssetEvent( inventory.AssetClassificationAzureStorageQueue, - []string{azureQueue.Id}, + azureQueue.Id, azureQueue.Name, inventory.WithRawAsset(azureQueue), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.AzureCloudProvider, - Service: &inventory.AssetCloudService{ - Name: "Azure", - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AzureCloudProvider, + ServiceName: "Azure", }), ), } diff --git a/internal/inventory/cloud_assets.xlsx b/internal/inventory/cloud_assets.xlsx index 5f231b0b3c..0a00779f6b 100644 Binary files a/internal/inventory/cloud_assets.xlsx and b/internal/inventory/cloud_assets.xlsx differ diff --git a/internal/inventory/gcpfetcher/fetcher_assets.go b/internal/inventory/gcpfetcher/fetcher_assets.go index 374a8db1c0..f7f59b062d 100644 --- a/internal/inventory/gcpfetcher/fetcher_assets.go +++ b/internal/inventory/gcpfetcher/fetcher_assets.go @@ -85,45 +85,39 @@ func (f *assetsInventory) fetch(ctx context.Context, assetChan chan<- inventory. for _, item := range gcpAssets { assetChan <- inventory.NewAssetEvent( classification, - []string{item.Name}, + item.Name, item.Name, inventory.WithRawAsset(item), inventory.WithRelatedAssetIds( - f.findRelatedAssetIds(classification.SubType, item), + f.findRelatedAssetIds(classification.Type, item), ), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.GcpCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: item.CloudAccount.AccountId, - Name: item.CloudAccount.AccountName, - }, - Organization: inventory.AssetCloudOrganization{ - Id: item.CloudAccount.OrganisationId, - Name: item.CloudAccount.OrganizationName, - }, - Service: &inventory.AssetCloudService{ - Name: assetType, - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.GcpCloudProvider, + AccountID: item.CloudAccount.AccountId, + AccountName: item.CloudAccount.AccountName, + ProjectID: item.CloudAccount.OrganisationId, + ProjectName: item.CloudAccount.OrganizationName, + ServiceName: assetType, }), ) } } -func (f *assetsInventory) findRelatedAssetIds(subType inventory.AssetSubType, item *gcpinventory.ExtendedGcpAsset) []string { +func (f *assetsInventory) findRelatedAssetIds(t inventory.AssetType, item *gcpinventory.ExtendedGcpAsset) []string { ids := []string{} ids = append(ids, item.Ancestors...) if item.Resource != nil { ids = append(ids, item.Resource.Parent) } - ids = append(ids, f.findRelatedAssetIdsForSubType(subType, item)...) + ids = append(ids, f.findRelatedAssetIdsForType(t, item)...) ids = lo.Compact(ids) ids = lo.Uniq(ids) return ids } -func (f *assetsInventory) findRelatedAssetIdsForSubType(subType inventory.AssetSubType, item *gcpinventory.ExtendedGcpAsset) []string { +func (f *assetsInventory) findRelatedAssetIdsForType(t inventory.AssetType, item *gcpinventory.ExtendedGcpAsset) []string { ids := []string{} var fields map[string]*structpb.Value @@ -131,8 +125,8 @@ func (f *assetsInventory) findRelatedAssetIdsForSubType(subType inventory.AssetS fields = item.GetResource().GetData().GetFields() } - switch subType { - case inventory.SubTypeGcpInstance: + switch t { + case inventory.AssetClassificationGcpInstance.Type: if v, ok := fields["networkInterfaces"]; ok { for _, networkInterface := range v.GetListValue().GetValues() { networkInterfaceFields := networkInterface.GetStructValue().GetFields() @@ -154,9 +148,9 @@ func (f *assetsInventory) findRelatedAssetIdsForSubType(subType inventory.AssetS } ids = appendIfExists(ids, fields, "machineType") ids = appendIfExists(ids, fields, "zone") - case inventory.SubTypeGcpFirewall, inventory.SubTypeGcpSubnet: + case inventory.AssetClassificationGcpFirewall.Type, inventory.AssetClassificationGcpSubnet.Type: ids = appendIfExists(ids, fields, "network") - case inventory.SubTypeGcpProject, inventory.SubTypeGcpBucket: + case inventory.AssetClassificationGcpProject.Type, inventory.AssetClassificationGcpBucket.Type: if item.IamPolicy == nil { break } diff --git a/internal/inventory/gcpfetcher/fetcher_assets_test.go b/internal/inventory/gcpfetcher/fetcher_assets_test.go index 5e8b39c3c8..4e96d4d024 100644 --- a/internal/inventory/gcpfetcher/fetcher_assets_test.go +++ b/internal/inventory/gcpfetcher/fetcher_assets_test.go @@ -50,23 +50,17 @@ func TestAccountFetcher_Fetch_Assets(t *testing.T) { expected := lo.Map(ResourcesToFetch, func(r ResourcesClassification, _ int) inventory.AssetEvent { return inventory.NewAssetEvent( r.classification, - []string{"/projects//some_resource"}, + "/projects//some_resource", "/projects//some_resource", inventory.WithRawAsset(assets[0]), inventory.WithRelatedAssetIds([]string{}), - inventory.WithCloud(inventory.AssetCloud{ - Provider: inventory.GcpCloudProvider, - Account: inventory.AssetCloudAccount{ - Id: "", - Name: "", - }, - Organization: inventory.AssetCloudOrganization{ - Id: "", - Name: "", - }, - Service: &inventory.AssetCloudService{ - Name: r.assetType, - }, + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.GcpCloudProvider, + AccountID: "", + AccountName: "", + ProjectID: "", + ProjectName: "", + ServiceName: r.assetType, }), ) }) diff --git a/internal/inventory/inventory.go b/internal/inventory/inventory.go index 3cb6d88c12..dd989ccaad 100644 --- a/internal/inventory/inventory.go +++ b/internal/inventory/inventory.go @@ -20,6 +20,7 @@ package inventory import ( "context" "fmt" + "strings" "time" "github.com/elastic/beats/v7/libbeat/beat" @@ -30,7 +31,7 @@ import ( ) const ( - indexTemplate = "logs-cloud_asset_inventory.asset_inventory-%s_%s_%s_%s-default" + indexTemplate = "logs-cloud_asset_inventory.asset_inventory-%s_%s-default" minimalPeriod = 30 * time.Second ) @@ -123,21 +124,23 @@ func (a *AssetInventory) runAllFetchersOnce(ctx context.Context) { func (a *AssetInventory) publish(assets []AssetEvent) { events := lo.Map(assets, func(e AssetEvent, _ int) beat.Event { var relatedEntity []string - relatedEntity = append(relatedEntity, e.Asset.Id...) - if len(e.Asset.RelatedEntityId) > 0 { - relatedEntity = append(relatedEntity, e.Asset.RelatedEntityId...) + relatedEntity = append(relatedEntity, e.Entity.Id) + if len(e.Entity.relatedEntityId) > 0 { + relatedEntity = append(relatedEntity, e.Entity.relatedEntityId...) } return beat.Event{ - Meta: mapstr.M{libevents.FieldMetaIndex: generateIndex(e.Asset)}, + Meta: mapstr.M{libevents.FieldMetaIndex: generateIndex(e.Entity)}, Timestamp: a.now(), Fields: mapstr.M{ - "asset": e.Asset, - "cloud": e.Cloud, - "host": e.Host, - "network": e.Network, - "iam": e.IAM, - "resource_policies": e.ResourcePolicies, - "related.entity": relatedEntity, + "entity": e.Entity, + "event": e.Event, + "cloud": e.Cloud, + "host": e.Host, + "network": e.Network, + "user": e.User, + "Attributes": e.RawAttributes, + "labels": e.Labels, + "related.entity": relatedEntity, }, } }) @@ -145,14 +148,19 @@ func (a *AssetInventory) publish(assets []AssetEvent) { a.publisher.PublishAll(events) } -func generateIndex(a Asset) string { - return fmt.Sprintf(indexTemplate, a.Category, a.SubCategory, a.Type, a.SubType) +func generateIndex(a Entity) string { + return fmt.Sprintf(indexTemplate, slugfy(string(a.Category)), slugfy(string(a.Type))) } -func (a *AssetInventory) Stop() { - close(a.assetCh) +func slugfy(s string) string { + chunks := strings.Split(s, " ") + clean := make([]string, len(chunks)) + for i, c := range chunks { + clean[i] = strings.ToLower(c) + } + return strings.Join(clean, "_") } -func removeEmpty(list []string) []string { - return lo.Filter(list, func(item string, _ int) bool { return item != "" }) +func (a *AssetInventory) Stop() { + close(a.assetCh) } diff --git a/internal/inventory/inventory_test.go b/internal/inventory/inventory_test.go index 30e4bb3deb..89c412b4a9 100644 --- a/internal/inventory/inventory_test.go +++ b/internal/inventory/inventory_test.go @@ -31,63 +31,47 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/elastic/cloudbeat/internal/resources/utils/pointers" "github.com/elastic/cloudbeat/internal/resources/utils/testhelper" ) func TestAssetInventory_Run(t *testing.T) { + var emptyRef *any now := func() time.Time { return time.Date(2024, 1, 1, 1, 1, 1, 0, time.Local) } expected := []beat.Event{ { - Meta: mapstr.M{libevents.FieldMetaIndex: "logs-cloud_asset_inventory.asset_inventory-infrastructure_compute_virtual-machine_ec2-instance-default"}, + Meta: mapstr.M{libevents.FieldMetaIndex: "logs-cloud_asset_inventory.asset_inventory-infrastructure_virtual_machine-default"}, Timestamp: now(), Fields: mapstr.M{ - "asset": Asset{ - Id: []string{"arn:aws:ec2:us-east::ec2/234567890"}, + "entity": Entity{ + Id: "arn:aws:ec2:us-east::ec2/234567890", Name: "test-server", AssetClassification: AssetClassification{ - Category: CategoryInfrastructure, - SubCategory: SubCategoryCompute, - Type: TypeVirtualMachine, - SubType: SubTypeEC2, + Category: CategoryInfrastructure, + Type: "Virtual Machine", }, - Tags: map[string]string{"Name": "test-server", "key": "value"}, }, - "cloud": &AssetCloud{ + "event": Event{ + Kind: "asset", + }, + "labels": map[string]string{"Name": "test-server", "key": "value"}, + "cloud": &Cloud{ Provider: AwsCloudProvider, Region: "us-east", }, - "host": &AssetHost{ - Architecture: string(types.ArchitectureValuesX8664), - ImageId: pointers.Ref("image-id"), - InstanceType: "instance-type", - Platform: "linux", - PlatformDetails: pointers.Ref("ubuntu"), - }, - "network": &AssetNetwork{ - NetworkId: pointers.Ref("vpc-id"), - SubnetIds: []string{"subnetId"}, - Ipv6Address: pointers.Ref("ipv6"), - PublicIpAddress: pointers.Ref("public-ip-addr"), - PrivateIpAddress: pointers.Ref("private-ip-addre"), - PublicDnsName: pointers.Ref("public-dns"), - PrivateDnsName: pointers.Ref("private-dns"), + "host": &Host{ + Architecture: string(types.ArchitectureValuesX8664), + Type: "instance-type", + ID: "i-a2", }, - "iam": &AssetIAM{ - Id: pointers.Ref("a123123"), - Arn: pointers.Ref("123123:123123:123123"), + "network": &Network{ + Name: "vpc-id", }, - "resource_policies": []AssetResourcePolicy{ - { - Version: pointers.Ref("2012-10-17"), - Id: pointers.Ref("Test 1"), - Effect: "Allow", - Principal: map[string]any{"*": "*"}, - Action: []string{"read"}, - Resource: []string{"s3/bucket"}, - }, + "user": &User{ + ID: "a123123", + Name: "name", }, "related.entity": []string{"arn:aws:ec2:us-east::ec2/234567890"}, + "Attributes": emptyRef, }, }, } @@ -102,45 +86,27 @@ func TestAssetInventory_Run(t *testing.T) { fetcher.EXPECT().Fetch(mock.Anything, mock.Anything).Run(func(_ context.Context, assetChannel chan<- AssetEvent) { assetChannel <- NewAssetEvent( AssetClassification{ - Category: CategoryInfrastructure, - SubCategory: SubCategoryCompute, - Type: TypeVirtualMachine, - SubType: SubTypeEC2, + Category: CategoryInfrastructure, + Type: "Virtual Machine", }, - []string{"arn:aws:ec2:us-east::ec2/234567890"}, + "arn:aws:ec2:us-east::ec2/234567890", "test-server", - WithTags(map[string]string{"Name": "test-server", "key": "value"}), - WithCloud(AssetCloud{ + WithLabels(map[string]string{"Name": "test-server", "key": "value"}), + WithCloud(Cloud{ Provider: AwsCloudProvider, Region: "us-east", }), - WithHost(AssetHost{ - Architecture: string(types.ArchitectureValuesX8664), - ImageId: pointers.Ref("image-id"), - InstanceType: "instance-type", - Platform: "linux", - PlatformDetails: pointers.Ref("ubuntu"), - }), - WithIAM(AssetIAM{ - Id: pointers.Ref("a123123"), - Arn: pointers.Ref("123123:123123:123123"), + WithHost(Host{ + Architecture: string(types.ArchitectureValuesX8664), + Type: "instance-type", + ID: "i-a2", }), - WithNetwork(AssetNetwork{ - NetworkId: pointers.Ref("vpc-id"), - SubnetIds: []string{"subnetId"}, - Ipv6Address: pointers.Ref("ipv6"), - PublicIpAddress: pointers.Ref("public-ip-addr"), - PrivateIpAddress: pointers.Ref("private-ip-addre"), - PublicDnsName: pointers.Ref("public-dns"), - PrivateDnsName: pointers.Ref("private-dns"), + WithUser(User{ + ID: "a123123", + Name: "name", }), - WithResourcePolicies(AssetResourcePolicy{ - Version: pointers.Ref("2012-10-17"), - Id: pointers.Ref("Test 1"), - Effect: "Allow", - Principal: map[string]any{"*": "*"}, - Action: []string{"read"}, - Resource: []string{"s3/bucket"}, + WithNetwork(Network{ + Name: "vpc-id", }), ) }) diff --git a/scripts/update_assets_md/main.go b/scripts/update_assets_md/main.go index 1f23982f6d..8925e2ef90 100644 --- a/scripts/update_assets_md/main.go +++ b/scripts/update_assets_md/main.go @@ -43,18 +43,21 @@ const ( ) type Classification struct { - Category string - SubCategory string - Type string - SubType string + Category string + OldType string + Type string } func (item Classification) ID() string { - return fmt.Sprintf("%s_%s_%s_%s", + if item.Type != "" { + return fmt.Sprintf("%s_%s", + strcase.ToKebab(item.Category), + strcase.ToKebab(item.Type), + ) + } + return fmt.Sprintf("%s_%s", strcase.ToKebab(item.Category), - strcase.ToKebab(item.SubCategory), - strcase.ToKebab(item.Type), - strcase.ToKebab(item.SubType), + strcase.ToKebab(item.OldType), ) } @@ -162,7 +165,7 @@ func loadClassificationsFromExcel(filepath string) (*ByProvider, error) { return nil, fmt.Errorf("failed to open Excel file: %w", err) } - sheets := map[int]string{1: AWS_PREFIX, 2: AZURE_PREFIX, 3: GCP_PREFIX} + sheets := map[int]string{3: AWS_PREFIX, 4: AZURE_PREFIX, 5: GCP_PREFIX} for sheetNo, provider := range sheets { sheetName := f.GetSheetName(sheetNo) rows, err := f.GetRows(sheetName) @@ -173,10 +176,9 @@ func loadClassificationsFromExcel(filepath string) (*ByProvider, error) { headers := rows[0] for _, row := range rows[1:] { cl := Classification{ - Category: row[getColumnIndex(headers, "asset.category")], - SubCategory: row[getColumnIndex(headers, "asset.subcategory")], - Type: row[getColumnIndex(headers, "asset.type")], - SubType: row[getColumnIndex(headers, "asset.subtype")], + Category: row[getColumnIndex(headers, "Category")], + OldType: row[getColumnIndex(headers, "(current) Type")], + Type: row[getColumnIndex(headers, "Updated Type")], } output.Assign(provider, cl) } @@ -205,8 +207,8 @@ func writeSummary(plannedByProvider, implementedByProvider *ByProvider, filepath // table of assets table := []string{ "
Full table\n", - "| Category | SubCategory | Type | SubType | Implemented? |", - "|---|---|---|---|---|", + "| Category | Old Type | Type | Implemented? |", + "|---|---|---|---|", } for _, key := range sortedKeys { @@ -221,8 +223,8 @@ func writeSummary(plannedByProvider, implementedByProvider *ByProvider, filepath } table = append(table, fmt.Sprintf( - "| %s | %s | %s | %s | %s |", - item.Category, item.SubCategory, item.Type, item.SubType, status, + "| %s | %s | %s | %s |", + item.Category, item.OldType, item.Type, status, ), ) } @@ -290,8 +292,8 @@ func extractClassification(expr ast.Expr) (Classification, error) { return output, fmt.Errorf("value is not a composite literal, skipping") } - if len(compLit.Elts) != 4 { - return output, fmt.Errorf("expected full, 4-field classification; got %d", len(compLit.Elts)) + if len(compLit.Elts) != 2 { + return output, fmt.Errorf("expected full, 2-field classification; got %d", len(compLit.Elts)) } classification := []string{} @@ -304,9 +306,7 @@ func extractClassification(expr ast.Expr) (Classification, error) { } output.Category = classification[0] - output.SubCategory = classification[1] - output.Type = classification[2] - output.SubType = classification[3] + output.Type = classification[1] return output, nil } diff --git a/tests/commonlib/io_utils.py b/tests/commonlib/io_utils.py index 4567a5e81e..6e10db97a2 100644 --- a/tests/commonlib/io_utils.py +++ b/tests/commonlib/io_utils.py @@ -59,28 +59,22 @@ def get_events_from_index( def get_assets_from_index( elastic_client, category: str, - sub_category: str, type_: str, - sub_type: str, time_after: datetime, ) -> list[Munch]: """ Resturns assets from a given index matching given classification. @param elastic_client: Client to connect to Elasticsearch. - @param category: Asset category used as a filter - @param sub_category: Asset subcategory used as a filter - @param type: Asset type used as a filter - @param sub_type: Asset subtype used as a filter + @param category: Entity category used as a filter + @param type: Entity type used as a filter @param time_after: Filter events having timestamp > time_after @return: List of Munch objects """ query = { "bool": { "must": [ - {"match": {"asset.category": category}}, - {"match": {"asset.sub_category": sub_category}}, - {"match": {"asset.type": type_}}, - {"match": {"asset.sub_type": sub_type}}, + {"match": {"entity.category": category}}, + {"match": {"entity.type": type_}}, ], "filter": [ { diff --git a/tests/commonlib/utils.py b/tests/commonlib/utils.py index d7d350f849..24a55015d7 100644 --- a/tests/commonlib/utils.py +++ b/tests/commonlib/utils.py @@ -84,9 +84,7 @@ def get_ES_assets( elastic_client, timeout, category, - sub_category, type_, - sub_type, exec_timestamp, resource_identifier=lambda r: True, ) -> Union[List[munch.Munch], None]: @@ -99,9 +97,7 @@ def get_ES_assets( assets = get_assets_from_index( elastic_client, category, - sub_category, type_, - sub_type, latest_timestamp, ) except Exception as e: diff --git a/tests/product/tests/data/asset_inventory_test_case.py b/tests/product/tests/data/asset_inventory_test_case.py index 7fc58157db..84ac563fcf 100644 --- a/tests/product/tests/data/asset_inventory_test_case.py +++ b/tests/product/tests/data/asset_inventory_test_case.py @@ -12,9 +12,7 @@ class AssetInventoryCase: """ category: str - sub_category: str type_: str - sub_type: str def __iter__(self): return iter(astuple(self)) diff --git a/tests/product/tests/data/aws_asset_inventory/test_cases.py b/tests/product/tests/data/aws_asset_inventory/test_cases.py index 3b308bbca8..41083fb5c4 100644 --- a/tests/product/tests/data/aws_asset_inventory/test_cases.py +++ b/tests/product/tests/data/aws_asset_inventory/test_cases.py @@ -7,135 +7,91 @@ test_cases = { "[Asset Inventory][AWS][EC2] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="compute", - type_="virtual-machine", - sub_type="ec2-instance", + category="Host", + type_="AWS EC2 Instance", ), "[Asset Inventory][AWS][IAM Role] assets found": AssetInventoryCase( - category="identity", - sub_category="digital-identity", - type_="role", - sub_type="iam-role", + category="Service Account", + type_="AWS IAM Role", ), "[Asset Inventory][AWS][ELBv1] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="network", - type_="load-balancer", - sub_type="elastic-load-balancer", + category="Load Balancer", + type_="AWS Elastic Load Balancer", ), "[Asset Inventory][AWS][ELBv2] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="network", - type_="load-balancer", - sub_type="elastic-load-balancer-v2", + category="Load Balancer", + type_="AWS Elastic Load Balancer v2", ), "[Asset Inventory][AWS][IAM Policy] assets found": AssetInventoryCase( - category="identity", - sub_category="digital-identity", - type_="policy", - sub_type="iam-policy", + category="Access Management", + type_="AWS IAM Policy", ), "[Asset Inventory][AWS][IAM User] assets found": AssetInventoryCase( - category="identity", - sub_category="digital-identity", - type_="user", - sub_type="iam-user", + category="Identity", + type_="AWS IAM User", ), "[Asset Inventory][AWS][Lambda Event Source Mapping] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="integration", - type_="event-source", - sub_type="lambda-event-source-mapping", + category="FaaS", + type_="AWS Lambda Event Source Mapping", ), "[Asset Inventory][AWS][Lambda Function] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="compute", - type_="serverless", - sub_type="lambda-function", + category="FaaS", + type_="AWS Lambda Function", ), "[Asset Inventory][AWS][Lambda Layer] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="compute", - type_="serverless", - sub_type="lambda-layer", + category="FaaS", + type_="AWS Lambda Layer", ), "[Asset Inventory][AWS][Internet Gateway] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="network", - type_="gateway", - sub_type="internet-gateway", + category="Gateway", + type_="AWS Internet Gateway", ), "[Asset Inventory][AWS][NAT Gateway] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="network", - type_="gateway", - sub_type="nat-gateway", + category="Gateway", + type_="AWS NAT Gateway", ), - "[Asset Inventory][AWS][VPC ACL] assets found": AssetInventoryCase( - category="identity", - sub_category="authorization", - type_="acl", - sub_type="s3-access-control-list", + "[Asset Inventory][AWS][EC2 Network ACL] assets found": AssetInventoryCase( + category="Networking", + type_="AWS EC2 Network ACL", ), "[Asset Inventory][AWS][EC2 Network Interface] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="network", - type_="interface", - sub_type="ec2-network-interface", + category="Networking", + type_="AWS EC2 Network Interface", ), "[Asset Inventory][AWS][Security Group] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="network", - type_="firewall", - sub_type="ec2-security-group", + category="Firewall", + type_="AWS EC2 Security Group", ), "[Asset Inventory][AWS][EC2 Subnet] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="network", - type_="subnet", - sub_type="ec2-subnet", + category="Networking", + type_="AWS EC2 Subnet", ), "[Asset Inventory][AWS][Transit Gateway] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="network", - type_="virtual-network", - sub_type="transit-gateway", + category="Gateway", + type_="AWS Transit Gateway", ), "[Asset Inventory][AWS][Transit Gateway Attachment] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="network", - type_="virtual-network", - sub_type="transit-gateway-attachment", + category="Gateway", + type_="AWS Transit Gateway Attachment", ), "[Asset Inventory][AWS][VPC Peering Connection] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="network", - type_="peering", - sub_type="vpc-peering-connection", + category="Networking", + type_="AWS VPC Peering Connection", ), "[Asset Inventory][AWS][VPC] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="network", - type_="virtual-network", - sub_type="vpc", + category="Networking", + type_="AWS VPC", ), "[Asset Inventory][AWS][RDS] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="database", - type_="relational", - sub_type="rds-instance", + category="Database", + type_="AWS RDS Instance", ), "[Asset Inventory][AWS][S3] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="storage", - type_="object-storage", - sub_type="s3-bucket", + category="Storage Bucket", + type_="AWS S3 Bucket", ), "[Asset Inventory][AWS][SNS Topic] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="messaging", - type_="notification-service", - sub_type="sns-topic", + category="Messaging Service", + type_="AWS SNS Topic", ), } diff --git a/tests/product/tests/data/azure_asset_inventory/test_cases.py b/tests/product/tests/data/azure_asset_inventory/test_cases.py index ae5162b05d..5bb20df53e 100644 --- a/tests/product/tests/data/azure_asset_inventory/test_cases.py +++ b/tests/product/tests/data/azure_asset_inventory/test_cases.py @@ -6,93 +6,75 @@ test_cases = { "[Asset Inventory][Azure][Azure App Service] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="application", - type_="web-application", - sub_type="azure-app-service", + category="Web Service", + type_="Azure App Service", ), "[Asset Inventory][Azure][Azure Virtual Machine] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="compute", - type_="virtual-machine", - sub_type="azure-virtual-machine", + category="Host", + type_="Azure Virtual Machine", ), "[Asset Inventory][Azure][Azure Container Registry] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="container", - type_="registry", - sub_type="azure-container-registry", + category="Container Registry", + type_="Azure Container Registry", ), + "[Asset Inventory][Azure][Azure Cosmos DB Account] assets found": AssetInventoryCase( + category="Infrastructure", + type_="Azure Cosmos DB Account", + ), + # "[Asset Inventory][Azure][Azure Cosmos DB SQL Database] assets found": AssetInventoryCase( + # category="Infrastructure", + # type_="Azure Cosmos DB SQL Database", + # ), "[Asset Inventory][Azure][Azure SQL Database] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="database", - type_="relational", - sub_type="azure-sql-database", + category="Database", + type_="Azure SQL Database", ), "[Asset Inventory][Azure][Azure SQL Server] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="database", - type_="relational", - sub_type="azure-sql-server", + category="Database", + type_="Azure SQL Server", + ), + "[Asset Inventory][Azure][Azure Principal] assets found": AssetInventoryCase( + category="Identity", + type_="Azure Principal", ), "[Asset Inventory][Azure][Azure Elastic Pool] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="database", - type_="scalability", - sub_type="azure-elastic-pool", + category="Database", + type_="Azure Elastic Pool", ), "[Asset Inventory][Azure][Azure Subscription] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="management", - type_="cloud-account", - sub_type="azure-subscription", + category="Access Management", + type_="Azure Subscription", ), "[Asset Inventory][Azure][Azure Tenant] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="management", - type_="cloud-account", - sub_type="azure-tenant", + category="Access Management", + type_="Azure Tenant", ), "[Asset Inventory][Azure][Azure Resource Group] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="management", - type_="resource-group", - sub_type="azure-resource-group", + category="Access Management", + type_="Azure Resource Group", ), "[Asset Inventory][Azure][Azure Disk] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="storage", - type_="disk", - sub_type="azure-disk", + category="Volume", + type_="Azure Disk", ), "[Asset Inventory][Azure][Azure Snapshot] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="storage", - type_="snapshot", - sub_type="azure-snapshot", + category="Snapshot", + type_="Azure Snapshot", ), "[Asset Inventory][Azure][Azure Storage Account] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="storage", - type_="storage", - sub_type="azure-storage-account", + category="Private Endpoint", + type_="Azure Storage Account", ), "[Asset Inventory][Azure][Azure Storage Queue] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="application-integration", - type_="message-queue", - sub_type="azure-storage-queue", + category="Messaging Service", + type_="Azure Storage Queue", ), "[Asset Inventory][Azure][Azure Storage Queue Service] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="application-integration", - type_="message-queue", - sub_type="azure-storage-queue-service", + category="Messaging Service", + type_="Azure Storage Queue Service", ), "[Asset Inventory][Azure][Azure Storage Blob Service] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="storage", - type_="object-storage", - sub_type="azure-storage-blob-service", + category="Storage Bucket", + type_="Azure Storage Blob Service", ), } diff --git a/tests/product/tests/data/gcp_asset_inventory/test_cases.py b/tests/product/tests/data/gcp_asset_inventory/test_cases.py index 4b9f83f039..f3541b1c6f 100644 --- a/tests/product/tests/data/gcp_asset_inventory/test_cases.py +++ b/tests/product/tests/data/gcp_asset_inventory/test_cases.py @@ -6,87 +6,59 @@ test_cases = { "[Asset Inventory][GCP][Service Account] assets found": AssetInventoryCase( - category="identity", - sub_category="service-identity", - type_="service-account", - sub_type="gcp-service-account", + category="Access Management", + type_="GCP Service Account", ), "[Asset Inventory][GCP][Service Account Key] assets found": AssetInventoryCase( - category="identity", - sub_category="service-identity", - type_="service-account-key", - sub_type="gcp-service-account-key", + category="Access Management", + type_="GCP Service Account Key", ), "[Asset Inventory][GCP][Instance] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="compute", - type_="virtual-machine", - sub_type="gcp-instance", + category="Host", + type_="GCP Compute Instance", ), "[Asset Inventory][GCP][Subnet] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="network", - type_="subnet", - sub_type="gcp-subnet", + category="Subnet", + type_="GCP Subnet", ), "[Asset Inventory][GCP][Project] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="management", - type_="cloud-account", - sub_type="gcp-project", + category="Account", + type_="GCP Project", ), # "[Asset Inventory][GCP][Organization] assets found": AssetInventoryCase( - # category="infrastructure", - # sub_category="management", + # category="Infrastructure", # type_="cloud-account", - # sub_type="gcp-organization", # ), # "[Asset Inventory][GCP][Folder] assets found": AssetInventoryCase( - # category="infrastructure", - # sub_category="management", + # category="Infrastructure", # type_="resource-hierarchy", - # sub_type="gcp-folder", # ), "[Asset Inventory][GCP][Bucket] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="storage", - type_="object-storage", - sub_type="gcp-bucket", + category="Storage Bucket", + type_="GCP Bucket", ), "[Asset Inventory][GCP][Firewall] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="network", - type_="firewall", - sub_type="gcp-firewall", + category="Firewall", + type_="GCP Firewall", ), # "[Asset Inventory][GCP][GKE Cluster] assets found": AssetInventoryCase( - # category="infrastructure", - # sub_category="container", + # category="Infrastructure", # type_="orchestration", - # sub_type="gcp-gke-cluster", # ), # "[Asset Inventory][GCP][Forwarding Rule] assets found": AssetInventoryCase( - # category="infrastructure", - # sub_category="network", + # category="Infrastructure", # type_="load-balancing", - # sub_type="gcp-forwarding-rule", # ), "[Asset Inventory][GCP][IAM Role] assets found": AssetInventoryCase( - category="identity", - sub_category="access-management", - type_="iam-role", - sub_type="gcp-iam-role", + category="Service Usage Technology", + type_="GCP IAM Role", ), # "[Asset Inventory][GCP][Cloud Function] assets found": AssetInventoryCase( - # category="infrastructure", - # sub_category="serverless", + # category="Infrastructure", # type_="function", - # sub_type="gcp-cloud-function", # ), "[Asset Inventory][GCP][Cloud Run Service] assets found": AssetInventoryCase( - category="infrastructure", - sub_category="container", - type_="serverless", - sub_type="gcp-cloud-run-service", + category="Container Service", + type_="GCP Cloud Run Service", ), } diff --git a/tests/product/tests/test_aws_asset_inventory.py b/tests/product/tests/test_aws_asset_inventory.py index 3b359b7f6f..1fa0eefb80 100644 --- a/tests/product/tests/test_aws_asset_inventory.py +++ b/tests/product/tests/test_aws_asset_inventory.py @@ -1,6 +1,6 @@ """ AWS Asset Inventory Elastic Compute Cloud verification. -This module verifies presence and correctness of retrieved assets +This module verifies presence and correctness of retrieved entities """ from datetime import datetime, timedelta @@ -16,37 +16,33 @@ def test_aws_asset_inventory( asset_inventory_client, category, - sub_category, type_, - sub_type, ): """ - This data driven test verifies assets published by cloudbeat agent. + This data driven test verifies entities published by cloudbeat agent. """ - assets = get_ES_assets( + entities = get_ES_assets( asset_inventory_client, timeout=10, category=category, - sub_category=sub_category, type_=type_, - sub_type=sub_type, exec_timestamp=datetime.utcnow() - timedelta(minutes=30), ) - assert assets is not None, "Expected a list of assets, got None" - assert isinstance(assets, list) and len(assets) > 0, "Expected the list to be non-empty" - for asset in assets: - assert asset.cloud, "Expected .cloud section" - assert asset.cloud.provider == "aws", f'Expected "aws" provider, got {asset.cloud.provider}' - assert len(asset.asset.id) > 0, "Expected .asset.id list to contain an ID" - assert len(asset.asset.id[0]) > 0, "Expected the ID to be non-empty" - assert asset.asset.raw, "Expected the resource under .asset.raw" + assert entities is not None, "Expected a list of entities, got None" + assert isinstance(entities, list) and len(entities) > 0, "Expected the list to be non-empty" + for entity in entities: + assert entity.cloud, "Expected .cloud section" + assert entity.cloud.Provider == "aws", f'Expected "aws" provider, got {entity.cloud.Provider}' + assert len(entity.entity.id) > 0, "Expected .entity.id list to contain an ID" + assert len(entity.entity.id[0]) > 0, "Expected the ID to be non-empty" + assert entity.Attributes, "Expected the resource under .Attributes" register_params( test_aws_asset_inventory, Parameters( - ("category", "sub_category", "type_", "sub_type"), + ("category", "type_"), [*aws_tc.test_cases.values()], ids=[*aws_tc.test_cases.keys()], ), diff --git a/tests/product/tests/test_azure_asset_inventory.py b/tests/product/tests/test_azure_asset_inventory.py index b249e47f1c..7b957fe7eb 100644 --- a/tests/product/tests/test_azure_asset_inventory.py +++ b/tests/product/tests/test_azure_asset_inventory.py @@ -1,6 +1,6 @@ """ Azure Asset Inventory Elastic Compute Cloud verification. -This module verifies presence and correctness of retrieved assets +This module verifies presence and correctness of retrieved entities """ from datetime import datetime, timedelta @@ -17,37 +17,33 @@ def test_azure_asset_inventory( asset_inventory_client, category, - sub_category, type_, - sub_type, ): """ - This data driven test verifies assets published by cloudbeat agent. + This data driven test verifies entities published by cloudbeat agent. """ - assets = get_ES_assets( + entities = get_ES_assets( asset_inventory_client, timeout=10, category=category, - sub_category=sub_category, type_=type_, - sub_type=sub_type, exec_timestamp=datetime.utcnow() - timedelta(minutes=30), ) - assert assets is not None, "Expected a list of assets, got None" - assert isinstance(assets, list) and len(assets) > 0, "Expected the list to be non-empty" - for asset in assets: - assert asset.cloud, "Expected .cloud section" - assert asset.cloud.provider == "azure", f'Expected "aws" provider, got {asset.cloud.provider}' - assert len(asset.asset.id) > 0, "Expected .asset.id list to contain an ID" - assert len(asset.asset.id[0]) > 0, "Expected the ID to be non-empty" - assert asset.asset.raw, "Expected the resource under .asset.raw" + assert entities is not None, "Expected a list of entities, got None" + assert isinstance(entities, list) and len(entities) > 0, "Expected the list to be non-empty" + for entity in entities: + assert entity.cloud, "Expected .cloud section" + assert entity.cloud.Provider == "azure", f'Expected "aws" provider, got {entity.cloud.Provider}' + assert len(entity.entity.id) > 0, "Expected .entity.id list to contain an ID" + assert len(entity.entity.id[0]) > 0, "Expected the ID to be non-empty" + assert entity.Attributes, "Expected the resource under .Attributes" register_params( test_azure_asset_inventory, Parameters( - ("category", "sub_category", "type_", "sub_type"), + ("category", "type_"), [*azure_tc.test_cases.values()], ids=[*azure_tc.test_cases.keys()], ), diff --git a/tests/product/tests/test_gcp_asset_inventory.py b/tests/product/tests/test_gcp_asset_inventory.py index 0706ff73cf..f24c260b88 100644 --- a/tests/product/tests/test_gcp_asset_inventory.py +++ b/tests/product/tests/test_gcp_asset_inventory.py @@ -1,6 +1,6 @@ """ GCP Asset Inventory Elastic Compute Cloud verification. -This module verifies presence and correctness of retrieved assets +This module verifies presence and correctness of retrieved entities """ from datetime import datetime, timedelta @@ -16,38 +16,34 @@ def test_gcp_asset_inventory( asset_inventory_client, category, - sub_category, type_, - sub_type, ): """ - This data driven test verifies assets published by cloudbeat agent. + This data driven test verifies entities published by cloudbeat agent. """ # pylint: disable=duplicate-code - assets = get_ES_assets( + entities = get_ES_assets( asset_inventory_client, timeout=10, category=category, - sub_category=sub_category, type_=type_, - sub_type=sub_type, exec_timestamp=datetime.utcnow() - timedelta(minutes=30), ) - assert assets is not None, "Expected a list of assets, got None" - assert isinstance(assets, list) and len(assets) > 0, "Expected the list to be non-empty" - for asset in assets: - assert asset.cloud, "Expected .cloud section" - assert asset.cloud.provider == "gcp", f'Expected "gcp" provider, got {asset.cloud.provider}' - assert len(asset.asset.id) > 0, "Expected .asset.id list to contain an ID" - assert len(asset.asset.id[0]) > 0, "Expected the ID to be non-empty" - assert asset.asset.raw, "Expected the resource under .asset.raw" + assert entities is not None, "Expected a list of entities, got None" + assert isinstance(entities, list) and len(entities) > 0, "Expected the list to be non-empty" + for entity in entities: + assert entity.cloud, "Expected .cloud section" + assert entity.cloud.Provider == "gcp", f'Expected "gcp" provider, got {entity.cloud.Provider}' + assert len(entity.entity.id) > 0, "Expected .entity.id list to contain an ID" + assert len(entity.entity.id[0]) > 0, "Expected the ID to be non-empty" + assert entity.Attributes, "Expected the resource under .Attributes" register_params( test_gcp_asset_inventory, Parameters( - ("category", "sub_category", "type_", "sub_type"), + ("category", "type_"), [*gcp_tc.test_cases.values()], ids=[*gcp_tc.test_cases.keys()], ),