Skip to content

Commit

Permalink
Merge branch 'master' into indigo3
Browse files Browse the repository at this point in the history
  • Loading branch information
micafer authored Dec 15, 2017
2 parents 0cb9831 + 69229c7 commit 3f4abb9
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 12 deletions.
2 changes: 1 addition & 1 deletion IM/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@
'InfrastructureInfo', 'InfrastructureManager', 'recipe', 'request', 'REST', 'retry',
'ServiceRequests', 'SSH', 'SSHRetry', 'timedcall', 'UnixHTTPAdapter', 'uriparse',
'VirtualMachine', 'VMRC', 'xmlobject']
__version__ = '1.6.5'
__version__ = '1.6.6'
__author__ = 'Miguel Caballer'
39 changes: 33 additions & 6 deletions IM/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def getAuthInfoByID(self, auth_id):
"""
res = []
for auth in self.auth_list:
if auth['id'] == auth_id:
if 'id' in auth and auth['id'] == auth_id:
res.append(auth)
return res

Expand Down Expand Up @@ -114,22 +114,49 @@ def compare(self, other_auth, auth_type):

return True

@staticmethod
def split_line(line):
"""
Split line using ; as separator char
considering single quotes as a way to delimit
tokens. (in particular to enable using char ; inside a token)
"""
tokens = []
token = ""
in_qoutes = False
in_dqoutes = False
for char in line:
if char == '"' and not in_qoutes:
in_dqoutes = not in_dqoutes
elif char == "'" and not in_dqoutes:
in_qoutes = not in_qoutes
elif char == ";" and not in_qoutes and not in_dqoutes:
tokens.append(token)
token = ""
else:
token += char
# Add the last token
if token.strip() != "":
tokens.append(token)

return tokens

@staticmethod
def read_auth_data(filename):
"""
Read a file to load the Authentication data.
The file has the following format:
id = one; type = OpenNebula; host = osenserve:2633; username = user; password = pass
type = InfrastructureManager; username = user; password = pass
type = VMRC; host = http://server:8080/vmrc; username = user; password = pass
id = one; type = OpenNebula; host = oneserver:2633; username = user; password = pass
type = InfrastructureManager; username = user; password = 'pass;test'
type = VMRC; host = http://server:8080/vmrc; username = user; password = "pass';test"
id = ec2; type = EC2; username = ACCESS_KEY; password = SECRET_KEY
id = oshost; type = OpenStack; host = oshost:8773; username = ACCESS_KEY; key = SECRET_KEY
id = occi; type = OCCI; host = occiserver:4567; username = user; password = file(/tmp/filename)
id = occi; type = OCCI; proxy = file(/tmp/proxy.pem)
Arguments:
- filename(str): The filename to read
- filename(str or list): The filename to read or list of auth lines
Returns: a list with all the auth data
"""
Expand All @@ -146,7 +173,7 @@ def read_auth_data(filename):
line = line.strip()
if len(line) > 0 and not line.startswith("#"):
auth = {}
tokens = line.split(";")
tokens = Authentication.split_line(line)
for token in tokens:
key_value = token.split(" = ")
if len(key_value) != 2:
Expand Down
7 changes: 7 additions & 0 deletions changelog
Original file line number Diff line number Diff line change
Expand Up @@ -362,3 +362,10 @@ IM 1.6.5
* Homogenize Inf ID log message
* Fix error cpu.count parameter is ignored in OpenStack conn.
* Fix ansible_version is not available in ctxt process.

IM 1.6.6
* Fix authorization file format does not allow passwords that contain ";".
* Improve error message in ONE conn in case net without leases.
* Fix error using disks.free_size in connectors.
* Add retries in Azure RG deletion.
* Avoid raising error in case that one auth line does not have the type field.
10 changes: 8 additions & 2 deletions doc/source/client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,14 @@ this::

id = id_value ; type = value_of_type ; username = value_of_username ; password = value_of_password

Values can contain "=", and "\\n" is replaced by carriage return. The available
keys are:
Values can contain "=", and "\\n" is replaced by carriage return.
You can also delimit the values using single or double quotes (e.g. if a semicolon or some quote character
appear in a value)(from version 1.6.6)::

id = id_value ; type = value_of_type ; username = value_of_username ; password = 'some;"password'
id = id_value ; type = value_of_type ; username = value_of_username ; password = "some;'password"

The available keys are:

* ``type`` indicates the service that refers the credential. The services
supported are ``InfrastructureManager``, ``VMRC``, ``OpenNebula``, ``EC2``,, ``FogBow``,
Expand Down
2 changes: 1 addition & 1 deletion docker-devel/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
FROM grycap/jenkins:ubuntu16.04-im
ARG BRANCH=devel
MAINTAINER Miguel Caballer <[email protected]>
LABEL version="1.6.5"
LABEL version="1.6.6"
LABEL description="Container image to run the IM service. (http://www.grycap.upv.es/im)"

EXPOSE 8899 8800
Expand Down
4 changes: 2 additions & 2 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Dockerfile to create a container with the IM service
FROM ubuntu:16.04
LABEL maintainer="Miguel Caballer <[email protected]>"
LABEL version="1.6.5"
LABEL version="1.6.6"
LABEL description="Container image to run the IM service. (http://www.grycap.upv.es/im)"
EXPOSE 8899 8800

Expand All @@ -18,7 +18,7 @@ RUN pip install msrest msrestazure azure-common azure-mgmt-storage azure-mgmt-co
RUN apt-get update && apt-get install --no-install-recommends -y gcc libmysqld-dev libssl-dev libffi-dev libsqlite3-dev && \
pip install MySQL-python && \
pip install xmltodict && \
pip install IM==1.6.5 && \
pip install IM==1.6.6 && \
apt-get remove -y gcc libmysqld-dev libssl-dev libffi-dev libsqlite3-dev python-dev python-pip && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*
Expand Down
4 changes: 4 additions & 0 deletions test/files/auth.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
type = InfrastructureManager; username = someurser; password = somepass
type = VMRC; host = http://server:8080/vmrc/vmrc; username = user; password = pass
id = one2; type = OpenNebula; host = server1.com:2633; username = user; password = pass
id = occi; type = OCCI; proxy = file(/tmp/privatekey.pem); host = https://server.com:11443
67 changes: 67 additions & 0 deletions test/unit/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#! /usr/bin/env python
#
# IM - Infrastructure Manager
# Copyright (C) 2011 - GRyCAP - Universitat Politecnica de Valencia
#
# 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 3 of the License, or
# (at your option) 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, see <http://www.gnu.org/licenses/>.

import unittest
import os
import shutil

from IM.auth import Authentication


class TestAuth(unittest.TestCase):
"""
Class to test the Authentication class
"""

def test_auth_read(self):
auth_lines = ["""id = 1; type = InfrastructureManager; username = someuser; password = somepass """,
"""id = 2; type = VMRC; username = someuser; password = somepass; """,
"""id = 3; type = OpenNebula; username = someuser; password = "some;'pass" """,
"""id = 4; type = EC2; username = someuser; password = 'some;"pass' """]
auth = Authentication.read_auth_data(auth_lines)
self.assertEqual(auth, [{'id': '1', 'password': "somepass",
'type': 'InfrastructureManager', 'username': 'someuser'},
{'id': '2', 'password': "somepass",
'type': 'VMRC', 'username': 'someuser'},
{'id': '3', 'password': "some;'pass",
'type': 'OpenNebula', 'username': 'someuser'},
{'id': '4', 'password': 'some;"pass',
'type': 'EC2', 'username': 'someuser'}])

tests_path = os.path.dirname(os.path.abspath(__file__))
shutil.copyfile(os.path.join(tests_path, "../files/privatekey.pem"), "/tmp/privatekey.pem")
auth = Authentication(Authentication.read_auth_data(os.path.join(tests_path, "../files/auth.dat")))
auth_data = auth.getAuthInfoByID("occi")
self.assertEqual(auth_data[0]['proxy'][:37], "-----BEGIN RSA PRIVATE KEY-----\nMIIEo")
os.unlink("/tmp/privatekey.pem")


def test_get_auth(self):
auth_lines = ["""id = 1; type = InfrastructureManager; username = someuser; password = somepass """,
"""id = 2; type = VMRC; username = someuser; password = somepass; """]
auth = Authentication(Authentication.read_auth_data(auth_lines))
auth_data = auth.getAuthInfoByID("1")
self.assertEqual(auth_data, [{'id': '1', 'password': "somepass",
'type': 'InfrastructureManager', 'username': 'someuser'}])
auth_data = auth.getAuthInfo("VMRC")
self.assertEqual(auth_data, [{'id': '2', 'password': "somepass",
'type': 'VMRC', 'username': 'someuser'}])


if __name__ == '__main__':
unittest.main()

0 comments on commit 3f4abb9

Please sign in to comment.