Explorar el Código

Merge branch 'develop' into optimization2

Ajay Tripathy hace 2 años
padre
commit
5d154d298c

+ 70 - 25
.github/workflows/build-and-publish-release.yml

@@ -1,24 +1,54 @@
 name: Build and Publish Release
 
 on:
+  push:
+    tags:
+      - 'v[0-9]+.[0-9]+.[0-9]+'
   workflow_dispatch:
     inputs:
       release_version:
-        description: "Version. Please DO NOT include the 'v' prefix"
+        description: "Version of the release"
         required: true
 
 concurrency:
   group: build-opencost
   cancel-in-progress: true
 
+env:
+  # Use docker.io for Docker Hub if empty
+  REGISTRY: ghcr.io
+  # github.repository as <account>/<repo>
+  IMAGE_NAME: ${{ github.repository }}
+
 jobs:
   build-and-publish-opencost:
     runs-on: ubuntu-latest
     permissions:
       contents: read
       packages: write
-
     steps:
+      - name: Get Version From Tag
+        id: tag
+        if: ${{ github.event_name }} == 'push'
+        run: |
+          echo "TRIGGERED_TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
+
+      - name: Determine Version Number
+        id: version_number
+        run: |
+          if [ -z "${TRIGGERED_TAG}" ];
+          then
+            version=${{ inputs.release_version }}
+          else
+            version=$TRIGGERED_TAG
+          fi
+          if [[ ${version:0:1} == "v" ]];
+            echo "RELEASE_VERSION=${version:1}" >> $GITHUB_OUTPUT
+          then
+            echo "RELEASE_VERSION=$version" >> $GITHUB_OUTPUT
+          else
+          fi
+
       - name: Show Input Values
         run: |
           echo "release version: ${{ inputs.release_version }}"
@@ -26,7 +56,8 @@ jobs:
       - name: Make Branch Name
         id: branch
         run: |
-          echo "BRANCH_NAME=v${${{ inputs.release_version}}%.*}" >> $GITHUB_ENV
+          VERSION_NUMBER=${{ steps.version_number.outputs.RELEASE_VERSION }}
+          echo "BRANCH_NAME=v${VERSION_NUMBER%.*}" >> $GITHUB_ENV
 
       - name: Checkout Repo
         uses: actions/checkout@v4
@@ -39,29 +70,43 @@ jobs:
         id: sha
         run: |
           pushd ./opencost
-          echo "OC_SHORTHASH=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
+          echo "OC_SHORTHASH=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
           popd
 
