From 8d0599b24b8fd44c1efbcbdd58ca0e0c120e2d96 Mon Sep 17 00:00:00 2001 From: Abhinandan Purkait Date: Thu, 9 Nov 2023 14:14:26 +0000 Subject: [PATCH 1/2] feat(event): update ua to ga4 analytics Signed-off-by: Abhinandan Purkait --- go.mod | 4 +- go.sum | 8 +- pkg/driver/controller.go | 15 +-- pkg/usage/googleanalytics.go | 25 +--- pkg/usage/ping.go | 2 +- pkg/usage/usage.go | 254 ++++++++++------------------------- pkg/usage/versionset.go | 61 +++++---- 7 files changed, 123 insertions(+), 246 deletions(-) diff --git a/go.mod b/go.mod index 3ad2015b..f716edb6 100644 --- a/go.mod +++ b/go.mod @@ -5,11 +5,11 @@ go 1.19 require ( github.com/container-storage-interface/spec v1.8.0 github.com/docker/go-units v0.4.0 - github.com/jpillora/go-ogle-analytics v0.0.0-20161213085824-14b04e0594ef github.com/kubernetes-csi/csi-lib-utils v0.9.0 github.com/onsi/ginkgo v1.16.4 github.com/onsi/gomega v1.27.4 - github.com/openebs/lib-csi v0.8.0 + github.com/openebs/go-ogle-analytics v0.1.1-0.20231110084411-b4989b1cee82 + github.com/openebs/lib-csi v0.8.2 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.15.1 github.com/spf13/cobra v1.6.0 diff --git a/go.sum b/go.sum index 70c9817f..bbab6b28 100644 --- a/go.sum +++ b/go.sum @@ -223,8 +223,6 @@ github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7P github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/jpillora/go-ogle-analytics v0.0.0-20161213085824-14b04e0594ef h1:jLpa0vamfyIGeIJ/CfUJEWoKriw4ODeOgF1XxDvgMZ4= -github.com/jpillora/go-ogle-analytics v0.0.0-20161213085824-14b04e0594ef/go.mod h1:PlwhC7q1VSK73InDzdDatVetQrTsQHIbOvcJAZzitY0= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -312,8 +310,10 @@ github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfad github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= -github.com/openebs/lib-csi v0.8.0 h1:lxhv/SRjS7DBz7vTLkaDPd/FJnUftofxSFTU4fdZzW0= -github.com/openebs/lib-csi v0.8.0/go.mod h1:4yc0Q1thH+oU80z73zGELfrOw2yeLdLNIRmcrxBxsBc= +github.com/openebs/go-ogle-analytics v0.1.1-0.20231110084411-b4989b1cee82 h1:aMJHous5CfQ2ieYftSwxZW5ry6+hud9As4I0oJPkK/A= +github.com/openebs/go-ogle-analytics v0.1.1-0.20231110084411-b4989b1cee82/go.mod h1:4xapXO4MRDVgGyUZdCD/5GQkPSwMgoen0f0qayOdW94= +github.com/openebs/lib-csi v0.8.2 h1:HmoiZX3VXFPglwqnRPnRus7K58ixDWBa19OpPZGk2Ws= +github.com/openebs/lib-csi v0.8.2/go.mod h1:4yc0Q1thH+oU80z73zGELfrOw2yeLdLNIRmcrxBxsBc= github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/pkg/driver/controller.go b/pkg/driver/controller.go index 0ce1c8b0..63bc9aca 100644 --- a/pkg/driver/controller.go +++ b/pkg/driver/controller.go @@ -99,12 +99,11 @@ var SupportedVolumeCapabilityAccessModes = []*csi.VolumeCapability_AccessMode{ } // sendEventOrIgnore sends anonymous local-pv provision/delete events -func sendEventOrIgnore(pvcName, pvName, capacity, stgType, method string) { +func sendEventOrIgnore(pvcName, pvName, capacity, method string) { if lvm.GoogleAnalyticsEnabled == "true" { - analytics.New().Build().ApplicationBuilder(). - SetVolumeType(stgType, method). - SetDocumentTitle(pvName). - SetCampaignName(pvcName). + analytics.New().CommonBuild().ApplicationBuilder(). + SetVolumeName(pvName). + SetVolumeClaimName(pvcName). SetLabel(analytics.EventLabelCapacity). SetReplicaCount(analytics.LocalPVReplicaCount, method). SetCategory(method). @@ -232,7 +231,7 @@ func (cs *controller) init() error { go pvcInformer.Informer().Run(stopCh) if lvm.GoogleAnalyticsEnabled == "true" { - analytics.New().Build().InstallBuilder(true).Send() + analytics.New().CommonBuild().InstallBuilder(true).Send() go analytics.PingCheck() } @@ -367,7 +366,7 @@ func (cs *controller) CreateVolume( } sendEventOrIgnore(params.PVCName, volName, strconv.FormatInt(int64(size), 10), - "lvm-localpv", analytics.VolumeProvision) + analytics.VolumeProvision) topology := map[string]string{lvm.LVMTopologyKey: vol.Spec.OwnerNodeID} cntx := map[string]string{lvm.VolGroupKey: vol.Spec.VolGroup, lvm.OpenEBSCasTypeKey: lvm.LVMCasTypeName} @@ -419,7 +418,7 @@ func (cs *controller) deleteVolume(ctx context.Context, volumeID string) error { if err = lvm.WaitForLVMVolumeDestroy(ctx, volumeID); err != nil { return err } - sendEventOrIgnore("", volumeID, vol.Spec.Capacity, "lvm-localpv", analytics.VolumeDeprovision) + sendEventOrIgnore("", volumeID, vol.Spec.Capacity, analytics.VolumeDeprovision) return nil } diff --git a/pkg/usage/googleanalytics.go b/pkg/usage/googleanalytics.go index ad058dbb..596c0ce6 100644 --- a/pkg/usage/googleanalytics.go +++ b/pkg/usage/googleanalytics.go @@ -17,7 +17,6 @@ limitations under the License. package usage import ( - analytics "github.com/jpillora/go-ogle-analytics" "k8s.io/klog/v2" ) @@ -27,26 +26,10 @@ import ( func (u *Usage) Send() { // Instantiate a Gclient with the tracking ID go func() { - // Un-wrap the gaClient struct back here - gaClient, err := analytics.NewClient(u.Gclient.trackID) - if err != nil { - return - } - gaClient.ClientID(u.clientID). - CampaignSource(u.campaignSource). - CampaignContent(u.clientID). - CampaignName(u.campaignName). - ApplicationID(u.appID). - ApplicationVersion(u.appVersion). - DataSource(u.dataSource). - ApplicationName(u.appName). - ApplicationInstallerID(u.appInstallerID). - DocumentTitle(u.documentTitle) - // Un-wrap the Event struct back here - event := analytics.NewEvent(u.category, u.action) - event.Label(u.label) - event.Value(u.value) - if err := gaClient.Send(event); err != nil { + client := u.AnalyticsClient + event := u.OpenebsEventBuilder.Build() + + if err := client.Send(event); err != nil { klog.Errorf(err.Error()) return } diff --git a/pkg/usage/ping.go b/pkg/usage/ping.go index ed73f99f..2026e2e7 100644 --- a/pkg/usage/ping.go +++ b/pkg/usage/ping.go @@ -42,7 +42,7 @@ func PingCheck() { duration := getPingPeriod() ticker := time.NewTicker(duration) for range ticker.C { - u.Build(). + u.CommonBuild(). InstallBuilder(true). SetCategory(Ping). Send() diff --git a/pkg/usage/usage.go b/pkg/usage/usage.go index fcafd352..502ffad7 100644 --- a/pkg/usage/usage.go +++ b/pkg/usage/usage.go @@ -17,221 +17,76 @@ limitations under the License. package usage import ( + "strconv" + + ga4Client "github.com/openebs/go-ogle-analytics/client" + ga4Event "github.com/openebs/go-ogle-analytics/event" k8sapi "github.com/openebs/lib-csi/pkg/client/k8s" ) // Usage struct represents all information about a usage metric sent to // Google Analytics with respect to the application type Usage struct { - // Embedded Event struct as we are currently only sending hits of type - // 'event' - Event - - // https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#an - // use-case: cstor or jiva volume, or m-apiserver application - // Embedded field for application - Application - - // Embedded Gclient struct - Gclient -} + // OpenebsEventBuilder to build the OpenEBSEvent + OpenebsEventBuilder *ga4Event.OpenebsEventBuilder -// Event is a represents usage of OpenEBS -// Event contains all the query param fields when hits is of type='event' -// Ref: https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#ec -type Event struct { - // (Required) Event Category, ec - category string - // (Required) Event Action, ea - action string - // (Optional) Event Label, el - label string - // (Optional) Event vallue, ev - // Non negative - value int64 -} - -// NewEvent returns an Event struct with eventCategory, eventAction, -// eventLabel, eventValue fields -func (u *Usage) NewEvent(c, a, l string, v int64) *Usage { - u.category = c - u.action = a - u.label = l - u.value = v - return u -} - -// Application struct holds details about the Application -type Application struct { - // eg. project version - appVersion string - - // eg. kubernetes version - appInstallerID string - - // Name of the application, usage(OpenEBS/NDM) - appID string - - // eg. usage(os-type/architecture) of system or volume's CASType - appName string -} - -// Gclient struct represents a Google Analytics hit -type Gclient struct { - // constant tracking-id used to send a hit - trackID string - - // anonymous client-id - clientID string - - // anonymous campaign source - campaignSource string - - // anonymous campaign name - campaignName string - - // https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#ds - // (usecase) node-detail - dataSource string - - // Document-title property in Google Analytics - // https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#dt - // use-case: uuid of the volume objects or a uuid to anonymously tell objects apart - documentTitle string + // GA4 Analytics Client + AnalyticsClient *ga4Client.MeasurementClient } // New returns an instance of Usage func New() *Usage { - return &Usage{} -} - -// SetDataSource : usage(os-type, kernel) -func (u *Usage) SetDataSource(dataSource string) *Usage { - u.dataSource = dataSource - return u -} - -// SetTrackingID Sets the GA-code for the project -func (u *Usage) SetTrackingID(track string) *Usage { - u.trackID = track - return u -} - -// SetCampaignSource : source of openebs installater like: -// helm or operator etc. This will have to be configured -// via ENV variable OPENEBS_IO_INSTALLER_TYPE -func (u *Usage) SetCampaignSource(campaignSrc string) *Usage { - u.campaignSource = campaignSrc - return u -} - -// SetDocumentTitle : usecase(anonymous-id) -func (u *Usage) SetDocumentTitle(documentTitle string) *Usage { - u.documentTitle = documentTitle - return u -} - -// SetApplicationName : usecase(os-type/arch, volume CASType) -func (u *Usage) SetApplicationName(appName string) *Usage { - u.appName = appName - return u -} - -// SetCampaignName : set the name of the PVC or will be empty. -func (u *Usage) SetCampaignName(campaignName string) *Usage { - u.campaignName = campaignName - return u -} - -// SetApplicationID : usecase(OpenEBS/NDM) -func (u *Usage) SetApplicationID(appID string) *Usage { - u.appID = appID - return u -} - -// SetApplicationVersion : usecase(project-version) -func (u *Usage) SetApplicationVersion(appVersion string) *Usage { - u.appVersion = appVersion - return u + client, err := ga4Client.NewMeasurementClient( + ga4Client.WithApiSecret("XXXXX"), + ga4Client.WithMeasurementId("G-XXXXXX"), + ) + if err != nil { + return nil + } + openebsEventBuilder := ga4Event.NewOpenebsEventBuilder() + return &Usage{AnalyticsClient: client, OpenebsEventBuilder: openebsEventBuilder} } -// SetApplicationInstallerID : usecase(k8s-version) -func (u *Usage) SetApplicationInstallerID(appInstallerID string) *Usage { - u.appInstallerID = appInstallerID +// SetVolumeName i.e pv name +func (u *Usage) SetVolumeName(name string) *Usage { + u.OpenebsEventBuilder.VolumeName(name) return u } -// SetClientID sets the anonymous user id -func (u *Usage) SetClientID(userID string) *Usage { - u.clientID = userID +// SetVolumeName i.e pvc name +func (u *Usage) SetVolumeClaimName(name string) *Usage { + u.OpenebsEventBuilder.VolumeClaimName(name) return u } // SetCategory sets the category of an event func (u *Usage) SetCategory(c string) *Usage { - u.category = c + u.OpenebsEventBuilder.Category(c) return u } // SetAction sets the action of an event func (u *Usage) SetAction(a string) *Usage { - u.action = a + u.OpenebsEventBuilder.Action(a) return u } // SetLabel sets the label for an event func (u *Usage) SetLabel(l string) *Usage { - u.label = l + u.OpenebsEventBuilder.Label(l) return u } // SetValue sets the value for an event's label -func (u *Usage) SetValue(v int64) *Usage { - u.value = v - return u -} - -// Build is a builder method for Usage struct -func (u *Usage) Build() *Usage { - // Default ApplicationID for openebs project is OpenEBS - v := NewVersion() - _ = v.getVersion(false) - u.SetApplicationID(AppName). - SetTrackingID(GAclientID). - SetClientID(v.id). - SetCampaignSource(v.installerType) - // TODO: Add condition for version over-ride - // Case: CAS/Jiva version, etc - return u -} - -// ApplicationBuilder Application builder is used for adding k8s&openebs environment detail -// for non install events -func (u *Usage) ApplicationBuilder() *Usage { - v := NewVersion() - _ = v.getVersion(false) - u.SetApplicationVersion(v.openebsVersion). - SetApplicationName(v.k8sArch). - SetApplicationInstallerID(v.k8sVersion). - SetDataSource(v.nodeType) +func (u *Usage) SetValue(v string) *Usage { + u.OpenebsEventBuilder.Value(v) return u } // SetVolumeCapacity sets the storage capacity of the volume for a volume event func (u *Usage) SetVolumeCapacity(volCapG string) *Usage { s, _ := toGigaUnits(volCapG) - u.SetValue(s) - return u -} - -// SetVolumeType Wrapper for setting the default storage-engine for volume-provision event -func (u *Usage) SetVolumeType(volType, method string) *Usage { - if method == VolumeProvision && volType == "" { - // Set the default storage engine, if not specified in the request - u.SetApplicationName(DefaultCASType) - } else { - u.SetApplicationName(volType) - } + u.SetValue(strconv.FormatInt(s, 10)) return u } @@ -242,26 +97,59 @@ func (u *Usage) SetReplicaCount(count, method string) *Usage { if method == VolumeProvision && count == "" { // Case: When volume-provision the replica count isn't specified // it is set to three by default by the m-apiserver - u.SetAction(DefaultReplicaCount) + u.OpenebsEventBuilder.Action(DefaultReplicaCount) } else { // Catch all case for volume-deprovision event and // volume-provision event with an overridden replica-count - u.SetAction(Replica + count) + u.OpenebsEventBuilder.Action(Replica + count) } return u } +// CommonBuild is a common builder method for Usage struct +func (u *Usage) CommonBuild() *Usage { + v := NewVersion() + _ = v.getVersion(false) + + u.OpenebsEventBuilder. + Project(AppName). + EngineInstaller(v.installerType). + K8sVersion(v.k8sVersion). + EngineVersion(v.openebsVersion). + EngineInstaller(v.installerType). + EngineName(DefaultCASType). + NodeArch(v.nodeArch). + NodeOs(v.nodeOs). + NodeKernelVersion(v.nodeKernelVersion) + + return u +} + +// ApplicationBuilder Application builder is used for adding k8s&openebs environment detail +// for non install events +func (u *Usage) ApplicationBuilder() *Usage { + v := NewVersion() + _ = v.getVersion(false) + + u.AnalyticsClient.SetClientId(v.id) + u.OpenebsEventBuilder.K8sDefaultNsUid(v.id) + + return u +} + // InstallBuilder is a concrete builder for install events func (u *Usage) InstallBuilder(override bool) *Usage { v := NewVersion() clusterSize, _ := k8sapi.NumberOfNodes() _ = v.getVersion(override) - u.SetApplicationVersion(v.openebsVersion). - SetApplicationName(v.k8sArch). - SetApplicationInstallerID(v.k8sVersion). - SetDataSource(v.nodeType). - SetDocumentTitle(v.id). - SetApplicationID(AppName). - NewEvent(InstallEvent, RunningStatus, EventLabelNode, int64(clusterSize)) + + u.AnalyticsClient.SetClientId(v.id) + u.OpenebsEventBuilder. + K8sDefaultNsUid(v.id). + Category(InstallEvent). + Action(RunningStatus). + Label(EventLabelNode). + Value(strconv.Itoa(clusterSize)) + return u } diff --git a/pkg/usage/versionset.go b/pkg/usage/versionset.go index 0d775878..686c3aa5 100644 --- a/pkg/usage/versionset.go +++ b/pkg/usage/versionset.go @@ -26,23 +26,25 @@ import ( ) var ( - clusterUUID = "OPENEBS_IO_USAGE_UUID" - clusterVersion = "OPENEBS_IO_K8S_VERSION" - clusterArch = "OPENEBS_IO_K8S_ARCH" - openEBSversion = "OPENEBS_IO_VERSION_TAG" - nodeType = "OPENEBS_IO_NODE_TYPE" - installerType = "OPENEBS_IO_INSTALLER_TYPE" + clusterUUID = "OPENEBS_IO_USAGE_UUID" + k8sVersion = "OPENEBS_IO_K8S_VERSION" + nodeArch = "OPENEBS_IO_K8S_ARCH" + openEBSversion = "OPENEBS_IO_VERSION_TAG" + nodeOs = "OPENEBS_IO_NODE_OS" + nodeKernelVersion = "OPENEBS_IO_NODE_KERNEL_VERSION" + installerType = "OPENEBS_IO_INSTALLER_TYPE" ) // VersionSet is a struct which stores (sort of) fixed information about a // k8s environment type VersionSet struct { - id string // OPENEBS_IO_USAGE_UUID - k8sVersion string // OPENEBS_IO_K8S_VERSION - k8sArch string // OPENEBS_IO_K8S_ARCH - openebsVersion string // OPENEBS_IO_VERSION_TAG - nodeType string // OPENEBS_IO_NODE_TYPE - installerType string // OPENEBS_IO_INSTALLER_TYPE + id string // OPENEBS_IO_USAGE_UUID + k8sVersion string // OPENEBS_IO_K8S_VERSION + nodeArch string // OPENEBS_IO_K8S_ARCH + openebsVersion string // OPENEBS_IO_VERSION_TAG + nodeOs string // OPENEBS_IO_NODE_OS + nodeKernelVersion string // OPENEBS_IO_NODE_KERNEL_VERSION + installerType string // OPENEBS_IO_INSTALLER_TYPE } // NewVersion returns a new versionSet struct @@ -53,30 +55,34 @@ func NewVersion() *VersionSet { // fetchAndSetVersion consumes the Kubernetes API to get environment constants // and returns a versionSet struct func (v *VersionSet) fetchAndSetVersion() error { - var err error + var ( + err error + kernelName string + arch string + ) + v.id, err = getUUIDbyNS("default") if err != nil { return err } - _ = env.Set(clusterUUID, v.id) k8s, err := k8sapi.GetServerVersion() if err != nil { return err } - // eg. linux/amd64 - v.k8sArch = k8s.Platform + v.k8sVersion = k8s.GitVersion - // Explicitly informing linters that we intended to avoid errors(errcheck) - _ = env.Set(clusterArch, v.k8sArch) - _ = env.Set(clusterVersion, v.k8sVersion) - v.nodeType, err = k8sapi.GetOSAndKernelVersion() - _ = env.Set(nodeType, v.nodeType) - if err != nil { - return err - } v.openebsVersion = openebsversion.GetVersionDetails() + v.nodeOs, kernelName, v.nodeKernelVersion, arch, _ = k8sapi.GetNodeInfo() + v.nodeArch = kernelName + "/" + arch + + _ = env.Set(clusterUUID, v.id) + _ = env.Set(nodeOs, v.nodeOs) + _ = env.Set(nodeKernelVersion, v.nodeKernelVersion) + _ = env.Set(nodeArch, v.nodeArch) + _ = env.Set(k8sVersion, v.k8sVersion) _ = env.Set(openEBSversion, v.openebsVersion) + return nil } @@ -92,9 +98,10 @@ func (v *VersionSet) getVersion(override bool) error { } // Fetch data from ENV v.id = env.Get(clusterUUID) - v.k8sArch = env.Get(clusterArch) - v.k8sVersion = env.Get(clusterVersion) - v.nodeType = env.Get(nodeType) + v.nodeArch = env.Get(nodeArch) + v.k8sVersion = env.Get(k8sVersion) + v.nodeOs = env.Get(nodeOs) + v.nodeKernelVersion = env.Get(nodeKernelVersion) v.openebsVersion = env.Get(openEBSversion) v.installerType = env.Get(installerType) return nil From d30026693e9bc729519b4d7d91019620e75a18dd Mon Sep 17 00:00:00 2001 From: Abhinandan Purkait Date: Fri, 17 Nov 2023 10:04:07 +0000 Subject: [PATCH 2/2] feat(google-analytics-4): remove the usage and use common usage Signed-off-by: Abhinandan Purkait --- go.mod | 4 +- go.sum | 8 +- pkg/driver/controller.go | 22 +++-- pkg/usage/const.go | 54 ------------ pkg/usage/googleanalytics.go | 37 --------- pkg/usage/ping.go | 66 --------------- pkg/usage/ping_test.go | 56 ------------- pkg/usage/size.go | 27 ------ pkg/usage/size_test.go | 61 -------------- pkg/usage/usage.go | 155 ----------------------------------- pkg/usage/versionset.go | 121 --------------------------- 11 files changed, 23 insertions(+), 588 deletions(-) delete mode 100644 pkg/usage/const.go delete mode 100644 pkg/usage/googleanalytics.go delete mode 100644 pkg/usage/ping.go delete mode 100644 pkg/usage/ping_test.go delete mode 100644 pkg/usage/size.go delete mode 100644 pkg/usage/size_test.go delete mode 100644 pkg/usage/usage.go delete mode 100644 pkg/usage/versionset.go diff --git a/go.mod b/go.mod index f716edb6..11952fd5 100644 --- a/go.mod +++ b/go.mod @@ -4,11 +4,10 @@ go 1.19 require ( github.com/container-storage-interface/spec v1.8.0 - github.com/docker/go-units v0.4.0 github.com/kubernetes-csi/csi-lib-utils v0.9.0 github.com/onsi/ginkgo v1.16.4 github.com/onsi/gomega v1.27.4 - github.com/openebs/go-ogle-analytics v0.1.1-0.20231110084411-b4989b1cee82 + github.com/openebs/google-analytics-4 v0.1.0 github.com/openebs/lib-csi v0.8.2 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.15.1 @@ -32,6 +31,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/emicklei/go-restful/v3 v3.10.2 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect diff --git a/go.sum b/go.sum index bbab6b28..ca2a07cd 100644 --- a/go.sum +++ b/go.sum @@ -71,8 +71,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= @@ -310,8 +310,8 @@ github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfad github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= -github.com/openebs/go-ogle-analytics v0.1.1-0.20231110084411-b4989b1cee82 h1:aMJHous5CfQ2ieYftSwxZW5ry6+hud9As4I0oJPkK/A= -github.com/openebs/go-ogle-analytics v0.1.1-0.20231110084411-b4989b1cee82/go.mod h1:4xapXO4MRDVgGyUZdCD/5GQkPSwMgoen0f0qayOdW94= +github.com/openebs/google-analytics-4 v0.1.0 h1:6aUDbQoh1ezb+NU/MkapFKffogW4QK3WYt8g2UmENe8= +github.com/openebs/google-analytics-4 v0.1.0/go.mod h1:3DkQfGCo79pZhL76Xtg0/R7LNLMttW6Bm/uP0yiZQHU= github.com/openebs/lib-csi v0.8.2 h1:HmoiZX3VXFPglwqnRPnRus7K58ixDWBa19OpPZGk2Ws= github.com/openebs/lib-csi v0.8.2/go.mod h1:4yc0Q1thH+oU80z73zGELfrOw2yeLdLNIRmcrxBxsBc= github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= diff --git a/pkg/driver/controller.go b/pkg/driver/controller.go index 63bc9aca..38b53f39 100644 --- a/pkg/driver/controller.go +++ b/pkg/driver/controller.go @@ -31,6 +31,7 @@ import ( clientset "github.com/openebs/lvm-localpv/pkg/generated/clientset/internalclientset" informers "github.com/openebs/lvm-localpv/pkg/generated/informer/externalversions" + "github.com/openebs/lvm-localpv/pkg/version" "github.com/container-storage-interface/spec/lib/go/csi" "golang.org/x/net/context" @@ -45,12 +46,12 @@ import ( "github.com/openebs/lib-csi/pkg/common/errors" schd "github.com/openebs/lib-csi/pkg/scheduler" + analytics "github.com/openebs/google-analytics-4/usage" lvmapi "github.com/openebs/lvm-localpv/pkg/apis/openebs.io/lvm/v1alpha1" "github.com/openebs/lvm-localpv/pkg/builder/snapbuilder" "github.com/openebs/lvm-localpv/pkg/builder/volbuilder" "github.com/openebs/lvm-localpv/pkg/lvm" csipayload "github.com/openebs/lvm-localpv/pkg/response" - analytics "github.com/openebs/lvm-localpv/pkg/usage" ) // size constants @@ -59,6 +60,16 @@ const ( GB = 1000 * 1000 * 1000 Mi = 1024 * 1024 Gi = 1024 * 1024 * 1024 + + // Ping event is sent periodically + Ping string = "lvm-ping" + + // DefaultCASType Event application name constant for volume event + DefaultCASType string = "lvm-localpv" + + // LocalPVReplicaCount is the constant used by usage to represent + // replication factor in LocalPV + LocalPVReplicaCount string = "1" ) // controller is the server implementation @@ -101,11 +112,11 @@ var SupportedVolumeCapabilityAccessModes = []*csi.VolumeCapability_AccessMode{ // sendEventOrIgnore sends anonymous local-pv provision/delete events func sendEventOrIgnore(pvcName, pvName, capacity, method string) { if lvm.GoogleAnalyticsEnabled == "true" { - analytics.New().CommonBuild().ApplicationBuilder(). + analytics.New().CommonBuild(DefaultCASType).ApplicationBuilder(). SetVolumeName(pvName). SetVolumeClaimName(pvcName). SetLabel(analytics.EventLabelCapacity). - SetReplicaCount(analytics.LocalPVReplicaCount, method). + SetReplicaCount(LocalPVReplicaCount, method). SetCategory(method). SetVolumeCapacity(capacity).Send() } @@ -231,8 +242,9 @@ func (cs *controller) init() error { go pvcInformer.Informer().Run(stopCh) if lvm.GoogleAnalyticsEnabled == "true" { - analytics.New().CommonBuild().InstallBuilder(true).Send() - go analytics.PingCheck() + analytics.RegisterVersionGetter(version.GetVersionDetails) + analytics.New().CommonBuild(DefaultCASType).InstallBuilder(true).Send() + go analytics.PingCheck(DefaultCASType, Ping) } if cs.leakProtection, err = csipv.NewLeakProtectionController(kubeClient, diff --git a/pkg/usage/const.go b/pkg/usage/const.go deleted file mode 100644 index cd9c17a6..00000000 --- a/pkg/usage/const.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright 2020 The OpenEBS Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package usage - -const ( - // GAclientID is the unique code of OpenEBS project in Google Analytics - GAclientID string = "UA-127388617-1" - - // supported events categories - - // InstallEvent event is sent on pod starts - InstallEvent string = "install" - // Ping event is sent periodically - Ping string = "lvm-ping" - // VolumeProvision event is sent when a volume is created - VolumeProvision string = "volume-provision" - // VolumeDeprovision event is sent when a volume is deleted - VolumeDeprovision string = "volume-deprovision" - // AppName the application name - AppName string = "OpenEBS" - - // RunningStatus status is running - RunningStatus string = "running" - // EventLabelNode holds the string label "nodes" - EventLabelNode string = "nodes" - // EventLabelCapacity holds the string label "capacity" - EventLabelCapacity string = "capacity" - - // Replica Event replication - Replica string = "replica:" - // DefaultReplicaCount holds the replica count string - DefaultReplicaCount string = "replica:1" - - // DefaultCASType Event application name constant for volume event - DefaultCASType string = "lvm-localpv" - - // LocalPVReplicaCount is the constant used by usage to represent - // replication factor in LocalPV - LocalPVReplicaCount string = "1" -) diff --git a/pkg/usage/googleanalytics.go b/pkg/usage/googleanalytics.go deleted file mode 100644 index 596c0ce6..00000000 --- a/pkg/usage/googleanalytics.go +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright 2020 The OpenEBS Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package usage - -import ( - "k8s.io/klog/v2" -) - -// Send sends a single usage metric to Google Analytics with some -// compulsory fields defined in Google Analytics API -// bindings(jpillora/go-ogle-analytics) -func (u *Usage) Send() { - // Instantiate a Gclient with the tracking ID - go func() { - client := u.AnalyticsClient - event := u.OpenebsEventBuilder.Build() - - if err := client.Send(event); err != nil { - klog.Errorf(err.Error()) - return - } - }() -} diff --git a/pkg/usage/ping.go b/pkg/usage/ping.go deleted file mode 100644 index 2026e2e7..00000000 --- a/pkg/usage/ping.go +++ /dev/null @@ -1,66 +0,0 @@ -/* -Copyright 2020 The OpenEBS Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package usage - -import ( - "fmt" - "time" - - "github.com/openebs/lib-csi/pkg/common/env" -) - -// OpenEBSPingPeriod ping interval of volume io analytics -var OpenEBSPingPeriod = "OPENEBS_IO_ANALYTICS_PING_INTERVAL" - -const ( - // defaultPingPeriod sets the default ping heartbeat interval - defaultPingPeriod time.Duration = 24 * time.Hour - // minimumPingPeriod sets the minimum possible configurable - // heartbeat period, if a value lower than this will be set, the - // defaultPingPeriod will be used - minimumPingPeriod time.Duration = 1 * time.Hour -) - -// PingCheck sends ping events to Google Analytics -func PingCheck() { - // Create a new usage field - u := New() - duration := getPingPeriod() - ticker := time.NewTicker(duration) - for range ticker.C { - u.CommonBuild(). - InstallBuilder(true). - SetCategory(Ping). - Send() - } -} - -// getPingPeriod sets the duration of health events, defaults to 24 -func getPingPeriod() time.Duration { - value := env.GetOrDefault(OpenEBSPingPeriod, fmt.Sprint(defaultPingPeriod)) - duration, _ := time.ParseDuration(value) - // Sanitychecks for setting time duration of health events - // This way, we are checking for negative and zero time duration and we - // also have a minimum possible configurable time duration between health events - if duration < minimumPingPeriod { - // Avoid corner case when the ENV value is undesirable - return time.Duration(defaultPingPeriod) - } - - return time.Duration(duration) - -} diff --git a/pkg/usage/ping_test.go b/pkg/usage/ping_test.go deleted file mode 100644 index 1d1f3bc5..00000000 --- a/pkg/usage/ping_test.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2020 The OpenEBS Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package usage - -import ( - "os" - "testing" - "time" -) - -func TestGetPingPeriod(t *testing.T) { - beforeFunc := func(value string) { - if err := os.Setenv(string(OpenEBSPingPeriod), value); err != nil { - t.Logf("Unable to set environment variable") - } - } - afterFunc := func() { - if err := os.Unsetenv(string(OpenEBSPingPeriod)); err != nil { - t.Logf("Unable to unset environment variable") - } - } - testSuite := map[string]struct { - OpenEBSPingPeriodValue string - ExpectedPeriodValue time.Duration - }{ - "24 seconds": {"24s", 86400000000000}, - "24 minutes": {"24m", 86400000000000}, - "24 hours": {"24h", 86400000000000}, - "Negative 24 hours": {"-24h", 86400000000000}, - "Random string input": {"Apache", 86400000000000}, - "Two hours": {"2h", 7200000000000}, - "Three hundred hours": {"300h", 1080000000000000}, - "Fifty two seconds": {"52000000000ns", 86400000000000}, - "Empty env value": {"", 86400000000000}, - } - for testKey, testData := range testSuite { - beforeFunc(testData.OpenEBSPingPeriodValue) - evaluatedValue := getPingPeriod() - if evaluatedValue != testData.ExpectedPeriodValue { - t.Fatalf("Tests failed for %s, expected=%d, got=%d", testKey, testData.ExpectedPeriodValue, evaluatedValue) - } - afterFunc() - } -} diff --git a/pkg/usage/size.go b/pkg/usage/size.go deleted file mode 100644 index c435d0d4..00000000 --- a/pkg/usage/size.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 2020 The OpenEBS Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package usage - -import units "github.com/docker/go-units" - -// toGigaUnits converts a size from xB to bytes where x={k,m,g,t,p...} -// and return the number of Gigabytes as an integer -// 1 gigabyte=1000 megabyte -func toGigaUnits(size string) (int64, error) { - sizeInBytes, err := units.FromHumanSize(size) - return sizeInBytes / units.GB, err -} diff --git a/pkg/usage/size_test.go b/pkg/usage/size_test.go deleted file mode 100644 index 23e85634..00000000 --- a/pkg/usage/size_test.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2020 The OpenEBS Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package usage - -import "testing" - -func TestToGigaUnits(t *testing.T) { - tests := map[string]struct { - stringSize string - expectedGsize int64 - positiveTest bool - }{ - "One Hundred Twenty Three thousand Four Hundred Fifty Six Teribytes": { - "123456 TiB", - 123456000, - true, - }, - "One Gibibyte": { - "1 GiB", - 1, - true, - }, - "One Megabyte": { - "1 MB", - 0, // One cannot express <1GB in integer - true, - }, - "One Megabyte negative-case": { - "1 MB", - 1, - false, - // 1 MB isn't 1 GB - }, - "One hundred four point five gigabyte": { - "104.5 GB", - 104, - true, - }, - } - - for testKey, testSuite := range tests { - gotValue, err := toGigaUnits(testSuite.stringSize) - if (gotValue != testSuite.expectedGsize || err != nil) && testSuite.positiveTest { - t.Fatalf("Tests failed for %s, expected=%d, got=%d", testKey, testSuite.expectedGsize, gotValue) - } - } -} diff --git a/pkg/usage/usage.go b/pkg/usage/usage.go deleted file mode 100644 index 502ffad7..00000000 --- a/pkg/usage/usage.go +++ /dev/null @@ -1,155 +0,0 @@ -/* -Copyright 2020 The OpenEBS Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package usage - -import ( - "strconv" - - ga4Client "github.com/openebs/go-ogle-analytics/client" - ga4Event "github.com/openebs/go-ogle-analytics/event" - k8sapi "github.com/openebs/lib-csi/pkg/client/k8s" -) - -// Usage struct represents all information about a usage metric sent to -// Google Analytics with respect to the application -type Usage struct { - // OpenebsEventBuilder to build the OpenEBSEvent - OpenebsEventBuilder *ga4Event.OpenebsEventBuilder - - // GA4 Analytics Client - AnalyticsClient *ga4Client.MeasurementClient -} - -// New returns an instance of Usage -func New() *Usage { - client, err := ga4Client.NewMeasurementClient( - ga4Client.WithApiSecret("XXXXX"), - ga4Client.WithMeasurementId("G-XXXXXX"), - ) - if err != nil { - return nil - } - openebsEventBuilder := ga4Event.NewOpenebsEventBuilder() - return &Usage{AnalyticsClient: client, OpenebsEventBuilder: openebsEventBuilder} -} - -// SetVolumeName i.e pv name -func (u *Usage) SetVolumeName(name string) *Usage { - u.OpenebsEventBuilder.VolumeName(name) - return u -} - -// SetVolumeName i.e pvc name -func (u *Usage) SetVolumeClaimName(name string) *Usage { - u.OpenebsEventBuilder.VolumeClaimName(name) - return u -} - -// SetCategory sets the category of an event -func (u *Usage) SetCategory(c string) *Usage { - u.OpenebsEventBuilder.Category(c) - return u -} - -// SetAction sets the action of an event -func (u *Usage) SetAction(a string) *Usage { - u.OpenebsEventBuilder.Action(a) - return u -} - -// SetLabel sets the label for an event -func (u *Usage) SetLabel(l string) *Usage { - u.OpenebsEventBuilder.Label(l) - return u -} - -// SetValue sets the value for an event's label -func (u *Usage) SetValue(v string) *Usage { - u.OpenebsEventBuilder.Value(v) - return u -} - -// SetVolumeCapacity sets the storage capacity of the volume for a volume event -func (u *Usage) SetVolumeCapacity(volCapG string) *Usage { - s, _ := toGigaUnits(volCapG) - u.SetValue(strconv.FormatInt(s, 10)) - return u -} - -// SetReplicaCount Wrapper for setting replica count for volume events -// NOTE: This doesn't get the replica count in a volume de-provision event. -// TODO: Pick the current value of replica-count from the CAS-engine -func (u *Usage) SetReplicaCount(count, method string) *Usage { - if method == VolumeProvision && count == "" { - // Case: When volume-provision the replica count isn't specified - // it is set to three by default by the m-apiserver - u.OpenebsEventBuilder.Action(DefaultReplicaCount) - } else { - // Catch all case for volume-deprovision event and - // volume-provision event with an overridden replica-count - u.OpenebsEventBuilder.Action(Replica + count) - } - return u -} - -// CommonBuild is a common builder method for Usage struct -func (u *Usage) CommonBuild() *Usage { - v := NewVersion() - _ = v.getVersion(false) - - u.OpenebsEventBuilder. - Project(AppName). - EngineInstaller(v.installerType). - K8sVersion(v.k8sVersion). - EngineVersion(v.openebsVersion). - EngineInstaller(v.installerType). - EngineName(DefaultCASType). - NodeArch(v.nodeArch). - NodeOs(v.nodeOs). - NodeKernelVersion(v.nodeKernelVersion) - - return u -} - -// ApplicationBuilder Application builder is used for adding k8s&openebs environment detail -// for non install events -func (u *Usage) ApplicationBuilder() *Usage { - v := NewVersion() - _ = v.getVersion(false) - - u.AnalyticsClient.SetClientId(v.id) - u.OpenebsEventBuilder.K8sDefaultNsUid(v.id) - - return u -} - -// InstallBuilder is a concrete builder for install events -func (u *Usage) InstallBuilder(override bool) *Usage { - v := NewVersion() - clusterSize, _ := k8sapi.NumberOfNodes() - _ = v.getVersion(override) - - u.AnalyticsClient.SetClientId(v.id) - u.OpenebsEventBuilder. - K8sDefaultNsUid(v.id). - Category(InstallEvent). - Action(RunningStatus). - Label(EventLabelNode). - Value(strconv.Itoa(clusterSize)) - - return u -} diff --git a/pkg/usage/versionset.go b/pkg/usage/versionset.go deleted file mode 100644 index 686c3aa5..00000000 --- a/pkg/usage/versionset.go +++ /dev/null @@ -1,121 +0,0 @@ -/* -Copyright 2020 The OpenEBS Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package usage - -import ( - k8sapi "github.com/openebs/lib-csi/pkg/client/k8s" - "github.com/openebs/lib-csi/pkg/common/env" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/klog/v2" - - openebsversion "github.com/openebs/lvm-localpv/pkg/version" -) - -var ( - clusterUUID = "OPENEBS_IO_USAGE_UUID" - k8sVersion = "OPENEBS_IO_K8S_VERSION" - nodeArch = "OPENEBS_IO_K8S_ARCH" - openEBSversion = "OPENEBS_IO_VERSION_TAG" - nodeOs = "OPENEBS_IO_NODE_OS" - nodeKernelVersion = "OPENEBS_IO_NODE_KERNEL_VERSION" - installerType = "OPENEBS_IO_INSTALLER_TYPE" -) - -// VersionSet is a struct which stores (sort of) fixed information about a -// k8s environment -type VersionSet struct { - id string // OPENEBS_IO_USAGE_UUID - k8sVersion string // OPENEBS_IO_K8S_VERSION - nodeArch string // OPENEBS_IO_K8S_ARCH - openebsVersion string // OPENEBS_IO_VERSION_TAG - nodeOs string // OPENEBS_IO_NODE_OS - nodeKernelVersion string // OPENEBS_IO_NODE_KERNEL_VERSION - installerType string // OPENEBS_IO_INSTALLER_TYPE -} - -// NewVersion returns a new versionSet struct -func NewVersion() *VersionSet { - return &VersionSet{} -} - -// fetchAndSetVersion consumes the Kubernetes API to get environment constants -// and returns a versionSet struct -func (v *VersionSet) fetchAndSetVersion() error { - var ( - err error - kernelName string - arch string - ) - - v.id, err = getUUIDbyNS("default") - if err != nil { - return err - } - - k8s, err := k8sapi.GetServerVersion() - if err != nil { - return err - } - - v.k8sVersion = k8s.GitVersion - v.openebsVersion = openebsversion.GetVersionDetails() - v.nodeOs, kernelName, v.nodeKernelVersion, arch, _ = k8sapi.GetNodeInfo() - v.nodeArch = kernelName + "/" + arch - - _ = env.Set(clusterUUID, v.id) - _ = env.Set(nodeOs, v.nodeOs) - _ = env.Set(nodeKernelVersion, v.nodeKernelVersion) - _ = env.Set(nodeArch, v.nodeArch) - _ = env.Set(k8sVersion, v.k8sVersion) - _ = env.Set(openEBSversion, v.openebsVersion) - - return nil -} - -// getVersion is a wrapper over fetchAndSetVersion -func (v *VersionSet) getVersion(override bool) error { - // If ENVs aren't set or the override is true, fetch the required - // values from the K8s APIserver - if _, present := env.Lookup(openEBSversion); !present || override { - if err := v.fetchAndSetVersion(); err != nil { - klog.Error(err.Error()) - return err - } - } - // Fetch data from ENV - v.id = env.Get(clusterUUID) - v.nodeArch = env.Get(nodeArch) - v.k8sVersion = env.Get(k8sVersion) - v.nodeOs = env.Get(nodeOs) - v.nodeKernelVersion = env.Get(nodeKernelVersion) - v.openebsVersion = env.Get(openEBSversion) - v.installerType = env.Get(installerType) - return nil -} - -// getUUIDbyNS returns the metadata.object.uid of a namespace in Kubernetes -func getUUIDbyNS(namespace string) (string, error) { - ns := k8sapi.Namespace() - NSstruct, err := ns.Get(namespace, metav1.GetOptions{}) - if err != nil { - return "", err - } - if NSstruct != nil { - return string(NSstruct.GetObjectMeta().GetUID()), nil - } - return "", nil -}