Explorar o código

pricing and feedback

Signed-off-by: nickcurie <nick.curie64@gmail.com>
nickcurie %!s(int64=3) %!d(string=hai) anos
pai
achega
0644fd8448
Modificáronse 3 ficheiros con 97 adicións e 37 borrados
  1. 37 13
      pkg/cloud/awsprovider.go
  2. 0 1
      pkg/cloud/azureprovider.go
  3. 60 23
      pkg/cloud/gcpprovider.go

+ 37 - 13
pkg/cloud/awsprovider.go

@@ -51,6 +51,9 @@ const (
 	APIPricingSource              = "Public API"
 	SpotPricingSource             = "Spot Data Feed"
 	ReservedInstancePricingSource = "Savings Plan, Reserved Instance, and Out-Of-Cluster"
+
+	InUseState    = "in-use"
+	AttachedState = "attached"
 )
 
 var (
@@ -1638,14 +1641,14 @@ func (aws *AWS) GetDisks() ([]byte, error) {
 
 func (aws *AWS) isDiskOrphaned(vol *ec2Types.Volume) bool {
 	// Do not consider volume orphaned if in use
-	if vol.State == "in-use" {
+	if vol.State == InUseState {
 		return false
 	}
 
 	// Do not consider volume orphaned if volume is attached to any attachments
 	if len(vol.Attachments) != 0 {
 		for _, attachment := range vol.Attachments {
-			if attachment.State == "attached" {
+			if attachment.State == AttachedState {
 				return false
 			}
 		}
@@ -1669,10 +1672,12 @@ func (aws *AWS) GetOrphanedResources() ([]OrphanedResource, error) {
 
 	for _, volume := range volumes {
 		if aws.isDiskOrphaned(volume) {
-			cost := aws.findCostForDisk(volume)
+			cost, err := aws.findCostForDisk(volume)
+			if err != nil {
+				return nil, err
+			}
 
 			var volumeSize int64
-			volumeSize = -1
 			if volume.Size != nil {
 				volumeSize = int64(*volume.Size)
 			}
@@ -1682,7 +1687,7 @@ func (aws *AWS) GetOrphanedResources() ([]OrphanedResource, error) {
 				Region:      *volume.AvailabilityZone,
 				Size:        &volumeSize,
 				DiskName:    *volume.VolumeId,
-				MonthlyCost: &cost,
+				MonthlyCost: cost,
 			}
 
 			orphanedResources = append(orphanedResources, or)
@@ -1705,18 +1710,37 @@ func (aws *AWS) GetOrphanedResources() ([]OrphanedResource, error) {
 	return orphanedResources, nil
 }
 
-func (aws *AWS) findCostForDisk(disk *ec2Types.Volume) float64 {
+func (aws *AWS) findCostForDisk(disk *ec2Types.Volume) (*float64, error) {
 	//todo: use AWS pricing
-	price := 0.04
-	if strings.Contains(string(disk.VolumeType), "ssd") {
-		price = 0.17
+	// price := 0.04
+	// if strings.Contains(string(disk.VolumeType), "ssd") {
+	// 	price = 0.17
+	// }
+	// if strings.Contains(string(disk.VolumeType), "gp2") {
+	// 	price = 0.1
+	// }
+	// cost := price * float64(*disk.Size)
+	// return &cost, nil
+	if disk.AvailabilityZone == nil {
+		return nil, fmt.Errorf("nil region")
+	}
+	if disk.Size == nil {
+		return nil, fmt.Errorf("nil disk size")
 	}
-	if strings.Contains(string(disk.VolumeType), "gp2") {
-		price = 0.1
+
+	class := volTypes[string(disk.VolumeType)]
+
+	key := "us-east-2" + "," + class
+
+	priceStr := aws.Pricing[key].PV.Cost
+
+	price, err := strconv.ParseFloat(priceStr, 64)
+	if err != nil {
+		return nil, err
 	}
 
-	cost := price * float64(*disk.Size)
-	return cost
+	cost := price * timeutil.HoursPerMonth * float64(*disk.Size)
+	return &cost, nil
 }
 
 // QueryAthenaPaginated executes athena query and processes results.

+ 0 - 1
pkg/cloud/azureprovider.go

@@ -1278,7 +1278,6 @@ func (az *Azure) GetOrphanedResources() ([]OrphanedResource, error) {
 			}
 
 			var diskSize int64
-			diskSize = -1
 			if d.DiskSizeGB != nil {
 				diskSize = int64(*d.DiskSizeGB)
 			}

+ 60 - 23
pkg/cloud/gcpprovider.go

@@ -339,21 +339,32 @@ func (gcp *GCP) getAllAddresses() (*compute.AddressAggregatedList, error) {
 	if err != nil {
 		return nil, err
 	}
+	log.Warnf("[NICK] - projId: %s", projID)
+
+	log.Warnf("[NICK] - getting all adds")
 
 	client, err := google.DefaultClient(oauth2.NoContext,
 		"https://www.googleapis.com/auth/compute.readonly")
 	if err != nil {
 		return nil, err
 	}
+	log.Warnf("[NICK] - got adds client")
+
 	svc, err := compute.New(client)
 	if err != nil {
 		return nil, err
 	}
+	log.Warnf("[NICK] - adds compute")
+
 	res, err := svc.Addresses.AggregatedList(projID).Do()
+	log.Warnf("[NICK] - got adds result")
 
 	if err != nil {
 		return nil, err
 	}
+
+	log.Warnf("[NICK] - returning adds")
+
 	return res, nil
 }
 
@@ -367,12 +378,8 @@ func (gcp *GCP) GetAddresses() ([]byte, error) {
 }
 
 func (gcp *GCP) isAddressOrphaned(address *compute.Address) bool {
-	// Do not consider address orphaned if it has more than 0 users
-	if len(address.Users) > 0 {
-		return false
-	}
-
-	return true
+	// Consider address orphaned if it has 0 users
+	return len(address.Users) == 0
 }
 
 func (gcp *GCP) getAllDisks() (*compute.DiskAggregatedList, error) {
@@ -380,22 +387,32 @@ func (gcp *GCP) getAllDisks() (*compute.DiskAggregatedList, error) {
 	if err != nil {
 		return nil, err
 	}
+	log.Warnf("[NICK] - projId: %s", projID)
+
+	log.Warnf("[NICK] - getting all disks")
 
 	client, err := google.DefaultClient(oauth2.NoContext,
 		"https://www.googleapis.com/auth/compute.readonly")
 	if err != nil {
 		return nil, err
 	}
+	log.Warnf("[NICK] - got disks client")
+
 	svc, err := compute.New(client)
 	if err != nil {
 		return nil, err
 	}
+	log.Warnf("[NICK] - disks compute")
+
 	res, err := svc.Disks.AggregatedList(projID).Do()
+	log.Warnf("[NICK] - got disks result")
 
 	if err != nil {
 		return nil, err
 	}
 
+	log.Warnf("[NICK] - returning disks")
+
 	return res, nil
 }
 
@@ -409,19 +426,23 @@ func (gcp *GCP) GetDisks() ([]byte, error) {
 	return json.Marshal(res)
 }
 
-func (gcp *GCP) isDiskOrphaned(disk *compute.Disk) bool {
+func (gcp *GCP) isDiskOrphaned(disk *compute.Disk) (bool, error) {
 	// Do not consider disk orphaned if it has more than 0 users
 	if len(disk.Users) > 0 {
-		return false
+		return false, nil
 	}
 
 	// Do not consider disk orphaned if it was used within the last hour
 	threshold := time.Now().Add(time.Duration(-1) * time.Hour)
-	lastUsed, _ := time.Parse(time.RFC3339, disk.LastDetachTimestamp)
+	lastUsed, err := time.Parse(time.RFC3339, disk.LastDetachTimestamp)
+	if err != nil {
+		// This can return false since errors are checked before the bool
+		return false, fmt.Errorf("error parsing time: %s", err)
+	}
 	if threshold.Before(lastUsed) {
-		return false
+		return false, nil
 	}
-	return true
+	return true, nil
 }
 
 func (gcp *GCP) GetOrphanedResources() ([]OrphanedResource, error) {
@@ -443,8 +464,15 @@ func (gcp *GCP) GetOrphanedResources() ([]OrphanedResource, error) {
 		}
 
 		for _, disk := range diskList.Disks {
-			if gcp.isDiskOrphaned(disk) {
-				cost := gcp.findCostForDisk(disk)
+			isOrphaned, err := gcp.isDiskOrphaned(disk)
+			if err != nil {
+				return nil, err
+			}
+			if isOrphaned {
+				cost, err := gcp.findCostForDisk(disk)
+				if err != nil {
+					return nil, err
+				}
 
 				or := OrphanedResource{
 					Kind:        "disk",
@@ -452,7 +480,7 @@ func (gcp *GCP) GetOrphanedResources() ([]OrphanedResource, error) {
 					Description: map[string]string{},
 					Size:        &disk.SizeGb,
 					DiskName:    disk.Name,
-					MonthlyCost: &cost,
+					MonthlyCost: cost,
 				}
 				orphanedResources = append(orphanedResources, or)
 			}
@@ -486,18 +514,27 @@ func (gcp *GCP) GetOrphanedResources() ([]OrphanedResource, error) {
 	return orphanedResources, nil
 }
 
-func (gcp *GCP) findCostForDisk(disk *compute.Disk) float64 {
+func (gcp *GCP) findCostForDisk(disk *compute.Disk) (*float64, error) {
 	//todo: use GCP pricing
-	price := 0.04
-	if strings.Contains(disk.Type, "ssd") {
-		price = 0.17
-	}
-	if strings.Contains(disk.Type, "gp2") {
-		price = 0.1
+	// price := 0.04
+	// if strings.Contains(disk.Type, "ssd") {
+	// 	price = 0.17
+	// }
+	// if strings.Contains(disk.Type, "gp2") {
+	// 	price = 0.1
+	// }
+
+	key := disk.Region + "," + disk.Type
+	log.Warnf("[NICK] - key: %s", key)
+
+	priceStr := gcp.Pricing[key].PV.Cost
+	price, err := strconv.ParseFloat(priceStr, 64)
+	if err != nil {
+		return nil, err
 	}
 
-	cost := price * float64(disk.SizeGb)
-	return cost
+	cost := price * timeutil.HoursPerMonth * float64(disk.SizeGb)
+	return &cost, nil
 }
 
 // GCPPricing represents GCP pricing data for a SKU