diff --git a/Dockerfile b/Dockerfile index a4ed358dd8..6a3ffe9223 100644 --- a/Dockerfile +++ b/Dockerfile @@ -51,7 +51,7 @@ ENV PACKAGES="\ " RUN apk add --update --no-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ ${PACKAGES} -ENV MOLECULE_EXTRAS="azure,docker,docs,vagrant,windows" +ENV MOLECULE_EXTRAS="docker,docs,windows" # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=917006 RUN pip3 install -U wheel @@ -132,7 +132,7 @@ ENV GEM_PACKAGES="\ etc \ " -ENV MOLECULE_EXTRAS="azure,docker,docs,lxc,vagrant,windows" +ENV MOLECULE_EXTRAS="docker,docs,windows" RUN \ apk add --update --no-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ ${BUILD_DEPS} ${PACKAGES} \ diff --git a/contrib/convert.py b/contrib/convert.py deleted file mode 100755 index b1d4000919..0000000000 --- a/contrib/convert.py +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env python -# -# Copyright (c) 2015-2018 Cisco Systems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. - -import errno -import glob -import os -import shutil - -import click -import sh - -from molecule import config -from molecule import logger -from molecule import migrate -from molecule import scenario -from molecule import util - -LOG = logger.get_logger(__name__) - - -class Convert(object): - def __init__(self, old_molecule_file, driver_name): - self._old_molecule_file = old_molecule_file - - if not os.path.isfile(old_molecule_file): - msg = 'Unable to find {}. Exiting.'.format(old_molecule_file) - util.sysexit_with_message(msg) - - self._m = migrate.Migrate(old_molecule_file) - self._old_role_dir = os.path.join(os.path.dirname(old_molecule_file)) - self._old_dot_molecule_dir = scenario.ephemeral_directory(self._old_role_dir) - self._old_test_dir = os.path.join(self._old_role_dir, 'tests') - self._old_playbook = os.path.join(self._old_role_dir, 'playbook.yml') - self._molecule_dir = config.molecule_directory(self._old_role_dir) - self._scenario_dir = os.path.join(self._molecule_dir, 'default') - self._test_dir = os.path.join(self._scenario_dir, 'tests') - self._molecule_file = config.molecule_file(self._scenario_dir) - - self._role_name = os.path.basename(os.path.normpath(self._old_role_dir)) - - def migrate(self): - self._create_scenario() - self._create_new_molecule_file() - self._copy_old_files() - self._cleanup_old_files() - - def _create_scenario(self): - options = { - 'role_name': self._role_name, - 'scenario_name': 'default', - 'driver_name': 'vagrant', - } - cmd = sh.molecule.bake('init', 'scenario', _cwd=self._old_role_dir, **options) - util.run_command(cmd) - - def _create_new_molecule_file(self): - with open(self._molecule_file, 'w') as stream: - msg = 'Writing molecule.yml to {}'.format(self._molecule_file) - LOG.info(msg) - stream.write(self._m.dump()) - - def _copy_old_files(self): - for f in glob.glob(r'{}/test_*.py'.format(self._old_test_dir)): - msg = 'Copying {} to {}'.format(f, self._test_dir) - LOG.info(msg) - shutil.copy(f, self._test_dir) - - if os.path.isfile(self._old_playbook): - msg = 'Copying {} to {}'.format(self._old_playbook, self._scenario_dir) - LOG.info(msg) - shutil.copy(self._old_playbook, self._scenario_dir) - - def _cleanup_old_files(self): - files = [ - self._old_dot_molecule_dir, - self._old_molecule_file, - self._old_playbook, - ] - for f in files: - if os.path.exists(f): - msg = 'Deleting {}'.format(f) - LOG.warn(msg) - try: - shutil.rmtree(f) - except OSError as exc: - if exc.errno == errno.ENOTDIR: - os.remove(f) - else: - raise - - -@click.command() -@click.argument('old_molecule_file', required=True) -@click.option( - '--driver-name', - '-d', - type=click.Choice(['vagrant']), - default='vagrant', - help='Name of driver to migrate. (vagrant)', -) -def main(old_molecule_file, driver_name): # pragma: no cover - """ Migrate a Molecule v1 role to the v2 format. """ - - c = Convert(old_molecule_file, driver_name) - c.migrate() - - -if __name__ == '__main__': - main() diff --git a/docs/ci.rst b/docs/ci.rst index ccd2066b88..a54fe8a230 100644 --- a/docs/ci.rst +++ b/docs/ci.rst @@ -63,7 +63,7 @@ A ``.travis.yml`` testing a role named foo1 with the Docker driver. - sudo apt-get -qq update install: - pip install molecule - # - pip install required driver (e.g. docker, python-vagrant, shade, boto, apache-libcloud) + # - pip install required driver (e.g. docker, shade, boto, apache-libcloud) script: - molecule test diff --git a/docs/configuration.rst b/docs/configuration.rst index 0ac836cc14..4a4751b91d 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -82,163 +82,6 @@ Podman .. autoclass:: molecule.driver.podman.Podman() :undoc-members: -Vagrant -^^^^^^^ - -.. autoclass:: molecule.driver.vagrant.Vagrant() - :undoc-members: - -.. _molecule_vagrant_module: - -Molecule Vagrant Module -^^^^^^^^^^^^^^^^^^^^^^^ - -Molecule manages Vagrant via an internal Ansible module. The following belongs -in the appropriate create or destroy playbooks, and uses the default provider. - -Supported Providers: - -* VirtualBox (default) -* VMware (vmware_fusion, vmware_workstation and vmware_desktop) -* Parallels -* Libvirt (requires vagrant-libvirt plugin) - -Create instances. - -.. code-block:: yaml - - - hosts: localhost - connection: local - tasks: - - name: Create instances - molecule_vagrant: - instance_name: "{{ item }}" - platform_box: ubuntu/trusty64 - state: up - with_items: - - instance-1 - - instance-2 - -Destroy instances. - -.. code-block:: yaml - - - hosts: localhost - connection: local - tasks: - - name: Destroy instances - molecule_vagrant: - instance_name: "{{ item }}" - platform_box: ubuntu/trusty64 - state: destroy - with_items: - - instance-1 - - instance-2 - -Halt instances (shutdown without destroy). - -.. code-block:: yaml - - - hosts: localhost - connection: local - tasks: - - name: Halt instances - molecule_vagrant: - instance_name: "{{ item }}" - platform_box: ubuntu/trusty64 - state: halt - with_items: - - instance-1 - - instance-2 - -Create instances with interfaces. - -.. code-block:: yaml - - - hosts: localhost - connection: local - tasks: - - name: Create instance with interfaces - molecule_vagrant: - instance_name: instance-1 - instance_interfaces: - - auto_config: true - network_name: private_network - type: dhcp - - auto_config: false - network_name: private_network - type: dhcp - - auto_config: true - ip: 192.168.11.3 - network_name: private_network - type: static - platform_box: ubuntu/trusty64 - state: up - -Create instances with additional provider options. - -.. code-block:: yaml - - - hosts: localhost - connection: local - tasks: - - name: Create instances - molecule_vagrant: - instance_name: "{{ item }}" - platform_box: ubuntu/trusty64 - provider_name: virtualbox - provider_memory: 1024 - provider_cpus: 4 - provider_raw_config_args: - - "customize ['modifyvm', :id, '--cpuexecutioncap', '50']" - provider_options: - gui: true - provision: true - state: up - with_items: - - instance-1 - - instance-2 - -Create instances with additional instance options. - -.. code-block:: yaml - - - hosts: localhost - connection: local - tasks: - - name: Create instances - molecule_vagrant: - instance_name: "{{ item }}" - platform_box: ubuntu/trusty64 - instance_raw_config_args: - - "vm.network 'forwarded_port', guest: 80, host: 8080" - state: up - with_items: - - instance-1 - - instance-2 - -Create instances on a remote Libvirt node using default create/destroy -templates. - -.. code-block:: yaml - - - hosts: localhost - connection: local - tasks: - - name: Create instances - molecule_vagrant: - instance_name: "{{ item }}" - platform_box: ubuntu/trusty64 - provider_raw_config_args: - - 'host = "remote-node.example.com"' - - 'connect_via_ssh = "True"' - - 'username = "sshuser"' - - 'driver = "kvm"' - - 'cpu_mode = "host-passthrough"' - state: up - with_items: - - instance-1 - - instance-2 .. _linters: diff --git a/docs/examples.rst b/docs/examples.rst index 335e30e31e..e440624553 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -213,30 +213,6 @@ project. env: ANSIBLE_$VAR: $VALUE -Vagrant Proxy Settings -====================== - -One way of passing in proxy settings to the Vagrant provider is using the -vagrant-proxyconf plugin and adding the vagrant-proxyconf configurations to -~/.vagrant.d/Vagrantfile. - -To install the plugin run: - -.. code-block:: bash - - $ vagrant plugin install vagrant-proxyconf - -On linux add the following Vagrantfile to ~/.vagrant.d/Vagrantfile. - -.. code-block:: ruby - - Vagrant.configure("2") do |config| - if Vagrant.has_plugin?("vagrant-proxyconf") - config.proxy.http = ENV['HTTP_PROXY'] - config.proxy.https = ENV['HTTP_PROXY'] - config.proxy.no_proxy = ENV['NO_PROXY'] - end - end Sharing Across Scenarios ======================== diff --git a/docs/index.rst b/docs/index.rst index 9305b1a26d..8b177e3690 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,7 +12,6 @@ Contents: usage examples configuration - porting testing contributing development diff --git a/docs/porting.rst b/docs/porting.rst deleted file mode 100644 index f1716673bf..0000000000 --- a/docs/porting.rst +++ /dev/null @@ -1,68 +0,0 @@ -************* -Porting Guide -************* - -Porting your existing role from Molecule to Molecule v2. - -Automatically -============= - -Molecule ships with a conversion script. This conversion script converts a -molecule v1 vagrant driver config into a molecule v2 vagrant config. The -script handles the creation of the initial directory structure, migration and -cleanup of files. - -.. note:: - - The script is fairly crude, and only supports Vagrant at the time of this - writing. The authors will be adding additional functionality as additional - roles are migrated to v2. - -.. code-block:: bash - - $ contrib/convert.py /path/to/v1/role/molecule.yml - -Manually -======== - -1. In the basedir of your existing role, create a new ``default`` scenario. This - scenario is equivalent to your existing Molecule v1 setup. - -.. code-block:: bash - - $ cd $role-name - $ molecule init scenario -r $role-name -s default -d $driver-name - -.. important: - - The linting checks will likely fail since the role was not created with - ``molecule init role``. The errors can be ignored by placing a ``.yamllint`` - file in the project root of the role. This will be corrected in the - future. - -2. Move existing Testinfra tests to the new scenario's test directory located - at ``molecule/default/tests/test_default.py``. - -3. If necessary port existing Serverspec tests to Testinfra. A Testinfra - skeleton has been created at ``molecule/default/tests/test_default.py``. - -4. Port role's existing ``molecule.yml`` to the new format located in the - scenario's directory at `molecule/default/molecule.yml`. - -5. Port role's existing ``playbook.yml`` to the new location in the scenario's - directory at `molecule/default/playbook.yml`. - -6. Cleanup - -.. code-block:: bash - - $ rm -rf .molecule/ - $ rm -rf molecule.yml - $ rm -rf playbook.yml - $ rm -rf tests/ - -6. Test - -.. code-block:: bash - - $ molecule test diff --git a/molecule/cookiecutter/molecule/{{cookiecutter.role_name}}/{{cookiecutter.molecule_directory}}/{{cookiecutter.scenario_name}}/molecule.yml b/molecule/cookiecutter/molecule/{{cookiecutter.role_name}}/{{cookiecutter.molecule_directory}}/{{cookiecutter.scenario_name}}/molecule.yml index c0804e2b8c..8cd85427ff 100644 --- a/molecule/cookiecutter/molecule/{{cookiecutter.role_name}}/{{cookiecutter.molecule_directory}}/{{cookiecutter.scenario_name}}/molecule.yml +++ b/molecule/cookiecutter/molecule/{{cookiecutter.role_name}}/{{cookiecutter.molecule_directory}}/{{cookiecutter.scenario_name}}/molecule.yml @@ -3,10 +3,6 @@ dependency: name: {{ cookiecutter.dependency_name }} driver: name: {{ cookiecutter.driver_name }} -{%- if cookiecutter.driver_name == 'vagrant' %} - provider: - name: virtualbox -{%- endif %} lint: name: {{ cookiecutter.lint_name }} platforms: @@ -16,9 +12,6 @@ platforms: {%- elif cookiecutter.driver_name == 'podman' %} - name: instance image: docker.io/centos:7 -{%- elif cookiecutter.driver_name == 'vagrant' %} - - name: instance - box: ubuntu/xenial64 {%- else %} - name: instance {%- endif %} diff --git a/molecule/cookiecutter/scenario/driver/vagrant/cookiecutter.json b/molecule/cookiecutter/scenario/driver/vagrant/cookiecutter.json deleted file mode 100644 index 2ec6fb298f..0000000000 --- a/molecule/cookiecutter/scenario/driver/vagrant/cookiecutter.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "molecule_directory": "molecule", - "role_name": "OVERRIDDEN", - "scenario_name": "OVERRIDDEN" -} diff --git a/molecule/cookiecutter/scenario/driver/vagrant/{{cookiecutter.molecule_directory}}/{{cookiecutter.scenario_name}}/INSTALL.rst b/molecule/cookiecutter/scenario/driver/vagrant/{{cookiecutter.molecule_directory}}/{{cookiecutter.scenario_name}}/INSTALL.rst deleted file mode 100644 index 4f44b6745b..0000000000 --- a/molecule/cookiecutter/scenario/driver/vagrant/{{cookiecutter.molecule_directory}}/{{cookiecutter.scenario_name}}/INSTALL.rst +++ /dev/null @@ -1,23 +0,0 @@ -******* -Vagrant driver installation guide -******* - -Requirements -============ - -* Vagrant -* Virtualbox, Parallels, VMware Fusion, VMware Workstation or VMware Desktop - -Install -======= - -Please refer to the `Virtual environment`_ documentation for installation best -practices. If not using a virtual environment, please consider passing the -widely recommended `'--user' flag`_ when invoking ``pip``. - -.. _Virtual environment: https://virtualenv.pypa.io/en/latest/ -.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site - -.. code-block:: bash - - $ pip install 'molecule[vagrant]' diff --git a/molecule/cookiecutter/scenario/driver/vagrant/{{cookiecutter.molecule_directory}}/{{cookiecutter.scenario_name}}/playbook.yml b/molecule/cookiecutter/scenario/driver/vagrant/{{cookiecutter.molecule_directory}}/{{cookiecutter.scenario_name}}/playbook.yml deleted file mode 100644 index fecf1c843b..0000000000 --- a/molecule/cookiecutter/scenario/driver/vagrant/{{cookiecutter.molecule_directory}}/{{cookiecutter.scenario_name}}/playbook.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -- name: Converge - hosts: all - tasks: - - name: "Include {{ cookiecutter.role_name }}" - include_role: - name: "{{ cookiecutter.role_name }}" diff --git a/molecule/cookiecutter/scenario/driver/vagrant/{{cookiecutter.molecule_directory}}/{{cookiecutter.scenario_name}}/prepare.yml b/molecule/cookiecutter/scenario/driver/vagrant/{{cookiecutter.molecule_directory}}/{{cookiecutter.scenario_name}}/prepare.yml deleted file mode 100644 index f6eb955614..0000000000 --- a/molecule/cookiecutter/scenario/driver/vagrant/{{cookiecutter.molecule_directory}}/{{cookiecutter.scenario_name}}/prepare.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -{% raw -%} -- name: Prepare - hosts: all - gather_facts: false - tasks: - - name: Install python for Ansible - raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal) - become: true - changed_when: false -{%- endraw %} diff --git a/molecule/driver/delegated.py b/molecule/driver/delegated.py index e043b725a0..3929d5367a 100644 --- a/molecule/driver/delegated.py +++ b/molecule/driver/delegated.py @@ -109,7 +109,7 @@ class Delegated(Driver): ansible_connection: ssh ansible_ssh_common_args: '-F /path/to/ssh-config' platforms: - - name: instance-vagrant + - name: instance Provide the files Molecule will preserve post ``destroy`` action. diff --git a/molecule/driver/vagrant.py b/molecule/driver/vagrant.py deleted file mode 100644 index 528406e12f..0000000000 --- a/molecule/driver/vagrant.py +++ /dev/null @@ -1,215 +0,0 @@ -# Copyright (c) 2015-2018 Cisco Systems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. - -import os - -from molecule import logger -from molecule import util -from molecule.api import Driver - - -LOG = logger.get_logger(__name__) - - -class Vagrant(Driver): - """ - The class responsible for managing `Vagrant`_ instances. `Vagrant`_ is - `not` the default driver used in Molecule. - - Molecule leverages Molecule's own :ref:`molecule_vagrant_module`, by - mapping variables from ``molecule.yml`` into ``create.yml`` and ``destroy.yml``. - - .. important:: - - This driver is alpha quality software. Do not perform any additonal - tasks inside the ``create`` playbook. Molecule does not know about the - Vagrant instances' configuration until the ``converge`` playbook is - executed. - - The ``create`` playbook boots instances, then the instance data is - written to disk. The instance data is then added to Molecule's Ansible - inventory on the next execution of `molecule.command.create`, which - happens to be the ``converge`` playbook. - - This is an area needing improvement. Gluing togher Ansible playbook - return data and molecule is clunky. Moving the playbook execution - from ``sh`` to python is less than ideal, since the playbook's return - data needs handled by an internal callback plugin. - - Operating this far inside Ansible's internals doesn't feel right. Nor - does orchestrating Ansible's CLI with Molecule. Ansible is throwing - pieces over the wall, which Molecule is picking up and reconstructing. - - .. code-block:: yaml - - driver: - name: vagrant - platforms: - - name: instance-1 - instance_raw_config_args: - - "vm.network 'forwarded_port', guest: 80, host: 8080" - interfaces: - - auto_config: true - network_name: private_network - type: dhcp - config_options: - synced_folder: True - box: debian/jessie64 - box_version: 10.1 - box_url: http://repo.example.com/images/postmerge/debian.json - memory: 1024 - cpus: 1 - provider_options: - gui: True - provider_raw_config_args: - - "customize ['modifyvm', :id, '--cpuexecutioncap', '50']" - - "customize ['modifyvm', :id, '--uartmode1', 'disconnected']" - provider_override_args: - - "vm.synced_folder './', '/vagrant', disabled: true, type: 'nfs'" - provision: True - - .. code-block:: bash - - $ pip install molecule[vagrant] - - Change the provider passed to Vagrant. - - .. code-block:: yaml - - driver: - name: vagrant - provider: - name: parallels - - Change the options passed to the ssh client. - - .. code-block:: yaml - - driver: - name: vagrant - ssh_connection_options: - - '-o ControlPath=~/.ansible/cp/%r@%h-%p' - - .. important:: - - Molecule does not merge lists, when overriding the developer must - provide all options. - - Provide a list of files Molecule will preserve, relative to the scenario - ephemeral directory, after any ``destroy`` subcommand execution. - - .. code-block:: yaml - - driver: - name: vagrant - safe_files: - - foo - - .. _`Vagrant`: https://www.vagrantup.com - """ # noqa - - def __init__(self, config=None): - super(Vagrant, self).__init__(config) - self._name = 'vagrant' - - @property - def name(self): - return self._name - - @name.setter - def name(self, value): - self._name = value - - @property - def testinfra_options(self): - return { - 'connection': 'ansible', - 'ansible-inventory': self._config.provisioner.inventory_file, - } - - @property - def login_cmd_template(self): - connection_options = ' '.join(self.ssh_connection_options) - - return ( - 'ssh {{address}} ' - '-l {{user}} ' - '-p {{port}} ' - '-i {{identity_file}} ' - '{}' - ).format(connection_options) - - @property - def default_safe_files(self): - return [ - self.vagrantfile, - self.vagrantfile_config, - self.instance_config, - os.path.join(self._config.scenario.ephemeral_directory, '.vagrant'), - os.path.join(self._config.scenario.ephemeral_directory, 'vagrant-*.out'), - os.path.join(self._config.scenario.ephemeral_directory, 'vagrant-*.err'), - ] - - @property - def default_ssh_connection_options(self): - return self._get_ssh_connection_options() - - def login_options(self, instance_name): - d = {'instance': instance_name} - - return util.merge_dicts(d, self._get_instance_config(instance_name)) - - def ansible_connection_options(self, instance_name): - try: - d = self._get_instance_config(instance_name) - - return { - 'ansible_user': d['user'], - 'ansible_host': d['address'], - 'ansible_port': d['port'], - 'ansible_private_key_file': d['identity_file'], - 'connection': 'ssh', - 'ansible_ssh_common_args': ' '.join(self.ssh_connection_options), - } - except StopIteration: - return {} - except IOError: - # Instance has yet to be provisioned , therefore the - # instance_config is not on disk. - return {} - - @property - def vagrantfile(self): - return os.path.join(self._config.scenario.ephemeral_directory, 'Vagrantfile') - - @property - def vagrantfile_config(self): - return os.path.join(self._config.scenario.ephemeral_directory, 'vagrant.yml') - - def _get_instance_config(self, instance_name): - instance_config_dict = util.safe_load_file(self._config.driver.instance_config) - - return next( - item for item in instance_config_dict if item['instance'] == instance_name - ) - - def sanity_checks(self): - # FIXME(decentral1se): Implement sanity checks - pass diff --git a/molecule/migrate.py b/molecule/migrate.py deleted file mode 100644 index dddceeed51..0000000000 --- a/molecule/migrate.py +++ /dev/null @@ -1,193 +0,0 @@ -# Copyright (c) 2015-2018 Cisco Systems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. - -import collections -import json - -import yaml - -from molecule import logger -from molecule import util -from molecule.model import schema_v1 -from molecule.model import schema_v2 - -LOG = logger.get_logger(__name__) - - -class MyDumper(yaml.Dumper): - def increase_indent(self, flow=False, indentless=False): - return super(MyDumper, self).increase_indent(flow, False) - - -class Migrate(object): - def __init__(self, molecule_file): - """ - Initialize a new migrate class and returns None. - - :param molecule_file: A string containing an absolute path to the - molecule v1 config to parse. - :return: None - """ - self._molecule_file = molecule_file - self._v2 = self._get_config() - self._v1 = self._get_v1_config() - - def dump(self): - od = self._convert() - yaml.add_representer(collections.OrderedDict, self._get_dict_representer) - - return yaml.dump( - od, - Dumper=MyDumper, - default_flow_style=False, - explicit_start=True, - line_break=1, - ) - - def _convert(self): - if self._v1.get('vagrant'): - msg = 'Vagrant syle v1 config found' - LOG.info(msg) - self._set_vagrant_platforms() - self._set_vagrant_provider() - else: - msg = 'Vagrant migrations only supported. Exiting.' - util.sysexit_with_message(msg) - - self._set_provisioner() - self._set_verifier() - - od = collections.OrderedDict(sorted(self._v2.items(), key=lambda t: t[0])) - errors = schema_v2.validate(self._to_dict(od)) - self._check_errors(errors) - - return od - - def _to_dict(self, od): - return json.loads(json.dumps(od)) - - def _set_vagrant_provider(self): - provider = self._v1['vagrant']['providers'][0] - - self._v2['driver']['provider']['name'] = provider['name'] - - def _set_vagrant_platforms(self): - platforms = self._v1['vagrant']['platforms'][0] - provider = self._v1['vagrant']['providers'][0] - - platforms_list = [] - instances = self._v1['vagrant']['instances'] - for instance in instances: - i = collections.OrderedDict({}) - i['name'] = instance['name'] - - if platforms.get('box'): - i['box'] = platforms['box'] - - if platforms.get('box_version'): - i['box_version'] = platforms['box_version'] - - if platforms.get('box_url'): - i['box_url'] = platforms['box_url'] - - if provider.get('options', {}).get('memory'): - i['memory'] = provider['options']['memory'] - - if provider.get('options', {}).get('cpus'): - i['cpus'] = provider['options']['cpus'] - - if instance.get('ansible_groups'): - i['groups'] = instance['ansible_groups'] - - if instance.get('interfaces'): - i['interfaces'] = instance['interfaces'] - - if instance.get('raw_config_args'): - i['raw_config_args'] = instance['raw_config_args'] - - platforms_list.append(i) - - self._v2['platforms'] = platforms_list - - def _set_provisioner(self): - ansible = self._v1.get('ansible', collections.OrderedDict({})) - - self._v2['provisioner']['name'] = 'ansible' - self._v2['provisioner']['env'] = collections.OrderedDict({}) - - if ansible.get('raw_env_vars'): - self._v2['provisioner']['env'] = self._v1['ansible']['raw_env_vars'] - - self._v2['provisioner']['options'] = collections.OrderedDict({}) - self._v2['provisioner']['lint'] = collections.OrderedDict({}) - self._v2['provisioner']['lint']['name'] = 'ansible-lint' - - if ansible.get('extra_vars'): - self._v2['provisioner']['options']['extra-vars'] = ansible['extra_vars'] - - if ansible.get('verbose'): - self._v2['provisioner']['options']['verbose'] = ansible['verbose'] - - if ansible.get('become'): - self._v2['provisioner']['options']['become'] = ansible['become'] - - if ansible.get('tags'): - self._v2['provisioner']['options']['tags'] = ansible['tags'] - - def _set_verifier(self): - verifier = self._v1['verifier'] - - self._v2['verifier']['name'] = 'testinfra' - self._v2['verifier']['options'] = collections.OrderedDict({}) - self._v2['verifier']['lint'] = collections.OrderedDict({}) - self._v2['verifier']['lint']['name'] = 'flake8' - - if verifier.get('options', {}).get('sudo'): - self._v2['verifier']['options']['sudo'] = verifier['options']['sudo'] - - def _get_dict_representer(self, dumper, data): - return dumper.represent_dict(data.items()) - - def _get_v1_config(self): - d = util.safe_load(open(self._molecule_file)) - errors = schema_v1.validate(d) - self._check_errors(errors) - - return d - - def _get_config(self): - d = collections.OrderedDict( - { - 'dependency': {'name': 'galaxy'}, - 'driver': {'name': 'vagrant', 'provider': collections.OrderedDict({})}, - 'lint': {'name': 'yamllint'}, - 'provisioner': collections.OrderedDict({}), - 'platforms': [], - 'scenario': {'name': 'default'}, - 'verifier': collections.OrderedDict({}), - } - ) - - return d - - def _check_errors(self, errors): - if errors: - msg = "Failed to validate.\n\n{}".format(errors) - util.sysexit_with_message(msg) diff --git a/molecule/model/schema_v1.py b/molecule/model/schema_v1.py index c2d1177373..34723e742a 100644 --- a/molecule/model/schema_v1.py +++ b/molecule/model/schema_v1.py @@ -38,52 +38,6 @@ }, }, 'driver': {'type': 'dict', 'schema': {'name': {'type': 'string'}}}, - 'vagrant': { - 'type': 'dict', - 'schema': { - 'platforms': { - 'type': 'list', - 'schema': { - 'type': 'dict', - 'schema': { - 'name': {'type': 'string'}, - 'box': {'type': 'string'}, - 'box_version': {'type': 'string'}, - 'box_url': {'type': 'string'}, - }, - }, - }, - 'providers': { - 'type': 'list', - 'schema': { - 'type': 'dict', - 'schema': { - 'name': {'type': 'string'}, - 'type': {'type': 'string'}, - 'options': {'type': 'dict'}, - }, - }, - }, - 'instances': { - 'type': 'list', - 'schema': { - 'type': 'dict', - 'schema': { - 'name': {'type': 'string'}, - 'ansible_groups': { - 'type': 'list', - 'schema': {'type': 'string'}, - }, - 'interfaces': {'type': 'list', 'schema': {'type': 'dict'}}, - 'raw_config_args': { - 'type': 'list', - 'schema': {'type': 'string'}, - }, - }, - }, - }, - }, - }, 'verifier': { 'type': 'dict', 'schema': {'name': {'type': 'string'}, 'options': {'type': 'dict'}}, diff --git a/molecule/model/schema_v2.py b/molecule/model/schema_v2.py index e4ed8cff24..3580bac8fa 100644 --- a/molecule/model/schema_v2.py +++ b/molecule/model/schema_v2.py @@ -302,61 +302,6 @@ def pre_validate_base_schema(env, keep_string): }, } -driver_vagrant_provider_section_schema = { - 'driver': { - 'type': 'dict', - 'schema': { - 'name': {'type': 'string'}, - 'provider': { - 'type': 'dict', - 'schema': { - 'name': { - 'type': 'string', - 'nullable': False, - 'allowed': [ - 'virtualbox', - 'vmware_fusion', - 'vmware_workstation', - 'vmware_desktop', - 'parallels', - 'libvirt', - ], - } - }, - }, - }, - } -} - -platforms_vagrant_schema = { - 'platforms': { - 'type': 'list', - 'schema': { - 'type': 'dict', - 'schema': { - 'name': {'type': 'string'}, - 'interfaces': {'type': 'list', 'schema': {'type': 'dict'}}, - 'instance_raw_config_args': { - 'type': 'list', - 'schema': {'type': 'string'}, - }, - 'config_options': {'type': 'dict'}, - 'box': {'type': 'string'}, - 'box_version': {'type': 'string'}, - 'box_url': {'type': 'string'}, - 'memory': {'type': 'integer'}, - 'cpus': {'type': 'integer'}, - 'provider_options': {'type': 'dict'}, - 'provider_raw_config_args': { - 'type': 'list', - 'schema': {'type': 'string'}, - }, - 'provision': {'type': 'boolean'}, - }, - }, - } -} - platforms_docker_schema = { 'platforms': { 'type': 'list', @@ -573,9 +518,6 @@ def validate(c): util.merge_dicts(schema, platforms_docker_schema) elif c['driver']['name'] == 'podman': util.merge_dicts(schema, platforms_podman_schema) - elif c['driver']['name'] == 'vagrant': - util.merge_dicts(schema, driver_vagrant_provider_section_schema) - util.merge_dicts(schema, platforms_vagrant_schema) # Verifier util.merge_dicts(schema, api.verifiers()[c['verifier']['name']].schema()) diff --git a/molecule/provisioner/ansible.py b/molecule/provisioner/ansible.py index 69dd40350c..14bdaed296 100644 --- a/molecule/provisioner/ansible.py +++ b/molecule/provisioner/ansible.py @@ -80,7 +80,7 @@ class Ansible(base.Base): name: ansible log: True - The create/destroy playbooks for Docker and Vagrant are bundled with + The create/destroy playbooks for Docker and Podman are bundled with Molecule. These playbooks have a clean API from `molecule.yml`, and are the most commonly used. The bundled playbooks can still be overridden. diff --git a/molecule/provisioner/ansible/playbooks/vagrant/create.yml b/molecule/provisioner/ansible/playbooks/vagrant/create.yml deleted file mode 100644 index a2cc3ef367..0000000000 --- a/molecule/provisioner/ansible/playbooks/vagrant/create.yml +++ /dev/null @@ -1,62 +0,0 @@ ---- -- name: Create - hosts: localhost - connection: local - gather_facts: false - no_log: "{{ molecule_no_log }}" - tasks: - - name: Create molecule instance(s) - molecule_vagrant: - instance_name: "{{ item.name }}" - instance_interfaces: "{{ item.interfaces | default(omit) }}" - instance_raw_config_args: "{{ item.instance_raw_config_args | default(omit) }}" - - config_options: "{{ item.config_options | default(omit) }}" - - platform_box: "{{ item.box }}" - platform_box_version: "{{ item.box_version | default(omit) }}" - platform_box_url: "{{ item.box_url | default(omit) }}" - - provider_name: "{{ molecule_yml.driver.provider.name }}" - provider_memory: "{{ item.memory | default(omit) }}" - provider_cpus: "{{ item.cpus | default(omit) }}" - provider_options: "{{ item.provider_options | default(omit) }}" - provider_raw_config_args: "{{ item.provider_raw_config_args | default(omit) }}" - provider_override_args: "{{ item.provider_override_args | default(omit) }}" - - provision: "{{ item.provision | default(omit) }}" - - state: up - register: server - with_items: "{{ molecule_yml.platforms }}" - loop_control: - label: "{{ item.name }}" - no_log: false - - # NOTE(retr0h): Vagrant/VBox sucks and parallelizing instance creation - # causes issues. - - # Mandatory configuration for Molecule to function. - - - name: Populate instance config dict - set_fact: - instance_conf_dict: { - 'instance': "{{ item.Host }}", - 'address': "{{ item.HostName }}", - 'user': "{{ item.User }}", - 'port': "{{ item.Port }}", - 'identity_file': "{{ item.IdentityFile }}", } - with_items: "{{ server.results }}" - register: instance_config_dict - when: server.changed | bool - - - name: Convert instance config dict to a list - set_fact: - instance_conf: "{{ instance_config_dict.results | map(attribute='ansible_facts.instance_conf_dict') | list }}" - when: server.changed | bool - - - name: Dump instance config - copy: - content: "{{ instance_conf | to_json | from_json | molecule_to_yaml | molecule_header }}" - dest: "{{ molecule_instance_config }}" - when: server.changed | bool diff --git a/molecule/provisioner/ansible/playbooks/vagrant/destroy.yml b/molecule/provisioner/ansible/playbooks/vagrant/destroy.yml deleted file mode 100644 index 74f9d06c5c..0000000000 --- a/molecule/provisioner/ansible/playbooks/vagrant/destroy.yml +++ /dev/null @@ -1,37 +0,0 @@ ---- -- name: Destroy - hosts: localhost - connection: local - gather_facts: false - no_log: "{{ molecule_no_log }}" - tasks: - - name: Destroy molecule instance(s) - molecule_vagrant: - instance_name: "{{ item.name }}" - platform_box: "{{ item.box }}" - provider_name: "{{ molecule_yml.driver.provider.name }}" - provider_options: "{{ item.provider_options | default(omit) }}" - provider_raw_config_args: "{{ item.provider_raw_config_args | default(omit) }}" - force_stop: "{{ item.force_stop | default(true) }}" - - state: destroy - register: server - with_items: "{{ molecule_yml.platforms }}" - loop_control: - label: "{{ item.name }}" - no_log: false - - # NOTE(retr0h): Vagrant/VBox sucks and parallelizing instance deletion - # causes issues. - - # Mandatory configuration for Molecule to function. - - - name: Populate instance config - set_fact: - instance_conf: {} - - - name: Dump instance config - copy: - content: "{{ instance_conf | to_json | from_json | molecule_to_yaml | molecule_header }}" - dest: "{{ molecule_instance_config }}" - when: server.changed | bool diff --git a/molecule/provisioner/ansible/plugins/modules/molecule_vagrant.py b/molecule/provisioner/ansible/plugins/modules/molecule_vagrant.py deleted file mode 100644 index 6f461ca6f0..0000000000 --- a/molecule/provisioner/ansible/plugins/modules/molecule_vagrant.py +++ /dev/null @@ -1,577 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright (c) 2015-2018 Cisco Systems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. - -import contextlib -import datetime -import os -import subprocess -import sys - -import molecule -import molecule.config -import molecule.util - -try: - import vagrant -except ImportError: - sys.exit('ERROR: Driver missing, install python-vagrant.') - -DOCUMENTATION = ''' ---- -module: vagrant -short_description: Manage Vagrant instances -description: - - Manage the life cycle of Vagrant instances. - - Supports check mode. Run with --check and --diff to view config difference, - and list of actions to be taken. -version_added: 2.0 -author: - - Cisco Systems, Inc. -options: - instance_name: - description: - - Assign a name to a new instance or match an existing instance. - required: True - default: None - instance_interfaces: - description: - - Assign interfaces to a new instance. - required: False - default: [] - instance_raw_config_args: - description: - - Additional Vagrant options not explcitly exposed by this module. - required: False - default: None - config_options: - description: - - Additional config options not explcitly exposed by this module. - required: False - default: {} - platform_box: - description: - - Name of Vagrant box. - required: True - default: None - platform_box_version: - description: - - Explicit version of Vagrant box to use. - required: False - default: None - platform_box_url: - description: - - The URL to a Vagrant box. - required: False - default: None - provider_name: - description: - - Name of the Vagrant provider to use. - required: False - default: virtualbox - provider_memory: - description: - - Ammount of memory to allocate to the instance. - required: False - default: 512 - provider_cpus: - description: - - Number of CPUs to allocate to the instance. - required: False - default: 2 - provider_options: - description: - - Additional provider options not explcitly exposed by this module. - required: False - default: {} - provider_override_args: - description: - - Additional override options not explcitly exposed by this module. - required: False - default: None - provider_raw_config_args: - description: - - Additional Vagrant options not explcitly exposed by this module. - required: False - default: None - force_stop: - description: - - Force halt the instance, then destroy the instance. - required: False - default: False - state: - description: - - The desired state of the instance. - required: True - choices: ['up', 'halt', 'destroy'] - default: None -requirements: - - python >= 2.6 - - python-vagrant - - vagrant -''' - -EXAMPLES = ''' -See doc/source/configuration.rst -''' - -VAGRANTFILE_TEMPLATE = ''' -require 'yaml' - -Vagrant.configure('2') do |config| - vagrant_config_hash = YAML::load_file('{{ vagrantfile_config }}') - - if Vagrant.has_plugin?('vagrant-cachier') - config.cache.scope = 'machine' - end - - ## - # Configs - ## - - c = vagrant_config_hash['config'] - if !c['options']['synced_folder'] - config.vm.synced_folder ".", "/vagrant", disabled: true - end - c['options'].delete('synced_folder') - - c['options'].each { |key, value| - eval("config.#{key} = #{value}") - } - - ## - # Platforms - ## - - platform = vagrant_config_hash['platform'] - - config.vm.box = platform['box'] - - if platform['box_version'] - config.vm.box_version = platform['box_version'] - end - - if platform['box_url'] - config.vm.box_url = platform['box_url'] - end - - ## - # Provider - ## - - provider = vagrant_config_hash['provider'] - provider_memory = provider['options']['memory'] - provider_cpus = provider['options']['cpus'] - provider['options'].delete('memory') - provider['options'].delete('cpus') - - ## - # Virtualbox - ## - - if provider['name'] == 'virtualbox' - config.vm.provider provider['name'] do |virtualbox, override| - virtualbox.memory = provider_memory - virtualbox.cpus = provider_cpus - - if provider['options']['linked_clone'] - if Gem::Version.new(Vagrant::VERSION) >= Gem::Version.new('1.8.0') - virtualbox.linked_clone = provider['options']['linked_clone'] - end - else - if Gem::Version.new(Vagrant::VERSION) >= Gem::Version.new('1.8.0') - virtualbox.linked_clone = true - end - end - - # Custom - provider['options'].each { |key, value| - if key != 'linked_clone' - eval("virtualbox.#{key} = #{value}") - end - } - - # Raw Configuration - if provider['raw_config_args'] - provider['raw_config_args'].each { |raw_config_arg| - eval("virtualbox.#{raw_config_arg}") - } - end - - if provider['override_args'] - provider['override_args'].each { |override_arg| - eval("override.#{override_arg}") - } - end - end - - # The vagrant-vbguest plugin attempts to update packages - # before a RHEL based VM is registered. - # TODO: Port from the old .j2, should be done in raw config - if (vagrant_config_hash['platform'] =~ /rhel/i) != nil - if Vagrant.has_plugin?('vagrant-vbguest') - config.vbguest.auto_update = false - end - end - end - - ## - # VMware (vmware_fusion, vmware_workstation and vmware_desktop) - ## - - if provider['name'].start_with?('vmware_') - config.vm.provider provider['name'] do |vmware, override| - vmware.vmx['memsize'] = provider_memory - vmware.vmx['numvcpus'] = provider_cpus - - # Custom - provider['options'].each { |key, value| - eval("vmware.#{key} = #{value}") - } - - # Raw Configuration - if provider['raw_config_args'] - provider['raw_config_args'].each { |raw_config_arg| - eval("vmware.#{raw_config_arg}") - } - end - - if provider['override_args'] - provider['override_args'].each { |override_arg| - eval("override.#{override_arg}") - } - end - end - end - - ## - # Parallels - ## - - if provider['name'] == 'parallels' - config.vm.provider provider['name'] do |parallels, override| - parallels.memory = provider_memory - parallels.cpus = provider_cpus - - # Custom - provider['options'].each { |key, value| - eval("parallels.#{key} = #{value}") - } - - # Raw Configuration - if provider['raw_config_args'] - provider['raw_config_args'].each { |raw_config_arg| - eval("parallels.#{raw_config_arg}") - } - end - - if provider['override_args'] - provider['override_args'].each { |override_arg| - eval("override.#{override_arg}") - } - end - end - end - - ## - # Libvirt - ## - - if provider['name'] == 'libvirt' - config.vm.provider provider['name'] do |libvirt, override| - libvirt.memory = provider_memory - libvirt.cpus = provider_cpus - - # Custom - provider['options'].each { |key, value| - eval("libvirt.#{key} = #{value}") - } - - # Raw Configuration - if provider['raw_config_args'] - provider['raw_config_args'].each { |raw_config_arg| - eval("libvirt.#{raw_config_arg}") - } - end - - if provider['override_args'] - provider['override_args'].each { |override_arg| - eval("override.#{override_arg}") - } - end - end - end - - - ## - # Instances - ## - - if vagrant_config_hash['instance'] - instance = vagrant_config_hash['instance'] - config.vm.define instance['name'] do |c| - c.vm.hostname = instance['name'] - - if instance['interfaces'] - instance['interfaces'].each { |interface| - c.vm.network "#{interface['network_name']}", - Hash[interface.select{|k| k != 'network_name'}.map{|k,v| [k.to_sym, v]}] - } - end - - if instance['raw_config_args'] - instance['raw_config_args'].each { |raw_config_arg| - eval("c.#{raw_config_arg}") - } - end - end - end -end -'''.strip() # noqa - - -class VagrantClient(object): - def __init__(self, module): - self._module = module - - self._config = self._get_config() - self._vagrantfile = self._config.driver.vagrantfile - self._vagrant = self._get_vagrant() - self._write_configs() - self._has_error = None - self._datetime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") - - @contextlib.contextmanager - def stdout_cm(self): - """ Redirect the stdout to a log file. """ - with open(self._get_stdout_log(), 'a+') as fh: - msg = '### {} ###\n'.format(self._datetime) - fh.write(msg) - fh.flush() - - yield fh - - @contextlib.contextmanager - def stderr_cm(self): - """ Redirect the stderr to a log file. """ - with open(self._get_stderr_log(), 'a+') as fh: - msg = '### {} ###\n'.format(self._datetime) - fh.write(msg) - fh.flush() - - try: - yield fh - except Exception as e: - self._has_error = True - fh.write(e.message) - fh.flush() - raise - - def up(self): - changed = False - if not self._created(): - changed = True - provision = self._module.params['provision'] - try: - self._vagrant.up(provision=provision) - except Exception: - # NOTE(retr0h): Ignore the exception since python-vagrant - # passes the actual error as a no-argument ContextManager. - pass - - # NOTE(retr0h): Ansible wants only one module return `fail_json` - # or `exit_json`. - if not self._has_error: - self._module.exit_json( - changed=changed, log=self._get_stdout_log(), **self._conf() - ) - else: - msg = "ERROR: See log file '{}'".format(self._get_stderr_log()) - self._module.fail_json(msg=msg) - - def destroy(self): - changed = False - if self._created(): - changed = True - if self._module.params['force_stop']: - self._vagrant.halt(force=True) - self._vagrant.destroy() - - self._module.exit_json(changed=changed) - - def halt(self): - changed = False - if self._created(): - changed = True - self._vagrant.halt(force=self._module.params['force_stop']) - - self._module.exit_json(changed=changed) - - def _conf(self): - instance_name = self._module.params['instance_name'] - - return self._vagrant.conf(vm_name=instance_name) - - def _status(self): - instance_name = self._module.params['instance_name'] - try: - s = self._vagrant.status(vm_name=instance_name)[0] - - return {'name': s.name, 'state': s.state, 'provider': s.provider} - except AttributeError: - pass - except subprocess.CalledProcessError: - pass - - def _created(self): - status = self._status() - if status and status['state'] == 'running': - return status - return {} - - def _get_config(self): - molecule_file = os.environ['MOLECULE_FILE'] - - return molecule.config.Config(molecule_file) - - def _write_vagrantfile(self): - template = molecule.util.render_template( - VAGRANTFILE_TEMPLATE, - vagrantfile_config=self._config.driver.vagrantfile_config, - ) - molecule.util.write_file(self._vagrantfile, template) - - def _write_vagrantfile_config(self, data): - molecule.util.write_file( - self._config.driver.vagrantfile_config, molecule.util.safe_dump(data) - ) - - def _write_configs(self): - self._write_vagrantfile_config(self._get_vagrant_config_dict()) - self._write_vagrantfile() - - def _get_vagrant(self): - env = os.environ.copy() - env['VAGRANT_CWD'] = os.environ['MOLECULE_EPHEMERAL_DIRECTORY'] - v = vagrant.Vagrant(out_cm=self.stdout_cm, err_cm=self.stderr_cm, env=env) - - return v - - def _get_vagrant_config_dict(self): - d = { - 'config': { - # NOTE(retr0h): Options provided here will be passed to - # Vagrant as "config.#{key} = #{value}". - 'options': { - # NOTE(retr0h): `synced_folder` does not represent the - # actual key used by Vagrant. Is used as a flag to - # simply enable/disable shared folder. - 'synced_folder': False, - 'ssh.insert_key': True, - } - }, - 'platform': { - 'box': self._module.params['platform_box'], - 'box_version': self._module.params['platform_box_version'], - 'box_url': self._module.params['platform_box_url'], - }, - 'instance': { - 'name': self._module.params['instance_name'], - 'interfaces': self._module.params['instance_interfaces'], - 'raw_config_args': self._module.params['instance_raw_config_args'], - }, - 'provider': { - 'name': self._module.params['provider_name'], - # NOTE(retr0h): Options provided here will be passed to - # Vagrant as "$provider_name.#{key} = #{value}". - 'options': { - 'memory': self._module.params['provider_memory'], - 'cpus': self._module.params['provider_cpus'], - }, - 'raw_config_args': self._module.params['provider_raw_config_args'], - 'override_args': self._module.params['provider_override_args'], - }, - } - - molecule.util.merge_dicts( - d['config']['options'], self._module.params['config_options'] - ) - - molecule.util.merge_dicts( - d['provider']['options'], self._module.params['provider_options'] - ) - - return d - - def _get_stdout_log(self): - return self._get_vagrant_log('out') - - def _get_stderr_log(self): - return self._get_vagrant_log('err') - - def _get_vagrant_log(self, __type): - instance_name = self._module.params['instance_name'] - - return os.path.join( - self._config.scenario.ephemeral_directory, - 'vagrant-{}.{}'.format(instance_name, __type), - ) - - -def main(): - module = AnsibleModule( # noqa - argument_spec=dict( - instance_name=dict(type='str', required=True), - instance_interfaces=dict(type='list', default=[]), - instance_raw_config_args=dict(type='list', default=None), - config_options=dict(type='dict', default={}), - platform_box=dict(type='str', required=False), - platform_box_version=dict(type='str'), - platform_box_url=dict(type='str'), - provider_name=dict(type='str', default='virtualbox'), - provider_memory=dict(type='int', default=512), - provider_cpus=dict(type='int', default=2), - provider_options=dict(type='dict', default={}), - provider_override_args=dict(type='list', default=None), - provider_raw_config_args=dict(type='list', default=None), - provision=dict(type='bool', default=False), - force_stop=dict(type='bool', default=False), - state=dict(type='str', default='up', choices=['up', 'destroy', 'halt']), - ), - supports_check_mode=False, - ) - - v = VagrantClient(module) - - if module.params['state'] == 'up': - v.up() - - if module.params['state'] == 'destroy': - v.destroy() - - if module.params['state'] == 'halt': - v.halt() - - -from ansible.module_utils.basic import * # noqa - -main() diff --git a/molecule/test/functional/conftest.py b/molecule/test/functional/conftest.py index d034767cdc..7a28fb64d9 100644 --- a/molecule/test/functional/conftest.py +++ b/molecule/test/functional/conftest.py @@ -75,7 +75,6 @@ def skip_test(request, driver_name): support_checks_map = { 'docker': supports_docker, 'podman': lambda: min_ansible("2.8.6"), - 'vagrant': supports_vagrant_virtualbox, 'delegated': demands_delegated, } try: @@ -244,10 +243,6 @@ def get_docker_executable(): return distutils.spawn.find_executable('docker') -def get_vagrant_executable(): - return distutils.spawn.find_executable('vagrant') - - def get_virtualbox_executable(): return distutils.spawn.find_executable('VBoxManage') @@ -270,11 +265,6 @@ def min_ansible(version): return False -@pytest.helpers.register -def supports_vagrant_virtualbox(): - return get_vagrant_executable() or get_virtualbox_executable() - - @pytest.helpers.register def demands_delegated(): return pytest.config.getoption('--delegated') diff --git a/molecule/test/functional/test_command.py b/molecule/test/functional/test_command.py index fcb8724ff2..0f5801db52 100644 --- a/molecule/test/functional/test_command.py +++ b/molecule/test/functional/test_command.py @@ -48,7 +48,6 @@ def driver_name(request): [ ('driver/docker', 'docker', 'default'), ('driver/delegated', 'delegated', 'docker'), - ('driver/vagrant', 'vagrant', 'default'), ('driver/podman', 'podman', 'default'), ], indirect=['scenario_to_test', 'driver_name', 'scenario_name'], @@ -64,7 +63,6 @@ def test_command_check(scenario_to_test, with_scenario, scenario_name): [ ('driver/docker', 'docker', 'default'), ('driver/delegated', 'delegated', 'docker'), - ('driver/vagrant', 'vagrant', 'default'), ('driver/podman', 'podman', 'default'), ], indirect=['scenario_to_test', 'driver_name', 'scenario_name'], @@ -80,7 +78,6 @@ def test_command_cleanup(scenario_to_test, with_scenario, scenario_name): [ ('driver/docker', 'docker', 'default'), ('driver/delegated', 'delegated', 'docker'), - ('driver/vagrant', 'vagrant', 'default'), ('driver/podman', 'podman', 'default'), ], indirect=['scenario_to_test', 'driver_name', 'scenario_name'], @@ -96,7 +93,6 @@ def test_command_converge(scenario_to_test, with_scenario, scenario_name): [ ('driver/docker', 'docker', 'default'), ('driver/delegated', 'delegated', 'docker'), - ('driver/vagrant', 'vagrant', 'default'), ('driver/podman', 'podman', 'default'), ], indirect=['scenario_to_test', 'driver_name', 'scenario_name'], @@ -114,7 +110,6 @@ def test_command_create(scenario_to_test, with_scenario, scenario_name): 'scenario_to_test, driver_name, scenario_name', [ ('dependency', 'docker', 'ansible-galaxy'), - ('dependency', 'vagrant', 'ansible-galaxy'), ('dependency', 'podman', 'ansible-galaxy'), ], indirect=['scenario_to_test', 'driver_name', 'scenario_name'], @@ -138,11 +133,7 @@ def test_command_dependency_ansible_galaxy( @pytest.mark.parametrize( 'scenario_to_test, driver_name, scenario_name', - [ - ('dependency', 'docker', 'gilt'), - ('dependency', 'vagrant', 'gilt'), - ('dependency', 'podman', 'gilt'), - ], + [('dependency', 'docker', 'gilt'), ('dependency', 'podman', 'gilt')], indirect=['scenario_to_test', 'driver_name', 'scenario_name'], ) def test_command_dependency_gilt( @@ -160,11 +151,7 @@ def test_command_dependency_gilt( @pytest.mark.parametrize( 'scenario_to_test, driver_name, scenario_name', - [ - ('dependency', 'docker', 'shell'), - ('dependency', 'vagrant', 'shell'), - ('dependency', 'podman', 'shell'), - ], + [('dependency', 'docker', 'shell'), ('dependency', 'podman', 'shell')], indirect=['scenario_to_test', 'driver_name', 'scenario_name'], ) def test_command_dependency_shell( @@ -185,7 +172,6 @@ def test_command_dependency_shell( [ ('driver/docker', 'docker', 'default'), ('driver/delegated', 'delegated', 'docker'), - ('driver/vagrant', 'vagrant', 'default'), ('driver/podman', 'podman', 'default'), ], indirect=['scenario_to_test', 'driver_name', 'scenario_name'], @@ -201,7 +187,6 @@ def test_command_destroy(scenario_to_test, with_scenario, scenario_name): [ ('driver/docker', 'docker', 'default'), ('driver/delegated', 'delegated', 'docker'), - ('driver/vagrant', 'vagrant', 'default'), ('driver/podman', 'podman', 'default'), ], indirect=['scenario_to_test', 'driver_name', 'scenario_name'], @@ -211,14 +196,14 @@ def test_command_idempotence(scenario_to_test, with_scenario, scenario_name): @pytest.mark.parametrize( - 'driver_name', [('docker'), ('vagrant'), ('podman')], indirect=['driver_name'] + 'driver_name', [('docker'), ('podman')], indirect=['driver_name'] ) def test_command_init_role(temp_dir, driver_name, skip_test): pytest.helpers.init_role(temp_dir, driver_name) @pytest.mark.parametrize( - 'driver_name', [('docker'), ('vagrant'), ('podman')], indirect=['driver_name'] + 'driver_name', [('docker'), ('podman')], indirect=['driver_name'] ) def test_command_init_scenario(temp_dir, driver_name, skip_test): pytest.helpers.init_scenario(temp_dir, driver_name) @@ -229,7 +214,6 @@ def test_command_init_scenario(temp_dir, driver_name, skip_test): [ ('driver/docker', 'docker', 'default'), ('driver/delegated', 'delegated', 'docker'), - ('driver/vagrant', 'vagrant', 'default'), ('driver/podman', 'podman', 'default'), ], indirect=['scenario_to_test', 'driver_name', 'scenario_name'], @@ -262,17 +246,6 @@ def test_command_lint(scenario_to_test, with_scenario, scenario_name): Instance Name Driver Name Provisioner Name Scenario Name Created Converged ---------------------------- ------------- ------------------ --------------- --------- ----------- delegated-instance-docker delegated ansible docker unknown true -""".strip(), - ), # noqa - ( - 'driver/vagrant', - 'vagrant', - """ -Instance Name Driver Name Provisioner Name Scenario Name Created Converged ---------------- ------------- ------------------ --------------- --------- ----------- -instance vagrant ansible default false false -instance-1 vagrant ansible multi-node false false -instance-2 vagrant ansible multi-node false false """.strip(), ), # noqa ( @@ -312,15 +285,6 @@ def test_command_list(scenario_to_test, with_scenario, expected): 'delegated', """ delegated-instance-docker delegated ansible docker unknown true -""".strip(), - ), - ( - 'driver/vagrant', - 'vagrant', - """ -instance vagrant ansible default false false -instance-1 vagrant ansible multi-node false false -instance-2 vagrant ansible multi-node false false """.strip(), ), ( @@ -356,12 +320,6 @@ def test_command_list_with_format_plain(scenario_to_test, with_scenario, expecte [['delegated-instance-docker', '.*delegated-instance-docker.*']], 'docker', ), - ( - 'driver/vagrant', - 'vagrant', - [['instance-1', '.*instance-1.*'], ['instance-2', '.*instance-2.*']], - 'multi-node', - ), ( 'driver/podman', 'podman', @@ -380,7 +338,6 @@ def test_command_login(scenario_to_test, with_scenario, login_args, scenario_nam [ ('driver/docker', 'docker', 'default'), ('driver/delegated', 'delegated', 'docker'), - ('driver/vagrant', 'vagrant', 'default'), ('driver/podman', 'podman', 'default'), ], indirect=['scenario_to_test', 'driver_name', 'scenario_name'], @@ -400,7 +357,6 @@ def test_command_prepare(scenario_to_test, with_scenario, scenario_name): [ ('driver/docker', 'docker', 'default'), ('driver/delegated', 'delegated', 'docker'), - ('driver/vagrant', 'vagrant', 'default'), ('driver/podman', 'podman', 'default'), ], indirect=['scenario_to_test', 'driver_name', 'scenario_name'], @@ -416,7 +372,6 @@ def test_command_side_effect(scenario_to_test, with_scenario, scenario_name): [ ('driver/docker', 'docker', 'default'), ('driver/delegated', 'delegated', 'docker'), - ('driver/vagrant', 'vagrant', 'default'), ('driver/podman', 'podman', 'default'), ], indirect=['scenario_to_test', 'driver_name', 'scenario_name'], @@ -434,7 +389,6 @@ def test_command_syntax(scenario_to_test, with_scenario, scenario_name): ('driver/docker', 'docker', 'ansible-verifier'), ('driver/docker', 'docker', 'multi-node'), ('driver/delegated', 'delegated', 'docker'), - ('driver/vagrant', 'vagrant', None), ('driver/podman', 'podman', 'default'), ], indirect=['scenario_to_test', 'driver_name', 'scenario_name'], @@ -448,7 +402,6 @@ def test_command_test(scenario_to_test, with_scenario, scenario_name, driver_nam [ ('driver/docker', 'docker', 'default'), ('driver/delegated', 'delegated', 'docker'), - ('driver/vagrant', 'vagrant', 'default'), ('driver/podman', 'podman', 'default'), ], indirect=['scenario_to_test', 'driver_name', 'scenario_name'], diff --git a/molecule/test/resources/molecule_v1_vagrant.yml b/molecule/test/resources/molecule_v1_vagrant.yml deleted file mode 100644 index f6c4acfe9c..0000000000 --- a/molecule/test/resources/molecule_v1_vagrant.yml +++ /dev/null @@ -1,40 +0,0 @@ ---- -ansible: - config_file: ansible.cfg - playbook: playbook.yml - raw_env_vars: - FOO: bar - extra_vars: foo=bar - verbose: true - become: true - tags: foo,bar -driver: - name: vagrant -vagrant: - platforms: - - name: rhel-7 - box: namespace/rhel-7 - box_version: 7.2.0 - box_url: http://example.com/pub/rhel-7.json - providers: - - name: virtualbox - type: virtualbox - options: - memory: 4096 - cpus: 2 - instances: - - name: host.example.com - ansible_groups: - - group1 - - group2 - interfaces: - - network_name: private_network - type: dhcp - auto_config: true - raw_config_args: - - foo - - bar -verifier: - name: testinfra - options: - sudo: true diff --git a/molecule/test/resources/playbooks/delegated/create.yml b/molecule/test/resources/playbooks/delegated/create.yml index 376893f2fb..6741f17289 100644 --- a/molecule/test/resources/playbooks/delegated/create.yml +++ b/molecule/test/resources/playbooks/delegated/create.yml @@ -5,4 +5,3 @@ gather_facts: false tasks: - include: create/docker.yml - # - include: create/vagrant.yml diff --git a/molecule/test/resources/playbooks/delegated/create/vagrant.yml b/molecule/test/resources/playbooks/delegated/create/vagrant.yml deleted file mode 100644 index 3c8e4739f9..0000000000 --- a/molecule/test/resources/playbooks/delegated/create/vagrant.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- name: Create molecule instance(s) - molecule_vagrant: - instance_name: delegated-instance-vagrant - platform_box: debian/jessie64 - state: up diff --git a/molecule/test/resources/playbooks/delegated/destroy.yml b/molecule/test/resources/playbooks/delegated/destroy.yml index 2af509cbba..e088e951ee 100644 --- a/molecule/test/resources/playbooks/delegated/destroy.yml +++ b/molecule/test/resources/playbooks/delegated/destroy.yml @@ -5,4 +5,3 @@ gather_facts: false tasks: - include: destroy/docker.yml - # - include: create/vagrant.yml diff --git a/molecule/test/resources/playbooks/delegated/destroy/vagrant.yml b/molecule/test/resources/playbooks/delegated/destroy/vagrant.yml deleted file mode 100644 index 3d2f825a54..0000000000 --- a/molecule/test/resources/playbooks/delegated/destroy/vagrant.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- name: Destroy molecule instance(s) - molecule_vagrant: - instance_name: delegated-instance-vagrant - platform_box: debian/jessie64 - state: destroy diff --git a/molecule/test/resources/playbooks/vagrant/create.yml b/molecule/test/resources/playbooks/vagrant/create.yml deleted file mode 100644 index 536bcdf6d3..0000000000 --- a/molecule/test/resources/playbooks/vagrant/create.yml +++ /dev/null @@ -1,59 +0,0 @@ ---- -- name: Create - hosts: localhost - connection: local - gather_facts: false - no_log: "{{ molecule_no_log }}" - tasks: - - name: Create molecule instance(s) - molecule_vagrant: - instance_name: "{{ item.name }}" - instance_interfaces: "{{ item.interfaces | default(omit) }}" - instance_raw_config_args: "{{ item.instance_raw_config_args | default(omit) }}" - - config_options: "{{ item.config_options | default(omit) }}" - - platform_box: "{{ item.box }}" - platform_box_version: "{{ item.box_version | default(omit) }}" - platform_box_url: "{{ item.box_url | default(omit) }}" - - provider_name: "{{ molecule_yml.driver.provider.name }}" - provider_memory: "{{ item.memory | default(omit) }}" - provider_cpus: "{{ item.cpus | default(omit) }}" - provider_options: "{{ item.provider_options | default(omit) }}" - provider_raw_config_args: "{{ item.provider_raw_config_args | default(omit) }}" - provider_override_args: "{{ item.provider_override_args | default(omit) }}" - - provision: "{{ item.provision | default(omit) }}" - - state: up - register: server - with_items: "{{ molecule_yml.platforms }}" - - # NOTE(retr0h): Vagrant/VBox sucks and parallelizing instance creation - # causes issues. - - # Mandatory configuration for Molecule to function. - - - name: Populate instance config dict - set_fact: - instance_conf_dict: { - 'instance': "{{ item.Host }}", - 'address': "{{ item.HostName }}", - 'user': "{{ item.User }}", - 'port': "{{ item.Port }}", - 'identity_file': "{{ item.IdentityFile }}", } - with_items: "{{ server.results }}" - register: instance_config_dict - when: server.changed | bool - - - name: Convert instance config dict to a list - set_fact: - instance_conf: "{{ instance_config_dict.results | map(attribute='ansible_facts.instance_conf_dict') | list }}" - when: server.changed | bool - - - name: Dump instance config - copy: - content: "{{ instance_conf | to_json | from_json | molecule_to_yaml | molecule_header }}" - dest: "{{ molecule_instance_config }}" - when: server.changed | bool diff --git a/molecule/test/resources/playbooks/vagrant/destroy.yml b/molecule/test/resources/playbooks/vagrant/destroy.yml deleted file mode 100644 index 9f97e39055..0000000000 --- a/molecule/test/resources/playbooks/vagrant/destroy.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -- name: Destroy - hosts: localhost - connection: local - gather_facts: false - no_log: "{{ molecule_no_log }}" - tasks: - - name: Destroy molecule instance(s) - molecule_vagrant: - instance_name: "{{ item.name }}" - platform_box: "{{ item.box }}" - provider_name: "{{ molecule_yml.driver.provider.name }}" - provider_options: "{{ item.provider_options | default(omit) }}" - provider_raw_config_args: "{{ item.provider_raw_config_args | default(omit) }}" - force_stop: "{{ item.force_stop | default(true) }}" - - state: destroy - register: server - with_items: "{{ molecule_yml.platforms }}" - - # NOTE(retr0h): Vagrant/VBox sucks and parallelizing instance deletion - # causes issues. - - # Mandatory configuration for Molecule to function. - - - name: Populate instance config - set_fact: - instance_conf: {} - - - name: Dump instance config - copy: - content: "{{ instance_conf | to_json | from_json | molecule_to_yaml | molecule_header }}" - dest: "{{ molecule_instance_config }}" - when: server.changed | bool diff --git a/molecule/test/scenarios/dependency/molecule/ansible-galaxy/molecule.yml b/molecule/test/scenarios/dependency/molecule/ansible-galaxy/molecule.yml index 1bfb1f5d26..345c0dd4b3 100644 --- a/molecule/test/scenarios/dependency/molecule/ansible-galaxy/molecule.yml +++ b/molecule/test/scenarios/dependency/molecule/ansible-galaxy/molecule.yml @@ -3,11 +3,6 @@ dependency: name: galaxy driver: name: docker - # NOTE(retr0h): Required for functional tests, since - # execute this as all drivers, and the schema validator - # requires this for `vagrant`. - provider: - name: virtualbox lint: name: yamllint options: diff --git a/molecule/test/scenarios/dependency/molecule/gilt/molecule.yml b/molecule/test/scenarios/dependency/molecule/gilt/molecule.yml index f4ff58fafb..0855320d77 100644 --- a/molecule/test/scenarios/dependency/molecule/gilt/molecule.yml +++ b/molecule/test/scenarios/dependency/molecule/gilt/molecule.yml @@ -3,11 +3,6 @@ dependency: name: gilt driver: name: docker - # NOTE(retr0h): Required for functional tests, since - # execute this as all drivers, and the schema validator - # requires this for `vagrant`. - provider: - name: virtualbox lint: name: yamllint options: diff --git a/molecule/test/scenarios/dependency/molecule/shell/molecule.yml b/molecule/test/scenarios/dependency/molecule/shell/molecule.yml index b200e599eb..b988514d7c 100644 --- a/molecule/test/scenarios/dependency/molecule/shell/molecule.yml +++ b/molecule/test/scenarios/dependency/molecule/shell/molecule.yml @@ -4,11 +4,6 @@ dependency: command: $MOLECULE_SCENARIO_DIRECTORY/run.bash driver: name: docker - # NOTE(retr0h): Required for functional tests, since - # execute this as all drivers, and the schema validator - # requires this for `vagrant`. - provider: - name: virtualbox lint: name: yamllint options: diff --git a/molecule/test/scenarios/driver/vagrant/molecule/default/molecule.yml b/molecule/test/scenarios/driver/vagrant/molecule/default/molecule.yml deleted file mode 100644 index a5e4e17923..0000000000 --- a/molecule/test/scenarios/driver/vagrant/molecule/default/molecule.yml +++ /dev/null @@ -1,40 +0,0 @@ ---- -dependency: - name: galaxy -driver: - name: vagrant - provider: - name: virtualbox -lint: - name: yamllint - options: - config-file: ../../../resources/.yamllint -platforms: - - name: instance - box: debian/jessie64 - interfaces: - - auto_config: true - network_name: private_network - type: dhcp - - virtualbox__intnet: test_network - network_name: private_network - ip: 192.168.0.1 - provision: false -provisioner: - name: ansible - config_options: - defaults: - callback_whitelist: profile_roles,profile_tasks,timer - playbooks: - create: ../../../../../resources/playbooks/vagrant/create.yml - destroy: ../../../../../resources/playbooks/vagrant/destroy.yml - env: - ANSIBLE_ROLES_PATH: ../../../../../resources/roles/ - lint: - name: ansible-lint -scenario: - name: default -verifier: - name: testinfra - lint: - name: flake8 diff --git a/molecule/test/scenarios/driver/vagrant/molecule/default/playbook.yml b/molecule/test/scenarios/driver/vagrant/molecule/default/playbook.yml deleted file mode 100644 index 2d0e971e3e..0000000000 --- a/molecule/test/scenarios/driver/vagrant/molecule/default/playbook.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -- name: Converge - hosts: all - gather_facts: false - become: true - roles: - - molecule diff --git a/molecule/test/scenarios/driver/vagrant/molecule/default/tests/test_default.py b/molecule/test/scenarios/driver/vagrant/molecule/default/tests/test_default.py deleted file mode 100644 index 0bcc018043..0000000000 --- a/molecule/test/scenarios/driver/vagrant/molecule/default/tests/test_default.py +++ /dev/null @@ -1,40 +0,0 @@ -import os - -import testinfra.utils.ansible_runner - -testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( - os.environ['MOLECULE_INVENTORY_FILE'] -).get_hosts('all') - - -def test_hostname(host): - assert 'instance' == host.check_output('hostname -s') - - -def test_etc_molecule_directory(host): - f = host.file('/etc/molecule') - - assert f.is_directory - assert f.user == 'root' - assert f.group == 'root' - assert f.mode == 0o755 - - -def test_etc_molecule_ansible_hostname_file(host): - f = host.file('/etc/molecule/instance') - - assert f.is_file - assert f.user == 'root' - assert f.group == 'root' - assert f.mode == 0o644 - - -def test_hostonly_interface(host): - i = host.interface('eth1').addresses - - # NOTE(retr0h): Contains ipv4 and ipv6 addresses. - assert len(i) == 2 - - -def test_internal_interface(host): - assert '192.168.0.1' in host.interface('eth2').addresses diff --git a/molecule/test/scenarios/driver/vagrant/molecule/multi-node/molecule.yml b/molecule/test/scenarios/driver/vagrant/molecule/multi-node/molecule.yml deleted file mode 100644 index dbb4172447..0000000000 --- a/molecule/test/scenarios/driver/vagrant/molecule/multi-node/molecule.yml +++ /dev/null @@ -1,62 +0,0 @@ ---- -dependency: - name: galaxy -driver: - name: vagrant - provider: - name: virtualbox -lint: - name: yamllint - options: - config-file: ../../../resources/.yamllint -platforms: - - name: instance-1 - box: debian/jessie64 - interfaces: - - auto_config: true - network_name: private_network - type: dhcp - - virtualbox__intnet: test_network - network_name: private_network - ip: 192.168.0.1 - groups: - - foo - - bar - memory: 1024 - cpus: 1 - config_options: - synced_folder: true - - name: instance-2 - box: centos/7 - interfaces: - - auto_config: true - network_name: private_network - type: dhcp - - virtualbox__intnet: test_network - network_name: private_network - ip: 192.168.0.2 - groups: - - foo - - baz - memory: 2048 - cpus: 2 -provisioner: - name: ansible - config_options: - defaults: - callback_whitelist: profile_roles,profile_tasks,timer - playbooks: - create: ../../../../../resources/playbooks/vagrant/create.yml - destroy: ../../../../../resources/playbooks/vagrant/destroy.yml - env: - ANSIBLE_ROLES_PATH: ../../../../../resources/roles/ - lint: - name: ansible-lint -scenario: - name: multi-node -verifier: - name: testinfra - options: - sudo: true - lint: - name: flake8 diff --git a/molecule/test/scenarios/driver/vagrant/molecule/multi-node/playbook.yml b/molecule/test/scenarios/driver/vagrant/molecule/multi-node/playbook.yml deleted file mode 100644 index 8fe4807ffd..0000000000 --- a/molecule/test/scenarios/driver/vagrant/molecule/multi-node/playbook.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- name: Converge - hosts: all - gather_facts: false - become: true - roles: - - molecule - -- name: Converge - hosts: bar - gather_facts: false - become: true - roles: - - molecule - -- name: Converge - hosts: foo - gather_facts: false - become: true - roles: - - molecule - -- name: Converge - hosts: baz - gather_facts: false - become: true - roles: - - molecule diff --git a/molecule/test/scenarios/driver/vagrant/molecule/multi-node/prepare.yml b/molecule/test/scenarios/driver/vagrant/molecule/multi-node/prepare.yml deleted file mode 100644 index 3418516da4..0000000000 --- a/molecule/test/scenarios/driver/vagrant/molecule/multi-node/prepare.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -- name: Prepare - hosts: all - gather_facts: false - become: true - tasks: - - name: Install prerequisite packages for tests - package: - name: "{{ item }}" - with_items: - - iproute diff --git a/molecule/test/scenarios/driver/vagrant/molecule/multi-node/tests/test_default.py b/molecule/test/scenarios/driver/vagrant/molecule/multi-node/tests/test_default.py deleted file mode 100644 index ad525557c2..0000000000 --- a/molecule/test/scenarios/driver/vagrant/molecule/multi-node/tests/test_default.py +++ /dev/null @@ -1,38 +0,0 @@ -import os -import re - -import testinfra.utils.ansible_runner - -testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( - os.environ['MOLECULE_INVENTORY_FILE'] -).get_hosts('all') - - -def test_hostname(host): - assert re.search(r'instance-[12]', host.check_output('hostname -s')) - - -def test_etc_molecule_directory(host): - f = host.file('/etc/molecule') - - assert f.is_directory - assert f.user == 'root' - assert f.group == 'root' - assert f.mode == 0o755 - - -def test_etc_molecule_ansible_hostname_file(host): - filename = '/etc/molecule/{}'.format(host.check_output('hostname -s')) - f = host.file(filename) - - assert f.is_file - assert f.user == 'root' - assert f.group == 'root' - assert f.mode == 0o644 - - -def test_hostonly_interface(host): - i = host.interface('eth1').addresses - - # NOTE(retr0h): Contains ipv4 and ipv6 addresses. - assert len(i) == 2 diff --git a/molecule/test/scenarios/driver/vagrant/molecule/multi-node/tests/test_instance-1.py b/molecule/test/scenarios/driver/vagrant/molecule/multi-node/tests/test_instance-1.py deleted file mode 100644 index 05b514f97a..0000000000 --- a/molecule/test/scenarios/driver/vagrant/molecule/multi-node/tests/test_instance-1.py +++ /dev/null @@ -1,35 +0,0 @@ -import os - -import testinfra.utils.ansible_runner - -testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( - os.environ['MOLECULE_INVENTORY_FILE'] -).get_hosts('instance-1') - - -def test_distro(host): - f = host.file('/etc/debian_version') - - assert f.is_file - - -def test_cpus(host): - cpus = host.ansible("setup")['ansible_facts']['ansible_processor_vcpus'] - - assert 1 == int(cpus) - - -def test_memory(host): - total_memory = host.ansible("setup")['ansible_facts']['ansible_memtotal_mb'] - - assert (1024 / 2) <= int(total_memory) <= 1024 - - -def test_has_shared_directory(host): - f = host.file('/vagrant') - - assert f.is_directory - - -def test_internal_interface(host): - assert '192.168.0.1' in host.interface('eth2').addresses diff --git a/molecule/test/scenarios/driver/vagrant/molecule/multi-node/tests/test_instance-2.py b/molecule/test/scenarios/driver/vagrant/molecule/multi-node/tests/test_instance-2.py deleted file mode 100644 index 968ad47d7f..0000000000 --- a/molecule/test/scenarios/driver/vagrant/molecule/multi-node/tests/test_instance-2.py +++ /dev/null @@ -1,35 +0,0 @@ -import os - -import testinfra.utils.ansible_runner - -testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( - os.environ['MOLECULE_INVENTORY_FILE'] -).get_hosts('instance-2') - - -def test_distro(host): - f = host.file('/etc/redhat-release') - - assert f.is_file - - -def test_cpus(host): - cpus = host.ansible("setup")['ansible_facts']['ansible_processor_vcpus'] - - assert 2 == int(cpus) - - -def test_memory(host): - total_memory = host.ansible("setup")['ansible_facts']['ansible_memtotal_mb'] - - assert (1024 + 1024 / 2) <= int(total_memory) <= 2048 - - -def test_does_not_have_shared_directory(host): - f = host.file('/vagrant') - - assert not f.is_directory - - -def test_internal_interface(host): - assert '192.168.0.2' in host.interface('eth2').addresses diff --git a/molecule/test/scenarios/overrride_driver/molecule/default/molecule.yml b/molecule/test/scenarios/overrride_driver/molecule/default/molecule.yml index 94f103edfc..737e072dce 100644 --- a/molecule/test/scenarios/overrride_driver/molecule/default/molecule.yml +++ b/molecule/test/scenarios/overrride_driver/molecule/default/molecule.yml @@ -2,10 +2,7 @@ dependency: name: galaxy driver: - # NOTE(retr0h): Functional test overrides this on command line. - name: vagrant - provider: - name: virtualbox + name: delegated lint: name: yamllint options: diff --git a/molecule/test/unit/cookiecutter/test_molecule.py b/molecule/test/unit/cookiecutter/test_molecule.py index 2b7cd6deec..6dc72812fb 100644 --- a/molecule/test/unit/cookiecutter/test_molecule.py +++ b/molecule/test/unit/cookiecutter/test_molecule.py @@ -78,21 +78,7 @@ def test_valid(temp_dir, _molecule_file, _role_directory, _command_args, _instan pytest.helpers.run_command(cmd) -def test_vagrant_driver( - temp_dir, _molecule_file, _role_directory, _command_args, _instance -): - _command_args['driver_name'] = 'vagrant' - _instance._process_templates('molecule', _command_args, _role_directory) - - data = util.safe_load_file(_molecule_file) - - assert {} == schema_v2.validate(data) - - cmd = sh.yamllint.bake('-s', _molecule_file) - pytest.helpers.run_command(cmd) - - -@pytest.mark.parametrize('driver', [('docker'), ('vagrant')]) +@pytest.mark.parametrize('driver', [('docker')]) def test_drivers( driver, temp_dir, _molecule_file, _role_directory, _command_args, _instance ): diff --git a/molecule/test/unit/driver/test_vagrant.py b/molecule/test/unit/driver/test_vagrant.py deleted file mode 100644 index 8dbd808b91..0000000000 --- a/molecule/test/unit/driver/test_vagrant.py +++ /dev/null @@ -1,248 +0,0 @@ -# Copyright (c) 2015-2018 Cisco Systems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. - -import os - -import pytest - -from molecule import config -from molecule.driver import vagrant - - -@pytest.fixture -def _driver_section_data(): - return { - 'driver': { - 'name': 'vagrant', - 'provider': {'name': 'virtualbox'}, - 'options': {}, - 'ssh_connection_options': ['-o foo=bar'], - 'safe_files': ['foo'], - } - } - - -# NOTE(retr0h): The use of the `patched_config_validate` fixture, disables -# config.Config._validate from executing. Thus preventing odd side-effects -# throughout patched.assert_called unit tests. -@pytest.fixture -def _instance(patched_config_validate, config_instance): - return vagrant.Vagrant(config_instance) - - -def test_config_private_member(_instance): - assert isinstance(_instance._config, config.Config) - - -def test_testinfra_options_property(_instance): - x = { - 'connection': 'ansible', - 'ansible-inventory': _instance._config.provisioner.inventory_file, - } - - assert x == _instance.testinfra_options - - -def test_name_property(_instance): - assert 'vagrant' == _instance.name - - -def test_options_property(_instance): - x = {'managed': True} - - assert x == _instance.options - - -@pytest.mark.parametrize('config_instance', ['_driver_section_data'], indirect=True) -def test_login_cmd_template_property(_instance): - x = 'ssh {address} -l {user} -p {port} -i {identity_file} -o foo=bar' - - assert x == _instance.login_cmd_template - - -@pytest.mark.parametrize('config_instance', ['_driver_section_data'], indirect=True) -def test_safe_files_property(_instance): - x = [ - os.path.join(_instance._config.scenario.ephemeral_directory, 'Vagrantfile'), - os.path.join(_instance._config.scenario.ephemeral_directory, 'vagrant.yml'), - os.path.join( - _instance._config.scenario.ephemeral_directory, 'instance_config.yml' - ), - os.path.join(_instance._config.scenario.ephemeral_directory, '.vagrant'), - os.path.join(_instance._config.scenario.ephemeral_directory, 'vagrant-*.out'), - os.path.join(_instance._config.scenario.ephemeral_directory, 'vagrant-*.err'), - 'foo', - ] - - assert x == _instance.safe_files - - -def test_default_safe_files_property(_instance): - x = [ - os.path.join(_instance._config.scenario.ephemeral_directory, 'Vagrantfile'), - os.path.join(_instance._config.scenario.ephemeral_directory, 'vagrant.yml'), - os.path.join( - _instance._config.scenario.ephemeral_directory, 'instance_config.yml' - ), - os.path.join(_instance._config.scenario.ephemeral_directory, '.vagrant'), - os.path.join(_instance._config.scenario.ephemeral_directory, 'vagrant-*.out'), - os.path.join(_instance._config.scenario.ephemeral_directory, 'vagrant-*.err'), - ] - - assert x == _instance.default_safe_files - - -def test_delegated_property(_instance): - assert not _instance.delegated - - -def test_managed_property(_instance): - assert _instance.managed - - -def test_default_ssh_connection_options_property(_instance): - x = [ - '-o UserKnownHostsFile=/dev/null', - '-o ControlMaster=auto', - '-o ControlPersist=60s', - '-o IdentitiesOnly=yes', - '-o StrictHostKeyChecking=no', - ] - - assert x == _instance.default_ssh_connection_options - - -def test_login_options(mocker, _instance): - m = mocker.patch('molecule.driver.vagrant.Vagrant._get_instance_config') - m.return_value = { - 'instance': 'foo', - 'address': '127.0.0.1', - 'user': 'vagrant', - 'port': 2222, - 'identity_file': '/foo/bar', - } - - x = { - 'instance': 'foo', - 'address': '127.0.0.1', - 'user': 'vagrant', - 'port': 2222, - 'identity_file': '/foo/bar', - } - assert x == _instance.login_options('foo') - - -@pytest.mark.parametrize('config_instance', ['_driver_section_data'], indirect=True) -def test_ansible_connection_options(mocker, _instance): - m = mocker.patch('molecule.driver.vagrant.Vagrant._get_instance_config') - m.return_value = { - 'instance': 'foo', - 'address': '127.0.0.1', - 'user': 'vagrant', - 'port': 2222, - 'identity_file': '/foo/bar', - } - - x = { - 'ansible_host': '127.0.0.1', - 'ansible_port': 2222, - 'ansible_user': 'vagrant', - 'ansible_private_key_file': '/foo/bar', - 'connection': 'ssh', - 'ansible_ssh_common_args': '-o foo=bar', - } - assert x == _instance.ansible_connection_options('foo') - - -def test_ansible_connection_options_handles_missing_instance_config(mocker, _instance): - m = mocker.patch('molecule.util.safe_load_file') - m.side_effect = IOError - - assert {} == _instance.ansible_connection_options('foo') - - -def test_ansible_connection_options_handles_missing_results_key(mocker, _instance): - m = mocker.patch('molecule.util.safe_load_file') - m.side_effect = StopIteration - - assert {} == _instance.ansible_connection_options('foo') - - -def test_vagrantfile_property(_instance): - x = os.path.join(_instance._config.scenario.ephemeral_directory, 'Vagrantfile') - - assert x == _instance.vagrantfile - - -def test_vagrantfile_config_property(_instance): - x = os.path.join(_instance._config.scenario.ephemeral_directory, 'vagrant.yml') - - assert x == _instance.vagrantfile_config - - -def test_instance_config_property(_instance): - x = os.path.join( - _instance._config.scenario.ephemeral_directory, 'instance_config.yml' - ) - - assert x == _instance.instance_config - - -@pytest.mark.parametrize('config_instance', ['_driver_section_data'], indirect=True) -def test_ssh_connection_options_property(_instance): - x = ['-o foo=bar'] - - assert x == _instance.ssh_connection_options - - -def test_status(mocker, _instance): - result = _instance.status() - - assert 2 == len(result) - - assert result[0].instance_name == 'instance-1' - assert result[0].driver_name == 'vagrant' - assert result[0].provisioner_name == 'ansible' - assert result[0].scenario_name == 'default' - assert result[0].created == 'false' - assert result[0].converged == 'false' - - assert result[1].instance_name == 'instance-2' - assert result[1].driver_name == 'vagrant' - assert result[1].provisioner_name == 'ansible' - assert result[1].scenario_name == 'default' - assert result[1].created == 'false' - assert result[1].converged == 'false' - - -def test_get_instance_config(mocker, _instance): - m = mocker.patch('molecule.util.safe_load_file') - m.return_value = [{'instance': 'foo'}, {'instance': 'bar'}] - - x = {'instance': 'foo'} - assert x == _instance._get_instance_config('foo') - - -def test_created(_instance): - assert 'false' == _instance._created() - - -def test_converged(_instance): - assert 'false' == _instance._converged() diff --git a/molecule/test/unit/model/test_schema_v1.py b/molecule/test/unit/model/test_schema_v1.py deleted file mode 100644 index 5ebb56c861..0000000000 --- a/molecule/test/unit/model/test_schema_v1.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (c) 2015-2018 Cisco Systems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. - -import os - -import pytest - -from molecule import util -from molecule.model import schema_v1 - - -@pytest.fixture -def _molecule_v1_file(): - return os.path.join( - os.path.dirname(__file__), - os.path.pardir, - os.path.pardir, - 'resources', - 'molecule_v1_vagrant.yml', - ) - - -@pytest.fixture -def _config(_molecule_v1_file, request): - d = util.safe_load(open(_molecule_v1_file)) - if hasattr(request, 'param'): - d = util.merge_dicts(d, request.getfuncargvalue(request.param)) - - return d - - -def test_base_config(_config): - assert {} == schema_v1.validate(_config) diff --git a/molecule/test/unit/model/v2/test_driver_section.py b/molecule/test/unit/model/v2/test_driver_section.py index fa38af77dd..a537f5bf2b 100644 --- a/molecule/test/unit/model/v2/test_driver_section.py +++ b/molecule/test/unit/model/v2/test_driver_section.py @@ -85,82 +85,6 @@ def test_driver_provider_name_nullable(_config): assert {} == schema_v2.validate(_config) -@pytest.fixture -def _model_driver_provider_name_not_nullable_when_vagrant_section_data(): - return {'driver': {'name': 'vagrant', 'provider': {'name': None}}} - - -@pytest.mark.parametrize( - '_config', - ['_model_driver_provider_name_not_nullable_when_vagrant_section_data'], - indirect=True, -) -def test_driver_provider_name_not_nullable_when_vagrant_driver(_config): - x = {'driver': [{'provider': [{'name': ['null value not allowed']}]}]} - - assert x == schema_v2.validate(_config) - - -@pytest.fixture -def _model_driver_provider_allows_virtualbox_section_data(): - return {'driver': {'name': 'vagrant', 'provider': {'name': 'virtualbox'}}} - - -@pytest.fixture -def _model_driver_provider_allows_vmware_fusion_section_data(): - return {'driver': {'name': 'vagrant', 'provider': {'name': 'vmware_fusion'}}} - - -@pytest.fixture -def _model_driver_provider_allows_vmware_workstation_section_data(): - return {'driver': {'name': 'vagrant', 'provider': {'name': 'vmware_workstation'}}} - - -@pytest.fixture -def _model_driver_provider_allows_vmware_desktop_section_data(): - return {'driver': {'name': 'vagrant', 'provider': {'name': 'vmware_desktop'}}} - - -@pytest.fixture -def _model_driver_provider_allows_parallels_section_data(): - return {'driver': {'name': 'vagrant', 'provider': {'name': 'parallels'}}} - - -@pytest.fixture -def _model_driver_provider_allows_libvirt_section_data(): - return {'driver': {'name': 'vagrant', 'provider': {'name': 'libvirt'}}} - - -@pytest.mark.parametrize( - '_config', - [ - ('_model_driver_provider_allows_virtualbox_section_data'), - ('_model_driver_provider_allows_vmware_fusion_section_data'), - ('_model_driver_provider_allows_vmware_workstation_section_data'), - ('_model_driver_provider_allows_vmware_desktop_section_data'), - ('_model_driver_provider_allows_parallels_section_data'), - ('_model_driver_provider_allows_libvirt_section_data'), - ], - indirect=True, -) -def test_driver_provider_allows_name(_config): - assert {} == schema_v2.validate(_config) - - -@pytest.fixture -def _model_driver_provider_errors_invalid_section_data(): - return {'driver': {'name': 'vagrant', 'provider': {'name': str()}}} - - -@pytest.mark.parametrize( - '_config', ['_model_driver_provider_errors_invalid_section_data'], indirect=True -) -def test_driver_invalid_provider_name_has_errors(_config): - x = {'driver': [{'provider': [{'name': ['unallowed value ']}]}]} - - assert x == schema_v2.validate(_config) - - @pytest.fixture def _model_driver_allows_delegated_section_data(): return {'driver': {'name': 'delegated'}} @@ -171,18 +95,12 @@ def _model_driver_allows_docker_section_data(): return {'driver': {'name': 'docker'}} -@pytest.fixture -def _model_driver_allows_vagrant_section_data(): - return {'driver': {'name': 'vagrant'}} - - ### @pytest.mark.parametrize( '_config', [ ('_model_driver_allows_delegated_section_data'), ('_model_driver_allows_docker_section_data'), - ('_model_driver_allows_vagrant_section_data'), ], indirect=True, ) diff --git a/molecule/test/unit/model/v2/test_platforms_section.py b/molecule/test/unit/model/v2/test_platforms_section.py index 417c5889d2..86eb0802fc 100644 --- a/molecule/test/unit/model/v2/test_platforms_section.py +++ b/molecule/test/unit/model/v2/test_platforms_section.py @@ -228,98 +228,6 @@ def test_platforms_docker_has_errors(_config): assert x == schema_v2.validate(_config) -@pytest.fixture -def _model_platforms_vagrant_section_data(): - return { - 'driver': {'name': 'vagrant'}, - 'platforms': [ - { - 'name': 'instance', - 'interfaces': [ - { - 'auto_config': True, - 'network_name': 'private_network', - 'type': 'dhcp', - } - ], - 'instance_raw_config_args': [ - "vm.network 'forwarded_port', guest: 80, host: 8080" - ], - 'config_options': {'ssh.insert_key': False}, - 'box': 'sleep infinity', - 'box_version': 'sleep infinity', - 'box_url': 'sleep infinity', - 'memory': 1024, - 'cpus': 2, - 'provider_options': {'gui': True}, - 'provider_raw_config_args': [ - "customize ['modifyvm', :id, '--cpuexecutioncap', '50']" - ], - 'provision': True, - } - ], - } - - -@pytest.mark.parametrize( - '_config', ['_model_platforms_vagrant_section_data'], indirect=True -) -def test_platforms_vagrant(_config): - assert {} == schema_v2.validate(_config) - - -@pytest.fixture -def _model_platforms_vagrant_errors_section_data(): - return { - 'driver': {'name': 'vagrant'}, - 'platforms': [ - { - 'name': int(), - 'interfaces': [], - 'instance_raw_config_args': [int()], - 'config_options': [], - 'box': int(), - 'box_version': int(), - 'box_url': int(), - 'memory': str(), - 'cpus': str(), - 'provider_options': [], - 'provider_raw_config_args': [int()], - 'provision': str(), - } - ], - } - - -@pytest.mark.parametrize( - '_config', ['_model_platforms_vagrant_errors_section_data'], indirect=True -) -def test_platforms_vagrant_has_errors(_config): - x = { - 'platforms': [ - { - 0: [ - { - 'box': ['must be of string type'], - 'box_version': ['must be of string type'], - 'config_options': ['must be of dict type'], - 'name': ['must be of string type'], - 'provider_raw_config_args': [{0: ['must be of string type']}], - 'cpus': ['must be of integer type'], - 'box_url': ['must be of string type'], - 'instance_raw_config_args': [{0: ['must be of string type']}], - 'memory': ['must be of integer type'], - 'provider_options': ['must be of dict type'], - 'provision': ['must be of boolean type'], - } - ] - } - ] - } - - assert x == schema_v2.validate(_config) - - def test_platforms_driver_name_required(_config): del _config['platforms'][0]['name'] x = {'platforms': [{0: [{'name': ['required field']}]}]} diff --git a/molecule/test/unit/test_config.py b/molecule/test/unit/test_config.py index 21d1193482..f8580bd82e 100644 --- a/molecule/test/unit/test_config.py +++ b/molecule/test/unit/test_config.py @@ -122,11 +122,6 @@ def _config_driver_delegated_section_data(): return {'driver': {'name': 'delegated', 'options': {'managed': False}}} -@pytest.fixture -def _config_driver_vagrant_section_data(): - return {'driver': {'name': 'vagrant', 'provider': {'name': 'virtualbox'}}} - - def test_env(config_instance): config_instance.args = {'env_file': '.env'} x = { diff --git a/molecule/test/unit/test_migrate.py b/molecule/test/unit/test_migrate.py deleted file mode 100644 index e6e93a0f90..0000000000 --- a/molecule/test/unit/test_migrate.py +++ /dev/null @@ -1,180 +0,0 @@ -# Copyright (c) 2015-2018 Cisco Systems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. - -import collections -import os - -import pytest - -from molecule import migrate - - -@pytest.fixture -def _instance(): - molecule_file = os.path.join( - os.path.dirname(__file__), - os.path.pardir, - 'resources', - 'molecule_v1_vagrant.yml', - ) - - return migrate.Migrate(molecule_file) - - -def test_get_v1_config(_instance): - data = _instance._get_v1_config() - - assert isinstance(data, dict) - - -def test_v1_member(_instance): - assert isinstance(_instance._v1, dict) - - -def test_v2_member(_instance): - assert isinstance(_instance._v2, collections.OrderedDict) - - -def test_dump(_instance): - x = """ ---- -dependency: - name: galaxy -driver: - name: vagrant - provider: - name: virtualbox -lint: - name: yamllint -platforms: - - name: host.example.com - box: namespace/rhel-7 - box_version: 7.2.0 - box_url: http://example.com/pub/rhel-7.json - memory: 4096 - cpus: 2 - groups: - - group1 - - group2 - interfaces: - - auto_config: true - network_name: private_network - type: dhcp - raw_config_args: - - foo - - bar -provisioner: - name: ansible - env: - FOO: bar - options: - extra-vars: foo=bar - verbose: true - become: true - tags: foo,bar - lint: - name: ansible-lint -scenario: - name: default -verifier: - name: testinfra - options: - sudo: true - lint: - name: flake8 -""".lstrip() - - assert x == _instance.dump() - - -def test_convert(_instance, patched_logger_info): - x = { - 'scenario': {'name': 'default'}, - 'platforms': [ - { - 'box': 'namespace/rhel-7', - 'box_version': '7.2.0', - 'name': 'host.example.com', - 'interfaces': [ - { - 'type': 'dhcp', - 'network_name': 'private_network', - 'auto_config': True, - } - ], - 'cpus': 2, - 'box_url': 'http://example.com/pub/rhel-7.json', - 'groups': ['group1', 'group2'], - 'memory': 4096, - 'raw_config_args': ['foo', 'bar'], - } - ], - 'lint': {'name': 'yamllint'}, - 'driver': {'name': 'vagrant', 'provider': {'name': 'virtualbox'}}, - 'dependency': {'name': 'galaxy'}, - 'verifier': { - 'lint': {'name': 'flake8'}, - 'name': 'testinfra', - 'options': {'sudo': True}, - }, - 'provisioner': { - 'lint': {'name': 'ansible-lint'}, - 'name': 'ansible', - 'env': {'FOO': 'bar'}, - 'options': { - 'become': True, - 'extra-vars': 'foo=bar', - 'verbose': True, - 'tags': 'foo,bar', - }, - }, - } - - data = _instance._convert() - assert x == _instance._to_dict(data) - - msg = 'Vagrant syle v1 config found' - patched_logger_info.assert_called_once_with(msg) - - -def test_convert_raises_on_invalid_migration_config(_instance, patched_logger_critical): - del _instance._v1['vagrant'] - - with pytest.raises(SystemExit) as e: - _instance._convert() - - assert 1 == e.value.code - - msg = 'Vagrant migrations only supported. Exiting.' - patched_logger_critical.assert_called_once_with(msg) - - -def test_check_errors(_instance): - assert _instance._check_errors({}) is None - - -def test_check_errors_raises_on_errors(_instance, patched_logger_critical): - with pytest.raises(SystemExit) as e: - _instance._check_errors('unit test error') - - assert 1 == e.value.code - - msg = 'Failed to validate.\n\nunit test error' - patched_logger_critical.assert_called_once_with(msg) diff --git a/setup.cfg b/setup.cfg index 7ae79060f4..a20626e2a5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -104,8 +104,6 @@ docker = # system selinux libraries but it will provide a clear message when user # has to do that. selinux; sys_platform=="linux2" -vagrant = - python-vagrant windows = pywinrm test = @@ -127,7 +125,6 @@ molecule.driver = docker = molecule.driver.docker:Docker delegated = molecule.driver.delegated:Delegated podman = molecule.driver.podman:Podman - vagrant = molecule.driver.vagrant:Vagrant molecule.verifier = testinfra = molecule.verifier.testinfra:Testinfra ansible = molecule.verifier.ansible:Ansible diff --git a/tox.ini b/tox.ini index 8221bcae5c..0ac2bea781 100644 --- a/tox.ini +++ b/tox.ini @@ -34,7 +34,6 @@ deps = extras = docker podman - vagrant windows test commands_pre =