Skip to content

Commit 0bce606

Browse files
feloyrm3l
andauthored
Set platform and platformVersion in telemetry (#6540)
* Set platform and platformVersion in telemetry * Vendor oc config client * Get OC version * Integration tests for odo dev * Integration tests for odo deploy * Update doc * Apply suggestions from code review Co-authored-by: Armel Soro <[email protected]> * Add integration test on odo init * Fix OC version when no complete version status --------- Co-authored-by: Armel Soro <[email protected]>
1 parent 34ecccd commit 0bce606

File tree

87 files changed

+19051
-8
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+19051
-8
lines changed

Diff for: USAGE_DATA.md

+7-6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ If the user has consented to `odo` collecting usage data, the following data wil
1111
* Command Success
1212
* Pseudonymized error message and error type (in case of failure)
1313
* Whether the command was run from a terminal
14+
* Whether the command was run in experimental mode
1415
* `odo` version in use
1516

1617
In addition to this, the following data about user's identity is also noted -
@@ -22,12 +23,12 @@ The following tables describe the additional information collected by `odo` comm
2223

2324
**odo v3**
2425

25-
| Command | Data |
26-
|-----------------------------------|-------------------------------------------------------------------------------|
27-
| odo init | Component Type, Devfile Name, Language, Project Type, Interactive Mode (bool) |
28-
| odo dev | Component Type, Devfile Name, Language, Project Type |
29-
| odo deploy | Component Type, Devfile Name, Language, Project Type |
30-
| odo <create/set/delete> namespace | Cluster Type (Possible values: OpenShift 3, OpenShift 4, Kubernetes) |
26+
| Command | Data |
27+
|-----------------------------------|-----------------------------------------------------------------------------------------------------------------|
28+
| odo init | Component Type, Devfile Name, Language, Project Type, Interactive Mode (bool) |
29+
| odo dev | Component Type, Devfile Name, Language, Project Type, Platform (podman, kubernetes, openshift), Platform version|
30+
| odo deploy | Component Type, Devfile Name, Language, Project Type, Platform (kubernetes, openshift), Platform version |
31+
| odo <create/set/delete> namespace | Cluster Type (Possible values: OpenShift 3, OpenShift 4, Kubernetes) |
3132

3233
**odo v2**
3334

Diff for: pkg/kclient/interface.go

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ type ClientInterface interface {
8989

9090
// oc_server.go
9191
GetServerVersion(timeout time.Duration) (*ServerInfo, error)
92+
GetOCVersion() (string, error)
9293

9394
// operators.go
9495
IsCSVSupported() (bool, error)

Diff for: pkg/kclient/kclient.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222

2323
// api clientsets
2424
servicecatalogclienset "github.com/kubernetes-sigs/service-catalog/pkg/client/clientset_generated/clientset/typed/servicecatalog/v1beta1"
25+
configclientset "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
2526
projectclientset "github.com/openshift/client-go/project/clientset/versioned/typed/project/v1"
2627
routeclientset "github.com/openshift/client-go/route/clientset/versioned/typed/route/v1"
2728
userclientset "github.com/openshift/client-go/user/clientset/versioned/typed/user/v1"
@@ -73,6 +74,7 @@ type Client struct {
7374
userClient userclientset.UserV1Interface
7475
projectClient projectclientset.ProjectV1Interface
7576
routeClient routeclientset.RouteV1Interface
77+
configClient *configclientset.ConfigV1Client
7678
}
7779

7880
var _ ClientInterface = (*Client)(nil)
@@ -187,7 +189,10 @@ func NewForConfig(config clientcmd.ClientConfig) (client *Client, err error) {
187189
if err != nil {
188190
return nil, err
189191
}
190-
192+
client.configClient, err = configclientset.NewForConfig(client.KubeClientConfig)
193+
if err != nil {
194+
return nil, err
195+
}
191196
return client, nil
192197
}
193198

Diff for: pkg/kclient/mock_Client.go

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: pkg/kclient/oc_server.go

+26
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import (
99
"time"
1010

1111
dfutil "github.com/devfile/library/v2/pkg/util"
12+
configv1 "github.com/openshift/api/config/v1"
13+
kerrors "k8s.io/apimachinery/pkg/api/errors"
14+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1215
"k8s.io/apimachinery/pkg/version"
1316
"k8s.io/klog"
1417
)
@@ -82,3 +85,26 @@ func (c *Client) GetServerVersion(timeout time.Duration) (*ServerInfo, error) {
8285

8386
return &info, nil
8487
}
88+
89+
func (c *Client) GetOCVersion() (string, error) {
90+
clusterVersion, err := c.configClient.ClusterVersions().Get(context.TODO(), "version", metav1.GetOptions{})
91+
if err != nil {
92+
return "", err
93+
}
94+
switch {
95+
case kerrors.IsForbidden(err), kerrors.IsNotFound(err):
96+
return "", err
97+
}
98+
if clusterVersion != nil {
99+
if len(clusterVersion.Status.History) == 1 {
100+
return clusterVersion.Status.History[0].Version, nil
101+
}
102+
for _, update := range clusterVersion.Status.History {
103+
if update.State == configv1.CompletedUpdate {
104+
// obtain the version from the last completed update
105+
return update.Version, nil
106+
}
107+
}
108+
}
109+
return "", errors.New("unable to get OC version")
110+
}

Diff for: pkg/odo/cli/deploy/deploy.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ func (o *DeployOptions) PreInit() string {
5252

5353
// Complete DeployOptions after they've been created
5454
func (o *DeployOptions) Complete(ctx context.Context, cmdline cmdline.Cmdline, args []string) (err error) {
55+
scontext.SetPlatform(ctx, o.clientset.KubernetesClient)
5556
return nil
5657
}
5758

@@ -104,7 +105,7 @@ func NewCmdDeploy(name, fullName string) *cobra.Command {
104105
return genericclioptions.GenericRun(o, cmd, args)
105106
},
106107
}
107-
clientset.Add(deployCmd, clientset.INIT, clientset.DEPLOY, clientset.FILESYSTEM)
108+
clientset.Add(deployCmd, clientset.INIT, clientset.DEPLOY, clientset.FILESYSTEM, clientset.KUBERNETES)
108109

109110
// Add a defined annotation in order to appear in the help menu
110111
util.SetCommandGroup(deployCmd, util.MainGroup)

Diff for: pkg/odo/cli/dev/dev.go

+2
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,12 @@ func (o *DevOptions) Validate(ctx context.Context) error {
107107
if o.clientset.KubernetesClient == nil {
108108
return errors.New("no connection to cluster defined")
109109
}
110+
scontext.SetPlatform(ctx, o.clientset.KubernetesClient)
110111
case commonflags.PlatformPodman:
111112
if o.clientset.PodmanClient == nil {
112113
return errors.New("unable to access podman. Do you have podman client installed?")
113114
}
115+
scontext.SetPlatform(ctx, o.clientset.PodmanClient)
114116
}
115117
return nil
116118
}

Diff for: pkg/podman/interface.go

+2
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,6 @@ type Client interface {
5353
GetRunningPodFromSelector(selector string) (*corev1.Pod, error)
5454

5555
ListAllComponents() ([]api.ComponentAbstract, error)
56+
57+
Version() (SystemVersionReport, error)
5658
}

Diff for: pkg/podman/mock.go

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: pkg/segment/context/context.go

+60
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@ import (
66
"os"
77
"strings"
88
"sync"
9+
"time"
910

1011
"github.com/spf13/pflag"
1112

1213
"github.com/redhat-developer/odo/pkg/kclient"
14+
"github.com/redhat-developer/odo/pkg/platform"
15+
"github.com/redhat-developer/odo/pkg/podman"
1316

1417
dfutil "github.com/devfile/library/v2/pkg/util"
1518

@@ -28,6 +31,8 @@ const (
2831
InteractiveMode = "interactive"
2932
ExperimentalMode = "experimental"
3033
Flags = "flags"
34+
Platform = "platform"
35+
PlatformVersion = "platformVersion"
3136
)
3237

3338
const (
@@ -98,6 +103,61 @@ func SetClusterType(ctx context.Context, client kclient.ClientInterface) {
98103
setContextProperty(ctx, ClusterType, value)
99104
}
100105

106+
// SetPlatform sets platform and platform_version properties for telemetry data
107+
func SetPlatform(ctx context.Context, client platform.Client) {
108+
switch client := client.(type) {
109+
case kclient.ClientInterface:
110+
setPlatformCluster(ctx, client)
111+
case podman.Client:
112+
setPlatformPodman(ctx, client)
113+
}
114+
}
115+
116+
func setPlatformCluster(ctx context.Context, client kclient.ClientInterface) {
117+
var value string
118+
if client == nil {
119+
value = NOTFOUND
120+
} else {
121+
// We are not checking ServerVersion to decide the cluster type because it does not always return the version,
122+
// it sometimes fails to retrieve the data if user is using minishift or plain oc cluster
123+
124+
isOC, err := client.IsProjectSupported()
125+
if err != nil {
126+
klog.V(3).Info(fmt.Errorf("unable to detect project support: %w", err))
127+
value = NOTFOUND
128+
} else {
129+
if isOC {
130+
value = "openshift"
131+
ocVersion, err := client.GetOCVersion()
132+
if err == nil {
133+
setContextProperty(ctx, PlatformVersion, ocVersion)
134+
} else {
135+
klog.V(3).Info(fmt.Errorf("unable to detect platform version: %w", err))
136+
}
137+
} else {
138+
value = "kubernetes"
139+
serverInfo, err := client.GetServerVersion(time.Second)
140+
if err == nil {
141+
setContextProperty(ctx, PlatformVersion, serverInfo.KubernetesVersion)
142+
} else {
143+
klog.V(3).Info(fmt.Errorf("unable to detect platform version: %w", err))
144+
}
145+
}
146+
}
147+
}
148+
setContextProperty(ctx, Platform, value)
149+
}
150+
151+
func setPlatformPodman(ctx context.Context, client podman.Client) {
152+
setContextProperty(ctx, Platform, "podman")
153+
version, err := client.Version()
154+
if err != nil {
155+
klog.V(3).Info(fmt.Errorf("unable to get podman version: %w", err))
156+
return
157+
}
158+
setContextProperty(ctx, PlatformVersion, version.Client.Version)
159+
}
160+
101161
// SetTelemetryStatus sets telemetry status before a command is run
102162
func SetTelemetryStatus(ctx context.Context, isEnabled bool) {
103163
setContextProperty(ctx, TelemetryStatus, isEnabled)

Diff for: tests/integration/cmd_dev_test.go

+8
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,14 @@ var _ = Describe("odo dev command tests", func() {
241241
experimentalValue = true
242242
}
243243
Expect(td.Properties.CmdProperties[segment.ExperimentalMode]).To(Equal(experimentalValue))
244+
if podman {
245+
Expect(td.Properties.CmdProperties[segment.Platform]).To(Equal("podman"))
246+
} else if os.Getenv("KUBERNETES") == "true" {
247+
Expect(td.Properties.CmdProperties[segment.Platform]).To(Equal("kubernetes"))
248+
} else {
249+
Expect(td.Properties.CmdProperties[segment.Platform]).To(Equal("openshift"))
250+
}
251+
Expect(td.Properties.CmdProperties[segment.PlatformVersion]).ToNot(BeEmpty())
244252
})
245253
}))
246254

Diff for: tests/integration/cmd_devfile_deploy_test.go

+7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"net/http"
66
"net/http/httptest"
7+
"os"
78
"path"
89
"path/filepath"
910
"regexp"
@@ -221,6 +222,12 @@ ComponentSettings:
221222
Expect(td.Properties.CmdProperties).Should(HaveKey(segment.Caller))
222223
Expect(td.Properties.CmdProperties[segment.Caller]).To(BeEmpty())
223224
Expect(td.Properties.CmdProperties[segment.ExperimentalMode]).To(Equal(false))
225+
if os.Getenv("KUBERNETES") == "true" {
226+
Expect(td.Properties.CmdProperties[segment.Platform]).To(Equal("kubernetes"))
227+
} else {
228+
Expect(td.Properties.CmdProperties[segment.Platform]).To(Equal("openshift"))
229+
}
230+
Expect(td.Properties.CmdProperties[segment.PlatformVersion]).ToNot(BeEmpty())
224231
})
225232
})
226233

Diff for: tests/integration/cmd_devfile_init_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,8 @@ var _ = Describe("odo devfile init command tests", func() {
567567
Expect(td.Properties.CmdProperties[segmentContext.Language]).To(ContainSubstring("Go"))
568568
Expect(td.Properties.CmdProperties[segmentContext.ProjectType]).To(ContainSubstring("Go"))
569569
Expect(td.Properties.CmdProperties[segmentContext.Flags]).To(ContainSubstring("devfile name"))
570+
Expect(td.Properties.CmdProperties[segmentContext.Platform]).To(BeNil())
571+
Expect(td.Properties.CmdProperties[segmentContext.PlatformVersion]).To(BeNil())
570572
tt.callerChecker(stdout, stderr, td)
571573
})
572574

0 commit comments

Comments
 (0)