Skip to content
This repository has been archived by the owner on Jan 20, 2022. It is now read-only.

Commit

Permalink
Populate price for unit resource (#175)
Browse files Browse the repository at this point in the history
With this commit we persist price for unit resource for AWS
  • Loading branch information
kreddyj authored Feb 20, 2019
1 parent e974f15 commit f1f74ed
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 9 deletions.
3 changes: 2 additions & 1 deletion cmd/controller/purserctrl.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ func startCronJobForPopulatingRateCard() {
cloud.PopulateRateCard()

c := cron.New()
err := c.AddFunc("@every 7d", cloud.PopulateRateCard)

err := c.AddFunc("@every 168h", cloud.PopulateRateCard)
if err != nil {
log.Error(err)
}
Expand Down
3 changes: 3 additions & 0 deletions pkg/controller/dgraph/models/rateCard.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ type NodePrice struct {
InstanceFamily string `json:"instanceFamily,omitempty"`
OperatingSystem string `json:"operatingSystem,omitempty"`
Price float64 `json:"price,omitempty"`
PricePerCPU string `json:"cpuPrice,omitempty"`
PricePerMemory string `json:"memoryPrice,omitempty"`
}

// StoragePrice structure
Expand All @@ -61,6 +63,7 @@ type StoragePrice struct {
VolumeType string `json:"volumeType,omitempty"`
UsageType string `json:"usageType,omitempty"`
Price float64 `json:"price,omitempty"`
PricePerGB string `json:"pricePerGB,omitempty"`
}

// StoreRateCard given a cloudProvider and region it gets rate card and stores(create/update) in dgraph
Expand Down
2 changes: 2 additions & 0 deletions pkg/pricing/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ type ProductAttributes struct {
PreInstalledSW string
VolumeType string
UsageType string
Vcpu string
Memory string
}

// GetAWSPricing function details
Expand Down
49 changes: 41 additions & 8 deletions pkg/pricing/aws/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package aws

import (
"strconv"
"strings"

"github.com/Sirupsen/logrus"
"github.com/vmware/purser/pkg/controller/dgraph"
Expand All @@ -34,6 +35,12 @@ const (
computeInstance = "Compute Instance"
priceError = -1.0
hoursInMonth = 720

// TODO: Determine priceSplitRatio according to instance type i.e, compute optimized or memory optimized etc
priceSplitRatio = 0.5
defaultCPUCostPerCPUPerHour = "0.024"
defaultMemCostPerGBPerHour = "0.01"
defaultStorageCostInFloat64 = 0.00013888888
)

// GetRateCardForAWS takes region as input and returns RateCard and error if any
Expand Down Expand Up @@ -66,13 +73,11 @@ func getResourcePricesFromAWSPricing(awsPricing *Pricing) ([]*models.NodePrice,
duplicateComputeInstanceChecker := make(map[string]bool)
for _, product := range products {
priceInFloat64, unit := getResourcePrice(product, planList)
if priceInFloat64 != priceError {
switch product.ProductFamily {
case computeInstance:
nodePrices = updateComputeInstancePrices(product, priceInFloat64, duplicateComputeInstanceChecker, nodePrices)
case storageInstance:
storagePrices = updateStorageInstancePrices(product, priceInFloat64, unit, storagePrices)
}
switch product.ProductFamily {
case computeInstance:
nodePrices = updateComputeInstancePrices(product, priceInFloat64, duplicateComputeInstanceChecker, nodePrices)
case storageInstance:
storagePrices = updateStorageInstancePrices(product, priceInFloat64, unit, storagePrices)
}
}
return nodePrices, storagePrices
Expand All @@ -99,13 +104,16 @@ func updateComputeInstancePrices(product Product, priceInFloat64 float64, duplic
if _, isPresent := duplicateComputeInstanceChecker[key]; !isPresent && product.Attributes.PreInstalledSW == na {
// Unit of Compute price USD-perHour
productXID := product.Attributes.InstanceType + deliminator + product.Attributes.InstanceFamily + deliminator + product.Attributes.OperatingSystem
pricePerCPU, pricePerGB := getPriceForUnitResource(product, priceInFloat64)
nodePrice := &models.NodePrice{
ID: dgraph.ID{Xid: productXID},
IsNodePrice: true,
InstanceType: product.Attributes.InstanceType,
InstanceFamily: product.Attributes.InstanceFamily,
OperatingSystem: product.Attributes.OperatingSystem,
Price: priceInFloat64,
PricePerCPU: pricePerCPU,
PricePerMemory: pricePerGB,
}
duplicateComputeInstanceChecker[key] = true
uid := models.StoreNodePrice(nodePrice, productXID)
Expand All @@ -118,17 +126,21 @@ func updateComputeInstancePrices(product Product, priceInFloat64 float64, duplic
}

func updateStorageInstancePrices(product Product, priceInFloat64 float64, unit string, storagePrices []*models.StoragePrice) []*models.StoragePrice {
if unit == gbMonth {
if priceInFloat64 == priceError {
priceInFloat64 = defaultStorageCostInFloat64
} else if unit == gbMonth {
// convert to GBHour
priceInFloat64 = priceInFloat64 / hoursInMonth
}

productXID := product.Attributes.VolumeType + deliminator + product.Attributes.UsageType
storagePrice := &models.StoragePrice{
ID: dgraph.ID{Xid: productXID},
IsStoragePrice: true,
VolumeType: product.Attributes.VolumeType,
UsageType: product.Attributes.UsageType,
Price: priceInFloat64,
PricePerGB: strconv.FormatFloat(priceInFloat64, 'f', 11, 64),
}
uid := models.StoreStoragePrice(storagePrice, productXID)
if uid != "" {
Expand All @@ -137,3 +149,24 @@ func updateStorageInstancePrices(product Product, priceInFloat64 float64, unit s
}
return storagePrices
}

func getPriceForUnitResource(product Product, priceInFloat64 float64) (string, string) {
pricePerCPU := defaultCPUCostPerCPUPerHour
pricePerGB := defaultMemCostPerGBPerHour

// priceInFloat64 should be greater than 0 otherwise this function returns default pricing
if priceInFloat64 != priceError && priceInFloat64 != 0 {
cpu, err := strconv.ParseFloat(product.Attributes.Vcpu, 64)
if err == nil {
pricePerCPU = strconv.FormatFloat(priceSplitRatio*priceInFloat64/cpu, 'f', 11, 64)
}

memWithUnits := product.Attributes.Memory
// memWithUnits format: "3,126 GiB"
mem, err := strconv.ParseFloat(strings.Join(strings.Split(strings.Split(memWithUnits, " GiB")[0], ","), ""), 64)
if err == nil {
pricePerGB = strconv.FormatFloat((1-priceSplitRatio)*priceInFloat64/mem, 'f', 11, 64)
}
}
return pricePerCPU, pricePerGB
}

0 comments on commit f1f74ed

Please sign in to comment.