Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions api/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -15430,7 +15430,7 @@ const docTemplate = `{
]
},
"DataSource": {
"description": "DataSource records, per field name (e.g. \"StorageTypeOptions\", \"StorageSizeRange\",\nor \"StorageSizeRange.Min\"/\"StorageSizeRange.Max\" for a partially-static range),\nwhether that field's value above was obtained live from the CSP API (\"API\") or is\na fixed value (\"Static\") for this response. A field with no entry here is \"API\".",
"description": "DataSource records, per field name (e.g. \"StorageTypeOptions\", \"StorageSizeRangeGB\",\nor \"StorageSizeRangeGB.Min\"/\"StorageSizeRangeGB.Max\" for a partially-static range),\nwhether that field's value above was obtained live from the CSP API (\"API\") or is\na fixed value (\"Static\") for this response. A field with no entry here is \"API\".",
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/spider.RDBMSDataSource"
Expand All @@ -15451,8 +15451,8 @@ const docTemplate = `{
"description": "true if SubnetNames is required at creation",
"type": "boolean"
},
"StorageSizeRange": {
"description": "Min/Max storage size in GB for the requested DB engine",
"StorageSizeRangeGB": {
"description": "Min/Max storage size in decimal GB (10^9 bytes) for the requested DB engine. Converted from the CSP's native unit when that unit is objectively known (see GiBToGB); left unconverted, with a DataSourceNotes caveat, when the native unit cannot be confirmed.",
"allOf": [
{
"$ref": "#/definitions/spider.StorageSizeRange"
Expand Down
6 changes: 3 additions & 3 deletions api/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -15427,7 +15427,7 @@
]
},
"DataSource": {
"description": "DataSource records, per field name (e.g. \"StorageTypeOptions\", \"StorageSizeRange\",\nor \"StorageSizeRange.Min\"/\"StorageSizeRange.Max\" for a partially-static range),\nwhether that field's value above was obtained live from the CSP API (\"API\") or is\na fixed value (\"Static\") for this response. A field with no entry here is \"API\".",
"description": "DataSource records, per field name (e.g. \"StorageTypeOptions\", \"StorageSizeRangeGB\",\nor \"StorageSizeRangeGB.Min\"/\"StorageSizeRangeGB.Max\" for a partially-static range),\nwhether that field's value above was obtained live from the CSP API (\"API\") or is\na fixed value (\"Static\") for this response. A field with no entry here is \"API\".",
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/spider.RDBMSDataSource"
Expand All @@ -15448,8 +15448,8 @@
"description": "true if SubnetNames is required at creation",
"type": "boolean"
},
"StorageSizeRange": {
"description": "Min/Max storage size in GB for the requested DB engine",
"StorageSizeRangeGB": {
"description": "Min/Max storage size in decimal GB (10^9 bytes) for the requested DB engine. Converted from the CSP's native unit when that unit is objectively known (see GiBToGB); left unconverted, with a DataSourceNotes caveat, when the native unit cannot be confirmed.",
"allOf": [
{
"$ref": "#/definitions/spider.StorageSizeRange"
Expand Down
11 changes: 7 additions & 4 deletions api/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1504,8 +1504,8 @@ definitions:
additionalProperties:
$ref: '#/definitions/spider.RDBMSDataSource'
description: |-
DataSource records, per field name (e.g. "StorageTypeOptions", "StorageSizeRange",
or "StorageSizeRange.Min"/"StorageSizeRange.Max" for a partially-static range),
DataSource records, per field name (e.g. "StorageTypeOptions", "StorageSizeRangeGB",
or "StorageSizeRangeGB.Min"/"StorageSizeRangeGB.Max" for a partially-static range),
whether that field's value above was obtained live from the CSP API ("API") or is
a fixed value ("Static") for this response. A field with no entry here is "API".
type: object
Expand All @@ -1523,10 +1523,13 @@ definitions:
RequiresSubnet:
description: true if SubnetNames is required at creation
type: boolean
StorageSizeRange:
StorageSizeRangeGB:
allOf:
- $ref: '#/definitions/spider.StorageSizeRange'
description: Min/Max storage size in GB for the requested DB engine
description: Min/Max storage size in decimal GB (10^9 bytes) for the requested
DB engine. Converted from the CSP's native unit when that unit is objectively
known (see GiBToGB); left unconverted, with a DataSourceNotes caveat, when
the native unit cannot be confirmed.
StorageTypeOptions:
description: Available storage types for the requested DB engine
example:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ func (handler *AlibabaRDBMSHandler) fetchRDBMSInstanceOptions(engineNames []alib
return nil, irs.StorageSizeRange{}, errors.New("DescribeAvailableClasses returned no storage size range")
}

// No unit conversion applied: DescribeAvailableClasses' DBInstanceStorageRange/StorageRange
// is widely documented as decimal GB, but the vendored SDK (auto-generated) carries no unit
// comment to confirm this independently, so it is passed through as-is rather than guessed.
return instanceSpecOptions, irs.StorageSizeRange{Min: minStorage, Max: maxStorage}, nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ func (handler *AwsRDBMSHandler) GetMetaInfo(dbEngine string) (irs.RDBMSMetaInfo,
LoggingError(hiscallInfo, err)
return irs.RDBMSMetaInfo{}, fmt.Errorf("DescribeOrderableDBInstanceOptions failed: %w", err)
}
// AWS RDS documents MinStorageSize/MaxStorageSize in GiB (gibibytes); convert to decimal GB
// for RDBMSMetaInfo.StorageSizeRangeGB, which is defined in GB.
storageSizeRange = irs.StorageSizeRange{
Min: irs.GiBToGB(storageSizeRange.Min),
Max: irs.GiBToGB(storageSizeRange.Max),
}

metaInfo, err := irs.BuildRDBMSMetaInfo(requestedEngine, supportedEngines, instanceSpecOptions, storageTypeOptions, storageSizeRange, true, true, true, true, true, "0-35", true, true, true, true, true)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ func (handler *AzureRDBMSHandler) GetMetaInfo(dbEngine string) (irs.RDBMSMetaInf
LoggingError(hiscallInfo, err)
return irs.RDBMSMetaInfo{}, fmt.Errorf("GetMetaInfo failed: %w", err)
}
// azureStorageMBToGB() only divides the raw capabilitySet value (MiB) by 1024,
// yielding GiB. Convert to decimal GB for RDBMSMetaInfo.StorageSizeRangeGB.
storageSizeRange = irs.StorageSizeRange{
Min: irs.GiBToGB(storageSizeRange.Min),
Max: irs.GiBToGB(storageSizeRange.Max),
}

// Azure MySQL Flexible Server provides SKU list via LocationBasedCapabilitySet API
instanceSpecOptions := map[string][]string{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,17 @@ func (handler *GCPRDBMSHandler) GetMetaInfo(dbEngine string) (irs.RDBMSMetaInfo,
LoggingError(hiscallInfo, err)
return irs.RDBMSMetaInfo{}, fmt.Errorf("fetch Cloud SQL instance options failed: %w", err)
}
// Max is derived from Tiers.List()'s DiskQuota (bytes), already divided down to GiB
// by fetchCloudSQLInstanceOptions; convert to decimal GB. Min is a hardcoded constant
// with no confirmed native unit, so it is left unconverted (see MarkStatic below).
storageSizeRange.Max = irs.GiBToGB(storageSizeRange.Max)

metaInfo, err := irs.BuildRDBMSMetaInfo(requestedEngine, supportedEngines, instanceSpecOptions, storageTypeOptions, storageSizeRange, true, true, true, true, true, "1-7", false, false, true, true, true)
if err != nil {
return irs.RDBMSMetaInfo{}, err
}
metaInfo.MarkStatic("StorageSizeRange", "Minimum storage size is a fixed constant; only the maximum is derived from the live Cloud SQL Tiers API.")
metaInfo.MarkStatic("StorageSizeRange.Min", "GCP Cloud SQL Admin API does not expose a minimum disk size; fixed at 10GB.")
metaInfo.MarkStatic("StorageSizeRangeGB", "Minimum storage size is a fixed constant; only the maximum is derived from the live Cloud SQL Tiers API.")
metaInfo.MarkStatic("StorageSizeRangeGB.Min", "GCP Cloud SQL Admin API does not expose a minimum disk size; fixed at 10GB (unit not independently confirmed, left unconverted).")

hiscallInfo.ElapsedTime = call.Elapsed(start)
calllogger.Info(call.String(hiscallInfo))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,17 @@ func (handler *IbmRDBMSHandler) GetMetaInfo(dbEngine string) (irs.RDBMSMetaInfo,
LoggingError(hiscallInfo, err)
return irs.RDBMSMetaInfo{}, err
}
// fetchRDBMSStorageSizeRange() returns Disk.MinimumMb/MaximumMb divided by
// ibmStorageUnitGB(1024), i.e. GiB — but that raw GiB value is also reused as-is by
// validateRDBMSStorageSizeRange()/CreateRDBMS() for request validation and the
// members_disk_allocation_mb calculation, so it must NOT be changed there. Convert to
// decimal GB only for this GetMetaInfo() response (RDBMSMetaInfo.StorageSizeRangeGB).
metaInfoStorageSizeRange := irs.StorageSizeRange{
Min: irs.GiBToGB(storageSizeRange.Min),
Max: irs.GiBToGB(storageSizeRange.Max),
}

metaInfo, err := irs.BuildRDBMSMetaInfo(requestedEngine, supportedEngines, instanceSpecOptions, storageTypeOptions, storageSizeRange, true, true, true, true, true, "NA", false, false, false, true, true)
metaInfo, err := irs.BuildRDBMSMetaInfo(requestedEngine, supportedEngines, instanceSpecOptions, storageTypeOptions, metaInfoStorageSizeRange, true, true, true, true, true, "NA", false, false, false, true, true)
if err != nil {
return irs.RDBMSMetaInfo{}, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func (handler *NcpVpcRDBMSHandler) getMysqlMetaInfo() (irs.RDBMSMetaInfo, error)
SupportedVersions: versions,
DBInstanceSpecOptions: instanceSpecs,
StorageTypeOptions: []string{"NA"},
StorageSizeRange: irs.StorageSizeRange{Min: 10, Max: 6000},
StorageSizeRangeGB: irs.StorageSizeRange{Min: 10, Max: 6000},
SupportsHighAvailability: true,
SupportsBackup: true,
SupportsPublicAccess: false, // NCP does not expose a public domain assignment API; must be done manually via NCP Console
Expand All @@ -132,7 +132,7 @@ func (handler *NcpVpcRDBMSHandler) getMysqlMetaInfo() (irs.RDBMSMetaInfo, error)
SupportsTag: false,
}
metaInfo.MarkStatic("StorageTypeOptions", "NCP G3 generation sets storage type (SSD) automatically; not user-selectable or queryable via API.")
metaInfo.MarkStatic("StorageSizeRange", "NCP has no storage-size query API; range shown (10-6000GB) is a known approximation, not authoritative.")
metaInfo.MarkStatic("StorageSizeRangeGB", "NCP has no storage-size query API; range shown (10-6000GB) is a known approximation, not authoritative. No unit conversion is applied because the value is not derived from any CSP-reported unit.")
if len(instanceSpecs) == 0 {
metaInfo.MarkStatic("DBInstanceSpecOptions", "MySQL G3 product spec query failed for this request; returned an empty list instead of live data.")
}
Expand Down Expand Up @@ -214,7 +214,7 @@ func (handler *NcpVpcRDBMSHandler) getPostgresqlMetaInfo() (irs.RDBMSMetaInfo, e
SupportedVersions: versions,
DBInstanceSpecOptions: instanceSpecs,
StorageTypeOptions: []string{"NA"},
StorageSizeRange: irs.StorageSizeRange{Min: 10, Max: 6000},
StorageSizeRangeGB: irs.StorageSizeRange{Min: 10, Max: 6000},
SupportsHighAvailability: true,
SupportsBackup: true,
SupportsPublicAccess: false,
Expand All @@ -226,7 +226,7 @@ func (handler *NcpVpcRDBMSHandler) getPostgresqlMetaInfo() (irs.RDBMSMetaInfo, e
RequiresSecurityGroup: false,
}
metaInfo.MarkStatic("StorageTypeOptions", "NCP G3 generation sets storage type (SSD) automatically; not user-selectable or queryable via API.")
metaInfo.MarkStatic("StorageSizeRange", "NCP has no storage-size query API; range shown (10-6000GB) is a known approximation, not authoritative.")
metaInfo.MarkStatic("StorageSizeRangeGB", "NCP has no storage-size query API; range shown (10-6000GB) is a known approximation, not authoritative. No unit conversion is applied because the value is not derived from any CSP-reported unit.")
if len(instanceSpecs) == 0 {
metaInfo.MarkStatic("DBInstanceSpecOptions", "PostgreSQL product spec query failed for this request; returned an empty list instead of live data.")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ func (handler *NhnCloudRDBMSHandler) GetMetaInfo(dbEngine string) (irs.RDBMSMeta
LoggingError(callLogInfo, err)
return irs.RDBMSMetaInfo{}, err
}
metaInfo.MarkStatic("StorageSizeRange", "NHN Cloud RDS API does not expose a storage size range; fixed at 20-2048GB.")
metaInfo.MarkStatic("StorageSizeRangeGB", "NHN Cloud RDS API does not expose a storage size range; fixed at 20-2048GB for both mysql and mariadb. No unit conversion is applied because the value is not derived from any CSP-reported unit.")

LoggingInfo(callLogInfo, start)
return metaInfo, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,13 @@ func (handler *OpenStackRDBMSHandler) GetMetaInfo(dbEngine string) (irs.RDBMSMet
}

// Min is never derived from a live value; Trove/Cinder don't expose a minimum disk size.
metaInfo.MarkStatic("StorageSizeRange", "Minimum storage size is a fixed constant; not derived from a live Cinder value.")
metaInfo.MarkStatic("StorageSizeRange.Min", "OpenStack Cinder does not expose a minimum volume size; fixed at 1GB.")
// No unit conversion is applied here: this range is not a Trove/RDBMS spec limit at all,
// it is the OpenStack project's (tenant's) Cinder block-storage quota, and Cinder's
// "gigabytes" quota has no documented/objective binary-vs-decimal basis to convert from.
metaInfo.MarkStatic("StorageSizeRangeGB", "Minimum storage size is a fixed constant; not derived from a live Cinder value. This range reflects the project's Cinder volume quota, not a per-flavor RDBMS storage limit; its native unit (decimal vs binary GB) is not documented by Cinder, so no conversion is applied.")
metaInfo.MarkStatic("StorageSizeRangeGB.Min", "OpenStack Cinder does not expose a minimum volume size; fixed at 1GB.")
if storageSizeRange.Max <= 0 {
metaInfo.MarkStatic("StorageSizeRange.Max", "No Cinder volume quota is configured for this project (unlimited); -1 is a sentinel, not a real upper bound.")
metaInfo.MarkStatic("StorageSizeRangeGB.Max", "No Cinder volume quota is configured for this project (unlimited); -1 is a sentinel, not a real upper bound.")
}

LoggingInfo(hiscallInfo, start)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ func (handler *TencentRDBMSHandler) fetchCDBMetaOptions() (map[string][]string,
// UNIVERSAL (local SSD) is always available; add it regardless of cloud disk support.
storageTypeSet["local_ssd"] = struct{}{}

// No unit conversion needed: CdbSellConfig.VolumeMin/VolumeMax are documented by Tencent's
// SDK ("磁盘最小规格/磁盘最大规格,单位为GB") as decimal GB, unlike Memory which needs a
// separate GiB*1000 correction (see resolveMemoryMBFromSpec).
memorySet := make(map[int64]struct{})
storageRange := irs.StorageSizeRange{}
for cfgID := range selectedConfigIDs {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package resources

import (
"fmt"
"math"
"strings"
"time"
)
Expand Down Expand Up @@ -49,7 +50,7 @@ type RDBMSMetaInfo struct {
SupportedVersions []string `json:"SupportedVersions" example:"8.0,8.4"` // Supported versions for the requested DB engine
DBInstanceSpecOptions []string `json:"DBInstanceSpecOptions,omitempty" example:"db.t3.medium,1000"` // Available DBInstanceSpec values for the requested DB engine. "NA" if CSP does not provide spec list API.
StorageTypeOptions []string `json:"StorageTypeOptions,omitempty" example:"gp2,gp3,io1"` // Available storage types for the requested DB engine
StorageSizeRange StorageSizeRange `json:"StorageSizeRange,omitempty"` // Min/Max storage size in GB for the requested DB engine
StorageSizeRangeGB StorageSizeRange `json:"StorageSizeRangeGB,omitempty"` // Min/Max storage size in decimal GB (10^9 bytes) for the requested DB engine. Converted from the CSP's native unit when that unit is objectively known (see GiBToGB); left unconverted, with a DataSourceNotes caveat, when the native unit cannot be confirmed.

SupportsHighAvailability bool `json:"SupportsHighAvailability"` // true if HA/Multi-AZ can be configured
SupportsBackup bool `json:"SupportsBackup"` // true if managed automatic backup is supported
Expand All @@ -66,8 +67,8 @@ type RDBMSMetaInfo struct {

SupportsTag bool `json:"SupportsTag"` // true if tagging is supported for RDBMS resources on this CSP

// DataSource records, per field name (e.g. "StorageTypeOptions", "StorageSizeRange",
// or "StorageSizeRange.Min"/"StorageSizeRange.Max" for a partially-static range),
// DataSource records, per field name (e.g. "StorageTypeOptions", "StorageSizeRangeGB",
// or "StorageSizeRangeGB.Min"/"StorageSizeRangeGB.Max" for a partially-static range),
// whether that field's value above was obtained live from the CSP API ("API") or is
// a fixed value ("Static") for this response. A field with no entry here is "API".
DataSource map[string]RDBMSDataSource `json:"DataSource,omitempty"`
Expand All @@ -78,7 +79,7 @@ type RDBMSMetaInfo struct {
}

// MarkStatic records that the given metadata field (e.g. "StorageTypeOptions",
// "StorageSizeRange", or a sub-path like "StorageSizeRange.Min") is a fixed value
// "StorageSizeRangeGB", or a sub-path like "StorageSizeRangeGB.Min") is a fixed value
// for this response rather than a live CSP API result, with an optional
// human-readable explanation.
func (m *RDBMSMetaInfo) MarkStatic(field string, note string) {
Expand Down Expand Up @@ -122,7 +123,7 @@ func BuildRDBMSMetaInfo(dbEngine string, supportedEngines map[string][]string, d
SupportedVersions: versions,
DBInstanceSpecOptions: instanceSpecs,
StorageTypeOptions: storageTypes,
StorageSizeRange: storageSizeRange,
StorageSizeRangeGB: storageSizeRange,
SupportsHighAvailability: supportsHighAvailability,
SupportsBackup: supportsBackup,
BackupRetentionRange: backupRetentionRange,
Expand All @@ -143,6 +144,28 @@ type StorageSizeRange struct {
Max int64 `json:"Max" example:"65536"` // Maximum storage in GB
}

// gibToGBFactor is 2^30 / 10^9: the ratio to convert a gibibyte (binary,
// 1024-based) quantity into decimal gigabytes (1000-based).
const gibToGBFactor = 1073741824.0 / 1000000000.0

// GiBToGB converts a gibibyte (2^30 bytes) quantity to the nearest whole
// decimal gigabyte (10^9 bytes), rounding to the nearest integer.
//
// Use this ONLY when the input is objectively known to be in GiB (or a
// binary-based unit convertible to GiB, e.g. MiB/1024) — for example AWS RDS
// storage sizes, or Azure/IBM values derived from documented MiB-based
// fields. Do NOT apply it to values whose native unit is unconfirmed
// (e.g. Alibaba's storage range) or that are not a real unit at all
// (e.g. a hardcoded approximation, or an OpenStack Cinder account quota) —
// those should be left unconverted and flagged via MarkStatic/DataSourceNotes
// instead.
func GiBToGB(gib int64) int64 {
if gib <= 0 {
return gib
}
return int64(math.Round(float64(gib) * gibToGBFactor))
}

// -------- Info Structure

// RDBMSInfo represents the details of a Relational Database instance.
Expand Down
Loading