+      # Login against a Docker registry except on PR
+      # https://github.com/docker/login-action
+      - name: Log into registry ${{ env.REGISTRY }}
+        uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
+        with:
+          registry: ${{ env.REGISTRY }}
+          username: ${{ github.actor }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+
       - name: Set OpenCost Image Tags
         id: tags
         run: |
           echo "IMAGE_TAG=ghcr.io/opencost/opencost:${{ steps.sha.outputs.OC_SHORTHASH }}" >> $GITHUB_OUTPUT
           echo "IMAGE_TAG_LATEST=ghcr.io/opencost/opencost:latest" >> $GITHUB_OUTPUT
-          echo "IMAGE_TAG_VERSION=ghcr.io/opencost/opencost:${{ inputs.release_version }}" >> $GITHUB_OUTPUT
+          echo "IMAGE_TAG_VERSION=ghcr.io/opencost/opencost:${{ steps.version_number.outputs.RELEASE_VERSION }}" >> $GITHUB_OUTPUT
           echo "IMAGE_TAG_UI=ghcr.io/opencost/opencost-ui:${{ steps.sha.outputs.OC_SHORTHASH }}" >> $GITHUB_OUTPUT
           echo "IMAGE_TAG_UI_LATEST=ghcr.io/opencost/opencost-ui:latest" >> $GITHUB_OUTPUT
-          echo "IMAGE_TAG_UI_VERSION=ghcr.io/opencost/opencost-ui:${{ inputs.release_version }}" >> $GITHUB_OUTPUT
-          echo "IMAGE_TAG_QUAY=quay.io/kubecost1/kubecost-cost-model:${{ steps.sha.outputs.OC_SHORTHASH }}" >> $GITHUB_OUTPUT
-          echo "IMAGE_TAG_LATEST_QUAY=quay.io/kubecost1/kubecost-cost-model:latest" >> $GITHUB_OUTPUT
-          echo "IMAGE_TAG_VERSION_QUAY=quay.io/kubecost1/kubecost-cost-model:prod-${{ inputs.release_version }}" >> $GITHUB_OUTPUT
-          echo "IMAGE_TAG_UI_QUAY=quay.io/kubecost1/opencost-ui:${{ steps.sha.outputs.OC_SHORTHASH }}" >> $GITHUB_OUTPUT
-          echo "IMAGE_TAG_UI_LATEST_QUAY=quay.io/kubecost1/opencost-ui:latest" >> $GITHUB_OUTPUT
-          echo "IMAGE_TAG_UI_VERSION_QUAY=quay.io/kubecost1/opencost-ui:prod-${{ inputs.release_version }}" >> $GITHUB_OUTPUT
+          echo "IMAGE_TAG_UI_VERSION=ghcr.io/opencost/opencost-ui:${{ steps.version_number.outputs.RELEASE_VERSION }}" >> $GITHUB_OUTPUT
+        #  echo "IMAGE_TAG_QUAY=quay.io/kubecost1/kubecost-cost-model:${{ steps.sha.outputs.OC_SHORTHASH }}" >> $GITHUB_OUTPUT
+        #  echo "IMAGE_TAG_LATEST_QUAY=quay.io/kubecost1/kubecost-cost-model:latest" >> $GITHUB_OUTPUT
+        #  echo "IMAGE_TAG_VERSION_QUAY=quay.io/kubecost1/kubecost-cost-model:prod-${{ steps.version_number.outputs.RELEASE_VERSION }}" >> $GITHUB_OUTPUT
+        #  echo "IMAGE_TAG_UI_QUAY=quay.io/kubecost1/opencost-ui:${{ steps.sha.outputs.OC_SHORTHASH }}" >> $GITHUB_OUTPUT
+        #  echo "IMAGE_TAG_UI_LATEST_QUAY=quay.io/kubecost1/opencost-ui:latest" >> $GITHUB_OUTPUT
+        #  echo "IMAGE_TAG_UI_VERSION_QUAY=quay.io/kubecost1/opencost-ui:prod-${{ inputs.release_version }}" >> $GITHUB_OUTPUT
 
       - name: Set up Docker Buildx
         uses: docker/setup-buildx-action@v3
         with:
           buildkitd-flags: --debug
+    
+      - name: Install Go
+        uses: actions/setup-go@v5
+        with:
+          go-version: 'stable'
 
       - name: Set up just
         uses: extractions/setup-just@v1
@@ -80,12 +125,12 @@ jobs:
           cp manifest-tool-linux-amd64 manifest-tool
           echo "$(pwd)" >> $GITHUB_PATH
 
-      - name: Login to Quay
-        uses: docker/login-action@v3
-        with:
-          registry: quay.io
-          username: ${{ secrets.QUAY_USERNAME }}
-          password: ${{ secrets.QUAY_PASSWORD }}
+    #  - name: Login to Quay
+    #    uses: docker/login-action@v3
+    #    with:
+    #      registry: quay.io
+    #      username: ${{ secrets.QUAY_USERNAME }}
+    #      password: ${{ secrets.QUAY_PASSWORD }}
 
       - name: Build and push (multiarch) OpenCost
         working-directory: ./opencost
@@ -93,15 +138,15 @@ jobs:
           just build '${steps.tags.outputs.IMAGE_TAG}'
           crane copy '${steps.tags.outputs.IMAGE_TAG}' '${steps.tags.outputs.IMAGE_TAG_LATEST}'
           crane copy '${steps.tags.outputs.IMAGE_TAG}' '${steps.tags.outputs.IMAGE_TAG_VERSION}'
-          crane copy '${steps.tags.outputs.IMAGE_TAG}' '${steps.tags.outputs.IMAGE_TAG_QUAY}'
-          crane copy '${steps.tags.outputs.IMAGE_TAG}' '${steps.tags.outputs.IMAGE_TAG_LATEST_QUAY}'
-          crane copy '${steps.tags.outputs.IMAGE_TAG}' '${steps.tags.outputs.IMAGE_TAG_VERSION_QUAY}'
+        #  crane copy '${steps.tags.outputs.IMAGE_TAG}' '${steps.tags.outputs.IMAGE_TAG_QUAY}'
+        #  crane copy '${steps.tags.outputs.IMAGE_TAG}' '${steps.tags.outputs.IMAGE_TAG_LATEST_QUAY}'
+        #  crane copy '${steps.tags.outputs.IMAGE_TAG}' '${steps.tags.outputs.IMAGE_TAG_VERSION_QUAY}'
 
       - name: Build and push (multiarch) OpenCost UI
         working-directory: ./opencost/ui
         run: |
-          just build '${steps.tags.outputs.IMAGE_TAG_UI}' '${steps.tags.outputs.IMAGE_TAG_UI_LATEST}'
+          just build '${steps.tags.outputs.IMAGE_TAG_UI}'
           crane copy '${steps.tags.outputs.IMAGE_TAG_UI}' '${steps.tags.outputs.IMAGE_TAG_UI_VERSION}'
-          crane copy '${steps.tags.outputs.IMAGE_TAG_UI}' '${steps.tags.outputs.IMAGE_TAG_UI_QUAY}'
-          crane copy '${steps.tags.outputs.IMAGE_TAG_UI}' '${steps.tags.outputs.IMAGE_TAG_UI_LATEST_QUAY}'
-          crane copy '${steps.tags.outputs.IMAGE_TAG_UI}' '${steps.tags.outputs.IMAGE_TAG_UI_VERSION_QUAY}'
+        #  crane copy '${steps.tags.outputs.IMAGE_TAG_UI}' '${steps.tags.outputs.IMAGE_TAG_UI_QUAY}'
+        #  crane copy '${steps.tags.outputs.IMAGE_TAG_UI}' '${steps.tags.outputs.IMAGE_TAG_UI_LATEST_QUAY}'
+        #  crane copy '${steps.tags.outputs.IMAGE_TAG_UI}' '${steps.tags.outputs.IMAGE_TAG_UI_VERSION_QUAY}'

+ 20 - 0
core/pkg/model/custom_cost_request.go

@@ -0,0 +1,20 @@
+package model
+
+import (
+	"time"
+
+	"github.com/opencost/opencost/core/pkg/opencost"
+)
+
+type CustomCostRequest struct {
+	TargetWindow *opencost.Window
+	Resolution   time.Duration
+}
+
+func (c *CustomCostRequest) GetTargetWindow() *opencost.Window {
+	return c.TargetWindow
+}
+
+func (c *CustomCostRequest) GetTargetResolution() time.Duration {
+	return c.Resolution
+}

+ 241 - 0
core/pkg/model/custom_cost_response.go

@@ -0,0 +1,241 @@
+package model
+
+import "github.com/opencost/opencost/core/pkg/opencost"
+
+type CustomCostResponse struct {
+	Metadata   map[string]string
+	Costsource string
+	Domain     string
+	Version    string
+	Currency   string
+	Window     opencost.Window
+	Costs      []*CustomCost
+	Errors     []error
+}
+
+type CustomCost struct {
+	Metadata       map[string]string
+	Zone           string
+	BilledCost     float32
+	AccountName    string
+	ChargeCategory string
+	Description    string
+	ListCost       float32
+	ListUnitPrice  float32
+	ResourceName   string
+	ResourceType   string
+	Id             string
+	ProviderId     string
+
+	Window             *opencost.Window
+	Labels             map[string]string
+	UsageQty           float32
+	UsageUnit          string
+	ExtendedAttributes *ExtendedCustomCostAttributes
+}
+
+type ExtendedCustomCostAttributes struct {
+	BillingPeriod              *opencost.Window
+	AccountID                  string
+	ChargeFrequency            string
+	Subcategory                string
+	CommitmentDiscountCategory string
+	CommitmentDiscountID       string
+	CommitmentDiscountName     string
+	CommitmentDiscountType     string
+	EffectiveCost              float32
+	InvoiceIssuer              string
+	Provider                   string
+	Publisher                  string
+	ServiceCategory            string
+	ServiceName                string
+	SkuID                      string
+	SkuPriceID                 string
+	SubAccountID               string
+	SubAccountName             string
+	PricingQuantity            float32
+	PricingUnit                string
+	PricingCategory            string
+}
+
+func (e *ExtendedCustomCostAttributes) GetBillingPeriod() *opencost.Window {
+	return e.BillingPeriod
+}
+
+func (e *ExtendedCustomCostAttributes) GetAccountID() string {
+	return e.AccountID
+}
+
+func (e *ExtendedCustomCostAttributes) GetChargeFrequency() string {
+	return e.ChargeFrequency
+}
+
+func (e *ExtendedCustomCostAttributes) GetSubcategory() string {
+	return e.Subcategory
+}
+
+func (e *ExtendedCustomCostAttributes) GetCommitmentDiscountCategory() string {
+	return e.CommitmentDiscountCategory
+}
+
+func (e *ExtendedCustomCostAttributes) GetCommitmentDiscountID() string {
+	return e.CommitmentDiscountID
+}
+
+func (e *ExtendedCustomCostAttributes) GetCommitmentDiscountName() string {
+	return e.CommitmentDiscountName
+}
+
+func (e *ExtendedCustomCostAttributes) GetCommitmentDiscountType() string {
+	return e.CommitmentDiscountType
+}
+
+func (e *ExtendedCustomCostAttributes) GetEffectiveCost() float32 {
+	return e.EffectiveCost
+}
+
+func (e *ExtendedCustomCostAttributes) GetInvoiceIssuer() string {
+	return e.InvoiceIssuer
+}
+
+func (e *ExtendedCustomCostAttributes) GetProvider() string {
+	return e.Provider
+}
+
+func (e *ExtendedCustomCostAttributes) GetPublisher() string {
+	return e.Publisher
+}
+
+func (e *ExtendedCustomCostAttributes) GetServiceCategory() string {
+	return e.ServiceCategory
+}
+
+func (e *ExtendedCustomCostAttributes) GetServiceName() string {
+	return e.ServiceName
+}
+
+func (e *ExtendedCustomCostAttributes) GetSKUID() string {
+	return e.SkuID
+}
+
+func (e *ExtendedCustomCostAttributes) GetSKUPriceID() string {
+	return e.SkuPriceID
+}
+
+func (e *ExtendedCustomCostAttributes) GetSubAccountID() string {
+	return e.SubAccountID
+}
+
+func (e *ExtendedCustomCostAttributes) GetSubAccountName() string {
+	return e.SubAccountName
+}
+func (e *ExtendedCustomCostAttributes) GetPricingQuantity() float32 {
+	return e.PricingQuantity
+}
+func (e *ExtendedCustomCostAttributes) GetPricingUnit() string {
+	return e.PricingUnit
+}
+
+func (e *ExtendedCustomCostAttributes) GetPricingCategory() string {
+	return e.PricingCategory
+}
+
+func (d *CustomCost) GetMetadata() map[string]string {
+	return d.Metadata
+}
+
+func (d *CustomCost) GetCostIncurredZone() string {
+	return d.Zone
+}
+
+func (d *CustomCost) GetBilledCost() float32 {
+	return d.BilledCost
+}
+
+func (d *CustomCost) GetAccountName() string {
+	return d.AccountName
+}
+
+func (d *CustomCost) GetChargeCategory() string {
+	return d.ChargeCategory
+}
+
+func (d *CustomCost) GetDescription() string {
+	return d.Description
+}
+
+func (d *CustomCost) GetListCost() float32 {
+	return d.ListCost
+}
+
+func (d *CustomCost) GetListUnitPrice() float32 {
+	return d.ListUnitPrice
+}
+
+func (d *CustomCost) GetResourceName() string {
+	return d.ResourceName
+}
+
+func (d *CustomCost) GetID() string {
+	return d.Id
+}
+
+func (d *CustomCost) GetProviderID() string {
+	return d.ProviderId
+}
+
+func (d *CustomCost) GetWindow() *opencost.Window {
+	return d.Window
+}
+
+func (d *CustomCost) GetLabels() map[string]string {
+	return d.Labels
+}
+
+func (d *CustomCost) GetUsageQuantity() float32 {
+	return d.UsageQty
+}
+
+func (d *CustomCost) GetUsageUnit() string {
+	return d.UsageUnit
+}
+
+func (d *CustomCost) GetExtendedAttributes() *ExtendedCustomCostAttributes {
+	return d.ExtendedAttributes
+}
+
+func (d *CustomCost) GetResourceType() string {
+	return d.ResourceType
+}
+
+func (d *CustomCostResponse) GetMetadata() map[string]string {
+	return d.Metadata
+}
+
+func (d *CustomCostResponse) GetCostSource() string {
+	return d.Costsource
+}
+
+func (d *CustomCostResponse) GetDomain() string {
+	return d.Domain
+}
+
+func (d *CustomCostResponse) GetVersion() string {
+	return d.Version
+}
+
+func (d *CustomCostResponse) GetCurrency() string {
+	return d.Currency
+}
+
+func (d *CustomCostResponse) GetWindow() opencost.Window {
+	return d.Window
+}
+
+func (d *CustomCostResponse) GetCosts() []*CustomCost {
+	return d.Costs
+}
+
+func (d *CustomCostResponse) GetErrors() []error {
+	return d.Errors
+}

+ 12 - 1
pkg/kubeconfig/loader.go

@@ -1,6 +1,8 @@
 package kubeconfig
 
 import (
+	"fmt"
+
 	"k8s.io/client-go/kubernetes"
 	_ "k8s.io/client-go/plugin/pkg/client/auth"
 	"k8s.io/client-go/rest"
@@ -17,7 +19,16 @@ func LoadKubeconfig(path string) (*rest.Config, error) {
 		loadingRules.ExplicitPath = path
 	}
 	loader := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{})
-	return loader.ClientConfig()
+	config, err := loader.ClientConfig()
+	if err != nil {
+		return nil, fmt.Errorf("loading kubeconfig: %w", err)
+	}
+	config.UserAgent = "opencost"
+	// use protobuf for faster serialization instead of default json
+	// https://kubernetes.io/docs/reference/using-api/api-concepts/#alternate-representations-of-resources
+	config.AcceptContentTypes = "application/vnd.kubernetes.protobuf,application/json"
+	config.ContentType = "application/vnd.kubernetes.protobuf"
+	return config, nil
 }
 
 // LoadKubeClient accepts a path to a kubeconfig to load and returns the clientset