diff --git a/.gitignore b/.gitignore index 358d7e2..ea278a3 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ coverage.xml nosetests.xml target +build/ +*.egg-info/ +.eggs/ .vagrant/ *.iml *.imr diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 6f8f393..0000000 --- a/Dockerfile +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2015 CenturyLink -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -FROM ansible/centos7-ansible -MAINTAINER WFaaS - -# install git and add the pub key -RUN yum install -y git -RUN yum install -y epel-release -RUN yum install -y python-pip -RUN yum install -y gcc -RUN yum install -y pycrypto - -# create an ansible.cfg -RUN echo "[defaults]" > /etc/ansible/ansible.cfg -RUN echo "inventory = /bin/clc_inv.py" >> /etc/ansible/ansible.cfg - -## add clc sdk and module -RUN pip install clc-sdk==2.44 clc-ansible-module - -## Set ANSIBLE_LIBRARY path -ENV ANSIBLE_LIBRARY /usr/lib/python2.7/site-packages/clc_ansible_module/ diff --git a/README.md b/README.md index ae18eb7..6ef5527 100644 --- a/README.md +++ b/README.md @@ -7,31 +7,33 @@ These are additional, unofficial Ansible modules for managing CenturyLink Cloud. ### Installation -``` +```bash sudo pip install clc-ansible-module ``` -
To use this, add the python dist/site-packages directory to to the ***ANSIBLE_LIBRARY*** environment variable, or symlink this directory to ./library underneath the directory containing the playbook that needs it. -The installation will install a dynamic inventory script to /usr/local/bin. In order to use the script you will need to fully reference the clc\_inv.py script with each Ansible command. You can avoid having to enter in this script for each command by creating a symlink in /etc/ansible to this script as such:
-``` +To use this, add the python dist/site-packages directory to to the ***ANSIBLE_LIBRARY*** environment variable, or symlink this directory to ./library underneath the directory containing the playbook that needs it. + +The installation will install a dynamic inventory script to /usr/local/bin. In order to use the script you will need to fully reference the clc\_inv.py script with each Ansible command. You can avoid having to enter in this script for each command by creating a symlink in /etc/ansible to this script as such: + +```bash ln -s /usr/local/bin/clc_inv.py /etc/ansible/hosts ``` ####Validation Validate that the clc-ansible-module package has been installed and is functioning: -``` +```bash ansible all -i /usr/local/bin/clc_inv.py --list-hosts ``` -
+ Validate that all packages are install and configured: -``` +```bash ansible-playbook -i /usr/local/bin/clc_inv.py my-playbook.yml ``` ####Dependencies This module has one dependency The [clc-python-sdk](https://github.com/CenturyLinkCloud/clc-python-sdk). You can install it with pip -``` +```bash sudo pip install clc-sdk ``` @@ -40,7 +42,7 @@ sudo pip install clc-sdk In order to use these playbooks, you must set the following environment variables: -``` +```bash export CLC_V2_API_USERNAME= export CLC_V2_API_PASSWD= ``` @@ -87,6 +89,7 @@ If you just specify *count* instead of *exact_count*, the module runs in non-ide - name: debug debug: var=clc.server_ids ``` + ```yaml --- - name: Create a Linux Server with 3 GBs of app space @@ -106,6 +109,7 @@ If you just specify *count* instead of *exact_count*, the module runs in non-ide - name: debug debug: var=clc ``` + ```yaml --- - name: Sample playbook which executes a blueprint package post build. @@ -290,6 +294,7 @@ Retrieve facts about servers in Centurylink Cloud. clc_server_fact: server_id: UC1ACCTSRVR10 ``` + ```yaml - name: Retrieve Server Facts With Credentials clc_server_fact: @@ -325,7 +330,8 @@ Create or deletes Server Groups at CenturyLink Cloud. - name: debug debug: var=clc ``` -``` + +```yaml --- - name: Delete Server Group hosts: localhost @@ -358,6 +364,7 @@ Retrieve facts about groups in Centurylink Cloud. ###Example Playbook ```yaml +--- - name: Retrieve Group Facts clc_group_fact: group_id: 31d13f501459411ba59304f3d47486eb @@ -370,7 +377,7 @@ Retrieve facts about groups in Centurylink Cloud. ## clc_aa_policy Module -Create or deletes Anti Affinity Policities at CenturyLink Cloud. +Create or deletes Anti Affinity Policies at CenturyLink Cloud. ###Example Playbook ```yaml @@ -390,7 +397,8 @@ Create or deletes Anti Affinity Policities at CenturyLink Cloud. - name: debug debug: var=policy ``` -``` + +```yaml --- - name: Delete AA Policy hosts: localhost @@ -444,6 +452,7 @@ Creates a public ip on an existing server or servers. - name: debug debug: var=clc ``` + ```yaml --- - name: Delete Public IP from Server @@ -493,6 +502,7 @@ Create/Delete/Restore a snapshot on an existing server or servers. wait: True state: present ``` + ```yaml --- - name: Restore a snapshot on a set of servers @@ -508,6 +518,7 @@ Create/Delete/Restore a snapshot on an existing server or servers. wait: True state: restore ``` + ```yaml --- - name: Delete a snapshot on a set of servers @@ -539,7 +550,6 @@ Executes a blue print package on existing set of servers. ### Example Playbook ```yaml --- ---- - name: Install a blue print package on set of servers hosts: localhost gather_facts: False @@ -588,6 +598,7 @@ Create/Delete a loadbalancer - { 'ipAddress': '10.82.152.16', 'privatePort': 80 } state: present ``` + ```yaml --- - name: Delete LoadbalancerPool @@ -603,6 +614,7 @@ Create/Delete a loadbalancer port: 443 state: port_absent ``` + ```yaml --- - name: Add nodes to an existing loadbalancer pool @@ -621,6 +633,7 @@ Create/Delete a loadbalancer - { 'ipAddress': '10.82.152.18', 'privatePort': 80 } state: nodes_present ``` + ```yaml --- - name: Remove nodes from an existing loadbalancer pool @@ -639,6 +652,7 @@ Create/Delete a loadbalancer - { 'ipAddress': '10.82.152.18', 'privatePort': 80 } state: nodes_absent ``` + ```yaml --- - name: Delete Loadbalancer @@ -690,6 +704,7 @@ Create/Update/Delete an alert policy in CLC threshold: 80 state: present ``` + ```yaml --- - name: Delete alert policy example @@ -739,6 +754,7 @@ Create/Delete a Firewall Policy ports: ['any'] destination_account_alias: WFAD ``` + ```yaml --- - name: Delete Firewall Policy @@ -793,7 +809,8 @@ Create or delete Network at CenturyLink Cloud. - debug: var=net ``` -``` + +```yaml --- - name: Delete Network hosts: localhost @@ -843,7 +860,7 @@ ansible all -i inventory/clc_inv.py -m ping Access the CLC hostvars from a play defined in yaml: -```JSON +```yaml --- - name: Read Hostvars for Servers hosts: all @@ -860,20 +877,14 @@ Our recommended approach to working with the clc-ansible-module code base is to ### Create a virtual environment - move to your normal development space on your system. We will be creating our virtual environment in this location. - Execute:` - virtualenv clc-ansible-module - ` +`virtualenv clc-ansible-module` +` - Make the virutual environment active:` - . ./clc-ansible-module/bin/activate - ` +`. ./clc-ansible-module/bin/activate` + ### Install necessary dependencies -- `pip install nose` -- `pip install coverage` -- `pip install pybuilder==0.10.63` -- `pip install mock` -- `pip install xmlrunner` -- `pip install ansible` -- `pip install clc_sdk=2.44` +- `pip install -r requirements.txt` ### Last minute updates to your environment Update your active PATH with reference some binaries we just installed. @@ -881,23 +892,28 @@ Update your active PATH with reference some binaries we just installed. `export PATH='pwd'/clc-ansible-module/bin:$PATH` ### Get the project -- `cd clc-ansible-module` -- `mkdir workspace` -- `cd workspace` -- `git clone https://github.com/CenturyLinkCloud/clc-ansible-module.git` -- `cd clc-ansible-module` +```bash +cd clc-ansible-module +mkdir workspace +cd workspace +git clone https://github.com/CenturyLinkCloud/clc-ansible-module.git +cd clc-ansible-module +``` ### Build the project -- `mvn clean install` - - This step isn't required to build the module set. It's primarily used to help the Runner team manage changes and releases. -- `pyb -v` +```bash +python ./setup.py build +python ./setup.py install +``` +- This step isn't required to build the module set. It's primarily used to help the Runner team manage changes and releases. ### Submitting Changes #####PR's are welcome! Please create an Issue in Github against the project prior to doing any custom work or submitting a PR. -All changes must be submitted as PR's against the Develop branch (Github Pull Requests). - `git checkout develop` +All changes must be submitted as PR's against the Develop branch (Github Pull Requests). - +`git checkout develop` Please create one PR for each change. Please keep the change small and specific. diff --git a/Vagrantfile b/Vagrantfile deleted file mode 100644 index c9ba95d..0000000 --- a/Vagrantfile +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2015 CenturyLink -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Vagrant.configure(2) do |config| - config.vm.box = "chef/centos-6.6" - config.vm.synced_folder "src/main/python/", "/usr/local/lib/" - config.vm.provision "shell", inline: <<-SHELL - sudo yum install -y epel-release - sudo yum install -y python-pip - sudo yum install -y gcc - sudo yum install -y pycrypto - sudo pip install ansible - sudo pip install clc-sdk - mkdir /etc/ansible && sudo ln -s /usr/local/lib/clc_inv.py /etc/ansible/hosts - echo "export ANSIBLE_LIBRARY=/usr/local/lib/clc_ansible_module" >> /home/vagrant/.bashrc - SHELL -end diff --git a/assembly.xml b/assembly.xml deleted file mode 100644 index 319428e..0000000 --- a/assembly.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - project - - zip - tar.gz - - - - ${basedir} - - ${project.build.directory}/** - assembly.xml - pom.xml - - - - diff --git a/build.py b/build.py deleted file mode 100644 index dee986a..0000000 --- a/build.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright 2015 CenturyLink -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -from pybuilder.core import init, use_plugin, Author, before - -# declare specific plugins we need to use: -use_plugin("python.core") -use_plugin("python.unittest") -use_plugin("python.coverage") -use_plugin("python.distutils") -use_plugin("filter_resources") -use_plugin("copy_resources") -use_plugin("source_distribution") -use_plugin("python.sonarqube") -use_plugin("exec") - -# define project level attributes: -name = 'clc-ansible-module' -version = '1.1.14' -summary = "Centurylink Cloud Ansible Modules" -description = "Ansible extension modules which allow users to interact with Centurylink Cloud to define and manage cloud components." -authors = [Author ("CenturyLink Cloud", "WFAAS-LLFT@centurylink.com")] -url = 'http://www.centurylinkcloud.com' -license = "CTL Corporate License" -keywords = "centurylink cloud clc ansible modules" - -# targets are: -# clean compile_sources init package prepare -# publish run_integration_tests run_unit_tests verify -default_task="publish" -@init -def initialize( project ): - # define unit test preferences and behavours: - # project.set_property("run_unit_tests_command", "export PYTHONPATH=%s:$PYTHONPATH nosetests -w src/unittest/python" % project.expand_path("$dir_source_main_python")) - project.set_property("run_unit_tests_command", "export PYTHONPATH=$PYTHONPATH:%s;PYTHONPATH=src/main/python nosetests -w %s --exe -v --with-xunit --xunit-file=target/reports/nosetests_results.xml" % (project.expand_path("$dir_source_main_python"), project.expand_path("$dir_source_unittest_python"))) - project.set_property("run_unit_tests_propagate_stdout", True) - project.set_property("run_unit_tests_propagate_stderr", True) - project.set_property('unittest_module_glob','test_*') - project.set_property('coverage_threshold_warn',0) - project.set_property('coverage_break_build', False) - # ---------------- - # identify all the module source locations: - project.get_property('filter_resources_glob').append('**/clc_ansible_module/*.py') - # ---------------- - # install clc-sdk during installation - project.depends_on("clc-sdk", "==2.45") - # ---------------- - # execute some installation scripts - project.set_property('dir_source_main_scripts', 'src/main/python') - # ---------------- - project.set_property('sonar.projectKey', 'com.ctlts:clc-ansible-module') - project.set_property('sonar.projectName', name) - project.set_property('sonar.projectVersion', version) - project.set_property('sonar.sources','src/main/python/clc-ansible-module') - project.set_property('sonar.tests','src/unittests') - project.set_property('sonar.python.coverage.reportPath','target/reports/coverage.xml') - project.set_property('sonar.python.coveragePlugin','cobertura') - # identify resource files which should be part of the distribution - # TODO: would like to include the exampls in the distro but it is currently not working as expected. - # project.set_property('copy_resources_target', '$dir_target') - # project.get_property('copy_resources_glob').append('**/example-playbooks/__init__.py') - # project.include_file('clc-ansible-module-0.0.4','deploy-servers-to-maint-grp-size.yml') - # ---------------- diff --git a/src/main/python/clc_ansible_module/__init__.py b/clc_ansible_module/__init__.py similarity index 100% rename from src/main/python/clc_ansible_module/__init__.py rename to clc_ansible_module/__init__.py diff --git a/src/main/python/clc_ansible_module/clc_aa_policy.py b/clc_ansible_module/clc_aa_policy.py similarity index 99% rename from src/main/python/clc_ansible_module/clc_aa_policy.py rename to clc_ansible_module/clc_aa_policy.py index 4833ffb..bf9c83d 100644 --- a/src/main/python/clc_ansible_module/clc_aa_policy.py +++ b/clc_ansible_module/clc_aa_policy.py @@ -165,7 +165,7 @@ CLC_FOUND = True -class ClcAntiAffinityPolicy: +class ClcAntiAffinityPolicy(object): clc = clc_sdk module = None @@ -278,7 +278,7 @@ def _create_policy(self, p): return self.clc.v2.AntiAffinity.Create( name=p['name'], location=p['location']) - except CLCException, ex: + except CLCException as ex: self.module.fail_json(msg='Failed to create anti affinity policy : {0}. {1}'.format( p['name'], ex.response_text )) @@ -292,7 +292,7 @@ def _delete_policy(self, p): try: policy = self.policy_dict[p['name']] policy.Delete() - except CLCException, ex: + except CLCException as ex: self.module.fail_json(msg='Failed to delete anti affinity policy : {0}. {1}'.format( p['name'], ex.response_text )) diff --git a/src/main/python/clc_ansible_module/clc_alert_policy.py b/clc_ansible_module/clc_alert_policy.py similarity index 99% rename from src/main/python/clc_ansible_module/clc_alert_policy.py rename to clc_ansible_module/clc_alert_policy.py index 641aa34..dc823d2 100644 --- a/src/main/python/clc_ansible_module/clc_alert_policy.py +++ b/clc_ansible_module/clc_alert_policy.py @@ -208,7 +208,7 @@ CLC_FOUND = True -class ClcAlertPolicy: +class ClcAlertPolicy(object): clc = clc_sdk module = None diff --git a/src/main/python/clc_ansible_module/clc_blueprint_package.py b/clc_ansible_module/clc_blueprint_package.py similarity index 99% rename from src/main/python/clc_ansible_module/clc_blueprint_package.py rename to clc_ansible_module/clc_blueprint_package.py index 456e06d..b170a14 100644 --- a/src/main/python/clc_ansible_module/clc_blueprint_package.py +++ b/clc_ansible_module/clc_blueprint_package.py @@ -129,7 +129,7 @@ CLC_FOUND = True -class ClcBlueprintPackage: +class ClcBlueprintPackage(object): clc = clc_sdk module = None diff --git a/src/main/python/clc_ansible_module/clc_firewall_policy.py b/clc_ansible_module/clc_firewall_policy.py similarity index 99% rename from src/main/python/clc_ansible_module/clc_firewall_policy.py rename to clc_ansible_module/clc_firewall_policy.py index e875bb9..28b2541 100644 --- a/src/main/python/clc_ansible_module/clc_firewall_policy.py +++ b/clc_ansible_module/clc_firewall_policy.py @@ -185,7 +185,9 @@ __version__ = '${version}' -import urlparse +from future import standard_library +standard_library.install_aliases() +import urllib.parse from time import sleep from distutils.version import LooseVersion @@ -207,7 +209,7 @@ CLC_FOUND = True -class ClcFirewallPolicy: +class ClcFirewallPolicy(object): clc = None @@ -306,7 +308,7 @@ def _get_policy_id_from_response(response): :return: policy_id: firewall policy id from creation call """ url = response.get('links')[0]['href'] - path = urlparse.urlparse(url).path + path = urllib.parse.urlparse(url).path path_list = os.path.split(path) policy_id = path_list[-1] return policy_id diff --git a/src/main/python/clc_ansible_module/clc_group.py b/clc_ansible_module/clc_group.py similarity index 99% rename from src/main/python/clc_ansible_module/clc_group.py rename to clc_ansible_module/clc_group.py index 50e4deb..833920b 100644 --- a/src/main/python/clc_ansible_module/clc_group.py +++ b/clc_ansible_module/clc_group.py @@ -374,7 +374,7 @@ def _delete_group(self, group_name): group, parent = self.group_dict.get(group_name) try: response = group.Delete() - except CLCException, ex: + except CLCException as ex: self.module.fail_json(msg='Failed to delete group :{0}. {1}'.format( group_name, ex.response_text )) @@ -435,7 +435,7 @@ def _create_group(self, group, parent, description): (parent, grandparent) = self.group_dict[parent] try: response = parent.Create(name=group, description=description) - except CLCException, ex: + except CLCException as ex: self.module.fail_json(msg='Failed to create group :{0}. {1}'.format( group, ex.response_text)) return response diff --git a/src/main/python/clc_ansible_module/clc_group_fact.py b/clc_ansible_module/clc_group_fact.py similarity index 99% rename from src/main/python/clc_ansible_module/clc_group_fact.py rename to clc_ansible_module/clc_group_fact.py index 0468b32..53f5cff 100644 --- a/src/main/python/clc_ansible_module/clc_group_fact.py +++ b/clc_ansible_module/clc_group_fact.py @@ -200,7 +200,7 @@ REQUESTS_FOUND = True -class ClcGroupFact: +class ClcGroupFact(object): def __init__(self, module): """ diff --git a/src/main/python/clc_ansible_module/clc_loadbalancer.py b/clc_ansible_module/clc_loadbalancer.py similarity index 99% rename from src/main/python/clc_ansible_module/clc_loadbalancer.py rename to clc_ansible_module/clc_loadbalancer.py index 2c99735..0833f3d 100644 --- a/src/main/python/clc_ansible_module/clc_loadbalancer.py +++ b/clc_ansible_module/clc_loadbalancer.py @@ -248,7 +248,7 @@ CLC_FOUND = True -class ClcLoadBalancer: +class ClcLoadBalancer(object): clc = None diff --git a/src/main/python/clc_ansible_module/clc_loadbalancer_fact.py b/clc_ansible_module/clc_loadbalancer_fact.py similarity index 99% rename from src/main/python/clc_ansible_module/clc_loadbalancer_fact.py rename to clc_ansible_module/clc_loadbalancer_fact.py index 8dbc3f0..55bec62 100644 --- a/src/main/python/clc_ansible_module/clc_loadbalancer_fact.py +++ b/clc_ansible_module/clc_loadbalancer_fact.py @@ -170,7 +170,7 @@ CLC_FOUND = True -class ClcLoadbalancerFact: +class ClcLoadbalancerFact(object): def __init__(self, module): """ diff --git a/src/main/python/clc_ansible_module/clc_modify_server.py b/clc_ansible_module/clc_modify_server.py similarity index 99% rename from src/main/python/clc_ansible_module/clc_modify_server.py rename to clc_ansible_module/clc_modify_server.py index c4f0014..639f452 100644 --- a/src/main/python/clc_ansible_module/clc_modify_server.py +++ b/clc_ansible_module/clc_modify_server.py @@ -382,7 +382,7 @@ CLC_FOUND = True -class ClcModifyServer: +class ClcModifyServer(object): clc = clc_sdk def __init__(self, module): diff --git a/src/main/python/clc_ansible_module/clc_network.py b/clc_ansible_module/clc_network.py similarity index 99% rename from src/main/python/clc_ansible_module/clc_network.py rename to clc_ansible_module/clc_network.py index 958cd94..973d522 100644 --- a/src/main/python/clc_ansible_module/clc_network.py +++ b/clc_ansible_module/clc_network.py @@ -184,7 +184,7 @@ CLC_FOUND = True -class ClcNetwork: +class ClcNetwork(object): clc = clc_sdk module = None diff --git a/src/main/python/clc_ansible_module/clc_network_fact.py b/clc_ansible_module/clc_network_fact.py similarity index 99% rename from src/main/python/clc_ansible_module/clc_network_fact.py rename to clc_ansible_module/clc_network_fact.py index 3e33278..8e91242 100644 --- a/src/main/python/clc_ansible_module/clc_network_fact.py +++ b/clc_ansible_module/clc_network_fact.py @@ -139,7 +139,7 @@ CLC_FOUND = True -class ClcNetworkFact: +class ClcNetworkFact(object): def __init__(self, module): """ diff --git a/src/main/python/clc_ansible_module/clc_publicip.py b/clc_ansible_module/clc_publicip.py similarity index 100% rename from src/main/python/clc_ansible_module/clc_publicip.py rename to clc_ansible_module/clc_publicip.py diff --git a/src/main/python/clc_ansible_module/clc_server.py b/clc_ansible_module/clc_server.py similarity index 99% rename from src/main/python/clc_ansible_module/clc_server.py rename to clc_ansible_module/clc_server.py index 7db485b..6d8cc34 100644 --- a/src/main/python/clc_ansible_module/clc_server.py +++ b/clc_ansible_module/clc_server.py @@ -538,7 +538,7 @@ CLC_FOUND = True -class ClcServer: +class ClcServer(object): clc = clc_sdk def __init__(self, module): @@ -634,7 +634,7 @@ def process_request(self): group = ClcServer._find_group(module=self.module, datacenter=datacenter, lookup_group=p.get('group')) servers = group.Servers().Servers() group = group.data - group['servers'] = map(lambda s: s.id, servers) + group['servers'] = [s.id for s in servers] self.module.exit_json( changed=changed, @@ -994,7 +994,7 @@ def _find_network_id(module, datacenter): # Validates provided network id # Allows lookup of network by id, name, or cidr notation if network_id: - network_id = datacenter.Networks().Get(network_id).id + network_id = datacenter.Networks(forced_load=True).Get(network_id).id if not network_id: try: diff --git a/src/main/python/clc_ansible_module/clc_server_fact.py b/clc_ansible_module/clc_server_fact.py similarity index 99% rename from src/main/python/clc_ansible_module/clc_server_fact.py rename to clc_ansible_module/clc_server_fact.py index f34af03..50f0059 100644 --- a/src/main/python/clc_ansible_module/clc_server_fact.py +++ b/clc_ansible_module/clc_server_fact.py @@ -249,7 +249,7 @@ REQUESTS_FOUND = True -class ClcServerFact: +class ClcServerFact(object): def __init__(self, module): """ diff --git a/src/main/python/clc_ansible_module/clc_server_snapshot.py b/clc_ansible_module/clc_server_snapshot.py similarity index 99% rename from src/main/python/clc_ansible_module/clc_server_snapshot.py rename to clc_ansible_module/clc_server_snapshot.py index ce7d605..2284a99 100644 --- a/src/main/python/clc_ansible_module/clc_server_snapshot.py +++ b/clc_ansible_module/clc_server_snapshot.py @@ -148,7 +148,7 @@ CLC_FOUND = True -class ClcSnapshot: +class ClcSnapshot(object): clc = clc_sdk module = None diff --git a/src/main/python/clc_inv.py b/clc_inv.py similarity index 99% rename from src/main/python/clc_inv.py rename to clc_inv.py index e138ed7..7712b69 100755 --- a/src/main/python/clc_inv.py +++ b/clc_inv.py @@ -46,6 +46,7 @@ from multiprocessing import Pool import itertools import json +from builtins import str import clc from clc import CLCException, APIFailedResponse diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 7e1621b..0000000 --- a/pom.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - 4.0.0 - com.ctlts - clc-ansible-module - 1.1.15-SNAPSHOT - clc-ansible-module - - UTF-8 - centurylinktechnology - - - ${project.basedir} - - - maven-jar-plugin - - - default-jar - never - - unwanted - unwanted - - - - - - external.atlassian.jgitflow - jgitflow-maven-plugin - 1.0-m4.3 - - - master - develop - feature- - release- - hotfix- - ${project.artifactId}- - - - - - org.apache.maven.plugins - maven-assembly-plugin - 2.5.4 - - assembly.xml - false - - - - create-archive - package - - single - - - - - - - - scm:git:https://github.com/CenturyLinkCloud/wf-clc-ansible-module.git - scm:git:https://github.com/CenturyLinkCloud/wf-clc-ansible-module.git - scm:git:https://github.com/CenturyLinkCloud/wf-clc-ansible-module.git - - - - releases - http://10.121.41.19:8081/content/repositories/releases - - - snapshots - http://10.121.41.19:8081/content/repositories/snapshots - - - diff --git a/requirements.txt b/requirements.txt index e0a0477..25d8d29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,27 +1,9 @@ ansible==2.0.2.0 -args==0.1.0 -cffi==1.6.0 clc-sdk==2.44 -clint==0.5.1 -coverage==4.0.3 -cryptography==1.3.1 -enum34==1.1.4 -funcsigs==1.0.2 -idna==2.1 -ipaddress==1.0.16 -Jinja2==2.8 -MarkupSafe==0.23 -mock==2.0.0 -nose==1.3.7 -paramiko==2.0.0 -pbr==1.9.1 -prettytable==0.7.2 -pyasn1==0.1.9 -PyBuilder==0.10.63 -pycparser==2.14 -pycrypto==2.6.1 -PyYAML==3.11 -requests==2.10.0 -six==1.10.0 -wheel==0.24.0 -xmlrunner==1.7.7 +coverage +future +mock +nose +requests>=2.7 +setuptools +wheel diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..2932e4d --- /dev/null +++ b/setup.py @@ -0,0 +1,45 @@ +# Copyright 2016 CenturyLink +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +try: + from setuptools import setup, find_packages +except ImportError: + print("clc_ansible_module now needs setuptools in order to build. " + "Install it using your package manager (usually python-setuptools) " + "or via pip (pip install setuptools).") + sys.exit(1) + +setup( + name='clc-ansible-module', + version='1.1.17', + description='Centurylink Cloud Ansible Modules', + author='CenturyLink Cloud', + author_email='WFAAS-LLFT@centurylink.com', + url='https://github.com/CenturylinkCloud/clc-ansible-module', + download_url='https://github.com/CenturylinkCloud/clc-ansible-module.git', + install_requires=[ + 'ansible==2.0.2.0', + 'clc-sdk==2.44', + 'future', + 'mock', + 'nose', + 'requests>=2.7', + 'setuptools', + ], + packages=find_packages(exclude=('tests',)), + scripts=['clc_inv.py'], + test_suite='nose.collector', + tests_require=['nose'], + keywords='centurylink cloud clc ansible modules' +) diff --git a/src/unittest/python/.coveragerc b/tests/.coveragerc similarity index 100% rename from src/unittest/python/.coveragerc rename to tests/.coveragerc diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/integrationtest/python/int_test_clc_server.yml b/tests/int_test_clc_server.yml similarity index 100% rename from src/integrationtest/python/int_test_clc_server.yml rename to tests/int_test_clc_server.yml diff --git a/src/unittest/python/test_clc_aa_policy.py b/tests/test_clc_aa_policy.py old mode 100755 new mode 100644 similarity index 97% rename from src/unittest/python/test_clc_aa_policy.py rename to tests/test_clc_aa_policy.py index 8c5733d..f84e36d --- a/src/unittest/python/test_clc_aa_policy.py +++ b/tests/test_clc_aa_policy.py @@ -171,8 +171,7 @@ def test_set_clc_credentials_w_no_creds(self): def test_clc_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'clc': raise ImportError return real_import(name, *args) @@ -186,8 +185,7 @@ def mock_import(name, *args): def test_requests_invalid_version(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.4.0' @@ -202,8 +200,7 @@ def mock_import(name, *args): def test_requests_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.7.0' diff --git a/src/unittest/python/test_clc_alert_policy.py b/tests/test_clc_alert_policy.py similarity index 99% rename from src/unittest/python/test_clc_alert_policy.py rename to tests/test_clc_alert_policy.py index 3975d1c..c2f7eef 100644 --- a/src/unittest/python/test_clc_alert_policy.py +++ b/tests/test_clc_alert_policy.py @@ -96,8 +96,7 @@ def test_set_clc_credentials_w_no_creds(self): def test_clc_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'clc': raise ImportError return real_import(name, *args) @@ -111,8 +110,7 @@ def mock_import(name, *args): def test_requests_invalid_version(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.4.0' @@ -127,8 +125,7 @@ def mock_import(name, *args): def test_requests_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.7.0' diff --git a/src/unittest/python/test_clc_blueprint_package.py b/tests/test_clc_blueprint_package.py old mode 100755 new mode 100644 similarity index 97% rename from src/unittest/python/test_clc_blueprint_package.py rename to tests/test_clc_blueprint_package.py index 749027a..7eb3b56 --- a/src/unittest/python/test_clc_blueprint_package.py +++ b/tests/test_clc_blueprint_package.py @@ -111,8 +111,7 @@ def test_set_clc_credentials_w_api_url(self, mock_clc_sdk): def test_clc_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'clc': raise ImportError return real_import(name, *args) @@ -126,8 +125,7 @@ def mock_import(name, *args): def test_requests_invalid_version(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.4.0' @@ -142,8 +140,7 @@ def mock_import(name, *args): def test_requests_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.7.0' diff --git a/src/unittest/python/test_clc_firewall_policy.py b/tests/test_clc_firewall_policy.py similarity index 99% rename from src/unittest/python/test_clc_firewall_policy.py rename to tests/test_clc_firewall_policy.py index 6db3eed..7c2dcdd 100644 --- a/src/unittest/python/test_clc_firewall_policy.py +++ b/tests/test_clc_firewall_policy.py @@ -42,8 +42,7 @@ def test_clc_set_credentials_w_creds(self): def test_clc_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'clc': raise ImportError return real_import(name, *args) @@ -57,8 +56,7 @@ def mock_import(name, *args): def test_requests_invalid_version(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.4.0' @@ -73,8 +71,7 @@ def mock_import(name, *args): def test_requests_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.7.0' diff --git a/src/unittest/python/test_clc_group.py b/tests/test_clc_group.py old mode 100755 new mode 100644 similarity index 98% rename from src/unittest/python/test_clc_group.py rename to tests/test_clc_group.py index 4a3a75d..f52e415 --- a/src/unittest/python/test_clc_group.py +++ b/tests/test_clc_group.py @@ -42,8 +42,7 @@ def build_mock_request_list(self, mock_server_list=None, status='succeeded'): def test_clc_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'clc': @@ -62,8 +61,7 @@ def mock_import(name, *args): def test_requests_invalid_version(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.4.0' @@ -80,8 +78,7 @@ def mock_import(name, *args): def test_requests_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.7.0' diff --git a/tests/test_clc_group_fact.py b/tests/test_clc_group_fact.py new file mode 100644 index 0000000..45f6abd --- /dev/null +++ b/tests/test_clc_group_fact.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright 2016 CenturyLink +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import clc_ansible_module.clc_group_fact as clc_group_fact +from clc_ansible_module.clc_group_fact import ClcGroupFact + +from clc import CLCException +import clc as clc_sdk +import mock +from mock import patch +import unittest + +class TestClcGroupFactFunctions(unittest.TestCase): + + def setUp(self): + self.clc = mock.MagicMock() + self.module = mock.MagicMock() + self.datacenter = mock.MagicMock() + + def test_requests_module_not_found(self): + # Setup Mock Import Function + real_import = __import__ + + def mock_import(name, *args): + if name == 'requests': + args[0]['requests'].__version__ = '2.7.0' + raise ImportError + return real_import(name, *args) + # Under Test + with mock.patch('__builtin__.__import__', side_effect=mock_import): + reload(clc_group_fact) + ClcGroupFact(self.module) + # Assert Expected Behavior + self.module.fail_json.assert_called_with( + msg='requests library is required for this module') + + # Reset + reload(clc_group_fact) + + def test_process_request(self): + pass + + def test_define_argument_spec(self): + result = ClcGroupFact._define_module_argument_spec() + self.assertIsInstance(result, dict) + self.assertTrue('argument_spec' in result) + self.assertEqual( + result['argument_spec'], + {'group_id': {'required': True}}) + + def test_get_endpoint(self): + under_test = ClcGroupFact(self.module) + under_test.api_url = 'http://unittest.example.com' + under_test.clc_alias = 'test_alias' + self.assertEqual( + under_test._get_endpoint('test_group'), + 'http://unittest.example.com/v2/groups/test_alias/test_group') + + def test_set_clc_credentials_from_env(self): + # Required combination of credentials not passed + with patch.dict( + 'os.environ', { + 'CLC_V2_API_URL': 'http://unittest.example.com', + }, + clear=True): + under_test = ClcGroupFact(self.module) + under_test._set_clc_credentials_from_env() + self.module.fail_json.assert_called_with( + msg='You must set the CLC_V2_API_USERNAME and CLC_V2_API_PASSWD ' + 'environment variables') + # Token and alias + with patch.dict( + 'os.environ', { + 'CLC_V2_API_URL': 'http://unittest.example.com', + 'CLC_V2_API_TOKEN': 'dummy_token', + 'CLC_ACCT_ALIAS': 'dummy_alias', + }, + clear=True): + under_test = ClcGroupFact(self.module) + under_test._set_clc_credentials_from_env() + self.assertEqual(under_test.v2_api_token, 'dummy_token') + self.assertEqual(under_test.clc_alias, 'dummy_alias') + # Username and password + # Mock requests response from endpoint + + +if __name__ == '__main__': + unittest.main() diff --git a/src/unittest/python/test_clc_inv.py b/tests/test_clc_inv.py similarity index 97% rename from src/unittest/python/test_clc_inv.py rename to tests/test_clc_inv.py index 5fc69f3..054349d 100644 --- a/src/unittest/python/test_clc_inv.py +++ b/tests/test_clc_inv.py @@ -142,8 +142,8 @@ def test_add_windows_hostvars(self, mock_clc_sdk, mock_add_windows_hostvars): mock_clc_sdk.v2.Server.return_value = server result = clc_inv._add_windows_hostvars(hostvars, server) - self.assertEquals(result[server.name]['ansible_ssh_port'], 5986) - self.assertEquals(result[server.name]['ansible_connection'], 'winrm') + self.assertEqual(result[server.name]['ansible_ssh_port'], 5986) + self.assertEqual(result[server.name]['ansible_connection'], 'winrm') @patch('clc_inv._add_windows_hostvars') @patch('clc_inv.clc') diff --git a/src/unittest/python/test_clc_loadbalancer.py b/tests/test_clc_loadbalancer.py old mode 100755 new mode 100644 similarity index 99% rename from src/unittest/python/test_clc_loadbalancer.py rename to tests/test_clc_loadbalancer.py index 8ad3b91..fb1ff2f --- a/src/unittest/python/test_clc_loadbalancer.py +++ b/tests/test_clc_loadbalancer.py @@ -29,8 +29,7 @@ def setUp(self): def test_clc_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'clc': @@ -49,8 +48,7 @@ def mock_import(name, *args): def test_requests_invalid_version(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.4.0' @@ -67,8 +65,7 @@ def mock_import(name, *args): def test_requests_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.7.0' diff --git a/tests/test_clc_loadbalancer_fact.py b/tests/test_clc_loadbalancer_fact.py new file mode 100644 index 0000000..9ea2ba5 --- /dev/null +++ b/tests/test_clc_loadbalancer_fact.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright 2016 CenturyLink +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest +import requests +from uuid import UUID +import clc as clc_sdk +from clc import CLCException +from clc import APIFailedResponse +import json +import mock +from mock import patch, create_autospec + +import clc_ansible_module.clc_loadbalancer_fact as clc_loadbalancer_fact +from clc_ansible_module.clc_loadbalancer_fact import ClcLoadbalancerFact + +class TestClcLoadbalancerFact(unittest.TestCase): + + def setUp(self): + self.clc = mock.MagicMock() + self.module = mock.MagicMock() + self.datacenter = mock.MagicMock() + + def test_clc_module_not_found(self): + # Setup Mock Import Function + real_import = __import__ + + def mock_import(name, *args): + if name == 'clc': + raise ImportError + return real_import(name, *args) + # Under Test + with mock.patch('__builtin__.__import__', side_effect=mock_import): + reload(clc_loadbalancer_fact) + ClcLoadbalancerFact(self.module) + # Assert Expected Behavior + self.module.fail_json.assert_called_with( + msg='clc-python-sdk required for this module') + + # Reset + reload(clc_loadbalancer_fact) + + def test_requests_invalid_version(self): + # Setup Mock Import Function + real_import = __import__ + + def mock_import(name, *args): + if name == 'requests': + args[0]['requests'].__version__ = '2.4.0' + return real_import(name, *args) + # Under Test + with mock.patch('__builtin__.__import__', side_effect=mock_import): + reload(clc_loadbalancer_fact) + ClcLoadbalancerFact(self.module) + # Assert Expected Behavior + self.module.fail_json.assert_called_with( + msg='requests library version should be >= 2.5.0') + + # Reset + reload(clc_loadbalancer_fact) + + def test_requests_module_not_found(self): + # Setup Mock Import Function + real_import = __import__ + + def mock_import(name, *args): + if name == 'requests': + args[0]['requests'].__version__ = '2.7.0' + raise ImportError + return real_import(name, *args) + # Under Test + with mock.patch('__builtin__.__import__', side_effect=mock_import): + reload(clc_loadbalancer_fact) + ClcLoadbalancerFact(self.module) + # Assert Expected Behavior + self.module.fail_json.assert_called_with( + msg='requests library is required for this module') + + # Reset + reload(clc_loadbalancer_fact) + + def test_process_request(self): + pass + + def test_define_argument_spec(self): + result = ClcLoadbalancerFact._define_module_argument_spec() + self.assertIsInstance(result, dict) + self.assertTrue('argument_spec' in result) + self.assertEqual( + result['argument_spec'], + {'name': {'required': True}, + 'location': {'required': True}, + 'alias': {'required': True}}) + + def test_set_clc_credentials_from_env(self): + # Required combination of credentials not passed + with patch.dict( + 'os.environ', { + 'CLC_V2_API_URL': 'http://unittest.example.com', + }, + clear=True): + under_test = ClcLoadbalancerFact(self.module) + under_test._set_clc_credentials_from_env() + self.assertEqual(under_test.clc.defaults.ENDPOINT_URL_V2, + 'http://unittest.example.com') + self.module.fail_json.assert_called_with( + msg='You must set the CLC_V2_API_USERNAME and CLC_V2_API_PASSWD ' + 'environment variables') + # Token and alias + with patch.dict( + 'os.environ', { + 'CLC_V2_API_URL': 'http://unittest.example.com', + 'CLC_V2_API_TOKEN': 'dummy_token', + 'CLC_ACCT_ALIAS': 'dummy_alias', + }, + clear=True): + under_test = ClcLoadbalancerFact(self.module) + under_test._set_clc_credentials_from_env() + self.assertEqual(under_test.clc._LOGIN_TOKEN_V2, 'dummy_token') + self.assertTrue(under_test.clc._V2_ENABLED) + self.assertEqual(under_test.clc.ALIAS, 'dummy_alias') + # Username and password + # Mock requests response from endpoint + + def test_get_loadbalancer_list(self): + pass + + def test_loadbalancer_id(self): + under_test = ClcLoadbalancerFact(self.module) + # Figure out correct object type + under_test.lb_dict = [ + {'name': 'lb1', 'id': 'lb_id1'}, + {'name': 'lb2', 'id': 'lb_id2'}, + {'name': 'lb4', 'id': 'lb_id4'}, + ] + self.assertEqual(under_test._get_loadbalancer_id('lb1'), 'lb_id1') + self.assertEqual(under_test._get_loadbalancer_id('lb2'), 'lb_id2') + self.assertIsNone(under_test._get_loadbalancer_id('lb3')) + + def test_get_endpoint(self): + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/src/unittest/python/test_clc_modify_server.py b/tests/test_clc_modify_server.py old mode 100755 new mode 100644 similarity index 99% rename from src/unittest/python/test_clc_modify_server.py rename to tests/test_clc_modify_server.py index 0b8214f..5f8654b --- a/src/unittest/python/test_clc_modify_server.py +++ b/tests/test_clc_modify_server.py @@ -36,8 +36,7 @@ def setUp(self): def test_clc_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'clc': raise ImportError return real_import(name, *args) @@ -53,8 +52,7 @@ def mock_import(name, *args): def test_requests_invalid_version(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.4.0' @@ -71,8 +69,7 @@ def mock_import(name, *args): def test_requests_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.7.0' diff --git a/src/unittest/python/test_clc_network.py b/tests/test_clc_network.py old mode 100755 new mode 100644 similarity index 98% rename from src/unittest/python/test_clc_network.py rename to tests/test_clc_network.py index cca6da1..f036e68 --- a/src/unittest/python/test_clc_network.py +++ b/tests/test_clc_network.py @@ -1,4 +1,6 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- + # Copyright 2016 CenturyLink # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -100,8 +102,7 @@ def test_set_clc_credentials_w_no_creds(self): def test_clc_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'clc': raise ImportError return real_import(name, *args) @@ -115,8 +116,7 @@ def mock_import(name, *args): def test_requests_invalid_version(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.4.0' @@ -131,8 +131,7 @@ def mock_import(name, *args): def test_requests_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.7.0' diff --git a/tests/test_clc_network_fact.py b/tests/test_clc_network_fact.py new file mode 100644 index 0000000..68899d3 --- /dev/null +++ b/tests/test_clc_network_fact.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python +# Copyright 2015 CenturyLink +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest +import requests +from uuid import UUID +import clc as clc_sdk +from clc import CLCException +from clc import APIFailedResponse +import mock +from mock import patch, create_autospec + +import clc_ansible_module.clc_network_fact as clc_network_fact +from clc_ansible_module.clc_network_fact import ClcNetworkFact + + +class TestClcNetworkFactFunctions(unittest.TestCase): + + def setUp(self): + self.clc = mock.MagicMock() + self.module = mock.MagicMock() + self.datacenter = mock.MagicMock() + + def test_clc_module_not_found(self): + # Setup Mock Import Function + real_import = __import__ + + def mock_import(name, *args): + if name == 'clc': + raise ImportError + return real_import(name, *args) + # Under Test + with mock.patch('__builtin__.__import__', side_effect=mock_import): + reload(clc_network_fact) + ClcNetworkFact(self.module) + # Assert Expected Behavior + self.module.fail_json.assert_called_with( + msg='clc-python-sdk required for this module') + + # Reset + reload(clc_network_fact) + + def test_requests_invalid_version(self): + # Setup Mock Import Function + real_import = __import__ + + def mock_import(name, *args): + if name == 'requests': + args[0]['requests'].__version__ = '2.4.0' + return real_import(name, *args) + # Under Test + with mock.patch('__builtin__.__import__', side_effect=mock_import): + reload(clc_network_fact) + ClcNetworkFact(self.module) + # Assert Expected Behavior + self.module.fail_json.assert_called_with( + msg='requests library version should be >= 2.5.0') + + # Reset + reload(clc_network_fact) + + def test_requests_module_not_found(self): + # Setup Mock Import Function + real_import = __import__ + + def mock_import(name, *args): + if name == 'requests': + args[0]['requests'].__version__ = '2.7.0' + raise ImportError + return real_import(name, *args) + # Under Test + with mock.patch('__builtin__.__import__', side_effect=mock_import): + reload(clc_network_fact) + ClcNetworkFact(self.module) + # Assert Expected Behavior + self.module.fail_json.assert_called_with( + msg='requests library is required for this module') + + # Reset + reload(clc_network_fact) + + @patch.object(clc_network_fact, 'clc_sdk') + def test_set_user_agent(self, mock_clc_sdk): + clc_network_fact.__version__ = "1" + ClcNetworkFact._set_user_agent(mock_clc_sdk) + + self.assertTrue(mock_clc_sdk.SetRequestsSession.called) + + def test_process_request(self): + pass + + def test_get_clc_networks(self): + pass + + def test_define_argument_spec(self): + result = ClcNetworkFact._define_module_argument_spec() + self.assertIsInstance(result, dict) + #self.assertTrue('argument_spec' in result) + self.assertEqual( + result, + {'id': {'required': False}, + 'location': {'required': True}}) + + def test_set_clc_credentials_from_env(self): + # Required combination of credentials not passed + with patch.dict( + 'os.environ', { + 'CLC_V2_API_URL': 'http://unittest.example.com', + }, + clear=True): + under_test = ClcNetworkFact(self.module) + under_test._set_clc_credentials_from_env() + self.assertEqual(under_test.clc.defaults.ENDPOINT_URL_V2, + 'http://unittest.example.com') + self.module.fail_json.assert_called_with( + msg='You must set the CLC_V2_API_USERNAME and CLC_V2_API_PASSWD ' + 'environment variables') + # Token and alias + with patch.dict( + 'os.environ', { + 'CLC_V2_API_URL': 'http://unittest.example.com', + 'CLC_V2_API_TOKEN': 'dummy_token', + 'CLC_ACCT_ALIAS': 'dummy_alias', + }, + clear=True): + under_test = ClcNetworkFact(self.module) + under_test._set_clc_credentials_from_env() + self.assertEqual(under_test.clc._LOGIN_TOKEN_V2, 'dummy_token') + self.assertTrue(under_test.clc._V2_ENABLED) + self.assertEqual(under_test.clc.ALIAS, 'dummy_alias') + # Username and password + # Mock requests response from endpoint + +if __name__ == '__main__': + unittest.main() diff --git a/src/unittest/python/test_clc_publicip.py b/tests/test_clc_publicip.py old mode 100755 new mode 100644 similarity index 98% rename from src/unittest/python/test_clc_publicip.py rename to tests/test_clc_publicip.py index 4ef6d31..9c98b88 --- a/src/unittest/python/test_clc_publicip.py +++ b/tests/test_clc_publicip.py @@ -112,8 +112,7 @@ def build_mock_server_id_list(self): def test_clc_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'clc': raise ImportError return real_import(name, *args) @@ -128,8 +127,7 @@ def mock_import(name, *args): def test_requests_invalid_version(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.4.0' @@ -144,8 +142,7 @@ def mock_import(name, *args): def test_requests_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.7.0' diff --git a/src/unittest/python/test_clc_server.py b/tests/test_clc_server.py old mode 100755 new mode 100644 similarity index 99% rename from src/unittest/python/test_clc_server.py rename to tests/test_clc_server.py index fa10eaa..90ba3b1 --- a/src/unittest/python/test_clc_server.py +++ b/tests/test_clc_server.py @@ -35,8 +35,7 @@ def setUp(self): def test_clc_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'clc': raise ImportError return real_import(name, *args) @@ -52,8 +51,7 @@ def mock_import(name, *args): def test_requests_invalid_version(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.4.0' @@ -70,8 +68,7 @@ def mock_import(name, *args): def test_requests_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.7.0' @@ -913,7 +910,7 @@ def test_find_network_id_by_id(self): result = ClcServer._find_network_id(self.module, self.datacenter) # Assert Result - self.datacenter.Networks.assert_called_with() + self.datacenter.Networks.assert_called_with(forced_load=True) self.datacenter.Networks().Get.assert_called_once_with('AwesomeIdHere') self.assertEqual(result, mock_network.id) self.assertEqual(self.module.fail_json.called, False) diff --git a/tests/test_clc_server_fact.py b/tests/test_clc_server_fact.py new file mode 100644 index 0000000..cf2f32c --- /dev/null +++ b/tests/test_clc_server_fact.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright 2016 CenturyLink +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import unittest +from uuid import UUID +import clc as clc_sdk +from clc import CLCException +from clc import APIFailedResponse +import mock +from mock import patch, create_autospec + +import clc_ansible_module.clc_server_fact as clc_server_fact +from clc_ansible_module.clc_server_fact import ClcServerFact + + +class TestClcServerFactFunctions(unittest.TestCase): + + def setUp(self): + self.clc = mock.MagicMock() + self.module = mock.MagicMock() + self.datacenter = mock.MagicMock() + + def test_requests_module_not_found(self): + # Setup Mock Import Function + real_import = __import__ + + def mock_import(name, *args): + if name == 'requests': + args[0]['requests'].__version__ = '2.7.0' + raise ImportError + return real_import(name, *args) + # Under Test + with mock.patch('__builtin__.__import__', side_effect=mock_import): + reload(clc_server_fact) + ClcServerFact(self.module) + # Assert Expected Behavior + self.module.fail_json.assert_called_with( + msg='requests library is required for this module') + + # Reset + reload(clc_server_fact) + + def test_process_request(self): + pass + + def test_define_argument_spec(self): + result = ClcServerFact._define_module_argument_spec() + self.assertIsInstance(result, dict) + self.assertTrue('argument_spec' in result) + self.assertEqual( + result['argument_spec'], + {'server_id': {'required': True}, + 'credentials': {'default': False}}) + + def test_get_server_credentials(self): + under_test = ClcServerFact(self.module) + under_test.api_url = 'http://unittest.example.com' + under_test.clc_alias = 'test_alias' + # Mock request response from endpoint + + def test_get_endpoint(self): + under_test = ClcServerFact(self.module) + under_test.api_url = 'http://unittest.example.com' + under_test.clc_alias = 'test_alias' + self.assertEqual( + under_test._get_endpoint('test_server'), + 'http://unittest.example.com/v2/servers/test_alias/test_server') + + def test_set_clc_credentials_from_env(self): + # Required combination of credentials not passed + with patch.dict( + 'os.environ', { + 'CLC_V2_API_URL': 'http://unittest.example.com', + }, + clear=True): + under_test = ClcServerFact(self.module) + under_test._set_clc_credentials_from_env() + self.module.fail_json.assert_called_with( + msg='You must set the CLC_V2_API_USERNAME and CLC_V2_API_PASSWD ' + 'environment variables') + # Token and alias + with patch.dict( + 'os.environ', { + 'CLC_V2_API_URL': 'http://unittest.example.com', + 'CLC_V2_API_TOKEN': 'dummy_token', + 'CLC_ACCT_ALIAS': 'dummy_alias', + }, + clear=True): + under_test = ClcServerFact(self.module) + under_test._set_clc_credentials_from_env() + self.assertEqual(under_test.v2_api_token, 'dummy_token') + self.assertEqual(under_test.clc_alias, 'dummy_alias') + # Username and password + # Mock requests response from endpoint + + +if __name__ == '__main__': + unittest.main() diff --git a/src/unittest/python/test_clc_server_snapshot.py b/tests/test_clc_server_snapshot.py similarity index 98% rename from src/unittest/python/test_clc_server_snapshot.py rename to tests/test_clc_server_snapshot.py index b90633c..cc746a2 100644 --- a/src/unittest/python/test_clc_server_snapshot.py +++ b/tests/test_clc_server_snapshot.py @@ -32,8 +32,7 @@ def setUp(self): def test_clc_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'clc': raise ImportError return real_import(name, *args) @@ -49,8 +48,7 @@ def mock_import(name, *args): def test_requests_invalid_version(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.4.0' @@ -67,8 +65,7 @@ def mock_import(name, *args): def test_requests_module_not_found(self): # Setup Mock Import Function - import __builtin__ as builtins - real_import = builtins.__import__ + real_import = __import__ def mock_import(name, *args): if name == 'requests': args[0]['requests'].__version__ = '2.7.0'