cloudcostexplorer

package module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 3, 2025 License: MIT Imports: 19 Imported by: 0

README

cloudcostexplorer

cloudcostexplorer is a developer-oriented local HTTP UI for the cost explorer APIs of various cloud providers.

Supported APIs:

  • AWS cost explorer
  • GCP billing export to BigQuery

The UI supports filtering and multiple groupings using the menus and clicking the column values, allowing drill-down cost analysis.

Advanced filters that are hard to use with the default cloud UIs like grouping and filtering by tags / labels / resources are available.

Screenshot

AWS

Usage

Download a binary from the Releases Github page, or if you have a Golang compiler available:

$ go install github.com/rrgmc/cloudcostexplorer/cmd/cloudcostexplorer@latest

Create a local cloudcostexplorer.conf configuration file based on cloudcostexplorer_example.conf, with the accounts that have access to your cost explorer APIs, and run the cloudcostexplorer cli.

It will try to find a cloudcostexplorer.conf file in the current directory, and start a local webserver on http://localhost:3335.

Golang library

It can also be used as a Go library, the interfaces are designed to serve this specific UI, but it can probably be useful in other use cases. See cloud.go to have an idea of what it looks like.

Author

Rangel Reale (rangelreale@gmail.com)

Documentation

Index

Constants

View Source
const DataSeparator = "|"
View Source
const (
	DefaultSkipDays = -2 // usually data is fresh only from 2 days ago
)

Variables

This section is empty.

Functions

func DateBetweenDates

func DateBetweenDates(dt timex.Date, start, end timex.Date) bool

DateBetweenDates returns whether the passed date is between start and end.

func DefaultHash

func DefaultHash(s string) string

DefaultHash is the default hash function.

func DefaultItemKeysHash

func DefaultItemKeysHash(keys []ItemKey) string

DefaultItemKeysHash is the default function for hashing the list of item keys.

func EllipticalTruncate

func EllipticalTruncate(text string, maxLen int) string

EllipticalTruncate truncates a string with ellipsis at the end.

func EndingOfMonth

func EndingOfMonth(date timex.Date) timex.Date

EndingOfMonth returns the last day of the month/year of the passed date.

func FormatMoney

func FormatMoney(value float64) string

FormatMoney formats a money value.

func FormatShortDate

func FormatShortDate(dt timex.Date) string

FormatShortDate formats a date like "Feb 15".

func FromCivilDate

func FromCivilDate(dt civil.Date) timex.Date

FromCivilDate converts from civil.Date to timex.Date.

func IndentJSON

func IndentJSON(data string) string

IndentJSON indents a string containing a JSON.

func Ptr

func Ptr[T any](v T) *T

Ptr returns a pointer to the passed value.

func RandString

func RandString(n int) string

RandString returns a random string of length n.

func ShortMonthName

func ShortMonthName(month time.Month) string

ShortMonthName returns the 3-letter english month abbreviation.

func SortMapByValue

func SortMapByValue[K comparable, V any](m map[K]V, cmp func(V, V) int, reverse bool) iter.Seq2[K, V]

SortMapByValue sorts a map by value.

func SortMapByValueOrdered

func SortMapByValueOrdered[K comparable, V cmp.Ordered](m map[K]V, reverse bool) iter.Seq2[K, V]

SortMapByValueOrdered sorts a map by value where the value is cmp.Ordered.

func TimeStartEnd

func TimeStartEnd(start, end timex.Date) (time.Time, time.Time)

TimeStartEnd converts 2 timex.Date values to 2 time.Time values, with the time part set to 00:00:00 and 23:59:59 respectively.

Types

type Cloud

type Cloud interface {
	// DaysDelay returns the number of days that the cloud service takes to process cost data. Usually the data
	// is only reliable on the next day.
	DaysDelay() int
	// MaxGroupBy returns the maximum number of groups that the cloud service supports.
	MaxGroupBy() int
	// Parameters returns the list of possible filtering and grouping parameter.
	Parameters() Parameters
	// ParameterTitle returns the string value of a parameter, or the passed value if unknown.
	ParameterTitle(id string, defaultValue string) string
	// Query executes the cost explorer query and returns an iterator for the data.
	Query(ctx context.Context, options ...QueryOption) iter.Seq2[CloudQueryItem, error]
	// QueryExtraOutput may return any extra output to be shown after the query data, like extra filters
	// not available in fields from the main query.
	QueryExtraOutput(ctx context.Context, extraData []QueryExtraData) QueryExtraOutput
}

Cloud is a cloud service abstraction.

type CloudQueryItem

type CloudQueryItem struct {
	Date  timex.Date
	Keys  []ItemKey
	Value float64
}

type EmptyValue

type EmptyValue struct {
}

EmptyValue implements ValueOutput always returning "[EMPTY VALUE]".

func (EmptyValue) Output

func (v EmptyValue) Output(ctx context.Context, vctx ValueContext, uq *URLQuery) (string, error)

