Skip to content

Commit

Permalink
Signed-off-by: Sajit Kunnumkal <[email protected]>
Browse files Browse the repository at this point in the history
Init commit

cmd files

intermediate stop

Changing signature

adding scripts to gitignore

address review comments

address review comments

ignore mock test

failing test

Signed-off-by: sajit  <[email protected]>
fixed test

Make test optional
Signed-off-by: sajit  <[email protected]>

adding tests
Signed-off-by: sajit <[email protected]>

Added tests
Signed-off-by: sajit  <[email protected]>

Delete unused struct
Signed-off-by: sajit  <[email protected]>
  • Loading branch information
sajit committed Aug 29, 2024
1 parent a50cd12 commit 9a4b2b4
Show file tree
Hide file tree
Showing 6 changed files with 827 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
build
*.out
mongodb-atlas/scripts
66 changes: 66 additions & 0 deletions mongodb-atlas/cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package main

import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"time"

"github.com/opencost/opencost-plugins/mongodb-atlas/plugin"
"github.com/opencost/opencost/core/pkg/log"
)

func main() {
fmt.Println("Initialize plugin")

}

type HTTPClient interface {
Do(req *http.Request) (*http.Response, error)
}

// pass list of orgs , start date, end date
func createCostExplorerQueryToken(org string, startDate time.Time, endDate time.Time,
client HTTPClient, url string) (string, error) {
// Define the layout for the desired format
layout := "2006-01-02"

// Convert the time.Time object to a string in yyyy-mm-dd format
startDateString := startDate.Format(layout)
endDateString := endDate.Format(layout)

payload := plugin.CreateCostExplorerQueryPayload{

EndDate: endDateString,
StartDate: startDateString,
Organizations: []string{org},
}
payloadJson, _ := json.Marshal(payload)

request, _ := http.NewRequest("POST", url, bytes.NewBuffer(payloadJson))

request.Header.Set("Accept", "application/vnd.atlas.2023-01-01+json")
request.Header.Set("Content-Type", "application/vnd.atlas.2023-01-01+json")

response, error := client.Do(request)
if error != nil {
msg := fmt.Sprintf("createCostExplorerQueryToken: error from server: %v", error)
log.Errorf(msg)
return "", fmt.Errorf(msg)

}
defer response.Body.Close()

body, _ := io.ReadAll(response.Body)
//fmt.Println("response Body:", string(body))
var createCostExplorerQueryResponse plugin.CreateCostExplorerQueryResponse
respUnmarshalError := json.Unmarshal([]byte(body), &createCostExplorerQueryResponse)
if respUnmarshalError != nil {
msg := fmt.Sprintf("createCostExplorerQueryToken: error unmarshalling response: %v", respUnmarshalError)
log.Errorf(msg)
return "", fmt.Errorf(msg)
}
return createCostExplorerQueryResponse.Token, nil
}
110 changes: 110 additions & 0 deletions mongodb-atlas/cmd/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package main

import (
"errors"
"net/http"
"net/http/httptest"
"os"
"testing"
"time"

"github.com/icholy/digest"
"github.com/stretchr/testify/assert"
)

type ClientMock struct {
}

func (c *ClientMock) Do(req *http.Request) (*http.Response, error) {
// Implement a mock response
return nil, errors.New("Test Error")
}

func TestCallToCreateCostExplorerQuery(t *testing.T) {

server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"Token":"mockToken"}`))
}))
defer server.Close()

mockClient := &http.Client{}
// Define the layout that matches the format of the date string
layout := "2006-01-02"
endTime, _ := time.Parse(layout, "2024-07-01")
startTime, _ := time.Parse(layout, "2023-12-01")
resp, error := createCostExplorerQueryToken("myOrg", startTime, endTime, mockClient, server.URL)
assert.Nil(t, error)
assert.Equal(t, "mockToken", resp)

}

// FOR INTEGRATION TESTING PURPOSES ONLY
// expects 3 env variables to be set to work
// mapuk = public key for mongodb atlas
// maprk = private key for mongodb atlas
// maOrgId = orgId to be testsed
func TestMain(t *testing.T) {

publicKey := os.Getenv("mapuk")
privateKey := os.Getenv("maprk")
orgId := os.Getenv("maorgid")
if publicKey == "" || privateKey == "" || orgId == "" {
t.Skip("Skipping integration test.")
}

assert.NotNil(t, publicKey)
assert.NotNil(t, privateKey)
assert.NotNil(t, orgId)

client := &http.Client{
Transport: &digest.Transport{
Username: publicKey,
Password: privateKey,
},
}

// Define the layout that matches the format of the date string
layout := "2006-01-02"
endTime, _ := time.Parse(layout, "2024-07-01")
startTime, _ := time.Parse(layout, "2023-12-01")
url := "https://cloud.mongodb.com/api/atlas/v2/orgs/" + orgId + "/billing/costExplorer/usage"
resp, err := createCostExplorerQueryToken(orgId, startTime, endTime, client, url)

assert.NotEmpty(t, resp)
assert.Nil(t, err)

}

func TestErrorFromServer(t *testing.T) {

client := &ClientMock{}
// Define the layout that matches the format of the date string
layout := "2006-01-02"
endTime, _ := time.Parse(layout, "2024-07-01")
startTime, _ := time.Parse(layout, "2023-12-01")
orgId := "1"
url := "https://cloud.mongodb.com/api/atlas/v2/orgs/" + orgId + "/billing/costExplorer/usage"
_, err := createCostExplorerQueryToken(orgId, startTime, endTime, client, url)

assert.NotEmpty(t, err)

}

func TestCallToCreateCostExplorerQueryBadMessage(t *testing.T) {

server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`this is not json`))
}))
defer server.Close()

mockClient := &http.Client{}
// Define the layout that matches the format of the date string
layout := "2006-01-02"
endTime, _ := time.Parse(layout, "2024-07-01")
startTime, _ := time.Parse(layout, "2023-12-01")
_, error := createCostExplorerQueryToken("myOrg", startTime, endTime, mockClient, server.URL)
assert.NotEmpty(t, error)

}
30 changes: 30 additions & 0 deletions mongodb-atlas/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module github.com/opencost/opencost-plugins/mongodb-atlas

go 1.22.5

require github.com/icholy/digest v0.1.23

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/magiconair/properties v1.8.5 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/opencost/opencost/core v0.0.0-20240827181822-a4065411ba4c // indirect
github.com/pelletier/go-toml v1.9.3 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rs/zerolog v1.26.1 // indirect
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.8.1 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit 9a4b2b4

Please sign in to comment.