Skip to content
This repository has been archived by the owner on Jul 28, 2023. It is now read-only.

Commit

Permalink
Merge upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
micafer committed Jul 26, 2016
2 parents 2baafb6 + 147dc31 commit 84c7d50
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 53 deletions.
39 changes: 22 additions & 17 deletions IM/connectors/Azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,12 @@ def gen_input_endpoints(self, radl):
# SSH port must be allways available
res = """
<InputEndpoints>
<InputEndpoint>
<LocalPort>3389</LocalPort>
<Name>RDP</Name>
<Port>3389</Port>
<Protocol>TCP</Protocol>
</InputEndpoint>
<InputEndpoint>
<LocalPort>5986</LocalPort>
<Name>WinRM</Name>
Expand All @@ -215,7 +221,7 @@ def gen_input_endpoints(self, radl):
outports = public_net.getOutPorts()
if outports:
for remote_port, remote_protocol, local_port, local_protocol in outports:
if local_port != 22 and local_port != 5986:
if local_port != 22 and local_port != 5986 and local_port != 3389:
protocol = remote_protocol
if remote_protocol != local_protocol:
self.logger.warn(
Expand Down Expand Up @@ -334,8 +340,9 @@ def get_azure_vm_create_xml(self, vm, storage_account, radl, num, auth_data):
hostname = "AzureNode" + str(num)

SourceImageName = url[1]
MediaLink = "https://%s.blob.core.windows.net/vhds/%s.vhd" % (
storage_account, SourceImageName)
MediaLink = "https://%s.blob.core.windows.net/vhds/%s" % (storage_account, SourceImageName)
if not MediaLink.endswith('.vhd'):
MediaLink = MediaLink + '.vhd'
instance_type = self.get_instance_type(system, auth_data)

DataVirtualHardDisks = self.gen_data_disks(system, storage_account)
Expand Down Expand Up @@ -531,9 +538,11 @@ def wait_operation_status(self, request_id, auth_data, delay=2, timeout=90):
self.logger.exception("Error waiting the operation")
return False

def get_storage_name(self, subscription_id):
res = subscription_id.replace("-", "")[:24]
return res
def get_storage_name(self, subscription_id, region=None):
if not region:
region = self.DEFAULT_LOCATION
res = region.replace(" ", "").lower() + subscription_id.replace("-", "")
return res[:24]

def create_storage_account(self, storage_account, auth_data, region, timeout=120):
"""
Expand Down Expand Up @@ -656,16 +665,14 @@ def launch(self, inf, radl, requested_radl, num_vm, auth_data):
i = 0
while i < num_vm:
try:
conn, subscription_id = self.get_connection_and_subscription_id(
auth_data)
conn, subscription_id = self.get_connection_and_subscription_id(auth_data)

# Create storage account
storage_account_name = self.get_storage_name(subscription_id)
storage_account = self.get_storage_account(
storage_account_name, auth_data)
storage_account_name = self.get_storage_name(subscription_id, region)
storage_account = self.get_storage_account(storage_account_name, auth_data)
if not storage_account:
storage_account_name, error_msg = self.create_storage_account(
self.get_storage_name(subscription_id), auth_data, region)
storage_account_name, error_msg = self.create_storage_account(storage_account_name,
auth_data, region)
if not storage_account_name:
res.append((False, error_msg))
break
Expand All @@ -683,17 +690,15 @@ def launch(self, inf, radl, requested_radl, num_vm, auth_data):
region = storage_account.GeoPrimaryRegion

# and the service
service_name, error_msg = self.create_service(
auth_data, region)
service_name, error_msg = self.create_service(auth_data, region)
if service_name is None:
res.append((False, error_msg))
break

self.logger.debug("Creating the VM with id: " + service_name)

# Create the VM to get the nodename
vm = VirtualMachine(inf, service_name,
self.cloud, radl, requested_radl, self)
vm = VirtualMachine(inf, service_name, self.cloud, radl, requested_radl, self)
vm.info.systems[0].setValue('instance_id', str(vm.id))

# Generate the XML to create the VM
Expand Down
1 change: 1 addition & 0 deletions changelog
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,4 @@ IM 1.4.6
* Add ANSIBLE_INSTALL_TIMEOUT var
* Create user with cloudinit in OpenStack connector
* Improve error msg in ssh wait
* Bugfixes in Azure connector
72 changes: 39 additions & 33 deletions doc/source/manual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,8 @@ IM needs at least Python 2.6 to run, as well as the next libraries:
Also, IM uses `Ansible <http://www.ansible.com>`_ (1.4.2 or later) to configure the
infrastructure nodes. The current recommended version is 1.9.4 untill the 2.X versions become stable.

These components are usually available from the distribution repositories. To
install them in Debian and Ubuntu based distributions, do::

$ apt-get install python-ply python-paramiko python-yaml python-soappy python-netaddr python-boto python-libcloud ansible

In Red Hat based distributions (RHEL, CentOS, Amazon Linux, Oracle Linux,
Fedora, etc.), do::

$ yum install python-ply python-paramiko python-netaddr PyYAML SOAPpy python-boto python-libcloud ansible
These components are usually available from the distribution repositories.

**WARNING: In some GNU/Linux distributions (RHEL 6 or equivalents) you must NOT install
the packages 'python-paramiko' and 'python-crypto' with yum. You MUST use pip to install them**

Finally, check the next values in the Ansible configuration file
:file:`ansible.cfg`, (usually found in :file:`/etc/ansible`)::

