2
0
Эх сурвалжийг харах

Define Proto

Signed-off-by: Sean Holcomb <seanholcomb@gmail.com>
Sean Holcomb 2 жил өмнө
parent
commit
3715842d9e

+ 165 - 0
core/pkg/model/customcost_helpers.go

@@ -0,0 +1,165 @@
+package model
+
+import (
+	"fmt"
+
+	"github.com/opencost/opencost/core/pkg/model/pb"
+	"github.com/opencost/opencost/core/pkg/opencost"
+	"google.golang.org/protobuf/types/known/timestamppb"
+)
+
+func ToCustomCostResponse(ccrpb *pb.CustomCostResponse) *CustomCostResponse {
+	window := opencost.NewClosedWindow(ccrpb.Start.AsTime().UTC(), ccrpb.End.AsTime().UTC())
+	var errs []error
+	for _, errStr := range ccrpb.Errors {
+		errs = append(errs, fmt.Errorf(errStr))
+	}
+	var costs []*CustomCost
+	for _, cost := range ccrpb.Costs {
+		costs = append(costs, ToCustomCost(cost, &window))
+	}
+	return &CustomCostResponse{
+		Metadata:   ccrpb.Metadata,
+		Costsource: ccrpb.CostSource,
+		Domain:     ccrpb.Domain,
+		Version:    ccrpb.Version,
+		Currency:   ccrpb.Currency,
+		Window:     window,
+		Costs:      costs,
+		Errors:     errs,
+	}
+}
+
+func ToCustomCost(ccpb *pb.CustomCost, window *opencost.Window) *CustomCost {
+	return &CustomCost{
+		Metadata:           ccpb.Metadata,
+		Zone:               ccpb.Zone,
+		BilledCost:         ccpb.BilledCost,
+		AccountName:        ccpb.AccountName,
+		ChargeCategory:     ccpb.ChargeCategory,
+		Description:        ccpb.Description,
+		ListCost:           ccpb.ListCost,
+		ListUnitPrice:      ccpb.ListUnitPrice,
+		ResourceName:       ccpb.ResourceName,
+		ResourceType:       ccpb.ResourceType,
+		Id:                 ccpb.Id,
+		ProviderId:         ccpb.ProviderId,
+		Window:             window,
+		Labels:             ccpb.Labels,
+		UsageQty:           ccpb.UsageQuantity,
+		UsageUnit:          ccpb.UsageUnit,
+		ExtendedAttributes: ToCustomCostExtendedAttributes(ccpb.ExtendedAttributes),
+	}
+}
+
+func ToCustomCostExtendedAttributes(ea *pb.CustomCostExtendedAttributes) *ExtendedCustomCostAttributes {
+	if ea == nil {
+		return nil
+	}
+	billingPeriod := opencost.NewClosedWindow(ea.BillingPeriodStart.AsTime().UTC(), ea.BillingPeriodEnd.AsTime().UTC())
+	return &ExtendedCustomCostAttributes{
+		BillingPeriod:              &billingPeriod,
+		AccountID:                  *ea.AccountId,
+		ChargeFrequency:            *ea.ChargeFrequency,
+		Subcategory:                *ea.Subcategory,
+		CommitmentDiscountCategory: *ea.CommitmentDiscountCategory,
+		CommitmentDiscountID:       *ea.CommitmentDiscountId,
+		CommitmentDiscountName:     *ea.CommitmentDiscountName,
+		CommitmentDiscountType:     *ea.CommitmentDiscountType,
+		EffectiveCost:              *ea.EffectiveCost,
+		InvoiceIssuer:              *ea.InvoiceIssuer,
+		Provider:                   *ea.Provider,
+		Publisher:                  *ea.Publisher,
+		ServiceCategory:            *ea.ServiceCategory,
+		ServiceName:                *ea.ServiceName,
+		SkuID:                      *ea.SkuId,
+		SkuPriceID:                 *ea.SkuPriceId,
+		SubAccountID:               *ea.SubAccountId,
+		SubAccountName:             *ea.SubAccountName,
+		PricingQuantity:            *ea.PricingQuantity,
+		PricingUnit:                *ea.PricingUnit,
+		PricingCategory:            *ea.PricingCategory,
+	}
+}
+
+func ToCustomCostResponsePB(ccr *CustomCostResponse) *pb.CustomCostResponse {
+	var errs []string
+	for _, err := range ccr.Errors {
+		errs = append(errs, err.Error())
+	}
+	var costs []*pb.CustomCost
+	for _, cost := range ccr.Costs {
+		costs = append(costs, ToCustomCostPB(cost))
+	}
+
+	return &pb.CustomCostResponse{
+		Metadata:   ccr.Metadata,
+		CostSource: ccr.Costsource,
+		Domain:     ccr.Domain,
+		Version:    ccr.Version,
+		Currency:   ccr.Currency,
+		Start:      timestamppb.New(ccr.Window.Start().UTC()),
+		End:        timestamppb.New(ccr.Window.End().UTC()),
+		Costs:      costs,
+		Errors:     errs,
+	}
+}
+
+func ToCustomCostPB(cc *CustomCost) *pb.CustomCost {
+	return &pb.CustomCost{
+		Metadata:           cc.Metadata,
+		Zone:               cc.Zone,
+		AccountName:        cc.AccountName,
+		ChargeCategory:     cc.ChargeCategory,
+		Description:        cc.Description,
+		ResourceName:       cc.ResourceName,
+		ResourceType:       cc.ResourceType,
+		Id:                 cc.Id,
+		ProviderId:         cc.ProviderId,
+		BilledCost:         cc.BilledCost,
+		ListCost:           cc.ListCost,
+		ListUnitPrice:      cc.ListUnitPrice,
+		UsageQuantity:      cc.UsageQty,
+		UsageUnit:          cc.UsageUnit,
+		Labels:             cc.Labels,
+		ExtendedAttributes: ToCustomCostExtendedAttributesPB(cc.ExtendedAttributes),
+	}
+}
+
+func ToCustomCostExtendedAttributesPB(ecca *ExtendedCustomCostAttributes) *pb.CustomCostExtendedAttributes {
+	if ecca == nil {
+		return nil
+	}
+
+	var billingPeriodStart *timestamppb.Timestamp
+	var billingPeriodEnd *timestamppb.Timestamp
+	if ecca != nil && !ecca.BillingPeriod.IsOpen() {
+		billingPeriodStart = timestamppb.New(ecca.BillingPeriod.Start().UTC())
+		billingPeriodEnd = timestamppb.New(ecca.BillingPeriod.End().UTC())
+	}
+
+	return &pb.CustomCostExtendedAttributes{
+		BillingPeriodStart:         billingPeriodStart,
+		BillingPeriodEnd:           billingPeriodEnd,
+		AccountId:                  &ecca.AccountID,
+		ChargeFrequency:            &ecca.ChargeFrequency,
+		Subcategory:                &ecca.Subcategory,
+		CommitmentDiscountCategory: &ecca.CommitmentDiscountCategory,
+		CommitmentDiscountId:       &ecca.CommitmentDiscountID,
+		CommitmentDiscountName:     &ecca.CommitmentDiscountName,
+		CommitmentDiscountType:     &ecca.CommitmentDiscountType,
+		EffectiveCost:              &ecca.EffectiveCost,
+		InvoiceIssuer:              &ecca.InvoiceIssuer,
+		Provider:                   &ecca.Provider,
+		Publisher:                  &ecca.Publisher,
+		ServiceCategory:            &ecca.ServiceCategory,
+		ServiceName:                &ecca.ServiceName,
+		SkuId:                      &ecca.SkuID,
+		SkuPriceId:                 &ecca.SkuPriceID,
+		SubAccountId:               &ecca.SubAccountID,
+		SubAccountName:             &ecca.SubAccountName,
+		PricingQuantity:            &ecca.PricingQuantity,
+		PricingUnit:                &ecca.PricingUnit,
+		PricingCategory:            &ecca.PricingCategory,
+	}
+}

