Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue(#823) mysql-instance #860

Merged
Merged
1 change: 1 addition & 0 deletions models/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type Resource struct {
Tags []Tag `json:"tags" bun:"tags,default:'[]'"`
Link string `json:"link" bson:"link"`
Value string `bun:",scanonly"` //to be deprecated
NodeCount int `json:"nodeCount"` // Add the NodeCount field
}

type Tag struct {
Expand Down
89 changes: 46 additions & 43 deletions providers/linode/compute/instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,51 +14,54 @@ import (
"github.com/tailwarden/komiser/providers"
)

func Linodes(ctx context.Context, client providers.ProviderClient) ([]Resource, error) {
resources := make([]Resource, 0)
type LinodeInstance struct {
Instance *linodego.Instance
NodeCount int
}

func Linodes(ctx context.Context, client providers.ProviderClient, linodeInstances []LinodeInstance) ([]Resource, error) {
resources := make([]Resource, 0)

instances, err := client.LinodeClient.ListInstances(ctx, &linodego.ListOptions{})
if err != nil {
return resources, err
}
for _, linodeInstance := range linodeInstances {
instance := linodeInstance.Instance

for _, instance := range instances {
tags := make([]Tag, 0)
for _, tag := range instance.Tags {
if strings.Contains(tag, ":") {
parts := strings.Split(tag, ":")
tags = append(tags, models.Tag{
Key: parts[0],
Value: parts[1],
})
} else {
tags = append(tags, models.Tag{
Key: tag,
Value: tag,
})
}
}
tags := make([]Tag, 0)
for _, tag := range instance.Tags {
if strings.Contains(tag, ":") {
parts := strings.Split(tag, ":")
tags = append(tags, models.Tag{
Key: parts[0],
Value: parts[1],
})
} else {
tags = append(tags, models.Tag{
Key: tag,
Value: tag,
})
}
}

resources = append(resources, models.Resource{
Provider: "Linode",
Account: client.Name,
Service: "Linode",
Region: instance.Region,
ResourceId: fmt.Sprintf("%d", instance.ID),
Cost: 0,
Name: instance.Label,
FetchedAt: time.Now(),
CreatedAt: *instance.Created,
Tags: tags,
Link: fmt.Sprintf("https://cloud.linode.com/linodes/%d", instance.ID),
})
}
resources = append(resources, models.Resource{
Provider: "Linode",
Account: client.Name,
Service: "Linode",
Region: instance.Region,
ResourceId: fmt.Sprintf("%d", instance.ID),
Cost: 0,
Name: instance.Label,
FetchedAt: time.Now(),
CreatedAt: *instance.Created,
Tags: tags,
Link: fmt.Sprintf("https://cloud.linode.com/linodes/%d", instance.ID),
NodeCount: linodeInstance.NodeCount, // Include the NodeCount value
})
}

log.WithFields(log.Fields{
"provider": "Linode",
"account": client.Name,
"service": "Linode",
"resources": len(resources),
}).Info("Fetched resources")
return resources, nil
log.WithFields(log.Fields{
"provider": "Linode",
"account": client.Name,
"service": "Linode",
"resources": len(resources),
}).Info("Fetched resources")
return resources, nil
}
4 changes: 3 additions & 1 deletion providers/linode/linode.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,21 @@ import (

"github.com/tailwarden/komiser/providers"
"github.com/tailwarden/komiser/providers/linode/compute"
"github.com/tailwarden/komiser/providers/linode/sql"
"github.com/tailwarden/komiser/providers/linode/storage"
"github.com/uptrace/bun"
)

func listOfSupportedServices() []providers.FetchDataFunction {
return []providers.FetchDataFunction{
compute.Linodes,
// compute.Linodes,
compute.LKEClusters,
storage.Volumes,
storage.Databases,
storage.Buckets,
networking.NodeBalancers,
networking.Firewalls,
sql.Instances,
}
}

Expand Down
136 changes: 136 additions & 0 deletions providers/linode/sql/mysql.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package sql

import (
"context"
"fmt"
"strings"
"time"

// "github.com/linode/linodego"
log "github.com/sirupsen/logrus"

"github.com/tailwarden/komiser/models"
"github.com/tailwarden/komiser/providers"
)

// Cost data for Dedicated CPU instances
var dedicatedCPUCosts = map[string]float64{
"Dedicated 4GB": 65.00,
"Dedicated 8GB": 130.00,
"Dedicated 16GB": 260.00,
"Dedicated 32GB": 520.00,
"Dedicated 64GB": 1040.00,
"Dedicated 96GB": 1560.00,
"Dedicated 128GB": 2080.00,
"Dedicated 256GB": 4160.00,
"Dedicated 512GB": 8320.00,
}

// Cost data for Shared CPU instances
var sharedCPUCosts = map[string]float64{
"Shared 1GB": 15.00,
"Shared 2GB": 30.00,
"Shared 4GB": 60.00,
"Shared 8GB": 120.00,
"Shared 16GB": 240.00,
"Shared 32GB": 480.00,
"Shared 64GB": 960.00,
"Shared 96GB": 1440.00,
"Shared 128GB": 1920.00,
"Shared 192GB": 2880.00,
"Shared 256GB": 3840.00,
}

// Instances fetches MySQL instances from the provider and returns them as resources.
func Instances(ctx context.Context, client providers.ProviderClient) ([]models.Resource, error) {
resources := make([]models.Resource, 0)

// Fetch MySQL databases from the Linode provider
databases, err := client.LinodeClient.ListMySQLDatabases(ctx, nil)
if err != nil {
return resources, err
}

for _, database := range databases {
// Get the cluster size for the database
clusterSize, err := GetClusterSize(ctx, client, database.ID)
if err != nil {
log.Warnf("Failed to get cluster size for MySQL database: %d, Error: %s", database.ID, err.Error())
// Skip this database and continue with the next one
continue
}

// Calculate the cost based on the database type and cluster size
cost, ok := InstancesCost(database.Type, clusterSize)
if !ok {
log.Warnf("Failed to calculate cost for MySQL database: %d, Type: %s", database.ID, database.Type)
// Skip this database and continue with the next one
continue
}

resources = append(resources, models.Resource{
Provider: "Linode",
Account: client.Name,
Service: "MySQL",
Region: database.Region,
ResourceId: fmt.Sprintf("%d", database.ID),
Cost: cost,
Name: database.Label,
FetchedAt: time.Now(),
CreatedAt: *database.Created,
Link: fmt.Sprintf("https://cloud.linode.com/databases/%d", database.ID),
})
}

log.WithFields(log.Fields{
"provider": "Linode",
"account": client.Name,
"service": "MySQL",
"resources": len(resources),
}).Info("Fetched resources")
return resources, nil
}

// InstancesCost calculates the cost for the given MySQL instance type and cluster size.
func InstancesCost(instanceType string, clusterSize int) (float64, bool) {
// Calculate cost based on instance type
if strings.Contains(instanceType, "Dedicated") {
cost, ok := dedicatedCPUCosts[instanceType]
if !ok {
return 0, false
}

// Adjust cost based on the cluster size
if clusterSize == 3 {
cost *= 3

return cost, true
}

} else if strings.Contains(instanceType, "Shared") {
cost, ok := sharedCPUCosts[instanceType]
if !ok {
return 0, false
}

// Adjust cost for the cluster size
if clusterSize == 3 {
cost *= 2.333

return cost, true
}

}

return 0, false
}

// GetClusterSize retrieves the cluster size for a specific MySQL instance.
func GetClusterSize(ctx context.Context, client providers.ProviderClient, instanceID int) (int, error) {
instance, err := client.LinodeClient.GetMySQLDatabase(ctx, instanceID)
if err != nil {
return 0, err
}

return instance.ClusterSize, nil
}