![](https://seccdn.libravatar.org/avatar/e2145bc5cf53dda95c308a3c75e8fef3.jpg?s=120&d=mm&r=g)
Hello community, here is the log from the commit of package python3-ipa for openSUSE:Factory checked in at 2018-11-13 17:00:30 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python3-ipa (Old) and /work/SRC/openSUSE:Factory/.python3-ipa.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python3-ipa" Tue Nov 13 17:00:30 2018 rev:9 rq:648462 version:2.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python3-ipa/python3-ipa.changes 2018-11-01 19:13:49.722044613 +0100 +++ /work/SRC/openSUSE:Factory/.python3-ipa.new/python3-ipa.changes 2018-11-13 17:41:42.088282691 +0100 @@ -1,0 +2,12 @@ +Fri Nov 9 22:59:00 UTC 2018 - Sean Marlow <sean.marlow@suse.com> + +- Update to v2.3.0 (2018-11-09) + + Move docs to Sphinx. + + Update python version support. + + Allow ipa to run without config file. + + No need for gpg auto import keys. + + Add --name option to az creds example. + + Explicit validation of GCE region input. + + Update license tests for content changes. + +------------------------------------------------------------------- Old: ---- python3-ipa-2.2.0.tar.gz New: ---- python3-ipa-2.3.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python3-ipa.spec ++++++ --- /var/tmp/diff_new_pack.2O1ml4/_old 2018-11-13 17:41:42.396282265 +0100 +++ /var/tmp/diff_new_pack.2O1ml4/_new 2018-11-13 17:41:42.400282259 +0100 @@ -18,7 +18,7 @@ %bcond_without test Name: python3-ipa -Version: 2.2.0 +Version: 2.3.0 Release: 0 Summary: Command line and API for testing custom images License: GPL-3.0-or-later ++++++ python3-ipa-2.2.0.tar.gz -> python3-ipa-2.3.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/CHANGES.md new/python3-ipa-2.3.0/CHANGES.md --- old/python3-ipa-2.2.0/CHANGES.md 2018-11-01 00:00:54.000000000 +0100 +++ new/python3-ipa-2.3.0/CHANGES.md 2018-11-09 23:46:28.000000000 +0100 @@ -1,3 +1,21 @@ +v2.3.0 (2018-11-09) +=================== + +- Move docs to sphinx. + [\#141](https://github.com/SUSE-Enceladus/ipa/pull/141) +- Update python version support. + [\#142](https://github.com/SUSE-Enceladus/ipa/pull/142) +- Allow ipa to run without config file. + [\#137](https://github.com/SUSE-Enceladus/ipa/pull/137) +- No need for gpg auto import keys. + [\#144](https://github.com/SUSE-Enceladus/ipa/pull/144) +- Add --name option to az creds example. + [\#145](https://github.com/SUSE-Enceladus/ipa/pull/145) +- Explicit validation of GCE region input. + [\#146](https://github.com/SUSE-Enceladus/ipa/pull/146) +- Update license tests for content changes. + [\#147](https://github.com/SUSE-Enceladus/ipa/pull/147) + v2.2.0 (2018-10-31) =================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/PKG-INFO new/python3-ipa-2.3.0/PKG-INFO --- old/python3-ipa-2.2.0/PKG-INFO 2018-11-01 00:07:50.000000000 +0100 +++ new/python3-ipa-2.3.0/PKG-INFO 2018-11-09 23:57:29.000000000 +0100 @@ -1,14 +1,18 @@ Metadata-Version: 2.1 Name: python3-ipa -Version: 2.2.0 +Version: 2.3.0 Summary: Package for automated testing of cloud images. Home-page: https://github.com/SUSE-Enceladus/ipa Author: SUSE Author-email: public-cloud-dev@susecloud.net License: GPLv3+ Description: [![Build Status](https://travis-ci.com/SUSE-Enceladus/ipa.svg?branch=master)](https://travis-ci.com/SUSE-Enceladus/ipa) + [![Codacy Badge](https://api.codacy.com/project/badge/Grade/845fb1620f334ae09488e8137dd6d256)](https://www.codacy.com/app/default-org/ipa?utm_source=github.com&utm_medium=referral&utm_content=SUSE-Enceladus/ipa&utm_campaign=Badge_Grade) + [![Documentation Status](https://readthedocs.org/projects/ipa/badge/?version=latest)](https://ipa.readthedocs.io/en/latest/?badge=latest) + [![Py Versions](https://img.shields.io/pypi/pyversions/python3-ipa.svg)](https://pypi.org/project/python3-ipa/) + [![License](https://img.shields.io/pypi/l/python3-ipa.svg)](https://pypi.org/project/python3-ipa/) - [![IPA](https://raw.githubusercontent.com/SUSE-Enceladus/ipa/master/docs/assets/imag... "IPA Logo")](https://github.com/SUSE-Enceladus/ipa) + [![IPA](https://raw.githubusercontent.com/SUSE-Enceladus/ipa/master/docs/source/_ima... "IPA Logo")](https://github.com/SUSE-Enceladus/ipa) overview ======== @@ -61,7 +65,7 @@ - PyYaml - testinfra - # [Docs](https://suse-enceladus.github.io/ipa/) + # [Docs](https://ipa.readthedocs.io/en/latest/) Tests ===== @@ -144,8 +148,9 @@ Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 Requires-Python: >=3.4 Description-Content-Type: text/markdown -Provides-Extra: test -Provides-Extra: dev Provides-Extra: tox +Provides-Extra: dev +Provides-Extra: test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/README.md new/python3-ipa-2.3.0/README.md --- old/python3-ipa-2.2.0/README.md 2018-10-31 17:45:00.000000000 +0100 +++ new/python3-ipa-2.3.0/README.md 2018-11-05 16:53:22.000000000 +0100 @@ -1,6 +1,10 @@ [![Build Status](https://travis-ci.com/SUSE-Enceladus/ipa.svg?branch=master)](https://travis-ci.com/SUSE-Enceladus/ipa) +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/845fb1620f334ae09488e8137dd6d256)](https://www.codacy.com/app/default-org/ipa?utm_source=github.com&utm_medium=referral&utm_content=SUSE-Enceladus/ipa&utm_campaign=Badge_Grade) +[![Documentation Status](https://readthedocs.org/projects/ipa/badge/?version=latest)](https://ipa.readthedocs.io/en/latest/?badge=latest) +[![Py Versions](https://img.shields.io/pypi/pyversions/python3-ipa.svg)](https://pypi.org/project/python3-ipa/) +[![License](https://img.shields.io/pypi/l/python3-ipa.svg)](https://pypi.org/project/python3-ipa/) -[![IPA](https://raw.githubusercontent.com/SUSE-Enceladus/ipa/master/docs/assets/imag... "IPA Logo")](https://github.com/SUSE-Enceladus/ipa) +[![IPA](https://raw.githubusercontent.com/SUSE-Enceladus/ipa/master/docs/source/_ima... "IPA Logo")](https://github.com/SUSE-Enceladus/ipa) overview ======== @@ -53,7 +57,7 @@ - PyYaml - testinfra -# [Docs](https://suse-enceladus.github.io/ipa/) +# [Docs](https://ipa.readthedocs.io/en/latest/) Tests ===== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/docs/index.md new/python3-ipa-2.3.0/docs/index.md --- old/python3-ipa-2.2.0/docs/index.md 2018-10-31 16:39:06.000000000 +0100 +++ new/python3-ipa-2.3.0/docs/index.md 1970-01-01 01:00:00.000000000 +0100 @@ -1,67 +0,0 @@ ---- -layout: default -title: Home -navigation_weight: 1 ---- - -# IPA - -Image Proofing App - -## overview - -**IPA** provides a command line utility to test images in the Public -Cloud (AWS, Azure, GCE, etc.). - -With **IPA** you can now test custom images in a provider agnostic way -with one tool and one API. In the first release, **IPA** supports the -openSUSE and SLES distributions. It also supports the three largest -cloud providers (AWS, Azure and GCE). However, it is intended to be -distribution agnostic and framework transparent so both are easily -extensible. - -For each distribution there are specific synchronization points that -must be provided. These currently include soft reboot and system update. -The synch points not only test functionality but also act as dividers to -separate distinct sections of a test suite. For example you can run a -test to ensure the proper repos exist before and after a system update. -The system update synch point will guarantee the order of tests. -Speaking of tests, if you're already familiar with Pytest conventions -there's no need to learn a whole new unit testing framework. **IPA** is -written in Python and leverages the Pytest framework through Testinfra. - -## Installation - -To install the openSUSE package use the following commands as root: - -```shell -$ zypper ar http://download.opensuse.org/repositories/Cloud:/Tools/<distribution> -$ zypper refresh -$ zypper in python3-ipa -``` - -From PyPI: - -```shell -$ pip install python3-ipa -``` - -Or you can install the latest development version from github: - -```shell -# latest source -$ pip install git+https://github.com/SUSE-Enceladus/ipa.git - -# specific branch or release -$ pip install git+https://github.com/SUSE-Enceladus/ipa.git@{branch/release} -``` - -See [PyPi -docs](https://pip.pypa.io/en/stable/reference/pip_install/#vcs-support) -for more information on vcs support. - -## Contents - -- [Getting Started](start.md) -- [Writing Tests](tests.md) -- [Source Overview](source.md) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/docs/source.md new/python3-ipa-2.3.0/docs/source.md --- old/python3-ipa-2.2.0/docs/source.md 2018-10-31 16:39:06.000000000 +0100 +++ new/python3-ipa-2.3.0/docs/source.md 1970-01-01 01:00:00.000000000 +0100 @@ -1,108 +0,0 @@ ---- -layout: default -title: Source -navigation_weight: 3 ---- - -CLI -=== - -## ipa test - -The test subcommand invokes a test suite on an image in the chosen -public cloud environment. The image id, tests and provider are required -arguments. See below for options: - -```shell -$ ipa test --ssh-private-key /path/to/key -d SLES azure test_image -``` - -## ipa results - -The results subcommand displays the test results information. The path -to the results xml is required. - -```shell -$ ipa results -v -``` - -The default location for results files is \~/ipa/results/ and the files -are encoded with the timestamp of execution. For example, the results -for an image test in ec2 would be found at -\~/ipa/results/ec2/{imageId}/{instanceId}/{datetime}.results. - -**Example results directory:** - - ec2/: - ami-43243232/: - i-3432r4324y3t2/: - {datetime}.results - i-432423j3j2432/: - {datetime}.results - -## ipa list - -The list subcommand displays the available tests. - -```shell -$ ipa list -test_broken -test_image -test_sles -``` - -The list subcommand will return a list of test files in the default test -directories. The verbose option will return a list of all available -tests in all test files. - -```shell -$ ipa list -v -test_broken::test_broken -test_image::test_image -test_sles::test_sles -test_sles::test_sles_1 -test_sles::test_sles_2 -``` - -API -=== - -The API used by CLI or used independently, is structured with a base -class in ipa\_provider.py. This contains the functionality required to -run tests and collect the test results. - -**ipa\_provider.py.** - -```python -class IpaProvider(object): -... -``` - -The base class is extended for each provider to implement specific -methods for manipulating the test instance. - -**ipa\_{cloud-provider}.py.** - -```python -class {CloudProvider}Provider(IpaProvider): -... -``` - -The controller (ipa\_controller.py) provides methods for testing an -image, displaying available tests and/or test files and displaying -results of a previous test run. These methods provide a layer between -the CLI and the API. They also provide an entry point for using **ipa** -directly from code. - -**ipa\_controller.py.** - -```python -def test_image(self): - """Creates a cloud provider instance and initiates testing.""" - -def list_tests(self): - """Returns a list of test files and/or tests.""" - -def collect_results(self): - """Returns the result (pass/fail) or verbose results.""" -``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/docs/start.md new/python3-ipa-2.3.0/docs/start.md --- old/python3-ipa-2.2.0/docs/start.md 2018-10-31 16:39:06.000000000 +0100 +++ new/python3-ipa-2.3.0/docs/start.md 1970-01-01 01:00:00.000000000 +0100 @@ -1,331 +0,0 @@ ---- -layout: default -title: Overview -navigation_weight: 2 ---- - -Requirements -============ - -- apache-libcloud -- azure-common -- azure-mgmt-compute -- azure-mgmt-network -- azure-mgmt-resource -- certifi -- Click -- cryptography -- paramiko -- pycryptodome -- pytest -- PyYaml -- testinfra - -Installation -============ - -To install the openSUSE package use the following commands as root: - -```shell -$ zypper ar http://download.opensuse.org/repositories/Cloud:/Tools/<distribution> -$ zypper refresh -$ zypper in python3-ipa -``` - -From PyPI: - -```shell -$ pip install python3-ipa -``` - -Or you can install the latest development version from github: - -```shell -# latest source -$ pip install git+https://github.com/SUSE-Enceladus/ipa.git - -# specific branch or release -$ pip install git+https://github.com/SUSE-Enceladus/ipa.git@{branch/release} -``` - -See [PyPi -docs](https://pip.pypa.io/en/stable/reference/pip_install/#vcs-support) -for more information on vcs support. - -Configuration -============= - -The framework configuration file is ini format \~/.config/ipa/config. -Anything specific to the test framework can be found in this file. Thus -anything that is cloud framework independent such as the tests dir and -results dir. - -To override the default configuration location the CLI option `-C` or -`--config` is provided. - -The following is an example configuration file. The ipa section is -required and the provider sections are optional and can be \[ec2\], -\[gce\], \[azure\] or \[ssh\]. - -```ini -[ipa] -tests=~/ipa/tests/ -results=~/ipa/results/ - -[ec2] -region=us-west-1 -``` - -Azure ------ - -Azure uses service principals for authentication. See [Azure -docs](https://docs.microsoft.com/en-us/python/azure/python-sdk-azure-authenticate?...) -for more info on creating a service principal json file. Additional -configuration options can be placed in the `azure` section of the `ipa` -configuration file. - -EC2 ---- - -For testing EC2 instances **ipa** will use the ec2utils configuration -file located at \~/.ec2utils.conf. See -[ec2utils](https://github.com/SUSE-Enceladus/Enceladus/tree/master/ec2utils) for -an example configuration file. - -GCE ---- - -GCE uses service accounts for authentication. The service account is -required to have the following: - -- Compute Instance Admin (v1) Role - ([roles/compute.instanceAdmin.v1](https://cloud.google.com/compute/docs/access/iam)) -- Service Account User Role - ([roles/iam.serviceAccountUser](https://cloud.google.com/compute/docs/access/iam)) -- Private key (JSON format) - - Save this file in a secure location as it cannot be recovered. - -The path to the JSON private key can be added to IPA configuration: - -**example.ipa.config.** - -```ini -[ipa] - -[gce] -service_account_file = /path/to/service-account.json -``` - -> Additional configuration options can be placed in the `gce` section of -> the `ipa` configuration file. - -To create a service account and generate the proper JSON file follow the -[Libcloud -docs](http://libcloud.readthedocs.io/en/latest/compute/drivers/gce.html#service-ac...) -or [Google -docs](https://cloud.google.com/iam/docs/creating-managing-service-accounts). - -For more information on updating an existing service account: - -- Create a new JSON private key: - [creating-managing-service-account-keys](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) -- Granting roles: - [granting-roles-to-service-accounts](https://cloud.google.com/iam/docs/granting-roles-to-service-accounts) - -SSH ---- -Requires no provider credentials to test instances. SSH user, SSH private key can -be placed in ssh section of config. The instance to be tested must be running. - -Provider Configuration location -------------------------------- - -To override the provider configuration the CLI option, -`--provider-config` is available. - -Usage -===== - -CLI ---- - -```shell -$ ipa test -``` - -Test image in the given framework using the supplied test files. - -#### Testing an image in EC2 - -```shell -$ ipa test -i {image-id} \ - -a {account} \ - --provider-config ~/.ec2utils.conf \ - --no-cleanup \ - -d openSUSE_Leap \ - ec2 test_image - -Starting instance -Running tests /home/{user}/ipa/tests/test_image.py -PASSED tests=1|pass=1|fail=0|error=0 -``` - -#### Testing an image in Azure - -```shell -$ ipa test -i {image-id} \ - --no-cleanup \ - -d openSUSE_Leap \ - --ssh-private-key {azure-ssh-key-file} \ - azure test_image - -Starting instance -Running tests /home/{user}/ipa/tests/test_image.py -PASSED tests=1|pass=1|fail=0|error=0 -``` - -#### Testing an image in GCE - -```shell -$ ipa test -i {image-id} \ - --no-cleanup \ - -d openSUSE_Leap \ - gce test_image - -Starting instance -Running tests /home/{user}/ipa/tests/test_image.py -PASSED tests=1|pass=1|fail=0|error=0 -``` - -#### Testing an image in SSH - -```shell -$ ipa test -ip-address 10.0.0.1 \ - -d openSUSE_Leap \ - ssh test_image - -Running tests /home/{user}/ipa/tests/test_image.py -PASSED tests=1|pass=1|fail=0|error=0 -``` - -### Verbosity - -The CLI output verbosity can be controlled via options: - -`--debug` - -Display debug level logging to console. - -`--verbose` - -(Default) Display logging info to console. - -`--quiet` - -Silence logging information on test run. - -### Cleanup - -By default the instance will be terminated if all tests pass. If a test -fails the instance will remain running. This behavior can be changed -with the `--cleanup` and `--no-cleanup` flags. - -`--cleanup` - -Instance will be terminated in all cases. - -`--no-cleanup` - -Instance will remain running in all cases. - -### ANSI Style - -By default the command line output will be colored. To disable color -output use the `--no-color` option. - -### Early Exit - -The early exit option will stop the test run on the first failure. -`--early-exit` is passed to Pytest as `-x`. See [Pytest -docs](https://docs.pytest.org/en/latest/usage.html#stopping-after-the-first-or-n-f...) -for more info. - -### Requirements and external test injection - -Using the `--inject` option; packages, archives and files can be -injected on the test instance. This also provides the ability to install -packages in an existing repository and run commands on the test -instance. The following sections may be provided in a YAML style config -file. Each section can be a single item or a list of items. All files -are copied and extracted to the default SSH location for the test -instance. This is generally the user's home directory. - -***inject\_packages*** - -an rpm path or list of rpm paths which will be copied and installed -on the test instance. - -***inject\_archives*** - -an archive or list of archives which will be copied and extracted on -the test instance. - -***inject\_files*** - -a file path or list of file paths which will be copied to the test -instance. - -***execute*** - -a command or list of commands to run on the test instance. - -***install*** - -a package name or list of package names to install from an existing -repo on the test instance. - -The order of processing for the sections is as follows: - -1. inject\_packages -2. inject\_archives -3. inject\_files -4. execute -5. install - -#### Example - -**testing\_injection.yaml.** - -```yaml -inject_packages: /home/user/test.noarch.rpm -inject_archives: /home/user/test.tar.xz -inject_files: /home/user/test.py -install: - - python3 - - python3-Django -execute: python test.py -``` - -```shell -$ ipa test ... --inject testing_injection.yaml -``` - -Code ----- - -**ipa** primarily provides a CLI tool for testing images. However, the -endpoints can be imported directly in Python 3 code through the -controller. - -```python -from ipa.ipa_controller import test_image - -status, results = test_image( - provider, - access_key_id, - ... - storage_container, - tests -) -``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/docs/tests.md new/python3-ipa-2.3.0/docs/tests.md --- old/python3-ipa-2.2.0/docs/tests.md 2018-10-31 16:39:06.000000000 +0100 +++ new/python3-ipa-2.3.0/docs/tests.md 1970-01-01 01:00:00.000000000 +0100 @@ -1,145 +0,0 @@ ---- -layout: default -title: Tests -navigation_weight: 4 ---- - -Tests are developed using the -[Testinfra](https://testinfra.readthedocs.io) package. The package -extends Pytest and provides a framework for writing Python tests to -verify the actual state of systems. - -Test directories -================ - -The default locations for test files are locally in \~/ipa/tests/ and -centralized in /usr/share/ipa/tests. These locations can be overridden -in the config and/or command line arguments. - -Test organization -================= - -Tests can be organized in a directory structure: - - ~/ipa/tests/: - conftest.py - test_image.py - openSUSE: - test_leap.py - EC2: - test_leap_ec2.py - GCE: - ... - SLES: - test_sles.py - test_sles_sap.py - EC2: - test_sles_ec2.py - ... - -Additionally, test descriptions in YAML format can be used to organize -tests: - -**test\_leap\_423.yaml.** - -```yaml -tests: - - test_image - - test_leap -``` - -Adding tests to command line args you simply drop the extension: - -```shell -$ ipa test ... test_leap_423 -``` - -This means there cannot be a name overlap with test files and/or test -descriptions. - -Test descriptions can also include other descriptions: - -**test\_leap\_423.yaml.** - -```yaml -tests: - - ... -include: - - test_another_description -``` - -Test invocation -=============== - -To invoke a specific test the Pytest conventions can be used: - - test_leap_ec2::test-services-running-enabled - -To run only one parameterized test append ids and use \[ID\]: - -**test\_leap\_ec2.py.** - -```python -@pytest.mark.parametrize("name", [ - ("cloud-init"), - ("amazon-ssm-agent"), -], ids=['ci', 'ssm']) -def test_leap_ec2(): - ... -``` - -```shell -$ ipa test ... test_leap_ec2::test-services-running-enabled[ssm] -``` - -Failures --------- - -By default all tests will run even with failure. Using the -`--early-exit` option will halt test invocation at first failure. - -[Incremental test -classes](http://pytest.org/dev/example/simple.html#incremental-testing-test-steps) -can be used to cause all subsequent tests to fail if the prev fails. To -prevent expected failures. - -Custom Test Modules -=================== - -[Modules](http://testinfra.readthedocs.io/en/latest/modules.html) are -provided for checking standard things such as packages, services, files, -etc. - -Modules can be easily written or extended from using [Pytest -fixtures](https://docs.pytest.org/en/latest/fixture.html). Any custom -modules reside in the conftest.py file inside the test directory: - -**conftest.py.** - -```python -import pytest - -@pytest.fixture() -def Echo(Command): - def f(arg): - return Command.check-output("echo %s", arg) - return f - - -@pytest.fixture() -def CheckRepo(File): - def f(repo, name): - repo = File('/etc/zypp/repos.d/' + repo + '.repo') - tests = [repo.exists, - repo.contains('enabled=1'), - repo.contains('name=%s' % name)] - return all(tests) - return f -``` - -Useful Links -============ - -For more info on writing tests see the -[Testinfra](http://testinfra.readthedocs.io/en/latest/) and -[Pytest](https://docs.pytest.org/en/latest/contents.html) documentation. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/ipa/__init__.py new/python3-ipa-2.3.0/ipa/__init__.py --- old/python3-ipa-2.2.0/ipa/__init__.py 2018-11-01 00:01:27.000000000 +0100 +++ new/python3-ipa-2.3.0/ipa/__init__.py 2018-11-09 23:53:51.000000000 +0100 @@ -22,4 +22,4 @@ __author__ = """SUSE""" __email__ = 'public-cloud-dev@susecloud.net' -__version__ = '2.2.0' +__version__ = '2.3.0' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/ipa/ipa_gce.py new/python3-ipa-2.3.0/ipa/ipa_gce.py --- old/python3-ipa-2.2.0/ipa/ipa_gce.py 2018-10-31 16:10:33.000000000 +0100 +++ new/python3-ipa-2.3.0/ipa/ipa_gce.py 2018-11-08 03:14:51.000000000 +0100 @@ -132,6 +132,8 @@ self._get_service_account_info() self.compute_driver = self._get_driver() + self._validate_region() + def _get_service_account_info(self): """Retrieve json dict from service account file.""" with open(self.service_account_file, 'r') as f: @@ -206,12 +208,6 @@ def _launch_instance(self): """Launch an instance of the given image.""" - if not self.region: - raise GCEProviderException( - 'Zone is required to launch a new GCE instance. ' - 'Example: us-west1-a' - ) - metadata = {'key': 'ssh-keys', 'value': self.ssh_public_key} self.running_instance_id = ipa_utils.generate_instance_name( 'gce-ipa-test' @@ -258,3 +254,24 @@ """If existing image used get image id.""" instance = self._get_instance() self.image_id = instance.image + + def _validate_region(self): + """Validate region was passed in and is a valid GCE zone.""" + if not self.region: + raise GCEProviderException( + 'Zone is required for GCE provider: ' + 'Example: us-west1-a' + ) + + try: + zone = self.compute_driver.ex_get_zone(self.region) + except Exception: + zone = None + + if not zone: + raise GCEProviderException( + '{region} is not a valid GCE zone. ' + 'Example: us-west1-a'.format( + region=self.region + ) + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/ipa/ipa_opensuse_leap.py new/python3-ipa-2.3.0/ipa/ipa_opensuse_leap.py --- old/python3-ipa-2.2.0/ipa/ipa_opensuse_leap.py 2018-10-31 16:10:33.000000000 +0100 +++ new/python3-ipa-2.3.0/ipa/ipa_opensuse_leap.py 2018-11-08 03:14:51.000000000 +0100 @@ -2,7 +2,7 @@ """openSUSE Leap distro module and sync points.""" -# Copyright (c) 2017 SUSE LLC +# Copyright (c) 2018 SUSE LLC # # This file is part of ipa. Ipa provides an api and command line # utilities for testing images in the Public Cloud. @@ -25,7 +25,3 @@ class openSUSE_Leap(SLES): """openSUSE Leap distro class.""" - - def get_refresh_repo_cmd(self): - """Return refresh repo command for SLES.""" - return 'zypper -n --gpg-auto-import-keys refresh' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/ipa/ipa_provider.py new/python3-ipa-2.3.0/ipa/ipa_provider.py --- old/python3-ipa-2.2.0/ipa/ipa_provider.py 2018-10-31 16:10:33.000000000 +0100 +++ new/python3-ipa-2.3.0/ipa/ipa_provider.py 2018-11-05 21:28:17.000000000 +0100 @@ -42,6 +42,7 @@ from ipa.ipa_opensuse_leap import openSUSE_Leap from ipa.ipa_sles import SLES from ipa.ipa_exceptions import ( + IpaException, IpaProviderException, IpaSSHException, IpaUtilsException @@ -92,8 +93,13 @@ # Get ipa ini config file self.config = config or IPA_CONFIG_FILE - self.ipa_config = ipa_utils.get_config(self.config) - self.logger.debug('Using ipa config file: %s' % self.config) + + try: + self.ipa_config = ipa_utils.get_config(self.config) + self.logger.debug('Using ipa config file: %s' % self.config) + except IpaException: + self.ipa_config = None + self.logger.debug('IPA config file not found: %s' % self.config) self.description = description self.host_key_fingerprint = None @@ -185,7 +191,7 @@ if arg or arg is False: value = arg - elif config_key: + elif config_key and self.ipa_config: with ipa_utils.ignored(IpaUtilsException): value = ipa_utils.get_from_config( self.ipa_config, @@ -254,16 +260,17 @@ self.test_dirs.update(test_dirs.split(',')) with ipa_utils.ignored(IpaUtilsException): - # ipa config arg - test_dirs = ipa_utils.get_from_config( - self.ipa_config, - self.provider, - 'ipa', - 'test_dirs' - ) + if self.ipa_config: + # ipa config arg + test_dirs = ipa_utils.get_from_config( + self.ipa_config, + self.provider, + 'ipa', + 'test_dirs' + ) - if test_dirs: - self.test_dirs.update(test_dirs.split(',')) + if test_dirs: + self.test_dirs.update(test_dirs.split(',')) if not no_default_test_dirs: self.test_dirs.update(TEST_PATHS) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/package/python3-ipa.spec new/python3-ipa-2.3.0/package/python3-ipa.spec --- old/python3-ipa-2.2.0/package/python3-ipa.spec 2018-11-01 00:01:27.000000000 +0100 +++ new/python3-ipa-2.3.0/package/python3-ipa.spec 2018-11-09 23:53:51.000000000 +0100 @@ -18,7 +18,7 @@ %bcond_without test Name: python3-ipa -Version: 2.2.0 +Version: 2.3.0 Release: 0 Summary: Command line and API for testing custom images License: GPL-3.0-or-later diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/python3_ipa.egg-info/PKG-INFO new/python3-ipa-2.3.0/python3_ipa.egg-info/PKG-INFO --- old/python3-ipa-2.2.0/python3_ipa.egg-info/PKG-INFO 2018-11-01 00:07:50.000000000 +0100 +++ new/python3-ipa-2.3.0/python3_ipa.egg-info/PKG-INFO 2018-11-09 23:57:29.000000000 +0100 @@ -1,14 +1,18 @@ Metadata-Version: 2.1 Name: python3-ipa -Version: 2.2.0 +Version: 2.3.0 Summary: Package for automated testing of cloud images. Home-page: https://github.com/SUSE-Enceladus/ipa Author: SUSE Author-email: public-cloud-dev@susecloud.net License: GPLv3+ Description: [![Build Status](https://travis-ci.com/SUSE-Enceladus/ipa.svg?branch=master)](https://travis-ci.com/SUSE-Enceladus/ipa) + [![Codacy Badge](https://api.codacy.com/project/badge/Grade/845fb1620f334ae09488e8137dd6d256)](https://www.codacy.com/app/default-org/ipa?utm_source=github.com&utm_medium=referral&utm_content=SUSE-Enceladus/ipa&utm_campaign=Badge_Grade) + [![Documentation Status](https://readthedocs.org/projects/ipa/badge/?version=latest)](https://ipa.readthedocs.io/en/latest/?badge=latest) + [![Py Versions](https://img.shields.io/pypi/pyversions/python3-ipa.svg)](https://pypi.org/project/python3-ipa/) + [![License](https://img.shields.io/pypi/l/python3-ipa.svg)](https://pypi.org/project/python3-ipa/) - [![IPA](https://raw.githubusercontent.com/SUSE-Enceladus/ipa/master/docs/assets/imag... "IPA Logo")](https://github.com/SUSE-Enceladus/ipa) + [![IPA](https://raw.githubusercontent.com/SUSE-Enceladus/ipa/master/docs/source/_ima... "IPA Logo")](https://github.com/SUSE-Enceladus/ipa) overview ======== @@ -61,7 +65,7 @@ - PyYaml - testinfra - # [Docs](https://suse-enceladus.github.io/ipa/) + # [Docs](https://ipa.readthedocs.io/en/latest/) Tests ===== @@ -144,8 +148,9 @@ Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 Requires-Python: >=3.4 Description-Content-Type: text/markdown -Provides-Extra: test -Provides-Extra: dev Provides-Extra: tox +Provides-Extra: dev +Provides-Extra: test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/python3_ipa.egg-info/SOURCES.txt new/python3-ipa-2.3.0/python3_ipa.egg-info/SOURCES.txt --- old/python3-ipa-2.2.0/python3_ipa.egg-info/SOURCES.txt 2018-11-01 00:07:50.000000000 +0100 +++ new/python3-ipa-2.3.0/python3_ipa.egg-info/SOURCES.txt 2018-11-09 23:57:29.000000000 +0100 @@ -10,10 +10,6 @@ setup.cfg setup.py tox.ini -docs/index.md -docs/source.md -docs/start.md -docs/tests.md ipa/__init__.py ipa/collect_items.py ipa/ipa_azure.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/python3_ipa.egg-info/requires.txt new/python3-ipa-2.3.0/python3_ipa.egg-info/requires.txt --- old/python3-ipa-2.2.0/python3_ipa.egg-info/requires.txt 2018-11-01 00:07:50.000000000 +0100 +++ new/python3-ipa-2.3.0/python3_ipa.egg-info/requires.txt 2018-11-09 23:57:29.000000000 +0100 @@ -18,6 +18,8 @@ pytest-cov bumpversion pip>=7.0.0 +Sphinx +sphinx-click [test] coverage diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/requirements-dev.txt new/python3-ipa-2.3.0/requirements-dev.txt --- old/python3-ipa-2.2.0/requirements-dev.txt 2018-10-31 16:39:06.000000000 +0100 +++ new/python3-ipa-2.3.0/requirements-dev.txt 2018-11-05 16:16:29.000000000 +0100 @@ -2,3 +2,5 @@ bumpversion pip>=7.0.0 +Sphinx +sphinx-click diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/setup.cfg new/python3-ipa-2.3.0/setup.cfg --- old/python3-ipa-2.2.0/setup.cfg 2018-11-01 00:07:50.000000000 +0100 +++ new/python3-ipa-2.3.0/setup.cfg 2018-11-09 23:57:29.000000000 +0100 @@ -1,5 +1,5 @@ [bumpversion] -current_version = 2.2.0 +current_version = 2.3.0 commit = True tag = False @@ -7,6 +7,8 @@ [bumpversion:file:ipa/__init__.py] +[bumpversion:file:docs/source/conf.py] + [bumpversion:file:package/python3-ipa.spec] [tool:pytest] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/setup.py new/python3-ipa-2.3.0/setup.py --- old/python3-ipa-2.2.0/setup.py 2018-11-01 00:01:27.000000000 +0100 +++ new/python3-ipa-2.3.0/setup.py 2018-11-09 23:53:51.000000000 +0100 @@ -43,7 +43,7 @@ setup( name='python3-ipa', - version='2.2.0', + version='2.3.0', description="Package for automated testing of cloud images.", long_description=readme, long_description_content_type="text/markdown", @@ -81,5 +81,6 @@ 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', ], ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/tests/test_ipa_gce.py new/python3-ipa-2.3.0/tests/test_ipa_gce.py --- old/python3-ipa-2.2.0/tests/test_ipa_gce.py 2018-10-31 16:10:33.000000000 +0100 +++ new/python3-ipa-2.3.0/tests/test_ipa_gce.py 2018-11-08 03:14:51.000000000 +0100 @@ -69,11 +69,13 @@ self.kwargs['ssh_private_key_file'] = 'tests/data/ida_test' + @patch.object(GCEProvider, '_validate_region') @patch.object(GCEProvider, '_get_ssh_public_key') @patch.object(GCEProvider, '_get_driver') def test_gce_get_service_account_info(self, mock_get_driver, - mock_get_ssh_key): + mock_get_ssh_key, + mock_validate_region): """Test get service account info method.""" mock_get_driver.return_value = None mock_get_ssh_key.return_value = None @@ -85,12 +87,14 @@ 'test@test.iam.gserviceaccount.com' assert provider.service_account_project == 'test' + @patch.object(GCEProvider, '_validate_region') @patch.object(GCEProvider, '_get_ssh_public_key') @patch.object(GCEProvider, '_get_driver') def test_gce_get_service_account_info_invalid( self, mock_get_driver, - mock_get_ssh_key + mock_get_ssh_key, + mock_validate_region ): """Test get service account info method.""" mock_get_driver.return_value = None @@ -108,11 +112,13 @@ 'docs for information on GCE configuration.' assert str(error.value) == msg + @patch.object(GCEProvider, '_validate_region') @patch.object(GCEProvider, '_get_ssh_public_key') @patch('libcloud.compute.drivers.gce.GCENodeDriver') def test_gce_get_driver(self, mock_node_driver, - mock_get_ssh_key): + mock_get_ssh_key, + mock_validate_region): """Test gce get driver method.""" driver = MagicMock() @@ -122,11 +128,13 @@ provider = GCEProvider(**self.kwargs) assert driver == provider.compute_driver + @patch.object(GCEProvider, '_validate_region') @patch.object(GCEProvider, '_get_ssh_public_key') @patch.object(GCEProvider, '_get_driver') def test_gce_get_instance(self, mock_get_driver, - mock_get_ssh_key): + mock_get_ssh_key, + mock_validate_region): """Test gce get instance method.""" instance = MagicMock() driver = MagicMock() @@ -154,16 +162,26 @@ assert str(error.value) == "Instance with id: test-instance cannot" \ " be found: 'Broken'" + @patch.object(GCEProvider, '_validate_region') @patch.object(GCEProvider, '_get_driver') - def test_gce_get_ssh_public_key(self, mock_get_driver): + def test_gce_get_ssh_public_key( + self, + mock_get_driver, + mock_validate_region + ): """Test GCE get instance method.""" mock_get_driver.return_value = None provider = GCEProvider(**self.kwargs) assert provider.ssh_public_key + @patch.object(GCEProvider, '_validate_region') @patch.object(GCEProvider, '_get_driver') - def test_gce_get_subnet(self, mock_get_driver): + def test_gce_get_subnet( + self, + mock_get_driver, + mock_validate_region + ): """Test GCE get subnetwork method.""" subnetwork = MagicMock() driver = MagicMock() @@ -176,8 +194,13 @@ assert result == subnetwork + @patch.object(GCEProvider, '_validate_region') @patch.object(GCEProvider, '_get_driver') - def test_gce_get_subnet_exception(self, mock_get_driver): + def test_gce_get_subnet_exception( + self, + mock_get_driver, + mock_validate_region + ): """Test GCE get subnetwork method.""" driver = MagicMock() driver.ex_get_subnetwork.side_effect = Exception('Cannot find subnet!') @@ -192,13 +215,15 @@ assert msg == str(error.value) + @patch.object(GCEProvider, '_validate_region') @patch.object(GCEProvider, '_get_subnet') @patch('ipa.ipa_utils.generate_instance_name') @patch.object(GCEProvider, '_get_driver') def test_gce_launch_instance(self, mock_get_driver, mock_generate_instance_name, - mock_get_subnet): + mock_get_subnet, + mock_validate_region): """Test GCE launch instance method.""" driver = MagicMock() instance = MagicMock() @@ -209,14 +234,6 @@ mock_generate_instance_name.return_value = 'test-instance' provider = GCEProvider(**self.kwargs) - provider.region = None - - with pytest.raises(GCEProviderException) as error: - provider._launch_instance() - - assert str(error.value) == \ - 'Zone is required to launch a new GCE instance. ' \ - 'Example: us-west1-a' provider.region = 'us-west1-a' provider.subnet_id = 'test-subnet' @@ -230,13 +247,15 @@ assert provider.running_instance_id == 'test-instance' + @patch.object(GCEProvider, '_validate_region') @patch.object(GCEProvider, '_get_ssh_public_key') @patch.object(GCEProvider, '_get_driver') @patch.object(GCEProvider, '_get_instance') def test_gce_set_image_id(self, mock_get_instance, mock_get_driver, - mock_get_ssh_key): + mock_get_ssh_key, + mock_validate_region): """Test ec2 provider set image id method.""" instance = MagicMock() instance.image = 'test-image' @@ -249,3 +268,26 @@ assert provider.image_id == instance.image assert mock_get_instance.call_count == 1 + + @patch.object(GCEProvider, '_get_driver') + def test_gce_validate_region(self, mock_get_driver): + """Test ec2 provider set image id method.""" + driver = MagicMock() + driver.ex_get_zone.return_value = None + mock_get_driver.return_value = driver + + with pytest.raises(GCEProviderException) as error: + GCEProvider(**self.kwargs) + + assert str(error.value) == \ + 'Zone is required for GCE provider: Example: us-west1-a' + + self.kwargs['region'] = 'fake' + + with pytest.raises(GCEProviderException) as error: + GCEProvider(**self.kwargs) + + driver.ex_get_zone.assert_called_once_with('fake') + + assert str(error.value) == \ + 'fake is not a valid GCE zone. Example: us-west1-a' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/usr/share/lib/ipa/tests/SLES/SAP/test_sles_sap_license.py new/python3-ipa-2.3.0/usr/share/lib/ipa/tests/SLES/SAP/test_sles_sap_license.py --- old/python3-ipa-2.2.0/usr/share/lib/ipa/tests/SLES/SAP/test_sles_sap_license.py 2018-10-31 16:10:33.000000000 +0100 +++ new/python3-ipa-2.3.0/usr/share/lib/ipa/tests/SLES/SAP/test_sles_sap_license.py 2018-11-09 17:57:12.000000000 +0100 @@ -1,26 +1,23 @@ -def test_sles_sap_license(host): - license_dir = '/etc/YaST2/licenses/ha' - license_content = 'SUSE End User License Agreement' +import pytest - lic_dir = host.file(license_dir) - try: - assert lic_dir.exists - assert lic_dir.is_directory - except AssertionError: - # SLE15 dir changed - license_dir = '/etc/YaST2/licenses/SLES_SAP' - lic_dir = host.file(license_dir) - assert lic_dir.exists - assert lic_dir.is_directory +def test_sles_sap_license( + host, confirm_sles_license_content, get_release_value +): + version = get_release_value('VERSION') - license = host.file(license_dir + '/license.txt') - assert license.exists - assert license.is_file + if version == '12-SP4': + # Skip SLES12-SP4 which has a combined license + pytest.skip('SLES12-SP4 has combined license.') - try: - assert license.contains(license_content) - except AssertionError: - # SLE15 license text changed - license_content = 'SUSE(R) Linux Enterprise End User License Agreement' - assert license.contains(license_content) + license_dirs = [ + '/etc/YaST2/licenses/ha/', + '/etc/YaST2/licenses/SLES_SAP/' + ] + result = confirm_sles_license_content(license_dirs) + + if result is False: + pytest.fail( + 'SUSE End User License Agreement not found ' + 'or license has incorrect content.' + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/usr/share/lib/ipa/tests/SLES/conftest.py new/python3-ipa-2.3.0/usr/share/lib/ipa/tests/SLES/conftest.py --- old/python3-ipa-2.2.0/usr/share/lib/ipa/tests/SLES/conftest.py 2018-10-31 20:06:48.000000000 +0100 +++ new/python3-ipa-2.3.0/usr/share/lib/ipa/tests/SLES/conftest.py 2018-11-09 17:57:12.000000000 +0100 @@ -265,15 +265,30 @@ @pytest.fixture() def is_sles_sap(host): def f(): - license_dir = '/etc/YaST2/licenses/ha' - lic_dir = host.file(license_dir) - try: - assert lic_dir.exists - assert lic_dir.is_directory - except AssertionError: - # SLE15 dir changed - license_dir = '/etc/YaST2/licenses/SLES_SAP' + sap = host.file('/etc/products.d/SLES_SAP.prod') + return sap.exists and sap.is_file + return f + + +@pytest.fixture() +def confirm_sles_license_content(host): + def f(license_dirs): + license_content = [ + 'SUSE End User License Agreement', + 'SUSE(R) Linux Enterprise End User License Agreement', + 'SUSE® Linux Enterprise End User License Agreement' + ] + + for license_dir in license_dirs: lic_dir = host.file(license_dir) - return lic_dir.exists and lic_dir.is_directory - return True + + if lic_dir.exists and lic_dir.is_directory: + lic = host.file(license_dir + 'license.txt') + return all([ + lic.exists, + lic.is_file, + any(lic.contains(content) for content in license_content) + ]) + + return False return f diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python3-ipa-2.2.0/usr/share/lib/ipa/tests/SLES/test_sles_license.py new/python3-ipa-2.3.0/usr/share/lib/ipa/tests/SLES/test_sles_license.py --- old/python3-ipa-2.2.0/usr/share/lib/ipa/tests/SLES/test_sles_license.py 2018-10-31 16:10:33.000000000 +0100 +++ new/python3-ipa-2.3.0/usr/share/lib/ipa/tests/SLES/test_sles_license.py 2018-11-09 17:57:12.000000000 +0100 @@ -1,22 +1,15 @@ -def test_sles_license(host): - license_dir = '/etc/YaST2/licenses/base' - license_content = 'SUSE End User License Agreement' +import pytest - lic_dir = host.file(license_dir) - if not lic_dir.exists: - license_dir = '/etc/YaST2/licenses/SLES' - lic_dir = host.file(license_dir) - assert lic_dir.exists - assert lic_dir.is_directory +def test_sles_license(host, confirm_sles_license_content): + license_dirs = [ + '/etc/YaST2/licenses/base/', + '/etc/YaST2/licenses/SLES/' + ] + result = confirm_sles_license_content(license_dirs) - license = host.file(license_dir + '/license.txt') - assert license.exists - assert license.is_file - - try: - assert license.contains(license_content) - except Exception: - # SLE15 license text changed - license_content = 'SUSE(R) Linux Enterprise End User License Agreement' - assert license.contains(license_content) + if result is False: + pytest.fail( + 'SUSE End User License Agreement not found ' + 'or license has incorrect content.' + )