Skip to content

Commit 66fbbb1

Browse files
Merge pull request #971 from jhadvig/OCPBUGS-45514_3
OCPBUGS-45514: Report email_domain to telemetry
2 parents 794a129 + a1c51d4 commit 66fbbb1

File tree

3 files changed

+52
-26
lines changed

3 files changed

+52
-26
lines changed

pkg/console/operator/operator.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,9 @@ type consoleOperator struct {
101101
type trackables struct {
102102
// used to keep track of OLM capability
103103
isOLMDisabled bool
104-
// track organization ID
104+
// track organization ID and mail
105105
organizationID string
106+
accountMail string
106107
}
107108

108109
func NewConsoleOperator(
@@ -208,6 +209,13 @@ func NewConsoleOperator(
208209
Resource: api.OLMConfigResource,
209210
}
210211

212+
// set default values for trackables
213+
c.trackables = trackables{
214+
isOLMDisabled: false,
215+
organizationID: "",
216+
accountMail: "",
217+
}
218+
211219
if found, _ := isResourceEnabled(dynamicClient, olmGroupVersionResource); found {
212220
olmConfigInformer := dynamicInformers.ForResource(olmGroupVersionResource)
213221
informers = append(informers, olmConfigInformer.Informer())

pkg/console/operator/sync_v400.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ func (co *consoleOperator) SyncConfigMap(
438438
// 2. get telemetry annotation from console-operator config
439439
// 3. get default telemetry value from telemetry-config configmap
440440
// 4. get CLUSTER_ID from the cluster-version config
441-
// 5. get ORGANIZATION_ID from OCM, if ORGANIZATION_ID is not already set
441+
// 5. get ORGANIZATION_ID and ACCOUNT_MAIL from OCM, if they are not already set
442442
func (co *consoleOperator) GetTelemetryConfiguration(ctx context.Context, operatorConfig *operatorv1.Console) (map[string]string, error) {
443443
telemetryConfig := make(map[string]string)
444444

@@ -480,12 +480,14 @@ func (co *consoleOperator) GetTelemetryConfiguration(ctx context.Context, operat
480480
if err != nil {
481481
return nil, err
482482
}
483-
organizationID, refreshCache := telemetry.GetOrganizationID(telemetryConfig, co.trackables.organizationID, clusterID, accessToken)
484-
// cache fetched ORGANIZATION_ID
483+
organizationID, accountMail, refreshCache := telemetry.GetOrganizationMeta(telemetryConfig, co.trackables.organizationID, co.trackables.accountMail, clusterID, accessToken)
484+
// cache fetched ORGANIZATION_ID and ACCOUNT_MAIL
485485
if refreshCache {
486486
co.trackables.organizationID = organizationID
487+
co.trackables.accountMail = accountMail
487488
}
488489
telemetryConfig["ORGANIZATION_ID"] = organizationID
490+
telemetryConfig["ACCOUNT_MAIL"] = accountMail
489491

490492
return telemetryConfig, nil
491493
}

pkg/console/telemetry/telemetry.go

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -81,26 +81,36 @@ func GetAccessToken(secretsLister v1.SecretLister) (string, error) {
8181
}
8282

8383
// check if:
84-
// 1. custom ORGANIZATION_ID is awailable as telemetry annotation on console-operator config or in telemetry-config configmap
85-
// 2. cached ORGANIZATION_ID is available on the operator controller instance
86-
// else fetch the ORGANIZATION_ID from OCM
87-
func GetOrganizationID(telemetryConfig map[string]string, cachedOrganizationID, clusterID, accessToken string) (string, bool) {
84+
// 1. custom ORGANIZATION_ID and ACCOUNT_MAIL is awailable as telemetry annotation on console-operator config or in telemetry-config configmap
85+
// 2. cached ORGANIZATION_ID and ACCOUNT_MAIL is available on the operator controller instance
86+
// else fetch the ORGANIZATION_ID and ACCOUNT_MAIL from OCM
87+
func GetOrganizationMeta(telemetryConfig map[string]string, cachedOrganizationID, cachedAccountEmail, clusterID, accessToken string) (string, string, bool) {
8888
customOrganizationID, isCustomOrgIDSet := telemetryConfig["ORGANIZATION_ID"]
89-
if isCustomOrgIDSet {
90-
klog.V(4).Infoln("telemetry config: using custom organization ID")
91-
return customOrganizationID, false
89+
customAccountMail, isCustomAccountMailSet := telemetryConfig["ACCOUNT_MAIL"]
90+
91+
if isCustomOrgIDSet && isCustomAccountMailSet {
92+
klog.V(4).Infoln("telemetry config: using custom data")
93+
return customOrganizationID, customAccountMail, false
9294
}
9395

94-
if cachedOrganizationID != "" {
95-
klog.V(4).Infoln("telemetry config: using cached organization ID")
96-
return cachedOrganizationID, false
96+
if cachedOrganizationID != "" && cachedAccountEmail != "" {
97+
klog.V(4).Infoln("telemetry config: using cached organization metadata")
98+
return cachedOrganizationID, cachedAccountEmail, false
9799
}
98100

99-
fetchedOrganizationID, err := FetchOrganizationID(clusterID, accessToken)
101+
fetchedOCMRespose, err := FetchSubscription(clusterID, accessToken)
100102
if err != nil {
101103
klog.Errorf("telemetry config error: %s", err)
104+
return "", "", false // Ensure safe return in case of error
105+
}
106+
107+
// Check if the fetched response is nil before accessing fields
108+
if fetchedOCMRespose == nil {
109+
klog.Errorf("telemetry config error: FetchSubscription returned nil response")
110+
return "", "", false
102111
}
103-
return fetchedOrganizationID, true
112+
113+
return fetchedOCMRespose.Organization.ExternalId, fetchedOCMRespose.Creator.Email, true
104114
}
105115

106116
// Needed to create our own types for OCM Subscriptions since their types and client are useless
@@ -111,23 +121,28 @@ type OCMAPIResponse struct {
111121
}
112122
type Subscription struct {
113123
Organization Organization `json:"organization,omitempty"`
124+
Creator Creator `json:"creator,omitempty"`
125+
}
126+
127+
type Creator struct {
128+
Email string `json:"email,omitempty"`
114129
}
115130

116131
type Organization struct {
117132
ExternalId string `json:"external_id,omitempty"`
118133
}
119134

120-
// FetchOrganizationID fetches the organization ID using the cluster ID and access token
121-
func FetchOrganizationID(clusterID, accessToken string) (string, error) {
135+
// FetchOrganizationMeta fetches the organization ID and Accout email using the cluster ID and access token
136+
func FetchSubscription(clusterID, accessToken string) (*Subscription, error) {
122137
klog.V(4).Infoln("telemetry config: fetching organization ID")
123138
u, err := buildURL(clusterID)
124139
if err != nil {
125-
return "", err // more contextual error handling can be added here if needed
140+
return nil, err // more contextual error handling can be added here if needed
126141
}
127142

128143
req, err := createRequest(u, clusterID, accessToken)
129144
if err != nil {
130-
return "", err
145+
return nil, err
131146
}
132147

133148
client := &http.Client{
@@ -138,29 +153,29 @@ func FetchOrganizationID(clusterID, accessToken string) (string, error) {
138153
}
139154
resp, err := client.Do(req)
140155
if err != nil {
141-
return "", fmt.Errorf("failed to GET (%s): %v", u.String(), err)
156+
return nil, fmt.Errorf("failed to GET (%s): %v", u.String(), err)
142157
}
143158
defer resp.Body.Close()
144159

145160
if resp.StatusCode != http.StatusOK {
146-
return "", fmt.Errorf("HTTP request failed with status '%s'", resp.Status)
161+
return nil, fmt.Errorf("HTTP request failed with status '%s'", resp.Status)
147162
}
148163

149164
body, err := io.ReadAll(resp.Body)
150165
if err != nil {
151-
return "", fmt.Errorf("failed to read response body: %v", err)
166+
return nil, fmt.Errorf("failed to read response body: %v", err)
152167
}
153168

154169
var ocmResponse OCMAPIResponse
155170
if err = json.Unmarshal(body, &ocmResponse); err != nil {
156-
return "", fmt.Errorf("error decoding JSON: %v", err)
171+
return nil, fmt.Errorf("error decoding JSON: %v", err)
157172
}
158173

159174
if len(ocmResponse.Items) == 0 {
160-
return "", fmt.Errorf("empty OCM response")
175+
return nil, fmt.Errorf("empty OCM response")
161176
}
162177

163-
return ocmResponse.Items[0].Organization.ExternalId, nil
178+
return &ocmResponse.Items[0], nil
164179
}
165180

166181
// buildURL constructs the URL for the API request
@@ -172,6 +187,7 @@ func buildURL(clusterID string) (*url.URL, error) {
172187
}
173188
q := u.Query()
174189
q.Add("fetchOrganization", "true")
190+
q.Add("fetchAccounts", "true")
175191
q.Add("search", fmt.Sprintf("external_cluster_id='%s'", clusterID))
176192
u.RawQuery = q.Encode()
177193
return u, nil

0 commit comments

Comments
 (0)