|
@@ -19,6 +19,8 @@ import (
|
|
|
|
|
|
|
|
const MAX_LOCAL_STORAGE_SIZE = 1024 * 1024 * 1024 * 1024
|
|
const MAX_LOCAL_STORAGE_SIZE = 1024 * 1024 * 1024 * 1024
|
|
|
|
|
|
|
|
|
|
+const localStoragePricePerGBHr = 0.04 / 730.0
|
|
|
|
|
+
|
|
|
// When ASSET_INCLUDE_LOCAL_DISK_COST is set to false, local storage
|
|
// When ASSET_INCLUDE_LOCAL_DISK_COST is set to false, local storage
|
|
|
// provisioned by sig-storage-local-static-provisioner is excluded
|
|
// provisioned by sig-storage-local-static-provisioner is excluded
|
|
|
// by checking if the volume is prefixed by "local-pv-".
|
|
// by checking if the volume is prefixed by "local-pv-".
|
|
@@ -124,23 +126,17 @@ func ClusterDisks(dataSource source.OpenCostDataSource, cp models.Provider, star
|
|
|
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/RootDeviceStorage.html
|
|
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/RootDeviceStorage.html
|
|
|
// https://learn.microsoft.com/en-us/azure/virtual-machines/managed-disks-overview#temporary-disk
|
|
// https://learn.microsoft.com/en-us/azure/virtual-machines/managed-disks-overview#temporary-disk
|
|
|
// https://cloud.google.com/compute/docs/disks/local-ssd
|
|
// https://cloud.google.com/compute/docs/disks/local-ssd
|
|
|
- resLocalStorageCost := []*source.LocalStorageCostResult{}
|
|
|
|
|
- resLocalStorageUsedCost := []*source.LocalStorageUsedCostResult{}
|
|
|
|
|
resLocalStorageUsedAvg := []*source.LocalStorageUsedAvgResult{}
|
|
resLocalStorageUsedAvg := []*source.LocalStorageUsedAvgResult{}
|
|
|
resLocalStorageUsedMax := []*source.LocalStorageUsedMaxResult{}
|
|
resLocalStorageUsedMax := []*source.LocalStorageUsedMaxResult{}
|
|
|
resLocalStorageBytes := []*source.LocalStorageBytesResult{}
|
|
resLocalStorageBytes := []*source.LocalStorageBytesResult{}
|
|
|
resLocalActiveMins := []*source.LocalStorageActiveMinutesResult{}
|
|
resLocalActiveMins := []*source.LocalStorageActiveMinutesResult{}
|
|
|
|
|
|
|
|
if env.IsAssetIncludeLocalDiskCost() {
|
|
if env.IsAssetIncludeLocalDiskCost() {
|
|
|
- resChLocalStorageCost := source.WithGroup(grp, mq.QueryLocalStorageCost(start, end))
|
|
|
|
|
- resChLocalStorageUsedCost := source.WithGroup(grp, mq.QueryLocalStorageUsedCost(start, end))
|
|
|
|
|
resChLocalStoreageUsedAvg := source.WithGroup(grp, mq.QueryLocalStorageUsedAvg(start, end))
|
|
resChLocalStoreageUsedAvg := source.WithGroup(grp, mq.QueryLocalStorageUsedAvg(start, end))
|
|
|
resChLocalStoreageUsedMax := source.WithGroup(grp, mq.QueryLocalStorageUsedMax(start, end))
|
|
resChLocalStoreageUsedMax := source.WithGroup(grp, mq.QueryLocalStorageUsedMax(start, end))
|
|
|
resChLocalStorageBytes := source.WithGroup(grp, mq.QueryLocalStorageBytes(start, end))
|
|
resChLocalStorageBytes := source.WithGroup(grp, mq.QueryLocalStorageBytes(start, end))
|
|
|
resChLocalActiveMins := source.WithGroup(grp, mq.QueryLocalStorageActiveMinutes(start, end))
|
|
resChLocalActiveMins := source.WithGroup(grp, mq.QueryLocalStorageActiveMinutes(start, end))
|
|
|
|
|
|
|
|
- resLocalStorageCost, _ = resChLocalStorageCost.Await()
|
|
|
|
|
- resLocalStorageUsedCost, _ = resChLocalStorageUsedCost.Await()
|
|
|
|
|
resLocalStorageUsedAvg, _ = resChLocalStoreageUsedAvg.Await()
|
|
resLocalStorageUsedAvg, _ = resChLocalStoreageUsedAvg.Await()
|
|
|
resLocalStorageUsedMax, _ = resChLocalStoreageUsedMax.Await()
|
|
resLocalStorageUsedMax, _ = resChLocalStoreageUsedMax.Await()
|
|
|
resLocalStorageBytes, _ = resChLocalStorageBytes.Await()
|
|
resLocalStorageBytes, _ = resChLocalStorageBytes.Await()
|
|
@@ -206,61 +202,6 @@ func ClusterDisks(dataSource source.OpenCostDataSource, cp models.Provider, star
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- for _, result := range resLocalStorageCost {
|
|
|
|
|
- cluster := result.Cluster
|
|
|
|
|
- if cluster == "" {
|
|
|
|
|
- cluster = coreenv.GetClusterID()
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- name := result.Instance
|
|
|
|
|
- if name == "" {
|
|
|
|
|
- log.Warnf("ClusterDisks: local storage data missing instance")
|
|
|
|
|
- continue
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- device := result.Device
|
|
|
|
|
- if device == "" {
|
|
|
|
|
- log.Warnf("ClusterDisks: local storage data missing device")
|
|
|
|
|
- continue
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- cost := result.Data[0].Value
|
|
|
|
|
- key := DiskIdentifier{cluster, name}
|
|
|
|
|
- ls, ok := localStorageDisks[key]
|
|
|
|
|
- if !ok || ls.device != device {
|
|
|
|
|
- continue
|
|
|
|
|
- }
|
|
|
|
|
- ls.disk.Cost = cost
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- for _, result := range resLocalStorageUsedCost {
|
|
|
|
|
- cluster := result.Cluster
|
|
|
|
|
- if cluster == "" {
|
|
|
|
|
- cluster = coreenv.GetClusterID()
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- name := result.Instance
|
|
|
|
|
- if name == "" {
|
|
|
|
|
- log.Warnf("ClusterDisks: local storage data missing instance")
|
|
|
|
|
- continue
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- device := result.Device
|
|
|
|
|
- if device == "" {
|
|
|
|
|
- log.Warnf("ClusterDisks: local storage data missing device")
|
|
|
|
|
- continue
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- cost := result.Data[0].Value
|
|
|
|
|
- key := DiskIdentifier{cluster, name}
|
|
|
|
|
- ls, ok := localStorageDisks[key]
|
|
|
|
|
- if !ok || ls.device != device {
|
|
|
|
|
- continue
|
|
|
|
|
- }
|
|
|
|
|
- ls.disk.Breakdown.System = cost / ls.disk.Cost
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
for _, result := range resLocalStorageUsedAvg {
|
|
for _, result := range resLocalStorageUsedAvg {
|
|
|
cluster := result.Cluster
|
|
cluster := result.Cluster
|
|
|
if cluster == "" {
|
|
if cluster == "" {
|
|
@@ -349,11 +290,23 @@ func ClusterDisks(dataSource source.OpenCostDataSource, cp models.Provider, star
|
|
|
e := time.Unix(int64(result.Data[len(result.Data)-1].Timestamp), 0)
|
|
e := time.Unix(int64(result.Data[len(result.Data)-1].Timestamp), 0)
|
|
|
mins := e.Sub(s).Minutes()
|
|
mins := e.Sub(s).Minutes()
|
|
|
|
|
|
|
|
- // TODO niko/assets if mins >= threshold, interpolate for missing data?
|
|
|
|
|
-
|
|
|
|
|
ls.disk.End = e
|
|
ls.disk.End = e
|
|
|
ls.disk.Start = s
|
|
ls.disk.Start = s
|
|
|
ls.disk.Minutes = mins
|
|
ls.disk.Minutes = mins
|
|
|
|
|
+
|
|
|
|
|
+ // Cost = GiB * hours * $-per-GB-hour
|
|
|
|
|
+ ls.disk.Cost = (ls.disk.Bytes / 1024 / 1024 / 1024) * (ls.disk.Minutes / 60) * localStoragePricePerGBHr
|
|
|
|
|
+
|
|
|
|
|
+ bytesUsedAvg := 0.0
|
|
|
|
|
+ if ls.disk.BytesUsedAvgPtr != nil {
|
|
|
|
|
+ bytesUsedAvg = *ls.disk.BytesUsedAvgPtr
|
|
|
|
|
+ }
|
|
|
|
|
+ // Used Cost = Used GiB * hours * $-per-GB-hour
|
|
|
|
|
+ if ls.disk.Cost > 0 {
|
|
|
|
|
+ ls.disk.Breakdown.System = ((bytesUsedAvg / 1024 / 1024 / 1024) * (ls.disk.Minutes / 60) * localStoragePricePerGBHr) / ls.disk.Cost
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ls.disk.Breakdown.System = 0
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// move local storage disks to main disk map
|
|
// move local storage disks to main disk map
|