type Item

type Item struct {
	Keys   []ItemKey
	Values []float64
}

Item contains the keys and values of a single cost explorer item, based on the query groups.

func NewItem

func NewItem(keys []ItemKey, periods int) *Item

func (*Item) Search

func (i *Item) Search(search string) bool

Search returns whether the search string is contained on any item key value.

type ItemKey

type ItemKey struct {
	ID    string
	Value any // can be ItemValue or ValueOutput.
}

ItemKey is the id and value of one item dimension, like "ID=service, Value=EC2".

type ItemValue

type ItemValue struct {
	Value float64
}

ItemValue is the default item value, a monetary cost.

type Parameter

type Parameter struct {
	ID              string // parameter ID, like "SERVICE".
	Name            string // parameter name, like "Service".
	MenuTitle       string // if set, this will be shown in menus instead of Name.
	DefaultPriority int    // if > 0, sets a priority to select a group if the previous group contains a single item.
	IsGroup         bool   // set whether the parameter can be used for grouping.
	IsGroupFilter   bool   // if IsGroup==true, sets whether the field value will have a link to filter by its value.
	IsFilter        bool   // sets whether the parameter can be used for filtering.
	HasData         bool   // sets whether the parameter may contain extra data in its name, separated by DataSeparator.
	DataRequired    bool   // if HasData==true, sets whether the parameter always contains data or only sometimes.
}

Parameter is the configuration of a filtering and/or grouping parameter available for the cloud service.

type Parameters

type Parameters []Parameter

func (Parameters) DefaultGroup

func (p Parameters) DefaultGroup() Parameter

DefaultGroup returns the parameter which is a group that should be the default group if none was selected.

func (Parameters) FindByGroupDefaultPriority

func (p Parameters) FindByGroupDefaultPriority(priority int) (Parameter, bool)

FindByGroupDefaultPriority finds a parameter which is a group and has the passed default priority.

func (Parameters) FindById

func (p Parameters) FindById(id string) (Parameter, bool)

FindById finds a parameter by ID. If the parameter was not found and has data, it is split by DataSeparator and searched for its first part.

type QueryExtraData

type QueryExtraData interface {
	ExtraDataType() string
}

QueryExtraData is possible extra data to be shown after the main cost table.

type QueryExtraOutput

type QueryExtraOutput interface {
	Close()
	ExtraOutputs() iter.Seq2[ValueOutput, error]
}

QueryExtraOutput returns a list of possible extra output to be shown after the main cost table.

type QueryFilter

type QueryFilter struct {
	ID    string
	Value string
}

QueryFilter is the ID and value of a filter.

type QueryGroup

type QueryGroup struct {
	ID   string
	Data string // only if group has data
}

QueryGroup is the ID and optional value of a group.

type QueryHandlerOption

type QueryHandlerOption func(options *queryHandlerOptions)

func WithQueryHandlerFilterKeys

func WithQueryHandlerFilterKeys(f func(keys []ItemKey) bool) QueryHandlerOption

WithQueryHandlerFilterKeys sets a function to use for filtering the item keys, if needed.

func WithQueryHandlerFilters

func WithQueryHandlerFilters(filters ...QueryFilter) QueryHandlerOption

WithQueryHandlerFilters sets the filters to use for querying.

func WithQueryHandlerGroups

func WithQueryHandlerGroups(groups ...QueryGroup) QueryHandlerOption

WithQueryHandlerGroups sets the groups to use for querying.

func WithQueryHandlerItemKeysHash

func WithQueryHandlerItemKeysHash(f func(keys []ItemKey) string) QueryHandlerOption

WithQueryHandlerItemKeysHash sets the function to use for hashing the item keys. The default is DefaultItemKeysHash.

func WithQueryHandlerOnPeriodMatchError

func WithQueryHandlerOnPeriodMatchError(onPeriodMatchError func(item CloudQueryItem, matchCount int) error) QueryHandlerOption

WithQueryHandlerOnPeriodMatchError sets a function to handle period mismatches. If the function returns an error, processing is stopped and the error is returned.

func WithQueryHandlerPeriodLists

func WithQueryHandlerPeriodLists(periodList ...QueryPeriodList) QueryHandlerOption

WithQueryHandlerPeriodLists sets a list of period lists to query.

func WithQueryHandlerPeriods

func WithQueryHandlerPeriods(periods ...QueryPeriod) QueryHandlerOption

WithQueryHandlerPeriods adds a list of periods to query.

type QueryOption

type QueryOption func(options *QueryOptions)

func WithQueryDates

func WithQueryDates(start, end timex.Date) QueryOption

WithQueryDates sets the date range to query.

func WithQueryExtraData

func WithQueryExtraData(extraDataCallback func(data QueryExtraData)) QueryOption

WithQueryExtraData sets a callback to receive any possible extra data that the query may return. A list of these values should be sent to [Cloud.QueryExtraOutput] after the main cost query finishes.

