product.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package oracle
  2. import (
  3. "embed"
  4. "encoding/json"
  5. "log"
  6. "strconv"
  7. "strings"
  8. )
  9. const blockVolumePartNumber = "B91961"
  10. const loadBalancerPartNumber = "B93030"
  11. // egressT1PartNumber for egress to NA, EU, and UK
  12. const egress1PartNumber = "B88327"
  13. // egressT2PartNumber for egress to APAC, and SA
  14. const egress2PartNumber = "B93455"
  15. // egressT3PartNumber for egress to ME, and AF
  16. const egress3PartNumber = "B93456"
  17. const enhancedClusterPartNumber = "B96545"
  18. const virualNodePartNumber = "B96109"
  19. // Compiled from cost estimator data at https://www.oracle.com/cloud/costestimator.html
  20. // The shapes.json endpoint can be queried for a snapshot of this data.
  21. // Note that this endpoint is subject to change and should not be queried directly.
  22. //
  23. //go:embed partnumbers
  24. var partNumbers embed.FS
  25. func init() {
  26. shapeInfo, err := partNumbers.ReadFile("partnumbers/shape_part_numbers.json")
  27. if err != nil {
  28. log.Fatalln("unable to read OCI Shape part numbers", err)
  29. }
  30. instanceProducts = map[string]Product{}
  31. if err := json.Unmarshal(shapeInfo, &instanceProducts); err != nil {
  32. log.Fatalln("unable to unmarshal OCI Shape part numbers", err)
  33. }
  34. }
  35. type Product struct {
  36. // OCPU product name
  37. OCPU string
  38. // Memory product name
  39. Memory string
  40. // GPU product name
  41. GPU string
  42. Disk string
  43. }
  44. type DefaultPricing struct {
  45. OCPU string
  46. Memory string
  47. GPU string
  48. Storage string
  49. LB string
  50. Egress string
  51. }
  52. type instanceProduct map[string]Product
  53. // instanceProducts maps instance types to associated part numbers.
  54. var instanceProducts instanceProduct
  55. func (i instanceProduct) get(shape string) Product {
  56. if product, ok := i[shape]; ok {
  57. return product
  58. }
  59. // If no product mapping exists, provide a default product
  60. return Product{}
  61. }
  62. func (d DefaultPricing) TotalInstanceCost() (float64, error) {
  63. var totalCost float64
  64. addValue := func(val string) error {
  65. if val != "" {
  66. f, err := strconv.ParseFloat(val, 64)
  67. if err != nil {
  68. return err
  69. }
  70. totalCost += f
  71. }
  72. return nil
  73. }
  74. if err := addValue(d.OCPU); err != nil {
  75. return totalCost, err
  76. }
  77. if err := addValue(d.Memory); err != nil {
  78. return totalCost, err
  79. }
  80. if err := addValue(d.GPU); err != nil {
  81. return totalCost, err
  82. }
  83. return totalCost, nil
  84. }
  85. func egressRegionPartNumber(region string) string {
  86. split := strings.Split(region, "-")
  87. switch split[0] {
  88. case "us", "ca", "eu", "uk", "mx":
  89. return egress1PartNumber
  90. case "ap", "sa":
  91. return egress2PartNumber
  92. case "me", "af", "il":
  93. return egress3PartNumber
  94. default:
  95. return ""
  96. }
  97. }