From 0ff00343061c971bd92b39dddf71223460d07ad3 Mon Sep 17 00:00:00 2001 From: zufardhiyaulhaq Date: Thu, 6 Jun 2024 20:14:41 +0700 Subject: [PATCH] feat: add used ip monitor Signed-off-by: zufardhiyaulhaq --- pkg/collector/collector.go | 18 ++++++++++++++ pkg/data/aws.go | 51 ++++++++++++++++++++++++++++++++++++++ pkg/data/data.go | 1 + pkg/data/google.go | 28 +++++++++++++++++++++ pkg/model/model.go | 6 +++++ 5 files changed, 104 insertions(+) diff --git a/pkg/collector/collector.go b/pkg/collector/collector.go index 1613934..430dd58 100644 --- a/pkg/collector/collector.go +++ b/pkg/collector/collector.go @@ -29,6 +29,15 @@ func (e *Collector) Collect(ch chan<- prometheus.Metric) { for _, unusedIP := range unusedIPs { ch <- prometheus.MustNewConstMetric(model.IPAddressUnusedGauge, prometheus.GaugeValue, 1, unusedIP.Cloud, unusedIP.Region, unusedIP.Value, unusedIP.Type, unusedIP.Identity) } + + usedIPs, err := e.google.GetUsedIP() + if err != nil { + return + } + + for _, usedIP := range usedIPs { + ch <- prometheus.MustNewConstMetric(model.IPAddressUsedGauge, prometheus.GaugeValue, 1, usedIP.Cloud, usedIP.Region, usedIP.Value, usedIP.Type, usedIP.Identity) + } } if e.settings.EnableAWS { @@ -40,6 +49,15 @@ func (e *Collector) Collect(ch chan<- prometheus.Metric) { for _, unusedIP := range unusedIPs { ch <- prometheus.MustNewConstMetric(model.IPAddressUnusedGauge, prometheus.GaugeValue, 1, unusedIP.Cloud, unusedIP.Region, unusedIP.Value, unusedIP.Type, unusedIP.Identity) } + + usedIPs, err := e.aws.GetUsedIP() + if err != nil { + return + } + + for _, usedIP := range usedIPs { + ch <- prometheus.MustNewConstMetric(model.IPAddressUsedGauge, prometheus.GaugeValue, 1, usedIP.Cloud, usedIP.Region, usedIP.Value, usedIP.Type, usedIP.Identity) + } } } diff --git a/pkg/data/aws.go b/pkg/data/aws.go index 51af879..442ab76 100644 --- a/pkg/data/aws.go +++ b/pkg/data/aws.go @@ -75,6 +75,57 @@ func (g *AWSData) GetUnusedIP() ([]model.IPAddress, error) { return IPs, nil } +func (g *AWSData) GetUsedIP() ([]model.IPAddress, error) { + var IPs []model.IPAddress + + for _, assumeRoleRegion := range g.assumeRolesRegions { + assume := strings.Split(assumeRoleRegion, ",") + role := assume[0] + region := assume[1] + + assumeRoleOutput, err := g.stsClient.AssumeRole(context.TODO(), &sts.AssumeRoleInput{ + RoleArn: &role, + DurationSeconds: aws.Int32(int32(g.assumeRoleDuration)), + }) + if err != nil { + return nil, err + } + + credentialProvider := credentials.NewStaticCredentialsProvider( + *assumeRoleOutput.Credentials.AccessKeyId, + *assumeRoleOutput.Credentials.SecretAccessKey, + *assumeRoleOutput.Credentials.SessionToken, + ) + cfg := aws.Config{ + Credentials: credentialProvider, + Region: region, + } + + ec2Client := ec2.NewFromConfig(cfg) + + input := &ec2.DescribeAddressesInput{} + output, err := ec2Client.DescribeAddresses(context.TODO(), input) + if err != nil { + return nil, err + } + + for _, address := range output.Addresses { + if address.AllocationId != nil && address.PublicIp != nil { + IPs = append(IPs, model.IPAddress{ + Cloud: "AWS", + Region: region, + Value: *address.PublicIp, + Type: "Public", + Used: true, + Identity: "Elastic IP", + }) + } + } + + } + return IPs, nil +} + func NewAWSData(settings settings.Settings) (*AWSData, error) { awsData := &AWSData{ assumeRolesRegions: settings.AWSAssumeRolesRegions, diff --git a/pkg/data/data.go b/pkg/data/data.go index 38d7e8e..a299056 100644 --- a/pkg/data/data.go +++ b/pkg/data/data.go @@ -4,4 +4,5 @@ import "github.com/gopaytech/unused-exporter/pkg/model" type Data interface { GetUnusedIP() ([]model.IPAddress, error) + GetUsedIP() ([]model.IPAddress, error) } diff --git a/pkg/data/google.go b/pkg/data/google.go index faa7f40..ddd472a 100644 --- a/pkg/data/google.go +++ b/pkg/data/google.go @@ -49,6 +49,34 @@ func (g *GoogleData) GetUnusedIP() ([]model.IPAddress, error) { return IPs, nil } +func (g *GoogleData) GetUsedIP() ([]model.IPAddress, error) { + var IPs []model.IPAddress + + for _, project := range g.projects { + aggregatedList, err := g.computeService.Addresses.AggregatedList(project).Do() + if err != nil { + return nil, err + } + + for region, addressesScopedList := range aggregatedList.Items { + for _, address := range addressesScopedList.Addresses { + if address.Status != "RESERVED" { + IPs = append(IPs, model.IPAddress{ + Cloud: "GCP", + Region: region, + Identity: project + "/" + address.Name, + Value: address.Address, + Type: address.AddressType, + Used: true, + }) + } + } + } + } + + return IPs, nil +} + func NewGoogleData(settings settings.Settings) (*GoogleData, error) { g := &GoogleData{ projects: settings.GCPProjects, diff --git a/pkg/model/model.go b/pkg/model/model.go index 6b9e71a..e36dd10 100644 --- a/pkg/model/model.go +++ b/pkg/model/model.go @@ -19,4 +19,10 @@ var ( "Indicates unused IP Address", []string{"cloud", "region", "value", "type", "identity"}, nil, ) + + IPAddressUsedGauge = prometheus.NewDesc( + prometheus.BuildFQName("ip_address", "", "used"), + "Indicates used IP Address", + []string{"cloud", "region", "value", "type", "identity"}, nil, + ) )