refactor: simplify code
parent
4625be141b
commit
904e7b38f3
|
@ -48,7 +48,7 @@ type DriftCTL struct {
|
|||
iacProgress globaloutput.Progress
|
||||
resourceSchemaRepository resource.SchemaRepositoryInterface
|
||||
opts *ScanOptions
|
||||
s memstore.Store
|
||||
store memstore.Store
|
||||
}
|
||||
|
||||
func NewDriftCTL(remoteSupplier resource.Supplier,
|
||||
|
@ -144,12 +144,12 @@ func (d DriftCTL) Run() (*analyser.Analysis, error) {
|
|||
analysis.Duration = time.Since(start)
|
||||
analysis.Date = time.Now()
|
||||
|
||||
d.s.Bucket(memstore.TelemetryBucket).Set("version", version.Current())
|
||||
d.s.Bucket(memstore.TelemetryBucket).Set("os", runtime.GOOS)
|
||||
d.s.Bucket(memstore.TelemetryBucket).Set("arch", runtime.GOARCH)
|
||||
d.s.Bucket(memstore.TelemetryBucket).Set("total_resources", analysis.Summary().TotalResources)
|
||||
d.s.Bucket(memstore.TelemetryBucket).Set("total_managed", analysis.Summary().TotalManaged)
|
||||
d.s.Bucket(memstore.TelemetryBucket).Set("duration", uint(analysis.Duration.Seconds()+0.5))
|
||||
d.store.Bucket(memstore.TelemetryBucket).Set("version", version.Current())
|
||||
d.store.Bucket(memstore.TelemetryBucket).Set("os", runtime.GOOS)
|
||||
d.store.Bucket(memstore.TelemetryBucket).Set("arch", runtime.GOARCH)
|
||||
d.store.Bucket(memstore.TelemetryBucket).Set("total_resources", analysis.Summary().TotalResources)
|
||||
d.store.Bucket(memstore.TelemetryBucket).Set("total_managed", analysis.Summary().TotalManaged)
|
||||
d.store.Bucket(memstore.TelemetryBucket).Set("duration", uint(analysis.Duration.Seconds()+0.5))
|
||||
|
||||
return &analysis, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package memstore
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Bucket interface {
|
||||
Set(string, interface{})
|
||||
Get(string) interface{}
|
||||
Values() map[string]interface{}
|
||||
}
|
||||
|
||||
type bucket struct {
|
||||
m *sync.RWMutex
|
||||
values map[string]interface{}
|
||||
}
|
||||
|
||||
func (b bucket) Set(key string, value interface{}) {
|
||||
b.m.Lock()
|
||||
defer b.m.Unlock()
|
||||
b.values[key] = value
|
||||
}
|
||||
|
||||
func (b bucket) Get(key string) interface{} {
|
||||
b.m.RLock()
|
||||
defer b.m.RUnlock()
|
||||
return b.values[key]
|
||||
}
|
||||
|
||||
func (b bucket) Values() map[string]interface{} {
|
||||
return b.values
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package memstore
|
||||
|
||||
type BucketName int
|
||||
|
||||
const (
|
||||
// TelemetryBucket is the name of the store bucket used by the telemetry service
|
||||
TelemetryBucket = "telemetry"
|
||||
TelemetryBucket BucketName = iota + 1
|
||||
)
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
package memstore
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Bucket interface {
|
||||
Set(string, interface{})
|
||||
Get(string) interface{}
|
||||
MarshallJSON() ([]byte, error)
|
||||
}
|
||||
|
||||
type Store interface {
|
||||
Bucket(string) Bucket
|
||||
}
|
||||
|
||||
type store struct {
|
||||
m *sync.Mutex
|
||||
buckets map[string]*bucket
|
||||
}
|
||||
|
||||
type bucket struct {
|
||||
m *sync.RWMutex
|
||||
values map[string]interface{}
|
||||
}
|
||||
|
||||
func New() Store {
|
||||
return &store{
|
||||
m: &sync.Mutex{},
|
||||
buckets: map[string]*bucket{},
|
||||
}
|
||||
}
|
||||
|
||||
func (s store) Bucket(name string) Bucket {
|
||||
s.m.Lock()
|
||||
defer s.m.Unlock()
|
||||
|
||||
if _, ok := s.buckets[name]; !ok {
|
||||
s.buckets[name] = &bucket{
|
||||
m: &sync.RWMutex{},
|
||||
values: map[string]interface{}{},
|
||||
}
|
||||
}
|
||||
|
||||
return s.buckets[name]
|
||||
}
|
||||
|
||||
func (b bucket) Set(key string, value interface{}) {
|
||||
b.m.Lock()
|
||||
defer b.m.Unlock()
|
||||
b.values[key] = value
|
||||
}
|
||||
|
||||
func (b bucket) Get(key string) interface{} {
|
||||
b.m.RLock()
|
||||
defer b.m.RUnlock()
|
||||
return b.values[key]
|
||||
}
|
||||
|
||||
func (b bucket) MarshallJSON() ([]byte, error) {
|
||||
return json.Marshal(b.values)
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package memstore
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Store interface {
|
||||
Bucket(BucketName) Bucket
|
||||
}
|
||||
|
||||
type store struct {
|
||||
m *sync.Mutex
|
||||
buckets map[int]*bucket
|
||||
}
|
||||
|
||||
func New() Store {
|
||||
return &store{
|
||||
m: &sync.Mutex{},
|
||||
buckets: map[int]*bucket{},
|
||||
}
|
||||
}
|
||||
|
||||
func (s store) Bucket(name BucketName) Bucket {
|
||||
s.m.Lock()
|
||||
defer s.m.Unlock()
|
||||
|
||||
key := int(name)
|
||||
if _, exist := s.buckets[key]; !exist {
|
||||
s.buckets[key] = &bucket{
|
||||
m: &sync.RWMutex{},
|
||||
values: map[string]interface{}{},
|
||||
}
|
||||
}
|
||||
|
||||
return s.buckets[key]
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package memstore
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
|
@ -11,13 +12,13 @@ import (
|
|||
func TestStore(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
bucket string
|
||||
bucket BucketName
|
||||
values map[string]interface{}
|
||||
expectedJSON string
|
||||
}{
|
||||
{
|
||||
name: "test basic store usage",
|
||||
bucket: "test-bucket-1",
|
||||
bucket: 0,
|
||||
values: map[string]interface{}{
|
||||
"test-value_|)": 13,
|
||||
"duration_key": "23",
|
||||
|
@ -28,13 +29,13 @@ func TestStore(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "test empty bucket",
|
||||
bucket: "test-bucket-empty",
|
||||
bucket: 2,
|
||||
values: map[string]interface{}{},
|
||||
expectedJSON: `{}`,
|
||||
},
|
||||
{
|
||||
name: "test bucket with nil values",
|
||||
bucket: "test-bucket-empty",
|
||||
bucket: 1,
|
||||
values: map[string]interface{}{
|
||||
"version": nil,
|
||||
"total_resources": nil,
|
||||
|
@ -56,13 +57,13 @@ func TestStore(t *testing.T) {
|
|||
defer wg.Done()
|
||||
kv.Bucket(tt.bucket).Set(key, val)
|
||||
assert.Equal(t, val, kv.Bucket(tt.bucket).Get(key))
|
||||
assert.Equal(t, nil, kv.Bucket("dummybucketname").Get(key))
|
||||
assert.Equal(t, nil, kv.Bucket(tt.bucket+1).Get(key))
|
||||
}(key, val, &wg)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
b, err := kv.Bucket(tt.bucket).MarshallJSON()
|
||||
b, err := json.Marshal(kv.Bucket(tt.bucket).Values())
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, tt.expectedJSON, string(b))
|
||||
})
|
|
@ -2,14 +2,50 @@ package telemetry
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/cloudskiff/driftctl/pkg/memstore"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type telemetry struct {
|
||||
Version string `json:"version"`
|
||||
Os string `json:"os"`
|
||||
Arch string `json:"arch"`
|
||||
TotalResources int `json:"total_resources"`
|
||||
TotalManaged int `json:"total_managed"`
|
||||
Duration uint `json:"duration"`
|
||||
}
|
||||
|
||||
func SendTelemetry(s memstore.Store) {
|
||||
body, err := s.Bucket(memstore.TelemetryBucket).MarshallJSON()
|
||||
t := &telemetry{}
|
||||
|
||||
if val, ok := s.Bucket(memstore.TelemetryBucket).Get("version").(string); ok {
|
||||
t.Version = val
|
||||
}
|
||||
|
||||
if val, ok := s.Bucket(memstore.TelemetryBucket).Get("os").(string); ok {
|
||||
t.Os = val
|
||||
}
|
||||
|
||||
if val, ok := s.Bucket(memstore.TelemetryBucket).Get("arch").(string); ok {
|
||||
t.Arch = val
|
||||
}
|
||||
|
||||
if val, ok := s.Bucket(memstore.TelemetryBucket).Get("total_resources").(int); ok {
|
||||
t.TotalResources = val
|
||||
}
|
||||
|
||||
if val, ok := s.Bucket(memstore.TelemetryBucket).Get("total_managed").(int); ok {
|
||||
t.TotalManaged = val
|
||||
}
|
||||
|
||||
if val, ok := s.Bucket(memstore.TelemetryBucket).Get("duration").(uint); ok {
|
||||
t.Duration = val
|
||||
}
|
||||
|
||||
body, err := json.Marshal(t)
|
||||
if err != nil {
|
||||
logrus.Debug(err)
|
||||
return
|
||||
|
|
|
@ -16,23 +16,15 @@ import (
|
|||
)
|
||||
|
||||
func TestSendTelemetry(t *testing.T) {
|
||||
type telemetry struct {
|
||||
Version string `json:"version"`
|
||||
Os string `json:"os"`
|
||||
Arch string `json:"arch"`
|
||||
TotalResources int `json:"total_resources"`
|
||||
TotalManaged int `json:"total_managed"`
|
||||
Duration uint `json:"duration"`
|
||||
}
|
||||
|
||||
httpmock.Activate()
|
||||
defer httpmock.DeactivateAndReset()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
analysis *analyser.Analysis
|
||||
expectedBody *telemetry
|
||||
response *http.Response
|
||||
name string
|
||||
analysis *analyser.Analysis
|
||||
expectedBody *telemetry
|
||||
response *http.Response
|
||||
setStoreValues func(memstore.Store, *analyser.Analysis)
|
||||
}{
|
||||
{
|
||||
name: "valid analysis",
|
||||
|
@ -51,6 +43,14 @@ func TestSendTelemetry(t *testing.T) {
|
|||
TotalManaged: 1,
|
||||
Duration: 123,
|
||||
},
|
||||
setStoreValues: func(s memstore.Store, a *analyser.Analysis) {
|
||||
s.Bucket(memstore.TelemetryBucket).Set("version", version.Current())
|
||||
s.Bucket(memstore.TelemetryBucket).Set("os", runtime.GOOS)
|
||||
s.Bucket(memstore.TelemetryBucket).Set("arch", runtime.GOARCH)
|
||||
s.Bucket(memstore.TelemetryBucket).Set("total_resources", a.Summary().TotalResources)
|
||||
s.Bucket(memstore.TelemetryBucket).Set("total_managed", a.Summary().TotalManaged)
|
||||
s.Bucket(memstore.TelemetryBucket).Set("duration", uint(a.Duration.Seconds()+0.5))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "valid analysis with round up",
|
||||
|
@ -65,23 +65,36 @@ func TestSendTelemetry(t *testing.T) {
|
|||
Arch: runtime.GOARCH,
|
||||
Duration: 124,
|
||||
},
|
||||
setStoreValues: func(s memstore.Store, a *analyser.Analysis) {
|
||||
s.Bucket(memstore.TelemetryBucket).Set("version", version.Current())
|
||||
s.Bucket(memstore.TelemetryBucket).Set("os", runtime.GOOS)
|
||||
s.Bucket(memstore.TelemetryBucket).Set("arch", runtime.GOARCH)
|
||||
s.Bucket(memstore.TelemetryBucket).Set("total_resources", a.Summary().TotalResources)
|
||||
s.Bucket(memstore.TelemetryBucket).Set("total_managed", a.Summary().TotalManaged)
|
||||
s.Bucket(memstore.TelemetryBucket).Set("duration", uint(a.Duration.Seconds()+0.5))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nil analysis",
|
||||
analysis: nil,
|
||||
},
|
||||
{
|
||||
name: "incomplete analysis values",
|
||||
analysis: func() *analyser.Analysis {
|
||||
a := &analyser.Analysis{}
|
||||
a.Duration = 123.5 * 1e9 // 123.5 seconds
|
||||
return a
|
||||
}(),
|
||||
expectedBody: &telemetry{},
|
||||
setStoreValues: func(s memstore.Store, a *analyser.Analysis) {},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := memstore.New()
|
||||
|
||||
if tt.analysis != nil {
|
||||
s.Bucket(memstore.TelemetryBucket).Set("version", version.Current())
|
||||
s.Bucket(memstore.TelemetryBucket).Set("os", runtime.GOOS)
|
||||
s.Bucket(memstore.TelemetryBucket).Set("arch", runtime.GOARCH)
|
||||
s.Bucket(memstore.TelemetryBucket).Set("total_resources", tt.analysis.Summary().TotalResources)
|
||||
s.Bucket(memstore.TelemetryBucket).Set("total_managed", tt.analysis.Summary().TotalManaged)
|
||||
s.Bucket(memstore.TelemetryBucket).Set("duration", uint(tt.analysis.Duration.Seconds()+0.5))
|
||||
tt.setStoreValues(s, tt.analysis)
|
||||
}
|
||||
|
||||
httpmock.Reset()
|
||||
|
|
Loading…
Reference in New Issue