Test Failed
Push — master ( e380d0...f5671d )
by W
02:58
created

runners/windows_runner/windows_runner/base.py (1 issue)

1
# Licensed to the StackStorm, Inc ('StackStorm') under one or more
2
# contributor license agreements.  See the NOTICE file distributed with
3
# this work for additional information regarding copyright ownership.
4
# The ASF licenses this file to You under the Apache License, Version 2.0
5
# (the "License"); you may not use this file except in compliance with
6
# the License.  You may obtain a copy of the License at
7
#
8
#     http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
16
from __future__ import absolute_import
17
18
import abc
19
from distutils.spawn import find_executable
20
21
import six
22
23
from st2common.runners.base import ActionRunner
24
25
__all__ = [
26
    'BaseWindowsRunner',
27
28
    'WINEXE_EXISTS',
29
    'SMBCLIENT_EXISTS'
30
]
31
32
WINEXE_EXISTS = find_executable('winexe') is not None
33
SMBCLIENT_EXISTS = find_executable('smbclient') is not None
34
35
# Constants which map winexe error codes to user-friendly error messages
36
ERROR_CODE_TO_MESSAGE_MAP = {
37
    'NT_STATUS_LOGON_FAILURE': 'Invalid or missing authentication credentials.',
38
    'NT_STATUS_IO_TIMEOUT': 'Connection timeout.',
39
    'NT_STATUS_NETWORK_UNREACHABLE': 'Network unavailable, unable to connect.',
40
    'NT_STATUS_NO_MEMORY': 'Failed to run the command.'
41
}
42
43
44
@six.add_metaclass(abc.ABCMeta)
45
class BaseWindowsRunner(ActionRunner):
46
    def _verify_winexe_exists(self):
47
        if not WINEXE_EXISTS:
48
            msg = ('Could not find "winexe" binary. Make sure it\'s installed and available'
49
                   'in $PATH')
50
            raise Exception(msg)
51
52
    def _verify_smbclient_exists(self):
53
        if not SMBCLIENT_EXISTS:
54
            msg = ('Could not find "smbclient" binary. Make sure it\'s installed and available'
55
                   'in $PATH')
56
            raise Exception(msg)
57
58
    def _get_winexe_command_args(self, host, username, password, command, domain=None):
59
        args = ['winexe']
60
61
        # Disable interactive mode
62
        args += ['--interactive', '0']
63
64
        if domain:
65
            args += ['-U', '%s\%s%%%s' % (domain, username, password)]
0 ignored issues
show
A suspicious escape sequence \% was found. Did you maybe forget to add an r prefix?

Escape sequences in Python are generally interpreted according to rules similar to standard C. Only if strings are prefixed with r or R are they interpreted as regular expressions.

The escape sequence that was used indicates that you might have intended to write a regular expression.

Learn more about the available escape sequences. in the Python documentation.

Loading history...
66
        else:
67
            args += ['-U', '%s%%%s' % (username, password)]
68
69
        args += ['//%s' % (host)]
70
        args += [command]
71
72
        return args
73
74
    def _get_smbclient_command_args(self, host, username, password, command, share='C$',
75
                                    domain=None):
76
        """
77
        :param command: Samba command string.
78
        :type command: ``str``
79
80
        :param share: Samba share name.
81
        :type share: ``str``
82
        """
83
        args = ['smbclient']
84
85
        values = {'domain': domain, 'username': username, 'password': password}
86
        if domain:
87
            auth_string = '%(domain)s\%(username)s%%%(password)s' % values
88
        else:
89
            auth_string = '%(username)s%%%(password)s' % values
90
91
        # Authentication info
92
        args += ['-U', auth_string]
93
94
        # Host and share
95
        args += ['//%(host)s/%(share)s' % {'host': host, 'share': share}]
96
97
        # Command
98
        args += ['-c', command]
99
        return args
100
101
    def _parse_winexe_error(self, stdout, stderr):
102
        for code, message in ERROR_CODE_TO_MESSAGE_MAP.items():
103
            if code in stdout:
104
                return message
105
106
        return None
107