Skip to content

Commit

Permalink
feat(ocean/aws): support getClusterAggregatedCosts API call(#194)
Browse files Browse the repository at this point in the history
  • Loading branch information
baruchis123 authored Jun 30, 2022
1 parent f12634a commit 5245386
Show file tree
Hide file tree
Showing 3 changed files with 261 additions and 0 deletions.
71 changes: 71 additions & 0 deletions examples/service/ocean/providers/aws/aggregatedcosts/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package main

import (
"context"
"encoding/json"
"github.com/spotinst/spotinst-sdk-go/service/ocean/providers/aws"
"github.com/spotinst/spotinst-sdk-go/spotinst"
"github.com/spotinst/spotinst-sdk-go/spotinst/credentials"
"github.com/spotinst/spotinst-sdk-go/spotinst/session"
"log"
"os"
)

func main() {
// All clients require a Session. The Session provides the client with
// shared configuration such as account and credentials.
// A Session should be shared where possible to take advantage of
// configuration and credential caching. See the session package for
// more information.
sess := session.New()

os.Setenv(credentials.EnvCredentialsVarToken, "secret token")
os.Setenv(credentials.EnvCredentialsVarAccount, "account")

cred := credentials.NewChainCredentials(
new(credentials.EnvProvider),
)

// Create a new instance of the service's client with a Session.
// Optional spotinst.Config values can also be provided as variadic
// arguments to the New function. This option allows you to provide
// service specific configuration.
svc := aws.New(sess, &spotinst.Config{Credentials: cred})

// Create a new context.
ctx := context.Background()

// Get aggregated costs of an ocean cluster.
AllMatch := []*aws.AllMatchInner{{
Type: spotinst.String("label"),
Key: spotinst.String("k8s-app"),
Operator: spotinst.String("notEquals"),
Value: spotinst.String("dns-controller"),
}}
AllMatchArray := []*aws.AllMatch{{AllMatches: AllMatch}}

out, err := svc.GetClusterAggregatedCosts(ctx, &aws.ClusterAggregatedCostInput{
OceanId: spotinst.String("o-12345"),
StartTime: spotinst.String("1655812800000"),
EndTime: spotinst.String("1655985600000"),
GroupBy: spotinst.String("namespace"),
Filter: &aws.AggregatedFilter{
Scope: spotinst.String("resource"),
Conditions: &aws.Conditions{AnyMatch: AllMatchArray},
},
})
if err != nil {
log.Fatalf("spotinst: Failed to revieve the aggregated costs: %v", err)
}

output, errJson := json.Marshal(out.AggregatedClusterCosts)
if errJson != nil {
log.Fatalf("spotinst: Failed to marshal output into Json: %v", err)
}
// Do something with output.
if out.AggregatedClusterCosts != nil {
log.Printf("Aggregated Costs:\n %s",
output)
}

}
188 changes: 188 additions & 0 deletions service/ocean/providers/aws/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,126 @@ type GetLogEventsOutput struct {
Events []*LogEvent `json:"events,omitempty"`
}

type ClusterAggregatedCostInput struct {
OceanId *string `json:"oceanId,omitempty"`
StartTime *string `json:"startTime,omitempty"`
EndTime *string `json:"endTime,omitempty"`
GroupBy *string `json:"groupBy,omitempty"`
Filter *AggregatedFilter `json:"filter,omitempty"`
}

type AggregatedFilter struct {
Scope *string `json:"scope,omitempty"`
Conditions *Conditions `json:"conditions,omitempty"`
}

type Conditions struct {
AnyMatch []*AllMatch `json:"anyMatch,omitempty"`
}

type AllMatch struct {
AllMatches []*AllMatchInner `json:"allMatch,omitempty"`
}

type AllMatchInner struct {
Type *string `json:"type,omitempty"`
Key *string `json:"key,omitempty"`
Operator *string `json:"operator,omitempty"`
Value *string `json:"value,omitempty"`
}

type ClusterAggregatedCostOutput struct {
AggregatedClusterCosts []*AggregatedClusterCost `json:"aggregatedClusterCosts,omitempty"`
}

type AggregatedClusterCost struct {
Result *Result `json:"result,omitempty"`
}

type Result struct {
TotalForDuration *TotalForDuration `json:"totalForDuration,omitempty"`
}

type TotalForDuration struct {
Summary *Summary `json:"summary,omitempty"`
StartTime *string `json:"startTime,omitempty"`
EndTime *string `json:"endTime,omitempty"`
DetailedCosts *DetailedCosts `json:"detailedCosts,omitempty"`
}

type DetailedCosts struct {
Aggregations map[string]Property `json:"aggregations,omitempty"`
GroupedBy *string `json:"groupedBy,omitempty"`
}

type Property struct {
Resources []AggregatedCostResource `json:"resources,omitempty"`
Summary *Summary `json:"summary,omitempty"`
}

type Summary struct {
Compute *AggregatedCompute `json:"compute,omitempty"`
Storage *AggregatedStorage `json:"storage,omitempty"`
Total *float64 `json:"total,omitempty"`
}

type AggregatedCostResource struct {
Compute *AggregatedCompute `json:"compute,omitempty"`
Storage *AggregatedStorage `json:"storage,omitempty"`
MetaData *MetaData `json:"metaData,omitempty"`
Total *float64 `json:"total,omitempty"`
}

type AggregatedCompute struct {
Headroom *Headroom `json:"headroom,omitempty"`
Total *float64 `json:"total,omitempty"`
Workloads *Workloads `json:"workloads,omitempty"`
}

type AggregatedStorage struct {
Block *Block `json:"block,omitempty"`
File *File `json:"file,omitempty"`
Total *float64 `json:"total,omitempty"`
}

type MetaData struct {
Name *string `json:"name,omitempty"`
Namespace *string `json:"namespace,omitempty"`
Type *string `json:"type,omitempty"`
CustomType *string `json:"customType,omitempty"`
}

type Headroom struct {
Total *float64 `json:"total,omitempty"`
}

type Workloads struct {
Total *float64 `json:"total,omitempty"`
}

type Block struct {
EbsPv *EbsPv `json:"ebsPv,omitempty"`
NonPv *NonPv `json:"nonPv,omitempty"`
Total *float64 `json:"total,omitempty"`
}

type File struct {
EfsPv *EfsPv `json:"efsPv,omitempty"`
Total *float64 `json:"total,omitempty"`
}

type EbsPv struct {
Total *float64 `json:"total,omitempty"`
}

type NonPv struct {
Total *float64 `json:"total,omitempty"`
}

type EfsPv struct {
Total *float64 `json:"total,omitempty"`
}

func clusterFromJSON(in []byte) (*Cluster, error) {
b := new(Cluster)
if err := json.Unmarshal(in, b); err != nil {
Expand Down Expand Up @@ -513,6 +633,45 @@ func logEventsFromHttpResponse(resp *http.Response) ([]*LogEvent, error) {
return logEventsFromJSON(body)
}

func clusterAggregatedCostFromJSON(in []byte) (*AggregatedClusterCost, error) {
b := new(AggregatedClusterCost)
if err := json.Unmarshal(in, b); err != nil {
return nil, err
}

return b, nil
}

func clusterAggregatedCostsFromJSON(in []byte) ([]*AggregatedClusterCost, error) {
var rw client.Response
if err := json.Unmarshal(in, &rw); err != nil {
return nil, err
}
out := make([]*AggregatedClusterCost, len(rw.Response.Items))

if len(out) == 0 {
return out, nil
}
for i, rb := range rw.Response.Items {
b, err := clusterAggregatedCostFromJSON(rb)
if err != nil {
return nil, err
}
out[i] = b
}

return out, nil
}

func clusterAggregatedCostsFromHttpResponse(resp *http.Response) ([]*AggregatedClusterCost, error) {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}

return clusterAggregatedCostsFromJSON(body)
}

func (s *ServiceOp) ListClusters(ctx context.Context, input *ListClustersInput) (*ListClustersOutput, error) {
r := client.NewRequest(http.MethodGet, "/ocean/aws/k8s/cluster")
resp, err := client.RequireOK(s.Client.Do(ctx, r))
Expand Down Expand Up @@ -835,6 +994,35 @@ func (s *ServiceOp) Roll(ctx context.Context, input *RollClusterInput) (*RollClu
return output, nil
}

func (s *ServiceOp) GetClusterAggregatedCosts(ctx context.Context, input *ClusterAggregatedCostInput) (*ClusterAggregatedCostOutput, error) {
path, err := uritemplates.Expand("/ocean/aws/k8s/cluster/{oceanId}/aggregatedCosts", uritemplates.Values{
"oceanId": spotinst.StringValue(input.OceanId),
})
if err != nil {
return nil, err
}

// We do not need the ID anymore so let's drop it.
input.OceanId = nil

r := client.NewRequest(http.MethodPost, path)

r.Obj = input

resp, err := client.RequireOK(s.Client.Do(ctx, r))
if err != nil {
return nil, err
}
defer resp.Body.Close()

costs, err := clusterAggregatedCostsFromHttpResponse(resp)
if err != nil {
return nil, err
}

return &ClusterAggregatedCostOutput{costs}, nil
}

// region Cluster

func (o Cluster) MarshalJSON() ([]byte, error) {
Expand Down
2 changes: 2 additions & 0 deletions service/ocean/providers/aws/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ type serviceKubernetes interface {
// Deprecated: Roll is obsolete, exists for backward compatibility only,
// and should not be used. Please use CreateRoll instead.
Roll(context.Context, *RollClusterInput) (*RollClusterOutput, error)

GetClusterAggregatedCosts(context.Context, *ClusterAggregatedCostInput) (*ClusterAggregatedCostOutput, error)
}

type serviceECS interface {
Expand Down

0 comments on commit 5245386

Please sign in to comment.