Browse Source

enough: use keys in clouds.yml instead of a different file

The clouds.yml is always in the config directory. Chosing a different
cloud is done by selecting an entry in the file rather than chosing a
different file.

* --clouds becomes --cloud
* --target-clouds becomes --target-cloud

Fixes: main/infrastructure#176
Fixes: main/infrastructure#185
keep-around/eaa481d88b6bab7c51af0302cdc823483979fecc
Loïc Dachary 1 year ago
committed by Loic Dachary
parent
commit
eaa481d88b
Signed by: dachary GPG Key ID: 992D23B392F9E4F2
  1. 22
      docs/user-guide.rst
  2. 5
      enough/cli/backup.py
  3. 2
      enough/cli/openstack.py
  4. 25
      enough/common/__init__.py
  5. 16
      enough/common/host.py
  6. 32
      enough/common/openstack.py
  7. 12
      enough/common/options.py
  8. 8
      enough/common/service.py
  9. 4
      enough/internal/cli/backup.py
  10. 3
      enough/internal/cli/test.py
  11. 2
      tests/conftest.py
  12. 2
      tests/enough/common/data/common/openstack/clouds.yml
  13. 5
      tests/enough/common/test_common_options.py
  14. 1
      tests/enough/common/test_common_service.py
  15. 2
      tests/enough/common/test_common_ssh.py
  16. 62
      tests/enough/common/test_init.py
  17. 26
      tests/enough/common/test_openstack.py

22
docs/user-guide.rst

@ -209,9 +209,6 @@ backup for:
* teaching
* etc.
Assuming the credentials for the OpenStack region on which the clone
must be placed are in the ``~/.enough/test-clouds.yml`` file:
.. code::
$ enough --domain example.com openstack volume snapshot list
@ -220,22 +217,30 @@ must be placed are in the ``~/.enough/test-clouds.yml`` file:
...
$ enough --domain example.com backup restore \
--target-domain test.d.enough.community \
--target-clouds ~/.enough/test-clouds.yml 2020-04-12-cloud-volume
2020-04-12-cloud-volume
Once the service is cloned, it will be available at
``https://cloud.test.d.enough.community``. In this example, the
cloning is done as follows:
* A volume is created from the ``2020-04-12-cloud-volume``, in the
``~/.enough/test-clouds.yml`` OpenStack region.
* A dedicated OpenStack region is used to restore the backup
.. note::
The OpenStack region where the backup is restored is in the
`clone` section of the `~/.enough/example.com/inventory/group_vars/all/clouds.yml`
file and it can be modified if the default is not suitable.
* A volume is created from the ``2020-04-12-cloud-volume``
* The :doc:`cloud service <services/nextcloud>` is created, as well as
all the services it depends on, if they do not already
exist. Including the :doc:`DNS server <services/bind>`.
* The ``test.d.enough.community`` domain is delegated to the
:doc:`DNS server <services/bind>` located in the ``~/.enough/test-clouds.yml``
OpenStack region so that ``https://cloud.test.d.enough.community`` resolves
:doc:`DNS server <services/bind>` located in the
OpenStack region where the backup was restored
so that ``https://cloud.test.d.enough.community`` resolves
to the newly created :doc:`cloud service <services/nextcloud>`.
Infrastructure services and access
@ -255,7 +260,6 @@ The default can also be changed for a given host (for instance
`weblate-host`) by setting the desired value in the
`~/.enough/example.com/inventory/host_vars/weblate-host/network.yml` file.
VPN
~~~

5
enough/cli/backup.py

@ -7,8 +7,9 @@ from enough.common import Enough
def set_common_options(parser):
parser.add_argument(
'--target-clouds',
help='Path to the target clouds.yml file')
'--target-cloud',
default='clone',
help='Name of the cloud in which resources must be restored')
return parser

2
enough/cli/openstack.py

@ -16,5 +16,5 @@ class Cli(Command):
def take_action(self, parsed_args):
args = vars(self.app.options)
args.update(vars(parsed_args))
o = OpenStack(settings.CONFIG_DIR, args['clouds'])
o = OpenStack(settings.CONFIG_DIR, **args)
o.run(args['args'])

25
enough/common/__init__.py

