Merge pull request #30 from uggla/python3compat2

Python-redfish, Python3 compatibility
This commit is contained in:
Bruno Cornec 2016-03-07 19:38:32 +01:00
commit 77d9ba4eaf
22 changed files with 180 additions and 65 deletions

View File

@ -13,6 +13,11 @@ NOTE::
is still at version 0.99.0a and may not reflect what the standard provides
fully
Documentation
-------------
The full documentation is available at
http://pythonhosted.org/python-redfish/installation.html
Project Structure
-------------------
@ -35,7 +40,7 @@ for build and test automation::
Requirements
------------
To use the enclosed examples, you will need Python 2.7
To use the enclosed examples, you will need Python 2.7 or Python 3.4
(https://www.python.org/downloads/). Note that Python 2.7.9 enforces greater
SSL verification requiring server certificates be installed. Parameters to
relax the requirements are available in the library, but these configurations
@ -44,6 +49,9 @@ are discouraged due to security.
Python requirements are listed in requirements.txt; additional requirements for
running the unit test suite are listed in test-requirements.txt.
Note: The program was tested with Python 2.7.10 and 3.4.2 however it might work
as well with all Python 3 releases.
Get the sources
---------------

11
doc/source/faq.rst Normal file
View File

@ -0,0 +1,11 @@
===
FAQ
===
- Q1 : error in setup command: Invalid environment marker: (python_version < '3')
This error is caused by old setuptools revisions that do not understant "python_version < '3'".
Upgrade setuptools using::
pip install --upgrade setuptools

View File

@ -18,6 +18,7 @@ Contents:
testing
classesdoc
contributing
faq
help
Indices and tables

View File

@ -15,6 +15,10 @@ refish-client tests
#. Install docker using the `procedure <https://docs.docker.com/engine/installation/>`_.
#. Ensure you can use docker with your current user.
#. Jump into redfish-python directory containing the sources.
#. Depending of your distribution, you may have to upgrade setuptools::
pip install --upgrade setuptools
#. Install required modules for testings::
pip install -t test-requirements.txt

View File

@ -1 +1,8 @@
__author__ = 'deva'
# coding=utf-8
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
__author__ = 'uggla'

View File

@ -1,6 +1,13 @@
# coding=utf-8
""" Simple example to use python-redfish on HP Proliant servers """
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import str
import os
import sys

View File

@ -1,6 +1,12 @@
# coding=utf-8
""" Simple example to use python-redfish with DMTF simulator """
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
import os
import sys

View File

@ -28,9 +28,17 @@ redfish-client ::
--libdebugfile FILE Specify python-redfish library log file [default: /var/log/python-redfish/python-redfish.log]
config commands : manage the configuration file.
manager commands : manage the manager (Ligh out management). If <manager_name>
manager commands : manage the manager (Light out management). If <manager_name>
is not provided use the 'default' entry
'''
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import str
from builtins import object
import os
import sys
@ -38,7 +46,7 @@ import json
import pprint
import docopt
import logging
import ConfigParser
import configparser
import jinja2
import requests.packages.urllib3
import redfish
@ -268,7 +276,7 @@ if __name__ == '__main__':
% (e.message, jinja2_env.loader.searchpath[0]))
sys.exit(1)
print template.render(r=remote_mgmt)
print(template.render(r=remote_mgmt))
#################################################################
# Main program
@ -340,7 +348,7 @@ if __name__ == '__main__':
logger.debug("Home directory : %s" % HOME)
# Load config
config = ConfigParser.ConfigParser(allow_no_value=True)
config = configparser.ConfigParser(allow_no_value=True)
logger.debug("Read configuration file")
configfile = 'PBCONFFILE'

View File

@ -6,6 +6,9 @@ apt-get install -y python-pip
COPY python-redfish.src.tar.gz /python-redfish.src.tar.gz
RUN mkdir /var/log/python-redfish
RUN tar xvvf python-redfish.src.tar.gz
# Need a really recent version of setuptools to support
# configparser>=3.3.0; python_version < '3' in requirements.txt
RUN pip install --upgrade setuptools
RUN cd python-redfish* && \
pip install -r requirements.txt && \
python setup.py install

View File

@ -1,6 +1,5 @@
FROM fedora:23
RUN dnf install -y python-pip && \
dnf install -y git && \
dnf install -y tar
COPY python-redfish.src.tar.gz /python-redfish.src.tar.gz
RUN mkdir /var/log/python-redfish

View File

@ -0,0 +1,11 @@
FROM fedora:23
RUN dnf install -y python3-pip && \
dnf install -y tar
COPY python-redfish.src.tar.gz /python-redfish.src.tar.gz
RUN mkdir /var/log/python-redfish
RUN tar xvvf python-redfish.src.tar.gz
RUN cd python-redfish* && \
pip3 install -r requirements.txt && \
python3 setup.py install
CMD ["/bin/bash"]

View File

@ -1,6 +1,5 @@
FROM fedora:23
RUN dnf install -y python-pip && \
dnf install -y git
RUN dnf install -y python-pip
RUN mkdir /var/log/python-redfish
RUN pip install python-redfish
CMD ["/bin/bash"]

View File

@ -6,6 +6,9 @@ apt-get install -y python-pip
COPY python-redfish.src.tar.gz /python-redfish.src.tar.gz
RUN mkdir /var/log/python-redfish
RUN tar xvvf python-redfish.src.tar.gz
# Need a really recent version of setuptools to support
# configparser>=3.3.0; python_version < '3' in requirements.txt
RUN pip install --upgrade setuptools
RUN cd python-redfish* && \
pip install -r requirements.txt && \
python setup.py install

View File

@ -1,3 +1,10 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import object
# coding=utf-8
import os
import stat
@ -7,7 +14,7 @@ from docker import Client
from path import Path
class DockerTest():
class DockerTest(object):
def __init__(self):
self.cli = Client(base_url='unix://var/run/docker.sock')
@ -30,7 +37,7 @@ class DockerTest():
self.cli.wait(container=container.get('Id'))
response = self.cli.logs(container=container.get('Id'),
stdout=True)
return(response)
return(response.decode('utf8'))
def test_dockersocket():
@ -49,7 +56,7 @@ def test_docker():
def test_sources():
output = subprocess.check_output(["python", "setup.py", "sdist"])
search = re.search(r"removing '(\S+)'", output)
search = re.search(r"removing '(\S+)'", str(output))
filename = Path('dist/' + search.group(1) + '.tar.gz')
filename.copy('redfish-client/tests/python-redfish.src.tar.gz')
assert Path('redfish-client/tests/python-redfish.src.tar.gz').isfile()
@ -57,20 +64,23 @@ def test_sources():
def test_dockerbuild():
docker = DockerTest()
# Warning : Image tag is derived from file name, do not use uppercase !!!
dockerfiles = ('redfish-client/tests/Dockerfile.ubuntu',
'redfish-client/tests/Dockerfile.debian',
'redfish-client/tests/Dockerfile.fedora',
'redfish-client/tests/Dockerfile.fedorap3',
'redfish-client/tests/Dockerfile.fedorapip')
for dockerfile in dockerfiles:
print('Testing : {}'.format(dockerfile))
response = docker.build(dockerfile)
status = response.pop()
status = str(response.pop())
assert 'Successfully built' in status
def test_install():
docker = DockerTest()
images = ('rfubuntu', 'rfdebian', 'rffedora', 'rffedorapip')
images = ('rfubuntu', 'rfdebian',
'rffedora', 'rffedorap3', 'rffedorapip')
for img in images:
print('Testing : {}'.format(img))
response = docker.run(img, 'redfish-client config showall')
@ -80,10 +90,11 @@ def test_install():
def test_versionformat():
docker = DockerTest()
images = ('rfubuntu', 'rfdebian', 'rffedora', 'rffedorapip')
images = ('rfubuntu', 'rfdebian',
'rffedora', 'rffedorap3', 'rffedorapip')
for img in images:
print('Testing : {}'.format(img))
response = docker.run(img, 'redfish-client --version')
print(response)
assert (re.match('redfish-client \d+\.\d+', response))
assert (re.match(r'redfish-client \d+\.\d+', response))

View File

@ -12,15 +12,21 @@
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
import pbr.version
from redfish.main import *
#import redfish.types
try:
__version__ = pbr.version.VersionInfo('redfish').release_string()
except Exception, e:
if "Versioning for this project requires either an sdist tarball" in e.message:
except Exception as e:
if "Versioning for this project requires either an sdist tarball" \
in e.args[0]:
pass
else:
raise

View File

@ -1,5 +1,11 @@
# coding=utf-8
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
import logging
import sys
import os

View File

@ -1,6 +1,13 @@
# -*- coding: utf-8 -*-
import config
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import str
from . import config
class RedfishException(Exception):
@ -32,16 +39,6 @@ class InvalidRedfishContentException(RedfishException):
' Most of the time you are not pointing to the rest API\n'
class NonTrustedCertificatException(RedfishException):
def __init__(self, message, **kwargs):
super(NonTrustedCertificatException, self).__init__(message, **kwargs)
self.advices = \
'1- Check if the url is the correct one\n' + \
'2- Check if your device has a valid trusted certificat\n' + \
' You can use openssl to validate it using the command :\n' + \
' openssl s_client -showcerts -connect <server>:443\n'
class AuthenticationFailureException(RedfishException):
def __init__(self, message, **kwargs):
super(AuthenticationFailureException, self).__init__(message, **kwargs)

View File

@ -1,3 +1,5 @@
# coding=utf-8
#
# Copyright 2014 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -114,17 +116,23 @@ Clients should always be prepared for:
* headers the service returns
"""
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import object
# coding=utf-8
import json
from urlparse import urlparse
from urllib.parse import urlparse
import requests
import config
import types
import mapping
import exception
from . import config
from . import types
from . import mapping
from . import exception
"""Function to wrap RedfishConnection"""
@ -199,10 +207,10 @@ class RedfishConnection(object):
"this is insecure and can allow" +
" a man in the middle attack")
config.logger.debug("Root url : %s", self.connection_parameters.rooturl)
config.logger.debug("Root url : %s",
self.connection_parameters.rooturl)
self.Root = types.Root(self.connection_parameters.rooturl,
self.connection_parameters
)
self.connection_parameters)
#self.api_url = tortilla.wrap(self.connection_parameters.rooturl,
# debug=TORTILLADEBUG)
#self.root = self.api_url.get(verify=self.connection_parameters.verify_cert)

View File

@ -1,4 +1,11 @@
# coding=utf-8
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import object
redfish_mapper = None
redfish_version = None

View File

@ -1,14 +1,22 @@
# coding=utf-8
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import object
import pprint
import re
from urlparse import urljoin
from urllib.parse import urljoin
import requests
import simplejson
import tortilla
import config
import mapping
import exception
import ssl
from . import config
from . import mapping
from . import exception
# Global variable
@ -24,15 +32,17 @@ class Base(object):
try:
if connection_parameters.auth_token is None:
self.data = self.api_url.get(verify=connection_parameters.verify_cert)
self.data = self.api_url.get(
verify=connection_parameters.verify_cert)
else:
self.data = self.api_url.get(verify=connection_parameters.verify_cert,
headers={'x-auth-token': connection_parameters.auth_token}
)
except requests.ConnectionError as e:
self.data = self.api_url.get(
verify=connection_parameters.verify_cert,
headers={
'x-auth-token': connection_parameters.auth_token})
except (requests.ConnectionError, ssl.SSLError) as e:
# Log and transmit the exception.
config.logger.info('Raise a RedfishException to upper level')
msg = 'Connection error : {}\n'.format(e.message)
msg = 'Connection error : {}\n'.format(e)
raise exception.ConnectionFailureException(msg)
except simplejson.scanner.JSONDecodeError as e:
# Log and transmit the exception.
@ -41,14 +51,6 @@ class Base(object):
'Ivalid content : Content does not appear to be a valid ' + \
'Redfish json\n'
raise exception.InvalidRedfishContentException(msg)
except TypeError as e:
# This happen connecting to a manager using non trusted
# SSL certificats.
# The exception is not what could be expected in such case but this
# is the one provided by Tortilla.
config.logger.info('Raise a RedfishException to upper level')
msg = 'Connection error\n'
raise exception.NonTrustedCertificatException(msg)
config.logger.debug(self.data)
def get_link_url(self, link_type):

View File

@ -8,3 +8,7 @@ Jinja2>=2.7.3
Sphinx>=1.2.3
docopt>=0.6.2
simplejson>=3.8.1
# Python3 compat
future>=0.15.2
configparser>=3.3.0; python_version < '3'

View File

@ -1,3 +1,10 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import object
#!/usr/bin/env python
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
@ -19,7 +26,7 @@ import fileinput
import re
import pprint
import distutils
import ConfigParser
import configparser
import setuptools
from setuptools import Distribution
from setuptools.command.install import install
@ -42,13 +49,13 @@ class OnlyGetScriptPath(install):
self.distribution.install_scripts = self.install_scripts
class DataFilesHelper():
class DataFilesHelper(object):
'''Class to help manage data files'''
def __init__(self):
'''Read setup.cfg and build the required data'''
self.data = {}
self.setupstruc = []
config = ConfigParser.ConfigParser()
config = configparser.ConfigParser()
config.read('setup.cfg')
for datafile in config.options('data_files_helper'):
src, dst = config.get('data_files_helper', datafile).split(',')
@ -65,7 +72,7 @@ class DataFilesHelper():
self.data['script'] = {'src': src,
'dst': 'bin',
'fdst': self.calculatedst(src, 'bin')}
except ConfigParser.NoOptionError:
except configparser.NoOptionError:
pass
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(self.data)