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

Leverage the inventory control stream to report updater metrics #38654

Merged
merged 4 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 27 additions & 17 deletions lib/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -1265,7 +1265,6 @@ func (a *Server) doInstancePeriodics(ctx context.Context) {
skipControlPlane := modules.GetModules().Features().Cloud

// set up aggregators for our periodics
imp := newInstanceMetricsPeriodic()
uep := newUpgradeEnrollPeriodic()

// stream all instances to all aggregators
Expand All @@ -1278,7 +1277,6 @@ func (a *Server) doInstancePeriodics(ctx context.Context) {
}
}

imp.VisitInstance(instances.Item())
uep.VisitInstance(instances.Item())
}

Expand All @@ -1287,21 +1285,7 @@ func (a *Server) doInstancePeriodics(ctx context.Context) {
return
}

// set instance metric values
totalInstancesMetric.Set(float64(imp.TotalInstances()))
enrolledInUpgradesMetric.Set(float64(imp.TotalEnrolledInUpgrades()))

// reset upgrader counts
upgraderCountsMetric.Reset()

for upgraderType, upgraderVersions := range imp.upgraderCounts {
for version, count := range upgraderVersions {
upgraderCountsMetric.With(prometheus.Labels{
teleport.TagUpgrader: upgraderType,
teleport.TagVersion: version,
}).Set(float64(count))
}
}
a.updateUpdaterVersionMetrics()

// create/delete upgrade enroll prompt as appropriate
enrollMsg, shouldPrompt := uep.GenerateEnrollPrompt()
Expand Down Expand Up @@ -1488,6 +1472,32 @@ func (a *Server) doReleaseAlertSync(ctx context.Context, current vc.Target, visi
}
}

// updateUpdaterVersionMetrics leverages the inventory control stream to report the
// number of teleport updaters installed and their versions. To get an accurate representation
// of versions in an entire cluster the metric must be aggregated with all auth instances.
func (a *Server) updateUpdaterVersionMetrics() {
imp := newInstanceMetricsPeriodic()

// record versions for all connected resources
a.inventory.Iter(func(handle inventory.UpstreamHandle) {
imp.VisitInstance(handle.Hello())
})

totalInstancesMetric.Set(float64(imp.TotalInstances()))
enrolledInUpgradesMetric.Set(float64(imp.TotalEnrolledInUpgrades()))

// reset the gauges so that any versions that fall off are removed from exported metrics
upgraderCountsMetric.Reset()
for upgraderType, upgraderVersions := range imp.upgraderCounts {
for version, count := range upgraderVersions {
upgraderCountsMetric.With(prometheus.Labels{
teleport.TagUpgrader: upgraderType,
teleport.TagVersion: version,
}).Set(float64(count))
}
}
}

// updateVersionMetrics leverages the inventory control stream to report the versions of
// all instances that are connected to a single auth server via prometheus metrics. To
// get an accurate representation of versions in an entire cluster the metric must be aggregated
Expand Down
3 changes: 2 additions & 1 deletion lib/auth/periodic.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

"golang.org/x/mod/semver"

"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/types"
vc "github.com/gravitational/teleport/lib/versioncontrol"
)
Expand Down Expand Up @@ -114,7 +115,7 @@ func newInstanceMetricsPeriodic() *instanceMetricsPeriodic {
}

// VisitInstance adds an instance to ongoing aggregations.
func (i *instanceMetricsPeriodic) VisitInstance(instance types.Instance) {
func (i *instanceMetricsPeriodic) VisitInstance(instance proto.UpstreamInventoryHello) {
i.totalInstances++
if upgrader := instance.GetExternalUpgrader(); upgrader != "" {
if _, exists := i.upgraderCounts[upgrader]; !exists {
Expand Down
16 changes: 7 additions & 9 deletions lib/auth/periodic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,21 @@ import (
"github.com/google/uuid"
"github.com/stretchr/testify/require"

"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/types"
)

func TestInstanceMetricsPeriodic(t *testing.T) {
tts := []struct {
desc string
specs []types.InstanceSpecV1
instances []proto.UpstreamInventoryHello
expectedCounts map[string]map[string]int
upgraders []string
expectEnrolled int
}{
{
desc: "mixed",
specs: []types.InstanceSpecV1{
instances: []proto.UpstreamInventoryHello{
{ExternalUpgrader: "kube", ExternalUpgraderVersion: "13.0.0"},
{ExternalUpgrader: "kube", ExternalUpgraderVersion: "14.0.0"},
{ExternalUpgrader: "unit", ExternalUpgraderVersion: "13.0.0"},
Expand Down Expand Up @@ -68,7 +69,7 @@ func TestInstanceMetricsPeriodic(t *testing.T) {
},
{
desc: "all-unenrolled",
specs: []types.InstanceSpecV1{
instances: []proto.UpstreamInventoryHello{
{},
{},
},
Expand All @@ -80,7 +81,7 @@ func TestInstanceMetricsPeriodic(t *testing.T) {
},
{
desc: "all-enrolled",
specs: []types.InstanceSpecV1{
instances: []proto.UpstreamInventoryHello{
{ExternalUpgrader: "kube", ExternalUpgraderVersion: "13.0.0"},
{ExternalUpgrader: "kube", ExternalUpgraderVersion: "13.0.0"},
{ExternalUpgrader: "unit", ExternalUpgraderVersion: "13.0.0"},
Expand All @@ -104,7 +105,7 @@ func TestInstanceMetricsPeriodic(t *testing.T) {
},
{
desc: "nil version",
specs: []types.InstanceSpecV1{
instances: []proto.UpstreamInventoryHello{
{ExternalUpgrader: "kube"},
{ExternalUpgrader: "unit"},
},
Expand Down Expand Up @@ -132,10 +133,7 @@ func TestInstanceMetricsPeriodic(t *testing.T) {
t.Run(tt.desc, func(t *testing.T) {
periodic := newInstanceMetricsPeriodic()

for _, upgrader := range tt.specs {
instance, err := types.NewInstance(uuid.New().String(), upgrader)
require.NoError(t, err)

for _, instance := range tt.instances {
periodic.VisitInstance(instance)
}

Expand Down
Loading