Просмотр исходного кода

WIP CostModel.ComputeAllocation: add to Aggregation type; fix Window expansion if nils exist

Niko Kovacevic 5 лет назад
Родитель
Сommit
d77b9da4fb
4 измененных файлов с 59 добавлено и 6 удалено
  1. 2 0
      pkg/costmodel/aggregation.go
  2. 39 5
      pkg/kubecost/allocation.go
  3. 3 0
      pkg/kubecost/asset.go
  4. 15 1
      pkg/kubecost/window.go

+ 2 - 0
pkg/costmodel/aggregation.go

@@ -47,6 +47,8 @@ type Aggregation struct {
 	Environment                string               `json:"environment"`
 	Environment                string               `json:"environment"`
 	Cluster                    string               `json:"cluster,omitempty"`
 	Cluster                    string               `json:"cluster,omitempty"`
 	Properties                 *kubecost.Properties `json:"-"`
 	Properties                 *kubecost.Properties `json:"-"`
+	Start                      time.Time            `json:"-"`
+	End                        time.Time            `json:"-"`
 	CPUAllocationHourlyAverage float64              `json:"cpuAllocationAverage"`
 	CPUAllocationHourlyAverage float64              `json:"cpuAllocationAverage"`
 	CPUAllocationVectors       []*util.Vector       `json:"-"`
 	CPUAllocationVectors       []*util.Vector       `json:"-"`
 	CPUAllocationTotal         float64              `json:"-"`
 	CPUAllocationTotal         float64              `json:"-"`

+ 39 - 5
pkg/kubecost/allocation.go

@@ -1,6 +1,7 @@
 package kubecost
 package kubecost
 
 
 import (
 import (
+	"bytes"
 	"encoding/json"
 	"encoding/json"
 	"fmt"
 	"fmt"
 	"sort"
 	"sort"
@@ -217,6 +218,39 @@ func (a *Allocation) PVBytes() float64 {
 	return a.PVByteHours / (a.Minutes() / 60.0)
 	return a.PVByteHours / (a.Minutes() / 60.0)
 }
 }
 
 
+// MarshalJSON implements json.Marshal interface
+func (a *Allocation) MarshalJSON() ([]byte, error) {
+	buffer := bytes.NewBufferString("{")
+	jsonEncodeString(buffer, "name", a.Name, ",")
+	jsonEncode(buffer, "properties", a.Properties, ",")
+	jsonEncode(buffer, "window", a.Window, ",")
+	jsonEncodeString(buffer, "start", a.Start.Format(timeFmt), ",")
+	jsonEncodeString(buffer, "end", a.End.Format(timeFmt), ",")
+	jsonEncodeFloat64(buffer, "minutes", a.Minutes(), ",")
+	jsonEncodeFloat64(buffer, "cpuCores", a.CPUCores(), ",")
+	jsonEncodeFloat64(buffer, "cpuCoreHours", a.CPUCoreHours, ",")
+	jsonEncodeFloat64(buffer, "cpuCost", a.CPUCost, ",")
+	jsonEncodeFloat64(buffer, "cpuEfficiency", a.CPUEfficiency, ",")
+	jsonEncodeFloat64(buffer, "gpuHours", a.GPUHours, ",")
+	jsonEncodeFloat64(buffer, "gpuCost", a.GPUCost, ",")
+	jsonEncodeFloat64(buffer, "networkCost", a.NetworkCost, ",")
+	jsonEncodeFloat64(buffer, "pvBytes", a.PVBytes(), ",")
+	jsonEncodeFloat64(buffer, "pvByteHours", a.PVByteHours, ",")
+	jsonEncodeFloat64(buffer, "pvCost", a.PVCost, ",")
+	jsonEncodeFloat64(buffer, "ramBytes", a.RAMBytes(), ",")
+	jsonEncodeFloat64(buffer, "ramByteHours", a.RAMByteHours, ",")
+	jsonEncodeFloat64(buffer, "ramCost", a.RAMCost, ",")
+	jsonEncodeFloat64(buffer, "ramEfficiency", a.RAMEfficiency, ",")
+	jsonEncodeFloat64(buffer, "sharedCost", a.SharedCost, ",")
+	jsonEncodeFloat64(buffer, "totalCost", a.TotalCost, ",")
+	jsonEncodeFloat64(buffer, "totalEfficiency", a.TotalEfficiency, "")
+	buffer.WriteString("}")
+	return buffer.Bytes(), nil
+}
+
+// TODO niko/cdmr
+// func (a *Allocation)UnmarshalJSON()
+
 // Resolution returns the duration of time covered by the Allocation
 // Resolution returns the duration of time covered by the Allocation
 func (a *Allocation) Resolution() time.Duration {
 func (a *Allocation) Resolution() time.Duration {
 	return a.End.Sub(a.Start)
 	return a.End.Sub(a.Start)
@@ -325,7 +359,7 @@ func (a *Allocation) add(that *Allocation) {
 		a.Start = that.Start
 		a.Start = that.Start
 	}
 	}
 
 
-	if that.End.Before(a.End) {
+	if that.End.After(a.End) {
 		a.End = that.End
 		a.End = that.End
 	}
 	}
 
 
@@ -1371,10 +1405,10 @@ func (as *AllocationSet) IdleAllocations() map[string]*Allocation {
 // but only if the Allocation is valid, i.e. matches the AllocationSet's window. If
 // but only if the Allocation is valid, i.e. matches the AllocationSet's window. If
 // there is no existing entry, one is created. Nil error response indicates success.
 // there is no existing entry, one is created. Nil error response indicates success.
 func (as *AllocationSet) Insert(that *Allocation) error {
 func (as *AllocationSet) Insert(that *Allocation) error {
-	return as.insert(that, false)
+	return as.insert(that)
 }
 }
 
 
-func (as *AllocationSet) insert(that *Allocation, accumulate bool) error {
+func (as *AllocationSet) insert(that *Allocation) error {
 	if as == nil {
 	if as == nil {
 		return fmt.Errorf("cannot insert into nil AllocationSet")
 		return fmt.Errorf("cannot insert into nil AllocationSet")
 	}
 	}
@@ -1565,14 +1599,14 @@ func (as *AllocationSet) accumulate(that *AllocationSet) (*AllocationSet, error)
 	defer that.RUnlock()
 	defer that.RUnlock()
 
 
 	for _, alloc := range as.allocations {
 	for _, alloc := range as.allocations {
-		err := acc.insert(alloc, true)
+		err := acc.insert(alloc)
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
 	}
 	}
 
 
 	for _, alloc := range that.allocations {
 	for _, alloc := range that.allocations {
-		err := acc.insert(alloc, true)
+		err := acc.insert(alloc)
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}

+ 3 - 0
pkg/kubecost/asset.go

@@ -187,6 +187,9 @@ func AssetToExternalAllocation(asset Asset, aggregateBy []string, allocationProp
 	return &Allocation{
 	return &Allocation{
 		Name:         strings.Join(names, "/"),
 		Name:         strings.Join(names, "/"),
 		Properties:   props,
 		Properties:   props,
+		Window:       asset.Window().Clone(),
+		Start:        asset.Start(),
+		End:          asset.End(),
 		ExternalCost: asset.TotalCost(),
 		ExternalCost: asset.TotalCost(),
 		TotalCost:    asset.TotalCost(),
 		TotalCost:    asset.TotalCost(),
 	}, nil
 	}, nil

+ 15 - 1
pkg/kubecost/window.go

@@ -393,7 +393,21 @@ func (w Window) ExpandEnd(end time.Time) Window {
 }
 }
 
 
 func (w Window) Expand(that Window) Window {
 func (w Window) Expand(that Window) Window {
-	return w.ExpandStart(*that.start).ExpandEnd(*that.end)
+	result := w
+
+	if that.start == nil {
+		result.start = nil
+	} else {
+		result = w.ExpandStart(*that.start)
+	}
+
+	if that.end == nil {
+		result.end = nil
+	} else {
+		result = w.ExpandEnd(*that.end)
+	}
+
+	return result
 }
 }
 
 
 func (w Window) Hours() float64 {
 func (w Window) Hours() float64 {