From d043045d12d28283ad2e3255eb9091f62ad19292 Mon Sep 17 00:00:00 2001 From: Petr Vobornik Date: Tue, 24 Oct 2023 13:25:41 +0000 Subject: [PATCH] feat: send conversions_success label when host was converted Read subscription-manager fact `conversions.success`, e.g., `conversions.success: True` and send it as label `conversions_success` with normalized value (lowercased). E.g.: "conversions_success="true". This is to indicate if a host was converted. Signed-off-by: Petr Vobornik --- hostinfo/info.go | 2 ++ hostinfo/info_test.go | 1 + hostinfo/subscription.go | 9 +++++++ hostinfo/subscription_test.go | 5 ++++ notify/prometheus.go | 4 +++ notify/prometheus_test.go | 50 ++++++++++++++++++++++++++++++----- test/bin/subscription-manager | 12 +++++++++ 7 files changed, 77 insertions(+), 6 deletions(-) diff --git a/hostinfo/info.go b/hostinfo/info.go index 7f2186c..fe76e4e 100644 --- a/hostinfo/info.go +++ b/hostinfo/info.go @@ -13,6 +13,7 @@ type HostInfo struct { Product string Support string Usage string + ConversionsSuccess string Billing BillingInfo } @@ -63,6 +64,7 @@ func (hi *HostInfo) String() string { fmt.Sprintf(" Product: %s", hi.Product), fmt.Sprintf(" Support: %s", hi.Support), fmt.Sprintf(" Usage: %s", hi.Usage), + fmt.Sprintf(" ConversionsSuccess: %s", hi.ConversionsSuccess), fmt.Sprintf(" Billing.Model: %s", hi.Billing.Model), fmt.Sprintf(" Billing.Marketplace: %s", hi.Billing.Marketplace), fmt.Sprintf(" Billing.MarketplaceAccount: %s", hi.Billing.MarketplaceAccount), diff --git a/hostinfo/info_test.go b/hostinfo/info_test.go index a1fcc17..323e090 100644 --- a/hostinfo/info_test.go +++ b/hostinfo/info_test.go @@ -28,6 +28,7 @@ func TestHostInfo(t *testing.T) { " Product: Red Hat Enterprise Linux Server\n" + " Support: Premium\n" + " Usage: Production\n" + + " ConversionsSuccess: true\n" + " Billing.Model: marketplace\n" + " Billing.Marketplace: aws\n" + " Billing.MarketplaceAccount: 000000000000\n" + diff --git a/hostinfo/subscription.go b/hostinfo/subscription.go index fc8e6e8..faa83fc 100644 --- a/hostinfo/subscription.go +++ b/hostinfo/subscription.go @@ -19,6 +19,7 @@ func LoadSubManInformation(hi *HostInfo) { facts, _ := GetSubManFacts() hi.SocketCount, _ = GetSocketCount(facts) hi.Product, _ = GetProduct(facts) + hi.ConversionsSuccess, _ = GetConversionsSuccess(facts) hi.Billing, _ = GetBillingInfo(facts) } @@ -59,6 +60,14 @@ func GetProduct(facts SubManValues) (string, error) { return facts.get("distribution.name") } +func GetConversionsSuccess(facts SubManValues) (string, error) { + value, err := facts.get("conversions.success") + if err == nil { + value = strings.ToLower(value) + } + return value, err +} + func GetBillingInfo(facts SubManValues) (BillingInfo, error) { bi := BillingInfo{ Model: "marketplace", diff --git a/hostinfo/subscription_test.go b/hostinfo/subscription_test.go index df3e372..e9fcc0e 100644 --- a/hostinfo/subscription_test.go +++ b/hostinfo/subscription_test.go @@ -13,6 +13,7 @@ func TestLoadSubManInformation(t *testing.T) { Product: "Red Hat Enterprise Linux Server", Support: "Premium", Usage: "Production", + ConversionsSuccess: "true", } // Test the host info for AWS. @@ -80,6 +81,10 @@ func compareHostInfo(t *testing.T, hi *HostInfo, expected *HostInfo) { t.Fatalf("an unexpected value of Usage: %v", hi.Usage) } + if hi.ConversionsSuccess != expected.ConversionsSuccess { + t.Fatalf("an unexpected value of ConversionsSuccess: %v", hi.ConversionsSuccess) + } + if hi.Billing.Model != expected.Billing.Model { t.Fatalf("an unexpected value of Model: %v", hi.Billing.Model) } diff --git a/notify/prometheus.go b/notify/prometheus.go index abde181..7f48993 100644 --- a/notify/prometheus.go +++ b/notify/prometheus.go @@ -177,6 +177,10 @@ func hostInfo2WriteRequest(hostinfo *hostinfo.HostInfo, samples []prompb.Sample) Name: "billing_model", Value: hostinfo.Billing.Model, }, + { + Name: "conversions_success", + Value: hostinfo.ConversionsSuccess, + }, { Name: "external_organization", Value: hostinfo.ExternalOrganization, diff --git a/notify/prometheus_test.go b/notify/prometheus_test.go index fc3223a..69a0921 100644 --- a/notify/prometheus_test.go +++ b/notify/prometheus_test.go @@ -280,6 +280,21 @@ func TestLabels(t *testing.T) { // With full host info hi := createHostInfo() createRequestAndCheckLabels(t, samples, hi) + writeRequest := hostInfo2WriteRequest(hi, samples) + checkLabelsPresence(t, writeRequest.Timeseries[0].Labels, []string{ + "__name__", + "_id", + "billing_marketplace", + "billing_marketplace_account", + "billing_marketplace_instance_id", + "billing_model", + "conversions_success", + "external_organization", + "product", + "socket_count", + "support", + "usage", + }) // With host info that is missing some values hi.Billing.MarketplaceAccount = "" @@ -296,6 +311,9 @@ func TestLabels(t *testing.T) { hi.Product = "" hi.Support = "" createRequestAndCheckLabels(t, samples, hi) + + hi.ConversionsSuccess = "" + createRequestAndCheckLabels(t, samples, hi) } func createRequestAndCheckLabels(t *testing.T, samples []prompb.Sample, hostinfo *hostinfo.HostInfo) { @@ -411,6 +429,24 @@ func checkLabels(t *testing.T, labels []prompb.Label) { } } +// Check that labels with expected names are present +func checkLabelsPresence(t *testing.T, labels []prompb.Label, expected_names []string) { + t.Helper() + // Test that labels are present + for _, name := range expected_names { + present := false + for _, label := range labels { + if label.Name == name { + present = true + break + } + } + if !present { + t.Fatalf("Expected %s label to be present", name) + } + } +} + // Data init functions // Test uses tlsInsecureSkipVerify = true, e.g. for mock server with self-signed certificate @@ -432,12 +468,14 @@ func createSamples() []prompb.Sample { // Dummy host info with all fields filled func createHostInfo() *hostinfo.HostInfo { return &hostinfo.HostInfo{ - CpuCount: 1, - HostId: "test", - SocketCount: "1", - Product: "test product", - Support: "test support", - Usage: "test usage", + CpuCount: 1, + HostId: "test", + SocketCount: "1", + Product: "test product", + Support: "test support", + Usage: "test usage", + ConversionsSuccess: "true", + ExternalOrganization: "test external organization", Billing: hostinfo.BillingInfo{ Model: "test model", Marketplace: "test marketplace", diff --git a/test/bin/subscription-manager b/test/bin/subscription-manager index 3b8a76d..a794c24 100755 --- a/test/bin/subscription-manager +++ b/test/bin/subscription-manager @@ -27,6 +27,18 @@ cpu.cpu(s): 8 cpu.cpu_socket(s): 3 cpu.thread(s)_per_core: 2 cpu.topology_source: kernel /sys cpu sibling lists +conversions.activity: conversion +conversions.activity_ended: 2023-10-06T14:32:44.223365Z +conversions.activity_started: 2023-10-06T14:16:45.898768Z +conversions.run_id: null +conversions.source_os.id: Core +conversions.source_os.name: CentOS Linux +conversions.source_os.version: 7.9 +conversions.success: True +conversions.target_os.id: Maipo +conversions.target_os.name: Red Hat Enterprise Linux Server +conversions.target_os.version: 7.9 +conversions.version: 1 distribution.id: Maipo distribution.name: Red Hat Enterprise Linux Server distribution.version: 7.9