diff --git a/cli/cmd/vm_ls.go b/cli/cmd/vm_ls.go index 57a93ca2d..277d052c9 100644 --- a/cli/cmd/vm_ls.go +++ b/cli/cmd/vm_ls.go @@ -119,6 +119,8 @@ func (r *runners) listVMs(_ *cobra.Command, args []string) error { vmsToPrint = append(vmsToPrint, newVM) } else { // Check if properties of existing vms have changed + // reset EstimatedCost (as it is calculated on the fly and not stored in the API response) + oldVM.EstimatedCost = 0 if !reflect.DeepEqual(newVM, oldVM) { vmsToPrint = append(vmsToPrint, newVM) } diff --git a/cli/print/clusters.go b/cli/print/clusters.go index d550bce07..f0c96a2d6 100644 --- a/cli/print/clusters.go +++ b/cli/print/clusters.go @@ -46,11 +46,6 @@ DISTRIBUTION: {{ $d.Name }} {{ end }}` var clusterVersionsTmpl = template.Must(template.New("clusterVersions").Funcs(funcs).Parse(clusterVersionsTmplSrc)) -func CreditsToDollarsDisplay(credits int64) string { - dollars := float64(credits) / 100000.0 - return fmt.Sprintf("$%.2f", dollars) -} - func Clusters(outputFormat string, w *tabwriter.Writer, clusters []*types.Cluster, header bool) error { for _, cluster := range clusters { updateEstimatedCost(cluster) diff --git a/cli/print/util.go b/cli/print/util.go index 8dc0a480d..b8dd565a1 100644 --- a/cli/print/util.go +++ b/cli/print/util.go @@ -30,3 +30,8 @@ var funcs = template.FuncMap{ return t.Local().Format("2006-01-02 15:04 MST") }, } + +func CreditsToDollarsDisplay(credits int64) string { + dollars := float64(credits) / 100000.0 + return fmt.Sprintf("$%.2f", dollars) +} diff --git a/cli/print/vms.go b/cli/print/vms.go index 56f8834aa..0940fa3ae 100644 --- a/cli/print/vms.go +++ b/cli/print/vms.go @@ -10,23 +10,27 @@ import ( "github.com/replicatedhq/replicated/pkg/types" ) +var vmFuncs = template.FuncMap{ + "CreditsToDollarsDisplay": CreditsToDollarsDisplay, +} + // Table formatting -var vmsTmplTableHeaderSrc = `ID NAME DISTRIBUTION VERSION STATUS CREATED EXPIRES` +var vmsTmplTableHeaderSrc = `ID NAME DISTRIBUTION VERSION STATUS CREATED EXPIRES COST` var vmsTmplTableRowSrc = `{{ range . -}} -{{ .ID }} {{ padding .Name 27 }} {{ padding .Distribution 12 }} {{ padding .Version 10 }} {{ padding (printf "%s" .Status) 12 }} {{ padding (printf "%s" (localeTime .CreatedAt)) 30 }} {{if .ExpiresAt.IsZero}}{{ padding "-" 30 }}{{else}}{{ padding (printf "%s" (localeTime .ExpiresAt)) 30 }}{{end}} +{{ .ID }} {{ padding .Name 27 }} {{ padding .Distribution 12 }} {{ padding .Version 10 }} {{ padding (printf "%s" .Status) 12 }} {{ padding (printf "%s" (localeTime .CreatedAt)) 30 }} {{if .ExpiresAt.IsZero}}{{ padding "-" 30 }}{{else}}{{ padding (printf "%s" (localeTime .ExpiresAt)) 30 }}{{end}} {{ padding (CreditsToDollarsDisplay .EstimatedCost) 11 }} {{ end }}` var vmsTmplTableSrc = fmt.Sprintln(vmsTmplTableHeaderSrc) + vmsTmplTableRowSrc -var vmsTmplTable = template.Must(template.New("vms").Funcs(funcs).Parse(vmsTmplTableSrc)) -var vmsTmplTableNoHeader = template.Must(template.New("vms").Funcs(funcs).Parse(vmsTmplTableRowSrc)) +var vmsTmplTable = template.Must(template.New("vms").Funcs(vmFuncs).Funcs(funcs).Parse(vmsTmplTableSrc)) +var vmsTmplTableNoHeader = template.Must(template.New("vms").Funcs(vmFuncs).Funcs(funcs).Parse(vmsTmplTableRowSrc)) // Wide table formatting -var vmsTmplWideHeaderSrc = `ID NAME DISTRIBUTION VERSION STATUS CREATED EXPIRES TAGS` +var vmsTmplWideHeaderSrc = `ID NAME DISTRIBUTION VERSION STATUS CREATED EXPIRES COST TAGS` var vmsTmplWideRowSrc = `{{ range . -}} -{{ .ID }} {{ padding .Name 27 }} {{ padding .Distribution 12 }} {{ padding .Version 10 }} {{ padding (printf "%s" .Status) 12 }} {{ padding (printf "%s" (localeTime .CreatedAt)) 30 }} {{if .ExpiresAt.IsZero}}{{ padding "-" 30 }}{{else}}{{ padding (printf "%s" (localeTime .ExpiresAt)) 30 }}{{end}} {{ range $index, $tag := .Tags }}{{if $index}}, {{end}}{{ $tag.Key }}={{ $tag.Value }}{{ end }} +{{ .ID }} {{ padding .Name 27 }} {{ padding .Distribution 12 }} {{ padding .Version 10 }} {{ padding (printf "%s" .Status) 12 }} {{ padding (printf "%s" (localeTime .CreatedAt)) 30 }} {{if .ExpiresAt.IsZero}}{{ padding "-" 30 }}{{else}}{{ padding (printf "%s" (localeTime .ExpiresAt)) 30 }}{{end}} {{ padding (CreditsToDollarsDisplay .EstimatedCost) 11 }} {{ range $index, $tag := .Tags }}{{if $index}}, {{end}}{{ $tag.Key }}={{ $tag.Value }}{{ end }} {{ end }}` var vmsTmplWideSrc = fmt.Sprintln(vmsTmplWideHeaderSrc) + vmsTmplWideRowSrc -var vmsTmplWide = template.Must(template.New("vms").Funcs(funcs).Parse(vmsTmplWideSrc)) -var vmsTmplWideNoHeader = template.Must(template.New("vms").Funcs(funcs).Parse(vmsTmplWideRowSrc)) +var vmsTmplWide = template.Must(template.New("vms").Funcs(vmFuncs).Funcs(funcs).Parse(vmsTmplWideSrc)) +var vmsTmplWideNoHeader = template.Must(template.New("vms").Funcs(vmFuncs).Funcs(funcs).Parse(vmsTmplWideRowSrc)) // VM versions var vmVersionsTmplSrc = `Supported VM distributions and versions are: @@ -42,6 +46,9 @@ DISTRIBUTION: {{ $d.Name }} var vmVersionsTmpl = template.Must(template.New("vmVersions").Funcs(funcs).Parse(vmVersionsTmplSrc)) func VMs(outputFormat string, w *tabwriter.Writer, vms []*types.VM, header bool) error { + for _, vm := range vms { + updateEstimatedVMCost(vm) + } switch outputFormat { case "table": if header { @@ -165,7 +172,7 @@ func updateEstimatedVMCost(vm *types.VM) { } else { expireDuration, _ := time.ParseDuration(vm.TTL) minutesRunning := int64(expireDuration.Minutes()) - totalCredits := int64(minutesRunning) * vm.CreditsPerHourPerVM / 60.0 + totalCredits := int64(minutesRunning) * vm.CreditsPerHour / 60.0 vm.EstimatedCost = vm.FlatFee + totalCredits } } diff --git a/pkg/types/vm.go b/pkg/types/vm.go index ce0b45372..3830fe87c 100644 --- a/pkg/types/vm.go +++ b/pkg/types/vm.go @@ -14,9 +14,9 @@ type VM struct { TTL string `json:"ttl"` - CreditsPerHourPerVM int64 `json:"credits_per_hour_per_vm"` - FlatFee int64 `json:"flat_fee"` - TotalCredits int64 `json:"total_credits"` + CreditsPerHour int64 `json:"credits_per_hour"` + FlatFee int64 `json:"flat_fee"` + TotalCredits int64 `json:"total_credits"` EstimatedCost int64 `json:"estimated_cost"` // Represents estimated credits for this vm based on the TTL