diff --git a/api/v1/interface.go b/api/v1/interface.go index b668573c..fe635d0c 100644 --- a/api/v1/interface.go +++ b/api/v1/interface.go @@ -10,6 +10,7 @@ import ( "github.com/flanksource/config-db/utils" "github.com/flanksource/duty/models" "github.com/flanksource/duty/types" + "github.com/flanksource/is-healthy/pkg/health" "github.com/ohler55/ojg/jp" "github.com/ohler55/ojg/oj" ) @@ -394,6 +395,24 @@ type ScrapeResult struct { RelationshipSelectors []RelationshipSelector `json:"-"` } +func (s ScrapeResult) WithHealthStatus(hs health.HealthStatus) ScrapeResult { + s.Ready = hs.Ready + + if hs.Health != "" { + s.Health = models.Health(hs.Health) + } + + if hs.Status != "" { + s.Status = string(hs.Status) + } + + if hs.Message != "" { + s.Description = hs.Message + } + + return s +} + func (s ScrapeResult) AsMap() map[string]any { output := make(map[string]any) diff --git a/go.mod b/go.mod index 020a5921..730edac9 100644 --- a/go.mod +++ b/go.mod @@ -308,4 +308,4 @@ replace go.opentelemetry.io/otel/trace => go.opentelemetry.io/otel/trace v1.22.0 // replace github.com/flanksource/postq => ../postq -// replace github.com/flanksource/is-healthy => ../is-healthy +replace github.com/flanksource/is-healthy => ../is-healthy diff --git a/go.sum b/go.sum index 39dc822b..58c005ea 100644 --- a/go.sum +++ b/go.sum @@ -859,9 +859,6 @@ github.com/flanksource/duty v1.0.470/go.mod h1:Fzi/DMrXGULFqPLpxfEm7H7wcAvafAhP6 github.com/flanksource/gomplate/v3 v3.20.4/go.mod h1:27BNWhzzSjDed1z8YShO6W+z6G9oZXuxfNFGd/iGSdc= github.com/flanksource/gomplate/v3 v3.24.2 h1:WZSriw1MaBhzrDV1IOP9eNsupIPxIHy0yTaMOVhCvsk= github.com/flanksource/gomplate/v3 v3.24.2/go.mod h1:94BxYobZqouGdVezuz6LNto5C+yLMG0LnNnM9CUPyoo= -github.com/flanksource/is-healthy v0.0.0-20230705092916-3b4cf510c5fc/go.mod h1:4pQhmF+TnVqJroQKY8wSnSp+T18oLson6YQ2M0qPHfQ= -github.com/flanksource/is-healthy v1.0.4 h1:r/dVsi7keR5NGLCTpgO/M6Hah2jRtYNfMh/XJNnxacc= -github.com/flanksource/is-healthy v1.0.4/go.mod h1:ijdyDDpdRzDtIt1UVZv5WNpAnb8V4hGUz75rnr3Ubhk= github.com/flanksource/ketall v1.1.6 h1:gGZsbDUf4ULznNMEC076cyrhGAZbaRnZXuhZ42PTyaE= github.com/flanksource/ketall v1.1.6/go.mod h1:s76Y3Anqptx5CdP4Jtav3LWjAu297ME8YXEsAiw/NcE= github.com/flanksource/kommons v0.31.4 h1:zksAgYjZuwPgS8XTejDIWEYB0nPSU1i3Jxcavm/vovI= @@ -1504,6 +1501,7 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1631,6 +1629,7 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1773,6 +1772,7 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1785,6 +1785,7 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1804,6 +1805,7 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/scrapers/aws/aws.go b/scrapers/aws/aws.go index cd0ee7e9..b4018a03 100644 --- a/scrapers/aws/aws.go +++ b/scrapers/aws/aws.go @@ -185,6 +185,8 @@ func (aws Scraper) eksClusters(ctx *AWSContext, config v1.AWS, results *v1.Scrap Relationship: "EKSSecuritygroups", }) + resourceHealth := health.GetAWSResourceHealth(string(cluster.Cluster.Status), health.AWSResourceTypeEKS) + cluster.Cluster.Tags["account"] = *ctx.Caller.Account cluster.Cluster.Tags["region"] = getRegionFromArn(*cluster.Cluster.Arn, "eks") @@ -203,8 +205,7 @@ func (aws Scraper) eksClusters(ctx *AWSContext, config v1.AWS, results *v1.Scrap ParentExternalID: *cluster.Cluster.ResourcesVpcConfig.VpcId, ParentType: v1.AWSEC2VPC, RelationshipResults: relationships, - Status: health.MapAWSStatus(string(cluster.Cluster.Status), health.AWSResourceTypeEKS), - }) + }.WithHealthStatus(resourceHealth)) } } @@ -404,6 +405,8 @@ func (aws Scraper) ebs(ctx *AWSContext, config v1.AWS, results *v1.ScrapeResults tags.Append("zone", *volume.AvailabilityZone) tags.Append("region", (*volume.AvailabilityZone)[:len(*volume.AvailabilityZone)-1]) + resourceHealth := health.GetAWSResourceHealth(health.AWSResourceTypeEBS, string(volume.State)) + *results = append(*results, v1.ScrapeResult{ Type: v1.AWSEBSVolume, Labels: labels, @@ -417,8 +420,7 @@ func (aws Scraper) ebs(ctx *AWSContext, config v1.AWS, results *v1.ScrapeResults ID: *volume.VolumeId, ParentExternalID: lo.FromPtr(ctx.Caller.Account), ParentType: v1.AWSAccount, - Status: health.MapAWSStatus(string(volume.State), health.AWSResourceTypeEBS), - }) + }.WithHealthStatus(resourceHealth)) } } @@ -457,6 +459,8 @@ func (aws Scraper) rds(ctx *AWSContext, config v1.AWS, results *v1.ScrapeResults }) } + resourceHealth := health.GetAWSResourceHealth(health.AWSResourceTypeRDS, lo.FromPtr(instance.DBInstanceStatus)) + *results = append(*results, v1.ScrapeResult{ Type: v1.AWSRDSInstance, Labels: labels, @@ -471,8 +475,7 @@ func (aws Scraper) rds(ctx *AWSContext, config v1.AWS, results *v1.ScrapeResults ParentExternalID: *instance.DBSubnetGroup.VpcId, ParentType: v1.AWSEC2VPC, RelationshipResults: relationships, - Status: health.MapAWSStatus(lo.FromPtr(instance.DBInstanceStatus), health.AWSResourceTypeRDS), - }) + }.WithHealthStatus(resourceHealth)) } } @@ -512,6 +515,8 @@ func (aws Scraper) vpcs(ctx *AWSContext, config v1.AWS, results *v1.ScrapeResult labels := getLabels(vpc.Tags) labels["network"] = *vpc.VpcId + + resourceHealth := health.GetAWSResourceHealth(health.AWSResourceTypeVPC, string(vpc.State)) *results = append(*results, v1.ScrapeResult{ Type: v1.AWSEC2VPC, Labels: labels, @@ -525,8 +530,7 @@ func (aws Scraper) vpcs(ctx *AWSContext, config v1.AWS, results *v1.ScrapeResult ParentExternalID: lo.FromPtr(ctx.Caller.Account), ParentType: v1.AWSAccount, RelationshipResults: relationships, - Status: health.MapAWSStatus(string(vpc.State), health.AWSResourceTypeVPC), - }) + }.WithHealthStatus(resourceHealth)) } } @@ -628,9 +632,10 @@ func (aws Scraper) instances(ctx *AWSContext, config v1.AWS, results *v1.ScrapeR tags.Append("zone", ctx.Subnets[instance.SubnetID].Zone) tags.Append("region", ctx.Subnets[instance.SubnetID].Region) + resourceHealth := health.GetAWSResourceHealth(health.AWSResourceTypeEC2, string(i.State.Name)) + *results = append(*results, v1.ScrapeResult{ Type: v1.AWSEC2Instance, - Status: health.MapAWSStatus(string(i.State.Name), health.AWSResourceTypeEC2), Labels: labels, BaseScraper: config.BaseScraper, Properties: []*types.Property{getConsoleLink(ctx.Session.Region, v1.AWSEC2Instance, instance.InstanceID)}, @@ -642,7 +647,7 @@ func (aws Scraper) instances(ctx *AWSContext, config v1.AWS, results *v1.ScrapeR ParentExternalID: instance.VpcID, ParentType: v1.AWSEC2VPC, RelationshipResults: relationships, - }) + }.WithHealthStatus(resourceHealth)) } } } @@ -913,6 +918,8 @@ func (aws Scraper) loadBalancers(ctx *AWSContext, config v1.AWS, results *v1.Scr } labels := make(map[string]string) + resourceHealth := health.GetAWSResourceHealth(health.AWSResourceTypeELB, string(lb.State.Code)) + *results = append(*results, v1.ScrapeResult{ Type: v1.AWSLoadBalancerV2, BaseScraper: config.BaseScraper, @@ -928,10 +935,8 @@ func (aws Scraper) loadBalancers(ctx *AWSContext, config v1.AWS, results *v1.Scr ParentExternalID: *lb.VpcId, ParentType: v1.AWSEC2VPC, RelationshipResults: relationships, - Status: health.MapAWSStatus(string(lb.State.Code), health.AWSResourceTypeELB), - }) + }.WithHealthStatus(resourceHealth)) } - } func (aws Scraper) subnets(ctx *AWSContext, config v1.AWS, results *v1.ScrapeResults) { @@ -987,6 +992,8 @@ func (aws Scraper) subnets(ctx *AWSContext, config v1.AWS, results *v1.ScrapeRes Relationship: "AvailabilityZoneIDSubnet", }) + resourceHealth := health.GetAWSResourceHealth(health.AWSResourceTypeSubnet, string(subnet.State)) + result := v1.ScrapeResult{ Type: v1.AWSEC2Subnet, BaseScraper: config.BaseScraper, @@ -997,10 +1004,9 @@ func (aws Scraper) subnets(ctx *AWSContext, config v1.AWS, results *v1.ScrapeRes Config: subnet, ParentExternalID: lo.FromPtr(subnet.VpcId), ParentType: v1.AWSEC2VPC, - Status: health.MapAWSStatus(string(subnet.State), health.AWSResourceTypeSubnet), Properties: []*types.Property{getConsoleLink(ctx.Session.Region, v1.AWSEC2Subnet, lo.FromPtr(subnet.SubnetId))}, RelationshipResults: relationships, - } + }.WithHealthStatus(resourceHealth) *results = append(*results, result) }