Return NTP stats (associations).

def get_ntp_stats(self):
        """Return NTP stats (associations)."""
        # NTP Peers does not have XML RPC defined
        # thus we need to retrieve raw text and parse...
        # :(

        ntp_stats = []

        REGEX = (
            r"^\s?(\+|\*|x|-)?([a-zA-Z0-9\.+-:]+)"
            r"\s+([a-zA-Z0-9\.]+)\s+([0-9]{1,2})"
            r"\s+(-|u)\s+([0-9h-]+)\s+([0-9]+)"
            r"\s+([0-9]+)\s+([0-9\.]+)\s+([0-9\.-]+)"
            r"\s+([0-9\.]+)\s?$"
        )

        ntp_assoc_output = self.device.cli("show ntp associations no-resolve")
        ntp_assoc_output_lines = ntp_assoc_output.splitlines()

        for ntp_assoc_output_line in ntp_assoc_output_lines[3:]:  # except last line
            line_search = re.search(REGEX, ntp_assoc_output_line, re.I)
            if not line_search:
                continue  # pattern not found
            line_groups = line_search.groups()
            try:
                ntp_stats.append(
                    {
                        "remote": napalm.base.helpers.ip(line_groups[1]),
                        "synchronized": (line_groups[0] == "*"),
                        "referenceid": py23_compat.text_type(line_groups[2]),
                        "stratum": int(line_groups[3]),
                        "type": py23_compat.text_type(line_groups[4]),
                        "when": py23_compat.text_type(line_groups[5]),
                        "hostpoll": int(line_groups[6]),
                        "reachability": int(line_groups[7]),
                        "delay": float(line_groups[8]),
                        "offset": float(line_groups[9]),
                        "jitter": float(line_groups[10]),
                    }
                )
            except Exception:
                continue  # jump to next line

        return ntp_stats