@ -26,17 +26,18 @@ class Enough(object):
self.args = self.init_args.copy()
self.args.update(kwargs)
if 'clouds' not in self.args:
self.args['clouds'] = f'{self.config_dir}/inventory/group_vars/all/clouds.yml'
self.dotenough = DotEnough(self.config_dir, self.args['domain'])
self.ansible = ansible_utils.Ansible(self.config_dir, self.share_dir)
if self.args.get('driver', 'openstack'):
if 'cloud' not in self.args:
self.args['cloud'] = self.ansible.get_global_variable('openstack_cloud')
self.hosts = Hosts(self.config_dir)
self.host = host_factory(self.config_dir, self.share_dir, **self.args)
self.service = service_factory(self.config_dir, self.share_dir, **self.args)
if self.args.get('driver', 'openstack'):
self.openstack = OpenStack(self.config_dir, self.args['clouds'])
self.heat = Heat(self.config_dir, self.args['clouds'], **self.args)
self.openstack = OpenStack(self.config_dir, **self.args)
self.heat = Heat(self.config_dir, **self.args)
self.playbook = ansible_utils.Playbook(self.config_dir, self.share_dir)
self.ansible = ansible_utils.Ansible(self.config_dir, self.share_dir)
def create_missings(self, hosts):
public_key = f'{self.config_dir}/infrastructure_key.pub'
@ -86,14 +87,13 @@ class Enough(object):
sh.sudo.kill(pid)
sh.sudo.rm('/var/run/openvpn-localhost.pid')
def clone(self, target_domain, target_clouds):
def clone(self, target_domain, target_cloud):
config_base = os.path.dirname(self.config_dir)
config_dir = f'{config_base}/{target_domain}'
sh.rsync('-a', '--delete',
'--exclude=private-key.yml',
'--exclude=hosts.yml',
'--exclude=group_vars/all/domain.yml',
'--exclude=group_vars/all/clouds.yml',
'--exclude=group_vars/all/production_domain.yml',
f'{self.config_dir}/', f'{config_dir}/')
clone_override_dir = f'{config_base}/clone-override'
@ -105,11 +105,10 @@ class Enough(object):
all_dir = f'{config_dir}/inventory/group_vars/all'
if not os.path.exists(all_dir):
os.makedirs(all_dir)
clouds = f'{all_dir}/clouds.yml'
shutil.copyfile(target_clouds, clouds)
kwargs = {
'domain': target_domain,
'driver': self.args['driver'],
'domain': target_domain,
'cloud': target_cloud,
}
clone = Enough(config_dir, self.share_dir, **kwargs)
return clone
@ -195,7 +194,7 @@ class Enough(object):
def restore(self):
return self.restore_remote(self.args['target_domain'],
self.args['target_clouds'],
self.args['target_cloud'],
self.args['name'])
def create_service_matching_snapshot(self, snapshot):
@ -206,8 +205,8 @@ class Enough(object):
self.service.create_or_update()
return host
def restore_remote(self, domain, clouds, snapshot):
clone = self.clone(domain, clouds)
def restore_remote(self, domain, cloud, snapshot):
clone = self.clone(domain, cloud)
to_volume = self.clone_volume_from_snapshot(clone, snapshot)
host = clone.create_service_matching_snapshot(snapshot)
clone.openstack.replace_volume(host, to_volume)

16
enough/common/host.py

@ -83,10 +83,8 @@ class HostOpenStack(Host):
self.dotenough.ensure()
def create_or_update(self):
h = openstack.Heat(self.config_dir, self.args['clouds'], **self.args)
s = openstack.Stack(self.config_dir,
self.args['clouds'],
h.get_stack_definition(self.args['name']))
h = openstack.Heat(self.config_dir, **self.args)
s = openstack.Stack(self.config_dir, h.get_stack_definition(self.args['name']), **self.args)
s.set_public_key(f'{self.config_dir}/infrastructure_key.pub')
return s.create_or_update()
@ -94,18 +92,14 @@ class HostOpenStack(Host):
self.delete_hosts(self.args['name'])
def delete_hosts(self, names):
h = openstack.Heat(self.config_dir, self.args['clouds'], **self.args)
h = openstack.Heat(self.config_dir, **self.args)
complete_deletion = []
for name in names:
s = openstack.Stack(self.config_dir,
self.args['clouds'],
h.get_stack_definition(name))
s = openstack.Stack(self.config_dir, h.get_stack_definition(name), **self.args)
if s.delete_no_wait():
complete_deletion.append(name)
for name in complete_deletion:
s = openstack.Stack(self.config_dir,
self.args['clouds'],
h.get_stack_definition(name))
s = openstack.Stack(self.config_dir, h.get_stack_definition(name), **self.args)
s.delete_wait()

