diff --git a/infracost-usage-example.yml b/infracost-usage-example.yml index 5c7539ccf92..83ea8ba789f 100644 --- a/infracost-usage-example.yml +++ b/infracost-usage-example.yml @@ -111,10 +111,14 @@ resource_type_default_usage: data_transfer_global: 1000 data_transfer_local: 1000 ibm_database: - database_ram_mb: 12288 - database_disk_mb: 131072 - database_core: 3 - database_members: 4 + postgresql_database_ram_mb: 12288 + postgresql_database_disk_mb: 131072 + postgresql_database_core: 3 + postgresql_database_members: 4 + elasticsearch_database_ram_mb: 12288 + elasticsearch_database_disk_mb: 131072 + elasticsearch_database_core: 3 + elasticsearch_database_members: 4 resource_usage: # @@ -1404,7 +1408,13 @@ resource_usage: data_transfer_global: 2500 # Monthly global traffic through the gateway in GB ibm_database.postgres: - database_ram_mb: 12288 # Allocated memory in MB per-member - database_disk_mb: 131072 # Allocated disk in MB per-member - database_core: 3 # Allocated dedicated CPU per-member - database_members: 4 # Allocated number of members in the cluster + postgresql_database_ram_mb: 12288 # Allocated memory in MB per-member + postgresql_database_disk_mb: 131072 # Allocated disk in MB per-member + postgresql_database_core: 3 # Allocated dedicated CPU per-member + postgresql_database_members: 4 # Allocated number of members in the cluster + + ibm_database.elasticsearch: + elasticsearch_database_ram_mb: 12288 # Allocated memory in MB per-member + elasticsearch_database_disk_mb: 131072 # Allocated disk in MB per-member + elasticsearch_database_core: 3 # Allocated dedicated CPU per-member + elasticsearch_database_members: 4 # Allocated number of members in the cluster diff --git a/internal/providers/terraform/ibm/ibm.go b/internal/providers/terraform/ibm/ibm.go index 1ea39b9da9b..683f3e77f39 100644 --- a/internal/providers/terraform/ibm/ibm.go +++ b/internal/providers/terraform/ibm/ibm.go @@ -79,6 +79,7 @@ var globalCatalogServiceId = map[string]catalogMetadata{ "sysdig-secure": {"e831e900-82d6-11ec-95c5-c12c5a5d9687", []string{}, nil, "https://cloud.ibm.com/workload-protection/catalog/security-and-compliance-center-workload-protection"}, "logdna": {"e13e1860-959c-11e8-871e-ad157af61ad7", []string{}, nil, "https://cloud.ibm.com/catalog/services/logdna"}, "databases-for-postgresql": {"databases-for-postgresql", []string{}, nil, "https://cloud.ibm.com/databases/databases-for-postgresql/create"}, + "databases-for-elasticsearch": {"databases-for-elasticsearch", []string{}, nil, "https://cloud.ibm.com/databases/databases-for-elasticsearch/create"}, "secrets-manager": {"ebc0cdb0-af2a-11ea-98c7-29e5db822649", []string{}, nil, "https://cloud.ibm.com/catalog/services/secrets-manager"}, "appid": {"AdvancedMobileAccess-d6aece47-d840-45b0-8ab9-ad15354deeea", []string{}, nil, "https://cloud.ibm.com/catalog/services/appid"}, "appconnect": {"96a0ebf2-2a02-4e32-815f-7c09a1268c78", []string{}, nil, "https://www.ibm.com/products/app-connect/pricing"}, diff --git a/internal/providers/terraform/ibm/testdata/database_test/database_test.golden b/internal/providers/terraform/ibm/testdata/database_test/database_test.golden index 9586db00386..1069e02cbe0 100644 --- a/internal/providers/terraform/ibm/testdata/database_test/database_test.golden +++ b/internal/providers/terraform/ibm/testdata/database_test/database_test.golden @@ -15,7 +15,30 @@ └─ Disk (first 1 GB-DISK) 1 GB-DISK $0.61 └─ Disk (over 0 GB-DISK) 1 GB-DISK $0.63 - OVERALL TOTAL $87.45 + ibm_database.test_es_enterprise_db1 + ├─ RAM (first 1 GB-RAM) 1 GB-RAM $15.70 + ├─ RAM (over 0 GB-RAM) 1 GB-RAM $16.17 + ├─ Disk (first 1 GB-DISK) 1 GB-DISK $0.61 + ├─ Disk (over 0 GB-DISK) 1 GB-DISK $0.63 + └─ Core (first 1 Virtual Processor Core) 1 Virtual Processor Core $31.40 + └─ Core (over 0 Virtual Processor Core) 1 Virtual Processor Core $32.34 + + ibm_database.test_es_enterprise_db2 + ├─ RAM (first 1 GB-RAM) 1 GB-RAM $15.70 + ├─ RAM (over 0 GB-RAM) 1 GB-RAM $16.17 + └─ Disk (first 1 GB-DISK) 1 GB-DISK $0.61 + └─ Disk (over 0 GB-DISK) 1 GB-DISK $0.63 + + ibm_database.test_es_platinum_db1 + ├─ RAM 36 GB-RAM $939.60 + ├─ Disk 384 GB-DISK $234.24 + └─ Core 9 Virtual Processor Core $282.60 + + ibm_database.test_es_platinum_db2 + ├─ RAM 4 GB-RAM $104.40 + └─ Disk 20 GB-DISK $12.20 + + OVERALL TOTAL $1,790.45 ────────────────────────────────── -2 cloud resources were detected: -∙ 2 were estimated, all of which include usage-based costs, see https://infracost.io/usage-file \ No newline at end of file +4 cloud resources were detected: +∙ 4 were estimated, all of which include usage-based costs, see https://infracost.io/usage-file \ No newline at end of file diff --git a/internal/providers/terraform/ibm/testdata/database_test/database_test.tf b/internal/providers/terraform/ibm/testdata/database_test/database_test.tf index 79c8430a45d..d7b3cb1390d 100644 --- a/internal/providers/terraform/ibm/testdata/database_test/database_test.tf +++ b/internal/providers/terraform/ibm/testdata/database_test/database_test.tf @@ -1,4 +1,3 @@ - terraform { required_providers { ibm = { @@ -58,3 +57,77 @@ resource "ibm_database" "test_db2" { } CONFIGURATION } + +resource "ibm_database" "test_es_enterprise_db1" { + name = "demo-es-enterprise" + service = "databases-for-elasticsearch" + plan = "enterprise" + location = "eu-gb" + + group { + group_id = "member" + memory { + allocation_mb = 12288 + } + disk { + allocation_mb = 131072 + } + cpu { + allocation_count = 3 + } + } +} + +resource "ibm_database" "test_es_enterprise_db2" { + name = "demo-es-enterprise2" + service = "databases-for-elasticsearch" + plan = "enterprise" + location = "eu-gb" + + group { + group_id = "member" + members { + allocation_count = 4 + } + memory { + allocation_mb = 15360 + } + } +} + +resource "ibm_database" "test_es_platinum_db1" { + name = "demo-es-platinum" + service = "databases-for-elasticsearch" + plan = "platinum" + location = "eu-gb" + + group { + group_id = "member" + memory { + allocation_mb = 12288 + } + disk { + allocation_mb = 131072 + } + cpu { + allocation_count = 3 + } + } +} + +resource "ibm_database" "test_es_platinum_db2" { + name = "demo-es-platinum2" + service = "databases-for-elasticsearch" + plan = "platinum" + location = "eu-gb" + + group { + group_id = "member" + members { + allocation_count = 4 + } + memory { + allocation_mb = 1024 + } + } +} \ No newline at end of file diff --git a/internal/providers/terraform/ibm/testdata/database_test/database_test.usage.yml b/internal/providers/terraform/ibm/testdata/database_test/database_test.usage.yml index 005e4927a0b..0885884199b 100644 --- a/internal/providers/terraform/ibm/testdata/database_test/database_test.usage.yml +++ b/internal/providers/terraform/ibm/testdata/database_test/database_test.usage.yml @@ -1,9 +1,23 @@ version: 0.1 resource_usage: ibm_database.test_db1: - database_ram_mb: 12288 - database_disk_mb: 131072 - database_core: 3 + postgresql_database_ram_mb: 12288 + postgresql_database_disk_mb: 131072 + postgresql_database_core: 3 ibm_database.test_db2: - database_ram_mb: 15360 - database_members: 4 \ No newline at end of file + postgresql_database_ram_mb: 15360 + postgresql_database_members: 4 + ibm_database.test_es_enterprise_db1: + elasticsearch_database_ram_mb: 12288 + elasticsearch_database_disk_mb: 131072 + elasticsearch_database_core: 3 + ibm_database.test_es_enterprise_db2: + elasticsearch_database_ram_mb: 15360 + elasticsearch_database_members: 4 + ibm_database.test_es_platinum_db1: + elasticsearch_database_ram_mb: 12288 + elasticsearch_database_disk_mb: 131072 + elasticsearch_database_core: 3 + ibm_database.test_es_platinum_db2: + elasticsearch_database_ram_mb: 1024 + elasticsearch_database_members: 4 \ No newline at end of file diff --git a/internal/resources/ibm/database.go b/internal/resources/ibm/database.go index 552f13ec092..fce5b72aa9d 100644 --- a/internal/resources/ibm/database.go +++ b/internal/resources/ibm/database.go @@ -21,10 +21,18 @@ type Database struct { // Databases For PostgreSQL // Catalog Link: https://cloud.ibm.com/catalog/services/databases-for-postgresql // Pricing Link: https://cloud.ibm.com/docs/databases-for-postgresql?topic=databases-for-postgresql-pricing - RAM *int64 `infracost_usage:"database_ram_mb"` - Disk *int64 `infracost_usage:"database_disk_mb"` - Core *int64 `infracost_usage:"database_core"` - Members *int64 `infracost_usage:"database_members"` + PostgreSQL_Ram *int64 `infracost_usage:"postgresql_database_ram_mb"` + PostgreSQL_Disk *int64 `infracost_usage:"postgresql_database_disk_mb"` + PostgreSQL_Core *int64 `infracost_usage:"postgresql_database_core"` + PostgreSQL_Members *int64 `infracost_usage:"postgresql_database_members"` + + // Databases For ElasticSearch + // Catalog Link: https://cloud.ibm.com/catalog/services/databases-for-elasticsearch + // Pricing Link: https://cloud.ibm.com/docs/databases-for-elasticsearch?topic=databases-for-elasticsearch-pricing + ElasticSearch_Ram *int64 `infracost_usage:"elasticsearch_database_ram_mb"` + ElasticSearch_Disk *int64 `infracost_usage:"elasticsearch_database_disk_mb"` + ElasticSearch_Core *int64 `infracost_usage:"elasticsearch_database_core"` + ElasticSearch_Members *int64 `infracost_usage:"elasticsearch_database_members"` } type DatabaseCostComponentsFunc func(*Database) []*schema.CostComponent @@ -37,17 +45,21 @@ func (r *Database) PopulateUsage(u *schema.UsageData) { // DatabaseUsageSchema defines a list which represents the usage schema of Database. var DatabaseUsageSchema = []*schema.UsageItem{ - {Key: "database_ram_mb", DefaultValue: 0, ValueType: schema.Int64}, - {Key: "database_disk_mb", DefaultValue: 0, ValueType: schema.Int64}, - {Key: "database_core", DefaultValue: 0, ValueType: schema.Int64}, - {Key: "database_members", DefaultValue: 0, ValueType: schema.Int64}, + {Key: "postgresql_database_ram_mb", DefaultValue: 0, ValueType: schema.Int64}, + {Key: "postgresql_database_disk_mb", DefaultValue: 0, ValueType: schema.Int64}, + {Key: "postgresql_database_core", DefaultValue: 0, ValueType: schema.Int64}, + {Key: "postgresql_database_members", DefaultValue: 0, ValueType: schema.Int64}, + {Key: "elasticsearch_database_ram_mb", DefaultValue: 0, ValueType: schema.Int64}, + {Key: "elasticsearch_database_disk_mb", DefaultValue: 0, ValueType: schema.Int64}, + {Key: "elasticsearch_database_core", DefaultValue: 0, ValueType: schema.Int64}, + {Key: "elasticsearch_database_members", DefaultValue: 0, ValueType: schema.Int64}, } var DatabaseCostMap map[string]DatabaseCostComponentsFunc = map[string]DatabaseCostComponentsFunc{ "databases-for-postgresql": GetPostgresCostComponents, // "databases-for-etcd": // "databases-for-redis": - // "databases-for-elasticsearch": + "databases-for-elasticsearch": GetElasticSearchCostComponents, // "messages-for-rabbitmq": // "databases-for-mongodb": // "databases-for-mysql": @@ -61,14 +73,14 @@ func ConvertMBtoGB(d decimal.Decimal) decimal.Decimal { func PostgresRAMCostComponent(r *Database) *schema.CostComponent { var R decimal.Decimal - if r.RAM != nil { - R = ConvertMBtoGB(decimal.NewFromInt(*r.RAM)) + if r.PostgreSQL_Ram != nil { + R = ConvertMBtoGB(decimal.NewFromInt(*r.PostgreSQL_Ram)) } else { // set the default R = decimal.NewFromInt(1) } var m decimal.Decimal - if r.Members != nil { - m = decimal.NewFromInt(*r.Members) + if r.PostgreSQL_Members != nil { + m = decimal.NewFromInt(*r.PostgreSQL_Members) } else { // set the default m = decimal.NewFromInt(2) } @@ -95,14 +107,14 @@ func PostgresRAMCostComponent(r *Database) *schema.CostComponent { func PostgresDiskCostComponent(r *Database) *schema.CostComponent { var d decimal.Decimal - if r.Disk != nil { - d = ConvertMBtoGB(decimal.NewFromInt(*r.Disk)) + if r.PostgreSQL_Disk != nil { + d = ConvertMBtoGB(decimal.NewFromInt(*r.PostgreSQL_Disk)) } else { // set the default d = decimal.NewFromInt(5) } var m decimal.Decimal - if r.Members != nil { - m = decimal.NewFromInt(*r.Members) + if r.PostgreSQL_Members != nil { + m = decimal.NewFromInt(*r.PostgreSQL_Members) } else { // set the default m = decimal.NewFromInt(2) } @@ -129,14 +141,14 @@ func PostgresDiskCostComponent(r *Database) *schema.CostComponent { func PostgresCoreCostComponent(r *Database) *schema.CostComponent { var c decimal.Decimal - if r.Core != nil { - c = decimal.NewFromInt(*r.Core) + if r.PostgreSQL_Core != nil { + c = decimal.NewFromInt(*r.PostgreSQL_Core) } else { // set the default c = decimal.NewFromInt(0) } var m decimal.Decimal - if r.Members != nil { - m = decimal.NewFromInt(*r.Members) + if r.PostgreSQL_Members != nil { + m = decimal.NewFromInt(*r.PostgreSQL_Members) } else { // set the default m = decimal.NewFromInt(2) } diff --git a/internal/resources/ibm/database_elasticsearch.go b/internal/resources/ibm/database_elasticsearch.go new file mode 100644 index 00000000000..f725d5edfc2 --- /dev/null +++ b/internal/resources/ibm/database_elasticsearch.go @@ -0,0 +1,122 @@ +package ibm + +import ( + "github.com/infracost/infracost/internal/schema" + "github.com/shopspring/decimal" +) + +func ElasticSearchRAMCostComponent(r *Database) *schema.CostComponent { + var R decimal.Decimal + if r.ElasticSearch_Ram != nil { + R = ConvertMBtoGB(decimal.NewFromInt(*r.ElasticSearch_Ram)) + } else { // set the default + R = decimal.NewFromInt(1) + } + var m decimal.Decimal + if r.ElasticSearch_Members != nil { + m = decimal.NewFromInt(*r.ElasticSearch_Members) + } else { // set the default + m = decimal.NewFromInt(3) + } + + cost := R.Mul(m) + costComponent := schema.CostComponent{ + Name: "RAM", + Unit: "GB-RAM", + MonthlyQuantity: &cost, + UnitMultiplier: decimal.NewFromInt(1), + ProductFilter: &schema.ProductFilter{ + VendorName: strPtr("ibm"), + Region: strPtr(r.Location), + Service: strPtr("databases-for-elasticsearch"), + ProductFamily: strPtr("service"), + AttributeFilters: []*schema.AttributeFilter{ + {Key: "planName", Value: &r.Plan}, + }, + }, + PriceFilter: &schema.PriceFilter{ + Unit: strPtr("GIGABYTE_MONTHS_RAM"), + }, + } + return &costComponent +} + +func ElasticSearchDiskCostComponent(r *Database) *schema.CostComponent { + var d decimal.Decimal + if r.ElasticSearch_Disk != nil { + d = ConvertMBtoGB(decimal.NewFromInt(*r.ElasticSearch_Disk)) + } else { // set the default + d = decimal.NewFromInt(5) + } + var m decimal.Decimal + if r.ElasticSearch_Members != nil { + m = decimal.NewFromInt(*r.ElasticSearch_Members) + } else { // set the default + m = decimal.NewFromInt(3) + } + + cost := d.Mul(m) + costComponent := schema.CostComponent{ + Name: "Disk", + Unit: "GB-DISK", + MonthlyQuantity: &cost, + UnitMultiplier: decimal.NewFromInt(1), + ProductFilter: &schema.ProductFilter{ + VendorName: strPtr("ibm"), + Region: strPtr(r.Location), + Service: strPtr("databases-for-elasticsearch"), + ProductFamily: strPtr("service"), + AttributeFilters: []*schema.AttributeFilter{ + {Key: "planName", Value: &r.Plan}, + }, + }, + PriceFilter: &schema.PriceFilter{ + Unit: strPtr("GIGABYTE_MONTHS_DISK"), + }, + } + return &costComponent +} + +func ElasticSearchCoreCostComponent(r *Database) *schema.CostComponent { + var c decimal.Decimal + if r.ElasticSearch_Core != nil { + c = decimal.NewFromInt(*r.ElasticSearch_Core) + } else { // set the default + c = decimal.NewFromInt(0) + } + var m decimal.Decimal + if r.ElasticSearch_Members != nil { + m = decimal.NewFromInt(*r.ElasticSearch_Members) + } else { // set the default + m = decimal.NewFromInt(3) + } + + cost := c.Mul(m) + costComponent := schema.CostComponent{ + Name: "Core", + Unit: "Virtual Processor Core", + MonthlyQuantity: &cost, + UnitMultiplier: decimal.NewFromInt(1), + ProductFilter: &schema.ProductFilter{ + VendorName: strPtr("ibm"), + Region: strPtr(r.Location), + Service: strPtr("databases-for-elasticsearch"), + ProductFamily: strPtr("service"), + AttributeFilters: []*schema.AttributeFilter{ + {Key: "planName", Value: &r.Plan}, + }, + }, + PriceFilter: &schema.PriceFilter{ + Unit: strPtr("VIRTUAL_PROCESSOR_CORES"), + }, + } + return &costComponent +} + +func GetElasticSearchCostComponents(r *Database) []*schema.CostComponent { + return []*schema.CostComponent{ + ElasticSearchRAMCostComponent(r), + ElasticSearchDiskCostComponent(r), + ElasticSearchCoreCostComponent(r), + } +} \ No newline at end of file