Expand Down Expand Up @@ -78,12 +67,48 @@ Optional Packages
with SSL certificates (see :confval:`REST_SSL`).
The Debian package for CherryPy is named ``python-cherrypy3``.
pyOpenSSL can be installed using pip.
* `MySQL <https://www.mysql.com/>`_ is needed if the IM data is going to be stored in DB.
(see DATA_DB configuration variable.

Installation
------------

From RPM packages (RH6 and RH7)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
From Pip (Recommended option)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**WARNING: In some linux old distributions (REL 6 or equivalents) you must unistall
the package python-crypto and python-paramiko before installing the IM with pip.**::

$ rpm -e python-crypto python-paramiko --nodeps

First you need to install pip tool and some packages needed to compile some of the IM requirements.
To install them in Debian and Ubuntu based distributions, do::

$ apt update
$ apt install gcc python-dev libffi-dev libssl-dev python-pip sshpass

In Red Hat based distributions (RHEL, CentOS, Amazon Linux, Oracle Linux,
Fedora, etc.), do::

$ yum install epel-release
$ yum install which gcc python-devel libffi-devel openssl-devel python-pip sshpass

For some problems with the dependencies of the apache-libcloud package in some systems (as ubuntu 14.04 or CentOS 6)
this package has to be installed manually::

$ pip install backports-ssl_match_hostname

Then you only have to call the install command of the pip tool with the IM package::

$ pip install IM

Pip will also install the, non installed, pre-requisites needed. So Ansible 1.4.2 or later will
be installed in the system.

You must also remember to modify the ansible.cfg file setting as specified in the
REQUISITES section.

From RPM packages (RH7)
^^^^^^^^^^^^^^^^^^^^^^^
Download the RPM package from `GitHub <https://github.com/grycap/im/releases/latest>`_.
Also remember to download the RPM of the RADL package also from `GitHub <https://github.com/grycap/radl/releases/latest>`_.
You must have the epel repository enabled::
Expand Down Expand Up @@ -117,25 +142,6 @@ Put all the .deb files in the same directory and do::
$ sudo dpkg -i *.deb
$ sudo apt install -f -y

From Pip
^^^^^^^^

**WARNING: In some linux distributions (REL 6 or equivalents) you must unistall
the packages python-paramiko and python-crypto before installing the IM with pip.**

You only have to call the install command of the pip tool with the IM package::

$ pip install IM

Pip will install all the pre-requisites needed. So Ansible 1.4.2 or later will
be installed in the system. Yo will also need to install the sshpass command
('sshpass' package in main distributions). In some cases it will need to have installed
the GCC compiler and the python developer libraries ('python-dev' or 'python-devel'
packages in main distributions).

You must also remember to modify the ansible.cfg file setting as specified in the
REQUISITES section.

From Source
^^^^^^^^^^^

Expand Down
4 changes: 2 additions & 2 deletions packages/generate_rpm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

yum -y install rpm-build python-setuptools
echo "%_unpackaged_files_terminate_build 0" > ~/.rpmmacros
python setup.py bdist_rpm --release="$1" --requires="tosca-parser, RADL, ansible, python-paramiko, PyYAML, SOAPpy, python-boto >= 2.29, python-libcloud, python-bottle, python-netaddr, python-scp"
python setup.py bdist_rpm --release="$1" --requires="which, tosca-parser, RADL, ansible, python-paramiko, PyYAML, SOAPpy, python-boto >= 2.29, python-libcloud, python-bottle, python-netaddr, python-scp"
mkdir dist_pkg
cp dist/*.noarch.rpm dist_pkg
cp dist/*.noarch.rpm dist_pkg
1 change: 1 addition & 0 deletions test/files/inventory
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
localhost
27 changes: 27 additions & 0 deletions test/files/play.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
- hosts: localhost
connection: local
tasks:
- command: /bin/true
- command: /bin/true {{item}}
with_items:
- OK1
- OK2
- debug: msg=OK
- debug: msg=OK
when: 0 == 1
- debug: msg={{item}}
with_items:
- OK1
- OK2
- debug: msg={{item}}
with_items:
- OK1
- OK2
when: 0 == 1
- fail: msg={{item}}
with_items:
- Error1
- Error2
ignore_errors: yes
- fail: msg=Error
ignore_errors: yes
2 changes: 1 addition & 1 deletion test/integration/TestIM.py
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ def test_75_destroy(self):

def test_80_create_ansible_host(self):
"""
Test the CreateInfrastructure IM function
Test the CreateInfrastructure IM function using an external ansible host
"""
ansible_radl = """
network publicnet (outbound = 'yes')
Expand Down
50 changes: 50 additions & 0 deletions test/unit/test_ansible.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#! /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
from multiprocessing import Queue
from StringIO import StringIO
import time

from IM.ansible.ansible_launcher import AnsibleThread
from mock import patch, MagicMock


class TestAnsible(unittest.TestCase):
"""
Class to test the Ansible related classes
"""

def test_ansible_thread(self):
result = Queue()
tests_path = os.path.dirname(os.path.abspath(__file__))
play_file_path = os.path.join(tests_path, "../files/play.yaml")
inventory = os.path.join(tests_path, "../files/inventory")
ansible_process = AnsibleThread(result, StringIO(), play_file_path, None, 1, None,
"password", 1, inventory, "username")
ansible_process.run()

_, (return_code, _), output = result.get()
self.assertEqual(return_code, 0)
self.assertIn("failed=0", output.getvalue())
self.assertIn("changed=2", output.getvalue())
print output.getvalue()

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

0 comments on commit 84c7d50

Please sign in to comment.