@@ -81,26 +81,36 @@ func GetAccessToken(secretsLister v1.SecretLister) (string, error) {
81
81
}
82
82
83
83
// 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 ) {
88
88
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
92
94
}
93
95
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
97
99
}
98
100
99
- fetchedOrganizationID , err := FetchOrganizationID (clusterID , accessToken )
101
+ fetchedOCMRespose , err := FetchSubscription (clusterID , accessToken )
100
102
if err != nil {
101
103
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
102
111
}
103
- return fetchedOrganizationID , true
112
+
113
+ return fetchedOCMRespose .Organization .ExternalId , fetchedOCMRespose .Creator .Email , true
104
114
}
105
115
106
116
// Needed to create our own types for OCM Subscriptions since their types and client are useless
@@ -111,23 +121,28 @@ type OCMAPIResponse struct {
111
121
}
112
122
type Subscription struct {
113
123
Organization Organization `json:"organization,omitempty"`
124
+ Creator Creator `json:"creator,omitempty"`
125
+ }
126
+
127
+ type Creator struct {
128
+ Email string `json:"email,omitempty"`
114
129
}
115
130
116
131
type Organization struct {
117
132
ExternalId string `json:"external_id,omitempty"`
118
133
}
119
134
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 ) {
122
137
klog .V (4 ).Infoln ("telemetry config: fetching organization ID" )
123
138
u , err := buildURL (clusterID )
124
139
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
126
141
}
127
142
128
143
req , err := createRequest (u , clusterID , accessToken )
129
144
if err != nil {
130
- return "" , err
145
+ return nil , err
131
146
}
132
147
133
148
client := & http.Client {
@@ -138,29 +153,29 @@ func FetchOrganizationID(clusterID, accessToken string) (string, error) {
138
153
}
139
154
resp , err := client .Do (req )
140
155
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 )
142
157
}
143
158
defer resp .Body .Close ()
144
159
145
160
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 )
147
162
}
148
163
149
164
body , err := io .ReadAll (resp .Body )
150
165
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 )
152
167
}
153
168
154
169
var ocmResponse OCMAPIResponse
155
170
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 )
157
172
}
158
173
159
174
if len (ocmResponse .Items ) == 0 {
160
- return "" , fmt .Errorf ("empty OCM response" )
175
+ return nil , fmt .Errorf ("empty OCM response" )
161
176
}
162
177
163
- return ocmResponse .Items [0 ]. Organization . ExternalId , nil
178
+ return & ocmResponse .Items [0 ], nil
164
179
}
165
180
166
181
// buildURL constructs the URL for the API request
@@ -172,6 +187,7 @@ func buildURL(clusterID string) (*url.URL, error) {
172
187
}
173
188
q := u .Query ()
174
189
q .Add ("fetchOrganization" , "true" )
190
+ q .Add ("fetchAccounts" , "true" )
175
191
q .Add ("search" , fmt .Sprintf ("external_cluster_id='%s'" , clusterID ))
176
192
u .RawQuery = q .Encode ()
177
193
return u , nil
0 commit comments