func WithQueryFilters

func WithQueryFilters(filters ...QueryFilter) QueryOption

WithQueryFilters sets the filters to use for the query.

func WithQueryGroupByDate

func WithQueryGroupByDate(groupByDate bool) QueryOption

WithQueryGroupByDate sets whether to group by date (day only), ignoring any possible time value.

func WithQueryGroups

func WithQueryGroups(groups ...QueryGroup) QueryOption

WithQueryGroups sets the grouping to use for the query.

type QueryOptions

type QueryOptions struct {
	Start, End        timex.Date
	GroupByDate       bool
	Groups            []QueryGroup
	Filters           []QueryFilter
	ExtraDataCallback func(data QueryExtraData)
}

func ParseQueryOptions

func ParseQueryOptions(options ...QueryOption) (QueryOptions, error)

ParseQueryOptions parses the default query options.

type QueryPeriod

type QueryPeriod struct {
	ID         string // optional ID that can be used by the caller to identify the returned period. Not used by the library.
	Start, End timex.Date
}

QueryPeriod is a single period to query.

func GenerateQueryPeriods

func GenerateQueryPeriods(start, end timex.Date, amount int) []QueryPeriod

GenerateQueryPeriods generates "amount" list of periods of the same number of days as the passed range, one before the other.

func NewQueryPeriod

func NewQueryPeriod(start, end timex.Date) QueryPeriod

func (QueryPeriod) String

func (q QueryPeriod) String() string

String returns a short string representation of the period.

func (QueryPeriod) StringFilter

func (q QueryPeriod) StringFilter() string

StringFilter returns a string representation of the period to be used as a filtering value.

func (QueryPeriod) StringWithDuration

func (q QueryPeriod) StringWithDuration(showDuration bool) string

StringWithDuration may append the duration to the String result.

type QueryPeriodList

type QueryPeriodList struct {
	Periods []QueryPeriod
}

QueryPeriodList is a list of periods to query.

func (QueryPeriodList) Range

func (l QueryPeriodList) Range() (bool, timex.Date, timex.Date)

type QueryResult

type QueryResult struct {
	Items               []*Item
	TotalValue          float64
	Groups              []QueryResultGroup
	PeriodsSameDuration bool
	Periods             []QueryResultPeriod
	ExtraOutput         QueryExtraOutput
}

func QueryHandler

func QueryHandler(ctx context.Context, cloud Cloud, options ...QueryHandlerOption) (*QueryResult, error)

QueryHandler handles calling [Cloud.Query] while supporting multiple periods.

type QueryResultGroup

type QueryResultGroup struct {
	Parameter
	Data string
}

QueryResultGroup is a group that was used to query the results.

func (QueryResultGroup) String

func (q QueryResultGroup) String() string

func (QueryResultGroup) Title

func (q QueryResultGroup) Title(isMenu bool) string

type QueryResultPeriod

type QueryResultPeriod struct {
	QueryPeriod
	TotalValue float64
}

QueryResultPeriod is a period that was used to query the results.

type URLQuery

type URLQuery struct {
	// contains filtered or unexported fields
}

URLQuery is a URL query builder.

func NewURLQuery

func NewURLQuery(path string) *URLQuery

func (*URLQuery) Clone

func (q *URLQuery) Clone() *URLQuery

Clone clones the query to a new instance.

func (*URLQuery) Copy

func (q *URLQuery) Copy(keyFrom, keyTo string) *URLQuery

func (*URLQuery) Get

func (q *URLQuery) Get(key string) string

func (*URLQuery) Move

func (q *URLQuery) Move(keyFrom, keyTo string) *URLQuery

func (*URLQuery) Params

func (q *URLQuery) Params() iter.Seq2[string, string]

func (*URLQuery) Path

func (q *URLQuery) Path() string

func (*URLQuery) Remove

func (q *URLQuery) Remove(keys ...string) *URLQuery

func (*URLQuery) Set

func (q *URLQuery) Set(key, value string) *URLQuery

func (*URLQuery) SetFromQuery

func (q *URLQuery) SetFromQuery(query url.Values, keys ...string) *URLQuery

func (*URLQuery) SetPath

func (q *URLQuery) SetPath(path string) *URLQuery

func (*URLQuery) String

func (q *URLQuery) String() string

func (*URLQuery) Swap

func (q *URLQuery) Swap(key1, key2 string) *URLQuery

type ValueContext

type ValueContext interface {
	GroupParamName() string           // the group parameter of the column.
	FilterParamName(id string) string // the URL query field name that should be used for filtering.
	Flush()                           // flushes the HTTP output.
}

type ValueOutput

type ValueOutput interface {
	Output(ctx context.Context, vctx ValueContext, uq *URLQuery) (string, error)
}

ValueOutput allows outputting custom values for cost table columns.

Directories

Path Synopsis
cloud
aws
gcp
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL