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

Set platform and platformVersion in telemetry #6540

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
13 changes: 7 additions & 6 deletions USAGE_DATA.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ If the user has consented to `odo` collecting usage data, the following data wil
* Command Success
* Pseudonymized error message and error type (in case of failure)
* Whether the command was run from a terminal
* Whether the command was run in experimental mode
* `odo` version in use

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

**odo v3**

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

**odo v2**

Expand Down
1 change: 1 addition & 0 deletions pkg/kclient/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ type ClientInterface interface {

// oc_server.go
GetServerVersion(timeout time.Duration) (*ServerInfo, error)
GetOCVersion() (string, error)

// operators.go
IsCSVSupported() (bool, error)
Expand Down
7 changes: 6 additions & 1 deletion pkg/kclient/kclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

// api clientsets
servicecatalogclienset "github.com/kubernetes-sigs/service-catalog/pkg/client/clientset_generated/clientset/typed/servicecatalog/v1beta1"
configclientset "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
projectclientset "github.com/openshift/client-go/project/clientset/versioned/typed/project/v1"
routeclientset "github.com/openshift/client-go/route/clientset/versioned/typed/route/v1"
userclientset "github.com/openshift/client-go/user/clientset/versioned/typed/user/v1"
Expand Down Expand Up @@ -73,6 +74,7 @@ type Client struct {
userClient userclientset.UserV1Interface
projectClient projectclientset.ProjectV1Interface
routeClient routeclientset.RouteV1Interface
configClient *configclientset.ConfigV1Client
}

var _ ClientInterface = (*Client)(nil)
Expand Down Expand Up @@ -187,7 +189,10 @@ func NewForConfig(config clientcmd.ClientConfig) (client *Client, err error) {
if err != nil {
return nil, err
}

client.configClient, err = configclientset.NewForConfig(client.KubeClientConfig)
if err != nil {
return nil, err
}
return client, nil
}

Expand Down
15 changes: 15 additions & 0 deletions pkg/kclient/mock_Client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions pkg/kclient/oc_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import (
"time"

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

return &info, nil
}

func (c *Client) GetOCVersion() (string, error) {
clusterVersion, err := c.configClient.ClusterVersions().Get(context.TODO(), "version", metav1.GetOptions{})
if err != nil {
return "", err
}
switch {
case kerrors.IsForbidden(err), kerrors.IsNotFound(err):
return "", err
}
if clusterVersion != nil {
if len(clusterVersion.Status.History) == 1 {
return clusterVersion.Status.History[0].Version, nil
}
for _, update := range clusterVersion.Status.History {
if update.State == configv1.CompletedUpdate {
// obtain the version from the last completed update
return update.Version, nil
}
}
}
return "", errors.New("unable to get OC version")
}
3 changes: 2 additions & 1 deletion pkg/odo/cli/deploy/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func (o *DeployOptions) PreInit() string {

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

Expand Down Expand Up @@ -104,7 +105,7 @@ func NewCmdDeploy(name, fullName string) *cobra.Command {
return genericclioptions.GenericRun(o, cmd, args)
},
}
clientset.Add(deployCmd, clientset.INIT, clientset.DEPLOY, clientset.FILESYSTEM)
clientset.Add(deployCmd, clientset.INIT, clientset.DEPLOY, clientset.FILESYSTEM, clientset.KUBERNETES)

// Add a defined annotation in order to appear in the help menu
util.SetCommandGroup(deployCmd, util.MainGroup)
Expand Down
2 changes: 2 additions & 0 deletions pkg/odo/cli/dev/dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,12 @@ func (o *DevOptions) Validate(ctx context.Context) error {
if o.clientset.KubernetesClient == nil {
return errors.New("no connection to cluster defined")
}
scontext.SetPlatform(ctx, o.clientset.KubernetesClient)
case commonflags.PlatformPodman:
if o.clientset.PodmanClient == nil {
return errors.New("unable to access podman. Do you have podman client installed?")
}
scontext.SetPlatform(ctx, o.clientset.PodmanClient)
}
return nil
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/podman/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,6 @@ type Client interface {
GetRunningPodFromSelector(selector string) (*corev1.Pod, error)

ListAllComponents() ([]api.ComponentAbstract, error)

Version() (SystemVersionReport, error)
}
15 changes: 15 additions & 0 deletions pkg/podman/mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 60 additions & 0 deletions pkg/segment/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import (
"os"
"strings"
"sync"
"time"

"github.com/spf13/pflag"

"github.com/redhat-developer/odo/pkg/kclient"
"github.com/redhat-developer/odo/pkg/platform"
"github.com/redhat-developer/odo/pkg/podman"

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

Expand All @@ -28,6 +31,8 @@ const (
InteractiveMode = "interactive"
ExperimentalMode = "experimental"
Flags = "flags"
Platform = "platform"
PlatformVersion = "platformVersion"
)

const (
Expand Down Expand Up @@ -98,6 +103,61 @@ func SetClusterType(ctx context.Context, client kclient.ClientInterface) {
setContextProperty(ctx, ClusterType, value)
}

// SetPlatform sets platform and platform_version properties for telemetry data
func SetPlatform(ctx context.Context, client platform.Client) {
switch client := client.(type) {
case kclient.ClientInterface:
setPlatformCluster(ctx, client)
case podman.Client:
setPlatformPodman(ctx, client)
}
}

func setPlatformCluster(ctx context.Context, client kclient.ClientInterface) {
var value string
if client == nil {
value = NOTFOUND
} else {
// We are not checking ServerVersion to decide the cluster type because it does not always return the version,
// it sometimes fails to retrieve the data if user is using minishift or plain oc cluster

isOC, err := client.IsProjectSupported()
if err != nil {
klog.V(3).Info(fmt.Errorf("unable to detect project support: %w", err))
value = NOTFOUND
} else {
if isOC {
value = "openshift"
ocVersion, err := client.GetOCVersion()
if err == nil {
setContextProperty(ctx, PlatformVersion, ocVersion)
} else {
klog.V(3).Info(fmt.Errorf("unable to detect platform version: %w", err))
}
} else {
value = "kubernetes"
serverInfo, err := client.GetServerVersion(time.Second)
if err == nil {
setContextProperty(ctx, PlatformVersion, serverInfo.KubernetesVersion)
} else {
klog.V(3).Info(fmt.Errorf("unable to detect platform version: %w", err))
}
}
}
}
setContextProperty(ctx, Platform, value)
}

func setPlatformPodman(ctx context.Context, client podman.Client) {
setContextProperty(ctx, Platform, "podman")
version, err := client.Version()
if err != nil {
klog.V(3).Info(fmt.Errorf("unable to get podman version: %w", err))
return
}
setContextProperty(ctx, PlatformVersion, version.Client.Version)
}

// SetTelemetryStatus sets telemetry status before a command is run
func SetTelemetryStatus(ctx context.Context, isEnabled bool) {
setContextProperty(ctx, TelemetryStatus, isEnabled)
Expand Down
8 changes: 8 additions & 0 deletions tests/integration/cmd_dev_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,14 @@ var _ = Describe("odo dev command tests", func() {
experimentalValue = true
}
Expect(td.Properties.CmdProperties[segment.ExperimentalMode]).To(Equal(experimentalValue))
if podman {
Expect(td.Properties.CmdProperties[segment.Platform]).To(Equal("podman"))
} else if os.Getenv("KUBERNETES") == "true" {
Expect(td.Properties.CmdProperties[segment.Platform]).To(Equal("kubernetes"))
} else {
Expect(td.Properties.CmdProperties[segment.Platform]).To(Equal("openshift"))
}
Expect(td.Properties.CmdProperties[segment.PlatformVersion]).ToNot(BeEmpty())
})
}))

