diff options
| -rw-r--r-- | glustolibs-gluster-gd2/glustolibs/gluster/lib_utils.py | 77 | ||||
| -rw-r--r-- | glustolibs-gluster-gd2/glustolibs/gluster/rest.py | 128 | 
2 files changed, 205 insertions, 0 deletions
diff --git a/glustolibs-gluster-gd2/glustolibs/gluster/lib_utils.py b/glustolibs-gluster-gd2/glustolibs/gluster/lib_utils.py new file mode 100644 index 0000000..3eb16e2 --- /dev/null +++ b/glustolibs-gluster-gd2/glustolibs/gluster/lib_utils.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +#  Copyright (C) 2018  Red Hat, Inc. <http://www.redhat.com> +# +#  This program is free software; you can redistribute it and/or modify +#  it under the terms of the GNU General Public License as published by +#  the Free Software Foundation; either version 2 of the License, or +#  any later version. +# +#  This program is distributed in the hope that it will be useful, +#  but WITHOUT ANY WARRANTY; without even the implied warranty of +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +#  GNU General Public License for more details. +# +#  You should have received a copy of the GNU General Public License along +#  with this program; if not, write to the Free Software Foundation, Inc., +#  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +""" +    Description: Helper library for gluster modules. +""" + +from glusto.core import Glusto as g + + +def inject_msg_in_logs(nodes, log_msg, list_of_dirs=None, list_of_files=None): +    """Injects the message to all log files under all dirs specified on nodes. +    Args: +        nodes (str|list): A server|List of nodes on which message has to be +            injected to logs +        log_msg (str): Message to be injected +        list_of_dirs (list): List of dirs to inject message on log files. +        list_of_files (list): List of files to inject message. +    Returns: +        bool: True if successfully injected msg on all log files. +    """ +    if isinstance(nodes, str): +        nodes = [nodes] + +    if list_of_dirs is None: +        list_of_dirs = "" + +    if isinstance(list_of_dirs, list): +        list_of_dirs = ' '.join(list_of_dirs) + +    if list_of_files is None: +        list_of_files = '' + +    if isinstance(list_of_files, list): +        list_of_files = ' '.join(list_of_files) + +    inject_msg_on_dirs = "" +    inject_msg_on_files = "" +    if list_of_dirs: +        inject_msg_on_dirs = ( +            "for dir in %s ; do " +            "for file in `find ${dir} -type f -name '*.log'`; do " +            "echo \"%s\" >> ${file} ; done ;" +            "done; " % (list_of_dirs, log_msg)) +    if list_of_files: +        inject_msg_on_files = ("for file in %s ; do " +                               "echo \"%s\" >> ${file} ; done; " % +                               (list_of_files, log_msg)) + +    cmd = inject_msg_on_dirs + inject_msg_on_files + +    results = g.run_parallel(nodes, cmd) + +    _rc = True +    # Check for return status +    for host in results: +        ret, _, _ = results[host] +        if ret != 0: +            g.log.error("Failed to inject log message '%s' in dirs '%s', " +                        "in files '%s',  on node'%s'", +                        log_msg, list_of_dirs, list_of_files, host) +            _rc = False +    return _rc diff --git a/glustolibs-gluster-gd2/glustolibs/gluster/rest.py b/glustolibs-gluster-gd2/glustolibs/gluster/rest.py new file mode 100644 index 0000000..f687ea3 --- /dev/null +++ b/glustolibs-gluster-gd2/glustolibs/gluster/rest.py @@ -0,0 +1,128 @@ +#  Copyright (C) 2018  Red Hat, Inc. <http://www.redhat.com> +# +#  This program is free software; you can redistribute it and/or modify +#  it under the terms of the GNU General Public License as published by +#  the Free Software Foundation; either version 2 of the License, or +#  any later version. +# +#  This program is distributed in the hope that it will be useful, +#  but WITHOUT ANY WARRANTY; without even the implied warranty of +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +#  GNU General Public License for more details. +# +#  You should have received a copy of the GNU General Public License along +#  with this program; if not, write to the Free Software Foundation, Inc., +#  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +""" +    Description: Library to handle all the common REST methods like GET, POST +    & DELETE +""" + +import json +import datetime +import hashlib +import jwt +import requests +from glusto.core import Glusto as g + + +class RestClient(object): +    ''' +        Class contains common methods for POST, GET, DELETE and +        verifies authentication +    ''' +    def __init__(self, mnode, port='24007', user='glustercli', secret=None, +                 verify=False): +        """ +        Function to form base url and to get secret key + +        Args: +            mnode (str): The server on which the command has to be executed +            port (str) : The port which API calls use +            user (str) : By default the user is glustercli +        """ + +        self.user = user +        self.mnode = mnode +        self.secret = secret +        self.verify = verify +        self.port = port +        self.base_url = ('http://{mnode}:{port}'.format(mnode=mnode, +                                                        port=port)) +        if self.secret is None: +            _, self.secret, _ = g.run(mnode, "cat /var/lib/glusterd2/auth") + +    def _set_token_in_header(self, method, url, headers=None): +        """ +        Function to set token in header + +        Args: +           method (str): It can be GET, POST or DELETE +           url (str): The url for operation + +        For Example: +          token =  _set_token_in_header('GET', '/v1/peers') + +        """ + +        if headers is None: +            headers = dict() +        claims = dict() +        claims['iss'] = self.user + +        # Issued at time +        claims['iat'] = datetime.datetime.utcnow() + +        # Expiration time +        claims['exp'] = datetime.datetime.utcnow() + datetime.timedelta( +            seconds=1) + +        # URI tampering protection +        val = b'%s&%s' % (method.encode('utf8'), url.encode('utf8')) +        claims['qsh'] = hashlib.sha256(val).hexdigest() + +        token = jwt.encode(claims, self.secret, algorithm='HS256') +        headers['Authorization'] = b'bearer ' + token + +        return headers + +    def handle_request(self, method, url, expected_status_code, data=None): +        """ Function that handles all the methods(GET, POST, DELETE) + +        Args: +            method (str): It can be GET, POST, DELETE +            url (str): The url of the operation +            expected_status_code (str) : The status_code expected after +                                      the API call +            data (str): The json input that needs to be passed + +        Returns: +            tuple: Tuple containing three elements (ret, out, err). +                The first element 'ret' is of type 'int' and returns the status +                code of command execution. + +                The second element 'out' is of type 'str' and is the +                stdout value + +                The third element 'err' is of type 'str' and is the +                stderr message|value of the command execution. + +        Example: +            handle_request('GET', "/v1/volumes", '200') +            handle_request('POST', "/vi/volumes", '201', data) +        """ + +        headers = self._set_token_in_header(method, url) +        resp = requests.request(method, self.base_url + url, +                                data=json.dumps(data), +                                headers=headers, verify=self.verify) + +        if resp.status_code != expected_status_code: +            return (1, None, json.dumps(resp.json())) + +        if resp.status_code == 204: +            return (resp.status_code, None, None) + +        return (0, json.dumps(resp.json()), None) +  | 
