Crystalnix/termius-cli

View on GitHub
termius/porting/providers/securecrt/parser.py

Summary

Maintainability
A
1 hr
Test Coverage
# -*- coding: utf-8 -*-
"""Module with SecureCRT parser."""
from os.path import expanduser


class SecureCRTConfigParser(object):
    """SecureCRT xml parser."""

    meta_sessions = ['Default']

    def __init__(self, xml):
        """Construct parser instance."""
        self.xml = xml
        self.tree = {}

    def parse_hosts(self):
        """Parse SecureCRT Sessions."""
        sessions = list(self.get_element_by_name(list(self.xml), 'Sessions'))

        self.parse_sessions(sessions, self.tree)

        return self.tree

    def parse_sessions(self, sessions, parent_node):
        """Parse SecureCRT sessions."""
        for session in sessions:
            if session.get('name') not in self.meta_sessions:
                if not self.is_session_group(session):
                    host = self.make_host(session)
                    if not host:
                        continue
                    parent_node[host['label']] = host
                else:
                    parent_node[session.get('name')] = {'__group': True}
                    self.parse_sessions(
                        list(session),
                        parent_node[session.get('name')]
                    )

    def is_session_group(self, session):
        """Check node element type."""
        return self.get_element_by_name(list(session), 'Hostname') is None

    def parse_identity(self):
        """Parse SecureCRT SSH2 raw key."""
        identity = self.get_element_by_name(list(self.xml), 'SSH2')
        if identity is None:
            return None

        identity_filename = self.get_element_by_name(
            list(identity),
            'Identity Filename V2'
        )

        if not self.check_attribute(identity_filename):
            return None

        path = identity_filename.text.split('/')
        public_key_name = path[-1].split('::')[0]
        private_key_name = public_key_name.split('.')[0]

        if path[0].startswith('$'):
            path.pop(0)
            path.insert(0, expanduser("~"))

        path[-1] = public_key_name
        public_key_path = '/'.join(path)
        path[-1] = private_key_name
        private_key_path = '/'.join(path)

        return private_key_path, public_key_path

    def make_host(self, session):
        """Adapt SecureCRT Session to Termius host."""
        session_attrs = list(session)

        hostname = self.get_element_by_name(session_attrs, 'Hostname')
        port = self.get_element_by_name(session_attrs, '[SSH2] Port')
        username = self.get_element_by_name(session_attrs, 'Username')

        if not self.check_attribute(hostname):
            return None

        return {
            'label': session.get('name'),
            'hostname': hostname.text,
            'port': port.text if self.check_attribute(port) else '22',
            'username': username.text
            if self.check_attribute(username) else None
        }

    def check_attribute(self, attr):
        """Check an attribute."""
        return attr is not None and attr.text

    def get_element_by_name(self, elements, name):
        """Get SecureCRT config block."""
        for element in elements:
            if element.get('name') == name:
                return element

        return None