]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/pybind/mgr/telemetry/module.py
import 15.2.0 Octopus source
[ceph.git] / ceph / src / pybind / mgr / telemetry / module.py
index c2f9657e686e5482bdae74e6697344d10610005f..4fbfe8f7c03e4e4e814d8cdac6e0598392211747 100644 (file)
@@ -159,7 +159,8 @@ class Module(MgrModule):
         },
         {
             "cmd": "telemetry send "
-                   "name=endpoint,type=CephChoices,strings=ceph|device,n=N,req=false",
+                   "name=endpoint,type=CephChoices,strings=ceph|device,n=N,req=false "
+                   "name=license,type=CephString,req=false",
             "desc": "Force sending data to Ceph telemetry",
             "perm": "rw"
         },
@@ -208,10 +209,6 @@ class Module(MgrModule):
         # wake up serve() thread
         self.event.set()
 
-    @staticmethod
-    def parse_timestamp(timestamp):
-        return datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S.%f')
-
     def load(self):
         self.last_upload = self.get_store('last_upload', None)
         if self.last_upload is not None:
@@ -402,7 +399,7 @@ class Module(MgrModule):
             # anonymize device id
             anon_devid = self.get_store('devid-id/%s' % devid)
             if not anon_devid:
-                anon_devid = devid[:devid.rfind('_')] + '_' + uuid.uuid1()
+                anon_devid = f"{devid.rsplit('_', 1)[0]}_{uuid.uuid1()}"
                 self.set_store('devid-id/%s' % devid, anon_devid)
             self.log.info('devid %s / %s, host %s / %s' % (devid, anon_devid,
                                                            host, anon_host))
@@ -451,7 +448,7 @@ class Module(MgrModule):
             fs_map = self.get('fs_map')
             df = self.get('df')
 
-            report['created'] = self.parse_timestamp(mon_map['created']).isoformat()
+            report['created'] = mon_map['created']
 
             # mons
             v1_mons = 0
@@ -677,30 +674,33 @@ class Module(MgrModule):
 
         return report
 
+    def _try_post(self, what, url, report):
+        self.log.info('Sending %s to: %s' % (what, url))
+        proxies = dict()
+        if self.proxy:
+            self.log.info('Send using HTTP(S) proxy: %s', self.proxy)
+            proxies['http'] = self.proxy
+            proxies['https'] = self.proxy
+        try:
+            resp = requests.put(url=url, json=report, proxies=proxies)
+            resp.raise_for_status()
+        except Exception as e:
+            fail_reason = 'Failed to send %s to %s: %s' % (what, url, str(e))
+            self.log.error(fail_reason)
+            return fail_reason
+        return None
+
     def send(self, report, endpoint=None):
         if not endpoint:
             endpoint = ['ceph', 'device']
         failed = []
         success = []
-        proxies = dict()
         self.log.debug('Send endpoints %s' % endpoint)
-        if self.proxy:
-            self.log.info('Send using HTTP(S) proxy: %s', self.proxy)
-            proxies['http'] = self.proxy
-            proxies['https'] = self.proxy
         for e in endpoint:
             if e == 'ceph':
-                self.log.info('Sending ceph report to: %s', self.url)
-                resp = requests.put(url=self.url, json=report, proxies=proxies)
-                if not resp.ok:
-                    self.log.error("Report send failed: %d %s %s" %
-                                   (resp.status_code, resp.reason, resp.text))
-                    failed.append('Failed to send report to %s: %d %s %s' % (
-                        self.url,
-                        resp.status_code,
-                        resp.reason,
-                        resp.text
-                    ))
+                fail_reason = self._try_post('ceph report', self.url, report)
+                if fail_reason:
+                    failed.append(fail_reason)
                 else:
                     now = int(time.time())
                     self.last_upload = now
@@ -709,9 +709,6 @@ class Module(MgrModule):
                     self.log.info('Sent report to {0}'.format(self.url))
             elif e == 'device':
                 if 'device' in self.get_active_channels():
-                    self.log.info('hi')
-                    self.log.info('Sending device report to: %s',
-                                  self.device_url)
                     devices = self.gather_device_report()
                     num_devs = 0
                     num_hosts = 0
@@ -719,19 +716,10 @@ class Module(MgrModule):
                         self.log.debug('host %s devices %s' % (host, ls))
                         if not len(ls):
                             continue
-                        resp = requests.put(url=self.device_url, json=ls,
-                                            proxies=proxies)
-                        if not resp.ok:
-                            self.log.error(
-                                "Device report failed: %d %s %s" %
-                                (resp.status_code, resp.reason, resp.text))
-                            failed.append(
-                                'Failed to send devices to %s: %d %s %s' % (
-                                    self.device_url,
-                                    resp.status_code,
-                                    resp.reason,
-                                    resp.text
-                                ))
+                        fail_reason = self._try_post('devices', self.device_url,
+                                                     ls)
+                        if fail_reason:
+                            failed.append(fail_reason)
                         else:
                             num_devs += len(ls)
                             num_hosts += 1
@@ -747,7 +735,8 @@ class Module(MgrModule):
             r = {}
             for opt in self.MODULE_OPTIONS:
                 r[opt['name']] = getattr(self, opt['name'])
-            return 0, json.dumps(r, indent=4), ''
+            r['last_upload'] = time.ctime(self.last_upload) if self.last_upload else self.last_upload
+            return 0, json.dumps(r, indent=4, sort_keys=True), ''
         elif command['prefix'] == 'telemetry on':
             if command.get('license') != LICENSE:
                 return -errno.EPERM, '', "Telemetry data is licensed under the " + LICENSE_NAME + " (" + LICENSE_URL + ").\nTo enable, add '--license " + LICENSE + "' to the 'ceph telemetry on' command."
@@ -756,9 +745,12 @@ class Module(MgrModule):
             return 0, '', ''
         elif command['prefix'] == 'telemetry off':
             self.set_module_option('enabled', False)
-            self.set_module_option('last_opt_revision', REVISION)
+            self.set_module_option('last_opt_revision', 1)
             return 0, '', ''
         elif command['prefix'] == 'telemetry send':
+            if self.last_opt_revision < LAST_REVISION_RE_OPT_IN and command.get('license') != LICENSE:
+                self.log.debug('A telemetry send attempt while opted-out. Asking for license agreement')
+                return -errno.EPERM, '', "Telemetry data is licensed under the " + LICENSE_NAME + " (" + LICENSE_URL + ").\nTo manually send telemetry data, add '--license " + LICENSE + "' to the 'ceph telemetry send' command.\nPlease consider enabling the telemetry module with 'ceph telemetry on'."
             self.last_report = self.compile_report()
             return self.send(self.last_report, command.get('endpoint'))
 
@@ -766,7 +758,7 @@ class Module(MgrModule):
             report = self.compile_report(
                 channels=command.get('channels', None)
             )
-            report = json.dumps(report, indent=4)
+            report = json.dumps(report, indent=4, sort_keys=True)
             if self.channel_device:
                report += '\n \nDevice report is generated separately. To see it run \'ceph telemetry show-device\'.'
             return 0, report, ''