32
enough/common/openstack.py

@ -23,12 +23,12 @@ class OpenStackBase(object):
INTERNAL_NETWORK = 'internal'
INTERNAL_NETWORK_CIDR = '10.20.30.0/24'
def __init__(self, config_dir, config_file, **kwargs):
def __init__(self, config_dir, **kwargs):
self.args = kwargs
self.config_dir = config_dir
self.config_file = config_file
self.config_file = f'{self.config_dir}/inventory/group_vars/all/clouds.yml'
self.o = sh.openstack.bake(
'--os-cloud=ovh',
'--os-cloud', kwargs.get('cloud', 'production'),
_tee=True,
_out=lambda x: log.info(x.strip()),
_err=lambda x: log.info(x.strip()),
@ -38,8 +38,8 @@ class OpenStackBase(object):
class Stack(OpenStackBase):
def __init__(self, config_dir, config_file, definition=None, **kwargs):
super().__init__(config_dir, config_file, **kwargs)
def __init__(self, config_dir, definition=None, **kwargs):
super().__init__(config_dir, **kwargs)
log.info(f'OS_CLIENT_CONFIG_FILE={self.config_file}')
self.definition = definition
@ -107,13 +107,13 @@ class Stack(OpenStackBase):
def create_internal_network(self):
network = self.definition.get('internal_network', OpenStackBase.INTERNAL_NETWORK)
cidr = self.definition.get('internal_network_cidr', OpenStackBase.INTERNAL_NETWORK_CIDR)
o = OpenStack(self.config_dir, self.config_file)
o = OpenStack(self.config_dir, **self.args)
o.network_and_subnet_create(network, cidr)
def connect_internal_network(self):
server = self.definition['name']
network = self.definition.get('internal_network', OpenStackBase.INTERNAL_NETWORK)
o = OpenStack(self.config_dir, self.config_file)
o = OpenStack(self.config_dir, **self.args)
if o.server_connected_to_network(server, network):
return
self.o.server.add.network(server, network)
@ -161,7 +161,7 @@ class Stack(OpenStackBase):
Hosts(self.config_dir).delete(name)
network = self.definition.get('internal_network', OpenStackBase.INTERNAL_NETWORK)
o = OpenStack(self.config_dir, self.config_file)
o = OpenStack(self.config_dir, **self.args)
o.network_delete_if_not_used(network)
def delete(self):
@ -225,7 +225,7 @@ class Heat(OpenStackBase):
# Launch the creation of all stacks in // and do not wait for them to complete
#
for name in names:
s = Stack(self.config_dir, self.config_file, self.get_stack_definition(name),
s = Stack(self.config_dir, self.get_stack_definition(name),
**self.args)
s.set_public_key(public_key)
info = s.create_or_update(return_on_create=True)
@ -237,7 +237,7 @@ class Heat(OpenStackBase):
# Verify all stacks previously launched complete as expected
#
for name in created:
s = Stack(self.config_dir, self.config_file, self.get_stack_definition(name),
s = Stack(self.config_dir, self.get_stack_definition(name),
**self.args)
s.set_public_key(public_key)
info = s.create_or_update(return_on_create=True)
@ -247,10 +247,10 @@ class Heat(OpenStackBase):
def create_test_subdomain(self, domain):
d = f"{self.config_dir}/inventory/group_vars/all"
assert os.path.exists(d)
if 'bind-host' not in Stack(self.config_dir, self.config_file, **self.args).list():
if 'bind-host' not in Stack(self.config_dir, **self.args).list():
return None
h = Heat(self.config_dir, self.config_file)
s = Stack(self.config_dir, self.config_file, h.get_stack_definition('bind-host'),
h = Heat(self.config_dir, **self.args)
s = Stack(self.config_dir, h.get_stack_definition('bind-host'),
**self.args)
s.set_public_key(f'{self.config_dir}/infrastructure_key.pub')
bind_host = s.create_or_update()
@ -288,9 +288,9 @@ class OpenStackBackupCreate(Exception):
class OpenStack(OpenStackBase):
def __init__(self, config_dir, config_file):
super().__init__(config_dir, config_file)
self.config = yaml.load(open(config_file))
def __init__(self, config_dir, **kwargs):
super().__init__(config_dir, **kwargs)
self.config = yaml.load(open(self.config_file))
@retry(OpenStackLeftovers, tries=7)
def destroy_everything(self, prefix):

12
enough/common/options.py

@ -1,16 +1,10 @@
import os
from enough import settings
def set_options(parser):
parser.add_argument('--driver', default='openstack')
parser.add_argument('--inventory', action='append')
o = parser.add_argument_group(title='OpenStack',
description='Only when --driver=openstack')
o.add_argument(
'--clouds',
default=os.environ.get('OS_CLIENT_CONFIG_FILE',
f'{settings.CONFIG_DIR}/inventory/group_vars/all/clouds.yml'),
help='Path to the clouds.yml file')
'--cloud',
default='production',
help='Name of the cloud in which resources are provisionned')
return parser

8
enough/common/service.py

@ -99,10 +99,10 @@ class ServiceOpenStack(Service):
if not r.ok:
raise ServiceOpenStack.PingException(f'{ping} does not respond')
h = openstack.Heat(self.config_dir, self.dotenough.clouds_file)
h = openstack.Heat(self.config_dir, cloud=self.args['cloud'])
s = openstack.Stack(self.config_dir,
self.dotenough.clouds_file,
h.get_stack_definition('bind-host'))
h.get_stack_definition('bind-host'),
cloud=self.args['cloud'])
s.set_public_key(self.dotenough.public_key())
bind_host = s.create_or_update()
r = requests.post(f'https://{api}/delegate-dns/',
@ -115,7 +115,7 @@ class ServiceOpenStack(Service):
def create_or_update(self):
hosts = self.service2hosts[self.args['name']]
h = openstack.Heat(self.config_dir, self.dotenough.clouds_file)
h = openstack.Heat(self.config_dir, cloud=self.args['cloud'])
h.create_missings(hosts, self.dotenough.public_key())
self.maybe_delegate_dns()
playbook = ansible_utils.Playbook(self.config_dir, self.share_dir)

4
enough/internal/cli/backup.py

@ -23,7 +23,7 @@ class Create(Command):
args.update(vars(parsed_args))
d = dotenough.DotEnoughOpenStack(settings.CONFIG_DIR, args['domain'])
d.ensure()
o = OpenStack(settings.CONFIG_DIR, args['clouds'])
o = OpenStack(settings.CONFIG_DIR, **args)
o.backup_create(args['volumes'])
@ -43,5 +43,5 @@ class Prune(Command):
args.update(vars(parsed_args))
d = dotenough.DotEnoughOpenStack(settings.CONFIG_DIR, args['domain'])
d.ensure()
o = OpenStack(settings.CONFIG_DIR, args['clouds'])
o = OpenStack(settings.CONFIG_DIR, **args)
o.backup_prune(args['days'])

3
enough/internal/cli/test.py

@ -9,8 +9,7 @@ class CreateTestSubdomain(ShowOne):
"Create and delegate a test subdomain, if possible"
def take_action(self, parsed_args):
clouds_file = f'{settings.CONFIG_DIR}/inventory/group_vars/all/clouds.yml'
h = openstack.Heat(settings.CONFIG_DIR, clouds_file)
h = openstack.Heat(settings.CONFIG_DIR)
r = h.create_test_subdomain(self.app.options.domain)
columns = ('name',)
data = (r,)

2
tests/conftest.py

@ -81,5 +81,5 @@ def docker_name():
def openstack_name():
prefix = 'enough_test_' + str(int(time.time()))
yield prefix
o = OpenStack('.', 'inventory/group_vars/all/clouds.yml')
o = OpenStack('.')
o.destroy_everything(prefix)

2
tests/enough/common/data/common/openstack/clouds.yml

@ -1,7 +1,7 @@
---
# https://docs.openstack.org/python-openstackclient/latest/configuration/index.html#configuration-files
clouds:
ovh:
production:
auth:
auth_url: "https://auth.cloud.ovh.net/v3" # OS_AUTH_URL
project_name: "XXXXXX" # OS_PROJECT_NAME

5
tests/enough/common/test_common_options.py

@ -7,9 +7,6 @@ def test_set_options():
parser = argparse.ArgumentParser()
assert options.set_options(parser) == parser
args = parser.parse_args([])
assert '/inventory/' in args.clouds
driver = 'DRIVER'
clouds = 'CLOUDS'
args = parser.parse_args(['--driver', driver, '--clouds', clouds])
assert args.clouds == clouds
args = parser.parse_args(['--driver', driver])
assert args.driver == driver

1
tests/enough/common/test_common_service.py

@ -20,6 +20,7 @@ def test_openstack_create_or_update(tmpdir, openstack_name, requests_mock):
'playbook': os.path.abspath('tests/enough/common/test_common_service/enough-playbook.yml'),
'domain': domain,
'name': 'essential',
'cloud': 'production',
})
s.dotenough.set_certificate('ownca')
s.dotenough.set_clouds_file('inventory/group_vars/all/clouds.yml')

2
tests/enough/common/test_common_ssh.py

@ -14,7 +14,7 @@ def test_ssh(openstack_name):
'flavor': 's1-2',
'port': '22',
}
s = Stack(settings.CONFIG_DIR, 'inventory/group_vars/all/clouds.yml', d)
s = Stack(settings.CONFIG_DIR, d)
s.set_public_key('infrastructure_key.pub')
s.create_or_update()
ssh = SSH(settings.CONFIG_DIR, domain='enough.community')