Expand Down
7 changes: 7 additions & 0 deletions tests/integration/cmd_devfile_deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"net/http"
"net/http/httptest"
"os"
"path"
"path/filepath"
"regexp"
Expand Down Expand Up @@ -221,6 +222,12 @@ ComponentSettings:
Expect(td.Properties.CmdProperties).Should(HaveKey(segment.Caller))
Expect(td.Properties.CmdProperties[segment.Caller]).To(BeEmpty())
Expect(td.Properties.CmdProperties[segment.ExperimentalMode]).To(Equal(false))
if os.Getenv("KUBERNETES") == "true" {
Expect(td.Properties.CmdProperties[segment.Platform]).To(Equal("kubernetes"))
} else {
Expect(td.Properties.CmdProperties[segment.Platform]).To(Equal("openshift"))
}
Expect(td.Properties.CmdProperties[segment.PlatformVersion]).ToNot(BeEmpty())
})
})

Expand Down
2 changes: 2 additions & 0 deletions tests/integration/cmd_devfile_init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,8 @@ var _ = Describe("odo devfile init command tests", func() {
Expect(td.Properties.CmdProperties[segmentContext.Language]).To(ContainSubstring("Go"))
Expect(td.Properties.CmdProperties[segmentContext.ProjectType]).To(ContainSubstring("Go"))
Expect(td.Properties.CmdProperties[segmentContext.Flags]).To(ContainSubstring("devfile name"))
Expect(td.Properties.CmdProperties[segmentContext.Platform]).To(BeNil())
Expect(td.Properties.CmdProperties[segmentContext.PlatformVersion]).To(BeNil())
tt.callerChecker(stdout, stderr, td)
})

Expand Down
Loading