+ 876 - 0
core/pkg/model/pb/messages.pb.go

@@ -0,0 +1,876 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.32.0
+// 	protoc        v4.25.3
+// source: protos/customcost/messages.proto
+
+package pb
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type CustomCostResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// provides metadata on the Custom CostResponse
+	// deliberately left unstructured
+	Metadata map[string]string `protobuf:"bytes,1,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	// declared by plugin
+	// eg snowflake == "data management",
+	// datadog == "observability" etc
+	// intended for top level agg
+	CostSource string `protobuf:"bytes,2,opt,name=cost_source,json=costSource,proto3" json:"cost_source,omitempty"`
+	// the name of the custom cost source
+	// e.g., "datadog"
+	Domain string `protobuf:"bytes,3,opt,name=domain,proto3" json:"domain,omitempty"`
+	// the version of the Custom Cost response
+	// is set by the plugin, will vary between
+	// different plugins
+	Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"`
+	// FOCUS billing currency
+	Currency string `protobuf:"bytes,5,opt,name=currency,proto3" json:"currency,omitempty"`
+	// the window of the returned objects
+	Start *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=start,proto3" json:"start,omitempty"`
+	End   *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=end,proto3" json:"end,omitempty"`
+	// array of CustomCosts
+	Costs []*CustomCost `protobuf:"bytes,8,rep,name=costs,proto3" json:"costs,omitempty"`
+	// any errors in processing
+	Errors []string `protobuf:"bytes,9,rep,name=errors,proto3" json:"errors,omitempty"`
+}
+
+func (x *CustomCostResponse) Reset() {
+	*x = CustomCostResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_protos_customcost_messages_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CustomCostResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CustomCostResponse) ProtoMessage() {}
+
+func (x *CustomCostResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_protos_customcost_messages_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CustomCostResponse.ProtoReflect.Descriptor instead.
+func (*CustomCostResponse) Descriptor() ([]byte, []int) {
+	return file_protos_customcost_messages_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *CustomCostResponse) GetMetadata() map[string]string {
+	if x != nil {
+		return x.Metadata
+	}
+	return nil
+}
+
+func (x *CustomCostResponse) GetCostSource() string {
+	if x != nil {
+		return x.CostSource
+	}
+	return ""
+}
+
+func (x *CustomCostResponse) GetDomain() string {
+	if x != nil {
+		return x.Domain
+	}
+	return ""
+}
+
+func (x *CustomCostResponse) GetVersion() string {
+	if x != nil {
+		return x.Version
+	}
+	return ""
+}
+
+func (x *CustomCostResponse) GetCurrency() string {
+	if x != nil {
+		return x.Currency
+	}
+	return ""
+}
+
+func (x *CustomCostResponse) GetStart() *timestamppb.Timestamp {
+	if x != nil {
+		return x.Start
+	}
+	return nil
+}
+
+func (x *CustomCostResponse) GetEnd() *timestamppb.Timestamp {
+	if x != nil {
+		return x.End
+	}
+	return nil
+}
+
+func (x *CustomCostResponse) GetCosts() []*CustomCost {
+	if x != nil {
+		return x.Costs
+	}
+	return nil
+}
+
+func (x *CustomCostResponse) GetErrors() []string {
+	if x != nil {
+		return x.Errors
+	}
+	return nil
+}
+
+type CustomCost struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// provides metadata on the Custom CostResponse
+	// deliberately left unstructured
+	Metadata map[string]string `protobuf:"bytes,1,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	// the region that the resource was incurred
+	// corresponds to 'availability zone' of FOCUS
+	Zone string `protobuf:"bytes,2,opt,name=zone,proto3" json:"zone,omitempty"`
+	// FOCUS billing account name
+	AccountName string `protobuf:"bytes,3,opt,name=account_name,json=accountName,proto3" json:"account_name,omitempty"`
+	// FOCUS charge category
+	ChargeCategory string `protobuf:"bytes,4,opt,name=charge_category,json=chargeCategory,proto3" json:"charge_category,omitempty"`
+	// FOCUS charge description
+	Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"`
+	// FOCUS Resource Name
+	ResourceName string `protobuf:"bytes,6,opt,name=resource_name,json=resourceName,proto3" json:"resource_name,omitempty"`
+	// FOCUS Resource type
+	// if not set, assumed to be domain
+	ResourceType string `protobuf:"bytes,7,opt,name=resource_type,json=resourceType,proto3" json:"resource_type,omitempty"`
+	// ID of the individual cost. should be globally
+	// unique. Assigned by plugin on read
+	Id string `protobuf:"bytes,8,opt,name=id,proto3" json:"id,omitempty"`
+	// the provider's ID for the cost, if
+	// available
+	// FOCUS resource ID
+	ProviderId string `protobuf:"bytes,9,opt,name=provider_id,json=providerId,proto3" json:"provider_id,omitempty"`
+	// FOCUS billed Cost
+	BilledCost float32 `protobuf:"fixed32,10,opt,name=billed_cost,json=billedCost,proto3" json:"billed_cost,omitempty"`
+	// FOCUS List Cost
+	ListCost float32 `protobuf:"fixed32,11,opt,name=list_cost,json=listCost,proto3" json:"list_cost,omitempty"`
+	// FOCUS List Unit Price
+	ListUnitPrice float32 `protobuf:"fixed32,12,opt,name=list_unit_price,json=listUnitPrice,proto3" json:"list_unit_price,omitempty"`
+	// FOCUS usage quantity
+	UsageQuantity float32 `protobuf:"fixed32,13,opt,name=usage_quantity,json=usageQuantity,proto3" json:"usage_quantity,omitempty"`
+	// FOCUS usage Unit
+	UsageUnit string `protobuf:"bytes,14,opt,name=usage_unit,json=usageUnit,proto3" json:"usage_unit,omitempty"`
+	// Returns key/value sets of labels
+	// equivalent to Tags in focus spec
+	Labels map[string]string `protobuf:"bytes,15,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	// Optional struct to implement other focus
+	// spec attributes
+	ExtendedAttributes *CustomCostExtendedAttributes `protobuf:"bytes,16,opt,name=extended_attributes,json=extendedAttributes,proto3,oneof" json:"extended_attributes,omitempty"`
+}
+
+func (x *CustomCost) Reset() {
+	*x = CustomCost{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_protos_customcost_messages_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CustomCost) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CustomCost) ProtoMessage() {}
+
+func (x *CustomCost) ProtoReflect() protoreflect.Message {
+	mi := &file_protos_customcost_messages_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CustomCost.ProtoReflect.Descriptor instead.
+func (*CustomCost) Descriptor() ([]byte, []int) {
+	return file_protos_customcost_messages_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *CustomCost) GetMetadata() map[string]string {
+	if x != nil {
+		return x.Metadata
+	}
+	return nil
+}
+
+func (x *CustomCost) GetZone() string {
+	if x != nil {
+		return x.Zone
+	}
+	return ""
+}
+
+func (x *CustomCost) GetAccountName() string {
+	if x != nil {
+		return x.AccountName
+	}
+	return ""
+}
+
+func (x *CustomCost) GetChargeCategory() string {
+	if x != nil {
+		return x.ChargeCategory
+	}
+	return ""
+}
+
+func (x *CustomCost) GetDescription() string {
+	if x != nil {
+		return x.Description
+	}
+	return ""
+}
+
+func (x *CustomCost) GetResourceName() string {
+	if x != nil {
+		return x.ResourceName
+	}
+	return ""
+}
+
+func (x *CustomCost) GetResourceType() string {
+	if x != nil {
+		return x.ResourceType
+	}
+	return ""
+}
+
+func (x *CustomCost) GetId() string {
+	if x != nil {
+		return x.Id
+	}
+	return ""
+}
+
+func (x *CustomCost) GetProviderId() string {
+	if x != nil {
+		return x.ProviderId
+	}
+	return ""
+}
+
+func (x *CustomCost) GetBilledCost() float32 {
+	if x != nil {
+		return x.BilledCost
+	}
+	return 0
+}
+
+func (x *CustomCost) GetListCost() float32 {
+	if x != nil {
+		return x.ListCost
+	}
+	return 0
+}
+
+func (x *CustomCost) GetListUnitPrice() float32 {
+	if x != nil {
+		return x.ListUnitPrice
+	}
+	return 0
+}
+
+func (x *CustomCost) GetUsageQuantity() float32 {
+	if x != nil {
+		return x.UsageQuantity
+	}
+	return 0
+}
+
+func (x *CustomCost) GetUsageUnit() string {
+	if x != nil {
+		return x.UsageUnit
+	}
+	return ""
+}
+
+func (x *CustomCost) GetLabels() map[string]string {
+	if x != nil {
+		return x.Labels
+	}
+	return nil
+}
+
+func (x *CustomCost) GetExtendedAttributes() *CustomCostExtendedAttributes {
+	if x != nil {
+		return x.ExtendedAttributes
+	}
+	return nil
+}
+
+type CustomCostExtendedAttributes struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// FOCUS billing period start
+	BillingPeriodStart *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=billing_period_start,json=billingPeriodStart,proto3,oneof" json:"billing_period_start,omitempty"`
+	// FOCUS billing period end
+	BillingPeriodEnd *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=billing_period_end,json=billingPeriodEnd,proto3,oneof" json:"billing_period_end,omitempty"`
+	// FOCUS Billing Account ID
+	AccountId *string `protobuf:"bytes,3,opt,name=account_id,json=accountId,proto3,oneof" json:"account_id,omitempty"`
+	// FOCUS Charge Frequency
+	ChargeFrequency *string `protobuf:"bytes,4,opt,name=charge_frequency,json=chargeFrequency,proto3,oneof" json:"charge_frequency,omitempty"`
+	// FOCUS Charge Subcategory
+	Subcategory *string `protobuf:"bytes,5,opt,name=subcategory,proto3,oneof" json:"subcategory,omitempty"`
+	// FOCUS Commitment Discount Category
+	CommitmentDiscountCategory *string `protobuf:"bytes,6,opt,name=commitment_discount_category,json=commitmentDiscountCategory,proto3,oneof" json:"commitment_discount_category,omitempty"`
+	// FOCUS Commitment Discount ID
+	CommitmentDiscountId *string `protobuf:"bytes,7,opt,name=commitment_discount_id,json=commitmentDiscountId,proto3,oneof" json:"commitment_discount_id,omitempty"`
+	// FOCUS Commitment Discount Name
+	CommitmentDiscountName *string `protobuf:"bytes,8,opt,name=commitment_discount_name,json=commitmentDiscountName,proto3,oneof" json:"commitment_discount_name,omitempty"`
+	// FOCUS Commitment Discount Type
+	CommitmentDiscountType *string `protobuf:"bytes,9,opt,name=commitment_discount_type,json=commitmentDiscountType,proto3,oneof" json:"commitment_discount_type,omitempty"`
+	// FOCUS Effective Cost
+	EffectiveCost *float32 `protobuf:"fixed32,10,opt,name=effective_cost,json=effectiveCost,proto3,oneof" json:"effective_cost,omitempty"`
+	// FOCUS Invoice Issuer
+	InvoiceIssuer *string `protobuf:"bytes,11,opt,name=invoice_issuer,json=invoiceIssuer,proto3,oneof" json:"invoice_issuer,omitempty"`
+	// FOCUS Provider
+	// if unset, assumed to be domain
+	Provider *string `protobuf:"bytes,12,opt,name=provider,proto3,oneof" json:"provider,omitempty"`
+	// FOCUS Publisher
+	// if unset, assumed to be domain
+	Publisher *string `protobuf:"bytes,13,opt,name=publisher,proto3,oneof" json:"publisher,omitempty"`
+	// FOCUS Service Category
+	// if unset, assumed to be cost source
+	ServiceCategory *string `protobuf:"bytes,14,opt,name=service_category,json=serviceCategory,proto3,oneof" json:"service_category,omitempty"`
+	// FOCUS Service Name
+	// if unset, assumed to be cost source
+	ServiceName *string `protobuf:"bytes,15,opt,name=service_name,json=serviceName,proto3,oneof" json:"service_name,omitempty"`
+	// FOCUS SKU ID
+	SkuId *string `protobuf:"bytes,16,opt,name=sku_id,json=skuId,proto3,oneof" json:"sku_id,omitempty"`
+	// FOCUS SKU Price ID
+	SkuPriceId *string `protobuf:"bytes,17,opt,name=sku_price_id,json=skuPriceId,proto3,oneof" json:"sku_price_id,omitempty"`
+	// FOCUS Sub Account ID
+	SubAccountId *string `protobuf:"bytes,18,opt,name=sub_account_id,json=subAccountId,proto3,oneof" json:"sub_account_id,omitempty"`
+	// FOCUS Sub Account Name
+	SubAccountName *string `protobuf:"bytes,19,opt,name=sub_account_name,json=subAccountName,proto3,oneof" json:"sub_account_name,omitempty"`
+	// FOCUS Pricing Quantity
+	PricingQuantity *float32 `protobuf:"fixed32,20,opt,name=pricing_quantity,json=pricingQuantity,proto3,oneof" json:"pricing_quantity,omitempty"`
+	// FOCUS Pricing Unit
+	PricingUnit *string `protobuf:"bytes,21,opt,name=pricing_unit,json=pricingUnit,proto3,oneof" json:"pricing_unit,omitempty"`
+	// FOCUS Pricing Category
+	PricingCategory *string `protobuf:"bytes,22,opt,name=pricing_category,json=pricingCategory,proto3,oneof" json:"pricing_category,omitempty"`
+}
+
+func (x *CustomCostExtendedAttributes) Reset() {
+	*x = CustomCostExtendedAttributes{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_protos_customcost_messages_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CustomCostExtendedAttributes) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CustomCostExtendedAttributes) ProtoMessage() {}
+
+func (x *CustomCostExtendedAttributes) ProtoReflect() protoreflect.Message {
+	mi := &file_protos_customcost_messages_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CustomCostExtendedAttributes.ProtoReflect.Descriptor instead.
+func (*CustomCostExtendedAttributes) Descriptor() ([]byte, []int) {
+	return file_protos_customcost_messages_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *CustomCostExtendedAttributes) GetBillingPeriodStart() *timestamppb.Timestamp {
+	if x != nil {
+		return x.BillingPeriodStart
+	}
+	return nil
+}
+
+func (x *CustomCostExtendedAttributes) GetBillingPeriodEnd() *timestamppb.Timestamp {
+	if x != nil {
+		return x.BillingPeriodEnd
+	}
+	return nil
+}
+
+func (x *CustomCostExtendedAttributes) GetAccountId() string {
+	if x != nil && x.AccountId != nil {
+		return *x.AccountId
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetChargeFrequency() string {
+	if x != nil && x.ChargeFrequency != nil {
+		return *x.ChargeFrequency
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetSubcategory() string {
+	if x != nil && x.Subcategory != nil {
+		return *x.Subcategory
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetCommitmentDiscountCategory() string {
+	if x != nil && x.CommitmentDiscountCategory != nil {
+		return *x.CommitmentDiscountCategory
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetCommitmentDiscountId() string {
+	if x != nil && x.CommitmentDiscountId != nil {
+		return *x.CommitmentDiscountId
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetCommitmentDiscountName() string {
+	if x != nil && x.CommitmentDiscountName != nil {
+		return *x.CommitmentDiscountName
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetCommitmentDiscountType() string {
+	if x != nil && x.CommitmentDiscountType != nil {
+		return *x.CommitmentDiscountType
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetEffectiveCost() float32 {
+	if x != nil && x.EffectiveCost != nil {
+		return *x.EffectiveCost
+	}
+	return 0
+}
+
+func (x *CustomCostExtendedAttributes) GetInvoiceIssuer() string {
+	if x != nil && x.InvoiceIssuer != nil {
+		return *x.InvoiceIssuer
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetProvider() string {
+	if x != nil && x.Provider != nil {
+		return *x.Provider
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetPublisher() string {
+	if x != nil && x.Publisher != nil {
+		return *x.Publisher
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetServiceCategory() string {
+	if x != nil && x.ServiceCategory != nil {
+		return *x.ServiceCategory
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetServiceName() string {
+	if x != nil && x.ServiceName != nil {
+		return *x.ServiceName
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetSkuId() string {
+	if x != nil && x.SkuId != nil {
+		return *x.SkuId
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetSkuPriceId() string {
+	if x != nil && x.SkuPriceId != nil {
+		return *x.SkuPriceId
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetSubAccountId() string {
+	if x != nil && x.SubAccountId != nil {
+		return *x.SubAccountId
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetSubAccountName() string {
+	if x != nil && x.SubAccountName != nil {
+		return *x.SubAccountName
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetPricingQuantity() float32 {
+	if x != nil && x.PricingQuantity != nil {
+		return *x.PricingQuantity
+	}
+	return 0
+}
+
+func (x *CustomCostExtendedAttributes) GetPricingUnit() string {
+	if x != nil && x.PricingUnit != nil {
+		return *x.PricingUnit
+	}
+	return ""
+}
+
+func (x *CustomCostExtendedAttributes) GetPricingCategory() string {
+	if x != nil && x.PricingCategory != nil {
+		return *x.PricingCategory
+	}
+	return ""
+}
+
+var File_protos_customcost_messages_proto protoreflect.FileDescriptor
+
+var file_protos_customcost_messages_proto_rawDesc = []byte{
+	0x0a, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x63,
+	0x6f, 0x73, 0x74, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x12, 0x13, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x63, 0x6f, 0x73, 0x74, 0x2e, 0x6d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
+	0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc2, 0x03, 0x0a, 0x12, 0x43, 0x75, 0x73,
+	0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x51, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x35, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x63, 0x6f, 0x73, 0x74, 0x2e, 0x6d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f,
+	0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64,
+	0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61,
+	0x74, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x73, 0x74, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x73, 0x74, 0x53, 0x6f, 0x75,
+	0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x76,
+	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65,
+	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63,
+	0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63,
+	0x79, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+	0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x74,
+	0x61, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+	0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x65, 0x6e,
+	0x64, 0x12, 0x35, 0x0a, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x1f, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x63, 0x6f, 0x73, 0x74, 0x2e, 0x6d, 0x65,
+	0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x73,
+	0x74, 0x52, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f,
+	0x72, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73,
+	0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72,
+	0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
+	0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xbe, 0x06,
+	0x0a, 0x0a, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x73, 0x74, 0x12, 0x49, 0x0a, 0x08,
+	0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d,
+	0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x63, 0x6f, 0x73, 0x74, 0x2e, 0x6d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x73, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x73, 0x74, 0x2e,
+	0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d,
+	0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61,
+	0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27,
+	0x0a, 0x0f, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x5f, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72,
+	0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x43,
+	0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
+	0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65,
+	0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73,
+	0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23,
+	0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18,
+	0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54,
+	0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f,
+	0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64,
+	0x65, 0x72, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x69, 0x6c, 0x6c, 0x65, 0x64, 0x5f, 0x63,
+	0x6f, 0x73, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0a, 0x62, 0x69, 0x6c, 0x6c, 0x65,
+	0x64, 0x43, 0x6f, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x63, 0x6f,
+	0x73, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x52, 0x08, 0x6c, 0x69, 0x73, 0x74, 0x43, 0x6f,
+	0x73, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x5f,
+	0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0d, 0x6c, 0x69, 0x73,
+	0x74, 0x55, 0x6e, 0x69, 0x74, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x75, 0x73,
+	0x61, 0x67, 0x65, 0x5f, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x0d, 0x20, 0x01,
+	0x28, 0x02, 0x52, 0x0d, 0x75, 0x73, 0x61, 0x67, 0x65, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74,
+	0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x18,
+	0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x61, 0x67, 0x65, 0x55, 0x6e, 0x69, 0x74,
+	0x12, 0x43, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x2b, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x63, 0x6f, 0x73, 0x74, 0x2e, 0x6d, 0x65,
+	0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x73,
+	0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c,
+	0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x67, 0x0a, 0x13, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65,
+	0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x10, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x31, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x63, 0x6f, 0x73, 0x74, 0x2e,
+	0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43,
+	0x6f, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69,
+	0x62, 0x75, 0x74, 0x65, 0x73, 0x48, 0x00, 0x52, 0x12, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65,
+	0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x88, 0x01, 0x01, 0x1a, 0x3b,
+	0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
+	0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
+	0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x39, 0x0a, 0x0b, 0x4c,
+	0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
+	0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05,
+	0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c,
+	0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e,
+	0x64, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0x94,
+	0x0c, 0x0a, 0x1c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x73, 0x74, 0x45, 0x78, 0x74,
+	0x65, 0x6e, 0x64, 0x65, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12,
+	0x51, 0x0a, 0x14, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f,
+	0x64, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
+	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
+	0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, 0x12, 0x62, 0x69, 0x6c,
+	0x6c, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x88,
+	0x01, 0x01, 0x12, 0x4d, 0x0a, 0x12, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x65,
+	0x72, 0x69, 0x6f, 0x64, 0x5f, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
+	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+	0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x01, 0x52, 0x10, 0x62, 0x69,
+	0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x45, 0x6e, 0x64, 0x88, 0x01,
+	0x01, 0x12, 0x22, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
+	0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x2e, 0x0a, 0x10, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x5f,
+	0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48,
+	0x03, 0x52, 0x0f, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
+	0x63, 0x79, 0x88, 0x01, 0x01, 0x12, 0x25, 0x0a, 0x0b, 0x73, 0x75, 0x62, 0x63, 0x61, 0x74, 0x65,
+	0x67, 0x6f, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, 0x0b, 0x73, 0x75,
+	0x62, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x88, 0x01, 0x01, 0x12, 0x45, 0x0a, 0x1c,
+	0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f,
+	0x75, 0x6e, 0x74, 0x5f, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01,
+	0x28, 0x09, 0x48, 0x05, 0x52, 0x1a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74,
+	0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79,
+	0x88, 0x01, 0x01, 0x12, 0x39, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e,
+	0x74, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20,
+	0x01, 0x28, 0x09, 0x48, 0x06, 0x52, 0x14, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e,
+	0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x3d,
+	0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x69, 0x73,
+	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09,
+	0x48, 0x07, 0x52, 0x16, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x69,
+	0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x3d, 0x0a,
+	0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x63,
+	0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x48,
+	0x08, 0x52, 0x16, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x69, 0x73,
+	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x88, 0x01, 0x01, 0x12, 0x2a, 0x0a, 0x0e,
+	0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x0a,
+	0x20, 0x01, 0x28, 0x02, 0x48, 0x09, 0x52, 0x0d, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76,
+	0x65, 0x43, 0x6f, 0x73, 0x74, 0x88, 0x01, 0x01, 0x12, 0x2a, 0x0a, 0x0e, 0x69, 0x6e, 0x76, 0x6f,
+	0x69, 0x63, 0x65, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09,
+	0x48, 0x0a, 0x52, 0x0d, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x49, 0x73, 0x73, 0x75, 0x65,
+	0x72, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
+	0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x48, 0x0b, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64,
+	0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x21, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68,
+	0x65, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x48, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c,
+	0x69, 0x73, 0x68, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x2e, 0x0a, 0x10, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x5f, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x0e, 0x20, 0x01,
+	0x28, 0x09, 0x48, 0x0d, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x61, 0x74,
+	0x65, 0x67, 0x6f, 0x72, 0x79, 0x88, 0x01, 0x01, 0x12, 0x26, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x48, 0x0e,
+	0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01,
+	0x12, 0x1a, 0x0a, 0x06, 0x73, 0x6b, 0x75, 0x5f, 0x69, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09,
+	0x48, 0x0f, 0x52, 0x05, 0x73, 0x6b, 0x75, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x25, 0x0a, 0x0c,
+	0x73, 0x6b, 0x75, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x11, 0x20, 0x01,
+	0x28, 0x09, 0x48, 0x10, 0x52, 0x0a, 0x73, 0x6b, 0x75, 0x50, 0x72, 0x69, 0x63, 0x65, 0x49, 0x64,
+	0x88, 0x01, 0x01, 0x12, 0x29, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75,
+	0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x48, 0x11, 0x52, 0x0c, 0x73,
+	0x75, 0x62, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x2d,
+	0x0a, 0x10, 0x73, 0x75, 0x62, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61,
+	0x6d, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x48, 0x12, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x41,
+	0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x2e, 0x0a,
+	0x10, 0x70, 0x72, 0x69, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74,
+	0x79, 0x18, 0x14, 0x20, 0x01, 0x28, 0x02, 0x48, 0x13, 0x52, 0x0f, 0x70, 0x72, 0x69, 0x63, 0x69,
+	0x6e, 0x67, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x88, 0x01, 0x01, 0x12, 0x26, 0x0a,
+	0x0c, 0x70, 0x72, 0x69, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x15, 0x20,
+	0x01, 0x28, 0x09, 0x48, 0x14, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x63, 0x69, 0x6e, 0x67, 0x55, 0x6e,
+	0x69, 0x74, 0x88, 0x01, 0x01, 0x12, 0x2e, 0x0a, 0x10, 0x70, 0x72, 0x69, 0x63, 0x69, 0x6e, 0x67,
+	0x5f, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x48,
+	0x15, 0x52, 0x0f, 0x70, 0x72, 0x69, 0x63, 0x69, 0x6e, 0x67, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f,
+	0x72, 0x79, 0x88, 0x01, 0x01, 0x42, 0x17, 0x0a, 0x15, 0x5f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e,
+	0x67, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x42, 0x15,
+	0x0a, 0x13, 0x5f, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f,
+	0x64, 0x5f, 0x65, 0x6e, 0x64, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e,
+	0x74, 0x5f, 0x69, 0x64, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x5f,
+	0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x73, 0x75,
+	0x62, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x42, 0x1f, 0x0a, 0x1d, 0x5f, 0x63, 0x6f,
+	0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e,
+	0x74, 0x5f, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x42, 0x19, 0x0a, 0x17, 0x5f, 0x63,
+	0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75,
+	0x6e, 0x74, 0x5f, 0x69, 0x64, 0x42, 0x1b, 0x0a, 0x19, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
+	0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61,
+	0x6d, 0x65, 0x42, 0x1b, 0x0a, 0x19, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e,
+	0x74, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x42,
+	0x11, 0x0a, 0x0f, 0x5f, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x6f,
+	0x73, 0x74, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x5f, 0x69,
+	0x73, 0x73, 0x75, 0x65, 0x72, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64,
+	0x65, 0x72, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72,
+	0x42, 0x13, 0x0a, 0x11, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x63, 0x61, 0x74,
+	0x65, 0x67, 0x6f, 0x72, 0x79, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x6b, 0x75, 0x5f, 0x69,
+	0x64, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x73, 0x6b, 0x75, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f,
+	0x69, 0x64, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x73, 0x75, 0x62, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75,
+	0x6e, 0x74, 0x5f, 0x69, 0x64, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x73, 0x75, 0x62, 0x5f, 0x61, 0x63,
+	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x70,
+	0x72, 0x69, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x42,
+	0x0f, 0x0a, 0x0d, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x6e, 0x69, 0x74,
+	0x42, 0x13, 0x0a, 0x11, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x61, 0x74,
+	0x65, 0x67, 0x6f, 0x72, 0x79, 0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
+	0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x73, 0x74, 0x2f, 0x6f, 0x70, 0x65,
+	0x6e, 0x63, 0x6f, 0x73, 0x74, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d,
+	0x6f, 0x64, 0x65, 0x6c, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_protos_customcost_messages_proto_rawDescOnce sync.Once
+	file_protos_customcost_messages_proto_rawDescData = file_protos_customcost_messages_proto_rawDesc
+)
+
+func file_protos_customcost_messages_proto_rawDescGZIP() []byte {
+	file_protos_customcost_messages_proto_rawDescOnce.Do(func() {
+		file_protos_customcost_messages_proto_rawDescData = protoimpl.X.CompressGZIP(file_protos_customcost_messages_proto_rawDescData)
+	})
+	return file_protos_customcost_messages_proto_rawDescData
+}
+
+var file_protos_customcost_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
+var file_protos_customcost_messages_proto_goTypes = []interface{}{
+	(*CustomCostResponse)(nil),           // 0: customcost.messages.CustomCostResponse
+	(*CustomCost)(nil),                   // 1: customcost.messages.CustomCost
+	(*CustomCostExtendedAttributes)(nil), // 2: customcost.messages.CustomCostExtendedAttributes
+	nil,                                  // 3: customcost.messages.CustomCostResponse.MetadataEntry
+	nil,                                  // 4: customcost.messages.CustomCost.MetadataEntry
+	nil,                                  // 5: customcost.messages.CustomCost.LabelsEntry
+	(*timestamppb.Timestamp)(nil),        // 6: google.protobuf.Timestamp
+}
+var file_protos_customcost_messages_proto_depIdxs = []int32{
+	3, // 0: customcost.messages.CustomCostResponse.metadata:type_name -> customcost.messages.CustomCostResponse.MetadataEntry
+	6, // 1: customcost.messages.CustomCostResponse.start:type_name -> google.protobuf.Timestamp
+	6, // 2: customcost.messages.CustomCostResponse.end:type_name -> google.protobuf.Timestamp
+	1, // 3: customcost.messages.CustomCostResponse.costs:type_name -> customcost.messages.CustomCost
+	4, // 4: customcost.messages.CustomCost.metadata:type_name -> customcost.messages.CustomCost.MetadataEntry
+	5, // 5: customcost.messages.CustomCost.labels:type_name -> customcost.messages.CustomCost.LabelsEntry
+	2, // 6: customcost.messages.CustomCost.extended_attributes:type_name -> customcost.messages.CustomCostExtendedAttributes
+	6, // 7: customcost.messages.CustomCostExtendedAttributes.billing_period_start:type_name -> google.protobuf.Timestamp
+	6, // 8: customcost.messages.CustomCostExtendedAttributes.billing_period_end:type_name -> google.protobuf.Timestamp
+	9, // [9:9] is the sub-list for method output_type
+	9, // [9:9] is the sub-list for method input_type
+	9, // [9:9] is the sub-list for extension type_name
+	9, // [9:9] is the sub-list for extension extendee
+	0, // [0:9] is the sub-list for field type_name
+}
+
+func init() { file_protos_customcost_messages_proto_init() }
+func file_protos_customcost_messages_proto_init() {
+	if File_protos_customcost_messages_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_protos_customcost_messages_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CustomCostResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_protos_customcost_messages_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CustomCost); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_protos_customcost_messages_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CustomCostExtendedAttributes); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	file_protos_customcost_messages_proto_msgTypes[1].OneofWrappers = []interface{}{}
+	file_protos_customcost_messages_proto_msgTypes[2].OneofWrappers = []interface{}{}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_protos_customcost_messages_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   6,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_protos_customcost_messages_proto_goTypes,
+		DependencyIndexes: file_protos_customcost_messages_proto_depIdxs,
+		MessageInfos:      file_protos_customcost_messages_proto_msgTypes,
+	}.Build()
+	File_protos_customcost_messages_proto = out.File
+	file_protos_customcost_messages_proto_rawDesc = nil
+	file_protos_customcost_messages_proto_goTypes = nil
+	file_protos_customcost_messages_proto_depIdxs = nil
+}

+ 6 - 0
generate.sh

@@ -0,0 +1,6 @@
+#!/bin/zsh
+#
+
+protoc --go_out=./core --go_opt=module=github.com/opencost/opencost/core \
+    --go-grpc_out=./core --go-grpc_opt=module=github.com/opencost/opencost/core \
+    protos/**/*.proto

+ 1 - 1
go.mod

@@ -32,6 +32,7 @@ require (
 	github.com/davecgh/go-spew v1.1.1
 	github.com/getsentry/sentry-go v0.25.0
 	github.com/google/uuid v1.6.0
+	github.com/hashicorp/go-hclog v1.6.2
 	github.com/hashicorp/go-plugin v1.6.0
 	github.com/jszwec/csvutil v1.2.1
 	github.com/julienschmidt/httprouter v1.3.0
@@ -123,7 +124,6 @@ require (
 	github.com/googleapis/gax-go/v2 v2.12.0 // indirect
 	github.com/gorilla/css v1.0.0 // indirect
 	github.com/hashicorp/errwrap v1.0.0 // indirect
-	github.com/hashicorp/go-hclog v1.6.2 // indirect
 	github.com/hashicorp/go-multierror v1.1.1 // indirect
 	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/hashicorp/yamux v0.1.1 // indirect

+ 136 - 0
protos/customcost/messages.proto

@@ -0,0 +1,136 @@
+syntax = "proto3";
+
+package customcost.messages;
+
+import "google/protobuf/timestamp.proto";
+
+// Sets the golang package for the protobuf generated code
+option go_package = "github.com/opencost/opencost/core/pkg/model/pb";
+
+// see design at https://link.excalidraw.com/l/ABLQ24dkKai/CBEQtjH6Mr
+// for additional details on how these objects work in the context of
+// opencost's plugin system
+
+message CustomCostResponse {
+  // provides metadata on the Custom CostResponse
+  // deliberately left unstructured
+  map<string, string>  metadata = 1;
+  // declared by plugin
+  // eg snowflake == "data management",
+  // datadog == "observability" etc
+  // intended for top level agg
+  string cost_source = 2;
+  // the name of the custom cost source
+  // e.g., "datadog"
+  string domain = 3;
+  // the version of the Custom Cost response
+  // is set by the plugin, will vary between
+  // different plugins
+  string version = 4;
+  // FOCUS billing currency
+  string currency = 5;
+  // the window of the returned objects
+  google.protobuf.Timestamp start = 6;
+  google.protobuf.Timestamp end = 7;
+
+  // array of CustomCosts
+  repeated CustomCost costs = 8;
+  // any errors in processing
+  repeated string errors = 9;
+}
+
+message CustomCost {
+  // provides metadata on the Custom CostResponse
+  // deliberately left unstructured
+  map<string, string>  metadata = 1;
+  // the region that the resource was incurred
+  // corresponds to 'availability zone' of FOCUS
+  string zone = 2;
+  // FOCUS billing account name
+  string account_name = 3;
+  // FOCUS charge category
+  string charge_category = 4;
+  // FOCUS charge description
+  string description = 5;
+  // FOCUS Resource Name
+  string resource_name = 6;
+  // FOCUS Resource type
+  // if not set, assumed to be domain
+  string resource_type = 7;
+  // ID of the individual cost. should be globally
+  // unique. Assigned by plugin on read
+  string id = 8;
+  // the provider's ID for the cost, if
+  // available
+  // FOCUS resource ID
+  string provider_id = 9;
+
+  // FOCUS billed Cost
+  float billed_cost = 10;
+  // FOCUS List Cost
+  float list_cost = 11;
+  // FOCUS List Unit Price
+  float list_unit_price = 12;
+  // FOCUS usage quantity
+  float usage_quantity = 13;
+  // FOCUS usage Unit
+  string usage_unit = 14;
+  // Returns key/value sets of labels
+  // equivalent to Tags in focus spec
+  map<string, string> labels = 15;
+  // Optional struct to implement other focus
+  // spec attributes
+  optional CustomCostExtendedAttributes extended_attributes = 16;
+
+}
+
+message CustomCostExtendedAttributes {
+  // FOCUS billing period start
+  optional google.protobuf.Timestamp billing_period_start = 1;
+  // FOCUS billing period end
+  optional google.protobuf.Timestamp billing_period_end = 2;
+  // FOCUS Billing Account ID
+  optional string account_id = 3;
+  // FOCUS Charge Frequency
+  optional string charge_frequency = 4;
+  // FOCUS Charge Subcategory
+  optional string subcategory = 5;
+  // FOCUS Commitment Discount Category
+  optional string commitment_discount_category = 6;
+  // FOCUS Commitment Discount ID
+  optional string commitment_discount_id = 7;
+  // FOCUS Commitment Discount Name
+  optional string commitment_discount_name = 8;
+  // FOCUS Commitment Discount Type
+  optional string commitment_discount_type = 9;
+  // FOCUS Effective Cost
+  optional float effective_cost = 10;
+  // FOCUS Invoice Issuer
+  optional string invoice_issuer = 11;
+  // FOCUS Provider
+  // if unset, assumed to be domain
+  optional string provider = 12;
+  // FOCUS Publisher
+  // if unset, assumed to be domain
+  optional string publisher = 13;
+  // FOCUS Service Category
+  // if unset, assumed to be cost source
+  optional string service_category = 14;
+  // FOCUS Service Name
+  // if unset, assumed to be cost source
+  optional string service_name = 15;
+  // FOCUS SKU ID
+  optional string sku_id = 16;
+  // FOCUS SKU Price ID
+  optional string sku_price_id = 17;
+  // FOCUS Sub Account ID
+  optional string sub_account_id = 18;
+  // FOCUS Sub Account Name
+  optional string sub_account_name = 19;
+  // FOCUS Pricing Quantity
+  optional float pricing_quantity = 20;
+  // FOCUS Pricing Unit
+  optional string pricing_unit = 21;
+  // FOCUS Pricing Category
+  optional string pricing_category = 22;
+}