62
tests/enough/common/test_init.py

@ -11,7 +11,6 @@ from enough.common.openstack import OpenStack, Stack
@pytest.mark.skipif('SKIP_OPENSTACK_INTEGRATION_TESTS' in os.environ,
reason='skip integration test')
def test_clone_and_destroy(tmpdir):
clone_clouds = os.path.expanduser("~/.enough/dev/clone-clouds.yml")
test_clouds = 'inventory/group_vars/all/clouds.yml'
clone_override_dir = f'{tmpdir}/clone-override'
@ -36,7 +35,7 @@ def test_clone_and_destroy(tmpdir):
assert original.openstack.o.server.list().strip() == ''
clone_domain = 'clone.com'
clone = original.clone(clone_domain, clone_clouds)
clone = original.clone(clone_domain, 'clone')
assert password == open(f'{clone.config_dir}.pass').read()
assert 'REPLACED CONTENT' == open(
@ -48,7 +47,9 @@ def test_clone_and_destroy(tmpdir):
assert not os.path.exists(clone.config_dir)
def create_enough(tmpdir, clouds, dotenough, **kwargs):
def create_enough(tmpdir, dotenough, **kwargs):
clouds = 'inventory/group_vars/all/clouds.yml'
enough_domain = 'enough.com'
enough_config_dir = f'{tmpdir}/{enough_domain}'
shutil.copytree(f'tests/enough/common/test_init/{dotenough}',
@ -67,13 +68,13 @@ def create_enough(tmpdir, clouds, dotenough, **kwargs):
return enough
def create_and_clone_server_and_volume(tmpdir, clone_clouds, test_clouds):
original = create_enough(tmpdir, test_clouds, 'backup')
def create_and_clone_server_and_volume(tmpdir, clone_cloud):
original = create_enough(tmpdir, 'backup')
original.set_args(name='sample', playbook='enough-playbook.yml')
original.service.create_or_update()
clone_domain = 'clone.com'
clone = original.clone(clone_domain, clone_clouds)
clone = original.clone(clone_domain, clone_cloud)
clone.set_args(name='sample', playbook='enough-playbook.yml')
clone.service.create_or_update()
@ -83,18 +84,15 @@ def create_and_clone_server_and_volume(tmpdir, clone_clouds, test_clouds):
@pytest.mark.skipif('SKIP_OPENSTACK_INTEGRATION_TESTS' in os.environ,
reason='skip integration test')
def test_clone_create_service(tmpdir):
clone_clouds = os.path.expanduser("~/.enough/dev/clone-clouds.yml")
test_clouds = 'inventory/group_vars/all/clouds.yml'
try:
(original, clone) = create_and_clone_server_and_volume(tmpdir, clone_clouds, test_clouds)
(original, clone) = create_and_clone_server_and_volume(tmpdir, 'clone')
assert 'sample-host' in original.openstack.o.server.list()
assert 'sample-volume' in original.openstack.o.volume.list()
assert 'sample-host' in clone.openstack.o.server.list()
assert 'sample-volume' in clone.openstack.o.volume.list()
finally:
for clouds in (test_clouds, clone_clouds):
o = OpenStack(settings.CONFIG_DIR, clouds)
for cloud in ('production', 'clone'):
o = OpenStack(settings.CONFIG_DIR, cloud=cloud)
# comment out the following line to re-use the content of the regions and save time
o.destroy_everything(None)
@ -102,10 +100,8 @@ def test_clone_create_service(tmpdir):
@pytest.mark.skipif('SKIP_OPENSTACK_INTEGRATION_TESTS' in os.environ,
reason='skip integration test')
def test_create_copy_host(tmpdir):
clouds = 'inventory/group_vars/all/clouds.yml'
try:
enough = create_enough(tmpdir, clouds, 'copy')
enough = create_enough(tmpdir, 'copy')
if 'copy-volume' not in enough.openstack.o.volume.list():
enough.openstack.o.volume.create('--size', '1', 'copy-volume')
ip = enough.create_copy_host('copy-from-host', 'some-volume', 'copy-volume')
@ -116,7 +112,7 @@ def test_create_copy_host(tmpdir):
'-i', enough.dotenough.private_key(), f'root@{ip}', 'mountpoint', '/srv').strip()
assert r == '/srv is a mountpoint'
finally:
o = OpenStack(settings.CONFIG_DIR, clouds)
o = OpenStack(settings.CONFIG_DIR)
# comment out the following line to re-use the content of the regions and save time
o.destroy_everything(None)
@ -124,11 +120,8 @@ def test_create_copy_host(tmpdir):
@pytest.mark.skipif('SKIP_OPENSTACK_INTEGRATION_TESTS' in os.environ,
reason='skip integration test')
def test_clone_volume_from_snapshot(tmpdir):
clone_clouds = os.path.expanduser("~/.enough/dev/clone-clouds.yml")
test_clouds = 'inventory/group_vars/all/clouds.yml'
try:
original = create_enough(tmpdir, test_clouds, 'backup')
original = create_enough(tmpdir, 'backup')
original.set_args(name='sample', playbook='enough-playbook.yml')
original.service.create_or_update()
ip = original.hosts.load().get_ip('sample-host')
@ -141,7 +134,7 @@ def test_clone_volume_from_snapshot(tmpdir):
assert snapshot in original.openstack.o.volume.snapshot.list()
clone_domain = 'clone.com'
clone = original.clone(clone_domain, clone_clouds)
clone = original.clone(clone_domain, 'clone')
(from_ip, to_ip, from_volume, to_volume) = original._clone_volume_from_snapshot_body(
clone, snapshot)
@ -160,8 +153,8 @@ def test_clone_volume_from_snapshot(tmpdir):
original._clone_volume_from_snapshot_cleanup(clone, from_volume)
finally:
for clouds in (test_clouds, clone_clouds):
o = OpenStack(settings.CONFIG_DIR, clouds)
for cloud in ('production', 'clone'):
o = OpenStack(settings.CONFIG_DIR, cloud=cloud)
# comment out the following line to re-use the content of the regions and save time
o.destroy_everything(None)
@ -169,16 +162,14 @@ def test_clone_volume_from_snapshot(tmpdir):
@pytest.mark.skipif('SKIP_OPENSTACK_INTEGRATION_TESTS' in os.environ,
reason='skip integration test')
def test_create_service_matching_snapshot(tmpdir):
test_clouds = 'inventory/group_vars/all/clouds.yml'
try:
enough = create_enough(tmpdir, test_clouds, 'backup')
enough = create_enough(tmpdir, 'backup')
host = enough.create_service_matching_snapshot('2020-02-20-sample-volume')
assert host == 'sample-host'
assert 'sample-volume' in enough.openstack.o.volume.list()
finally:
o = OpenStack(settings.CONFIG_DIR, test_clouds)
o = OpenStack(settings.CONFIG_DIR)
# comment out the following line to re-use the content of the regions and save time
o.destroy_everything(None)
@ -186,11 +177,8 @@ def test_create_service_matching_snapshot(tmpdir):
@pytest.mark.skipif('SKIP_OPENSTACK_INTEGRATION_TESTS' in os.environ,
reason='skip integration test')
def test_restore_remote(tmpdir):
clone_clouds = os.path.expanduser("~/.enough/dev/clone-clouds.yml")
test_clouds = 'inventory/group_vars/all/clouds.yml'
try:
original = create_enough(tmpdir, test_clouds, 'backup')
original = create_enough(tmpdir, 'backup')
original.set_args(name='sample', playbook='enough-playbook.yml')
original.service.create_or_update()
ip = original.hosts.load().get_ip('sample-host')
@ -201,7 +189,7 @@ def test_restore_remote(tmpdir):
snapshot = f'{original.openstack.backup_date()}-sample-volume'
assert snapshot in original.openstack.o.volume.snapshot.list()
clone = original.restore_remote('test.com', clone_clouds, snapshot)
clone = original.restore_remote('test.com', 'clone', snapshot)
assert 'sample-volume' in clone.openstack.o.volume.list()
hosts = clone.hosts.load()
Stack.wait_for_ssh(hosts.get_ip('sample-host'), hosts.get_port('sample-host'))
@ -210,8 +198,8 @@ def test_restore_remote(tmpdir):
'test', '-e', '/srv/STONE').exit_code == 0
finally:
for clouds in (test_clouds, clone_clouds):
o = OpenStack(settings.CONFIG_DIR, clouds)
for cloud in ('production', 'clone'):
o = OpenStack(settings.CONFIG_DIR, cloud=cloud)
# comment out the following line to re-use the content of the regions and save time
o.destroy_everything(None)
@ -219,10 +207,8 @@ def test_restore_remote(tmpdir):
@pytest.mark.skipif('SKIP_OPENSTACK_INTEGRATION_TESTS' in os.environ,
reason='skip integration test')
def test_create_missings(tmpdir):
test_clouds = 'inventory/group_vars/all/clouds.yml'
try:
enough = create_enough(tmpdir, test_clouds, 'create-missings')
enough = create_enough(tmpdir, 'create-missings')
r = enough.create_missings(['bind-host'])
assert 'bind-host' in r
internal_dns = enough.openstack.o.subnet.show(
@ -230,6 +216,6 @@ def test_create_missings(tmpdir):
bind_internal_ip = enough.openstack.server_ip_in_network('bind-host', 'internal')
assert bind_internal_ip == internal_dns
finally:
o = OpenStack(settings.CONFIG_DIR, test_clouds)
o = OpenStack(settings.CONFIG_DIR)
# comment out the following line to re-use the content of the regions and save time
o.destroy_everything(None)

26
tests/enough/common/test_openstack.py

@ -25,7 +25,7 @@ def test_stack_create_or_update_default(openstack_name):
},
],
}
s = Stack(settings.CONFIG_DIR, 'inventory/group_vars/all/clouds.yml', d)
s = Stack(settings.CONFIG_DIR, d)
s.set_public_key('infrastructure_key.pub')
r = s.create_or_update()
assert r['port'] == '22'
@ -48,12 +48,12 @@ def test_stack_create_or_update_with_internal_network(openstack_name):
'internal_network': network,
'internal_network_cidr': cidr,
}
s = Stack(settings.CONFIG_DIR, 'inventory/group_vars/all/clouds.yml', d)
s = Stack(settings.CONFIG_DIR, d)
s.set_public_key('infrastructure_key.pub')
r = s.create_or_update()
assert r['port'] == '22'
ipv4 = r['ipv4']
o = OpenStack(settings.CONFIG_DIR, 'inventory/group_vars/all/clouds.yml')
o = OpenStack(settings.CONFIG_DIR)
assert o.server_connected_to_network(name, network)
assert r == s.create_or_update()
assert o.server_connected_to_network(name, network)
@ -66,7 +66,7 @@ def test_stack_create_or_update_with_internal_network(openstack_name):
# Heat
#
def test_heat_definition():
h = Heat(settings.CONFIG_DIR, 'inventory/group_vars/all/clouds.yml')
h = Heat(settings.CONFIG_DIR)
definitions = h.get_stack_definitions()
assert 'bind-host' in definitions
definition = h.get_stack_definition('bind-host')
@ -74,14 +74,14 @@ def test_heat_definition():
def test_host_from_volume():
h = Heat(settings.CONFIG_DIR, 'inventory/group_vars/all/clouds.yml')
h = Heat(settings.CONFIG_DIR)
assert h.host_from_volume('cloud-volume') == 'cloud-host'
assert h.host_from_volume('unknown-volume') is None
def test_heat_definition_encrypted():
d = 'tests/enough/common/test_openstack/config_dir'
h = Heat(d, 'inventory/group_vars/all/clouds.yml')
h = Heat(d)
definitions = h.get_stack_definitions(share_dir=d)
assert 'my-host' in definitions
assert definitions['my-host']['myvariable'] == 'myvalue'
@ -90,7 +90,7 @@ def test_heat_definition_encrypted():
def test_create_test_subdomain_no_bind(mocker):
mocker.patch('os.path.exists', return_value=True)
mocker.patch('enough.common.openstack.Stack.list', return_value=[])
h = Heat(settings.CONFIG_DIR, 'inventory/group_vars/all/clouds.yml')
h = Heat(settings.CONFIG_DIR)
assert h.create_test_subdomain('my.tld') is None
@ -107,7 +107,7 @@ def test_create_test_subdomain_with_bind(tmpdir, mocker, requests_mock):
})
mocker.patch('enough.common.openstack.Heat.get_stack_definition')
requests_mock.post(requests_mock_module.ANY, status_code=201)
h = Heat(settings.CONFIG_DIR, 'inventory/group_vars/all/clouds.yml')
h = Heat(settings.CONFIG_DIR)
with modified_environ(ENOUGH_API_TOKEN="TOKEN"):
fqdn = h.create_test_subdomain('my.tld')
assert '.test.my.tld' in fqdn
@ -120,7 +120,7 @@ def test_create_test_subdomain_with_bind(tmpdir, mocker, requests_mock):
@pytest.mark.skipif('SKIP_OPENSTACK_INTEGRATION_TESTS' in os.environ,
reason='skip integration test')
def test_network(openstack_name):
o = OpenStack(settings.CONFIG_DIR, 'inventory/group_vars/all/clouds.yml')
o = OpenStack(settings.CONFIG_DIR)
o.network_and_subnet_create(openstack_name, '10.11.12.0/24')
assert o.network_exists(openstack_name)
assert o.subnet_exists(openstack_name)
@ -134,7 +134,7 @@ def test_network(openstack_name):
@pytest.mark.skipif('SKIP_OPENSTACK_INTEGRATION_TESTS' in os.environ,
reason='skip integration test')
def test_backup_create_with_name(openstack_name, caplog):
o = OpenStack(settings.CONFIG_DIR, 'inventory/group_vars/all/clouds.yml')
o = OpenStack(settings.CONFIG_DIR)
o.o.volume.create('--size=1', openstack_name)
assert o.backup_create([openstack_name]) == 1
assert o.backup_create([openstack_name]) == 0
@ -147,7 +147,7 @@ def test_backup_create_with_name(openstack_name, caplog):
@pytest.mark.skipif('SKIP_OPENSTACK_INTEGRATION_TESTS' in os.environ,
reason='skip integration test')
def test_backup_create_no_names(openstack_name, caplog):
o = OpenStack(settings.CONFIG_DIR, 'inventory/group_vars/all/clouds.yml')
o = OpenStack(settings.CONFIG_DIR)
o.o.volume.create('--size=1', openstack_name)
o.backup_create([])
available_snapshot = f'AVAILABLE {o.backup_date()}-{openstack_name}'
@ -168,11 +168,11 @@ def test_openstack_replace_volume(openstack_name):
},
],
}
s = Stack(settings.CONFIG_DIR, 'inventory/group_vars/all/clouds.yml', d)
s = Stack(settings.CONFIG_DIR, d)
s.set_public_key('infrastructure_key.pub')
s.create_or_update()
other_volume = f'{openstack_name}_other'
o = OpenStack(settings.CONFIG_DIR, 'inventory/group_vars/all/clouds.yml')
o = OpenStack(settings.CONFIG_DIR)
o.o.volume.create('--size=1', other_volume)
assert openstack_name in o.o.volume.list('--name', openstack_name)
o.replace_volume(openstack_name, other_volume)

Loading…
Cancel
Save