Browse Source

infrastructure: move the test subdomain delegation to the enough cli

keep-around/4336d63a9d52017613164f1d65d91551312c201a
singuliere 2 years ago
parent
commit
4336d63a9d
No known key found for this signature in database GPG Key ID: 900857755EF189C2
  1. 35
      enough/common/openstack.py
  2. 54
      molecule/infrastructure/create.yml
  3. 1
      requirements-dev.in
  4. 5
      requirements-dev.txt
  5. 1
      setup.cfg
  6. 30
      tests/enough/common/test_openstack.py

35
enough/common/openstack.py

@ -1,3 +1,4 @@
import base64
from bs4 import BeautifulSoup
import copy
import hashlib
@ -6,6 +7,8 @@ import json
import os
import requests
import sh
import textwrap
import time
import yaml
from enough import settings
@ -149,6 +152,38 @@ class Heat(object):
os.makedirs(d)
open(f'{d}/hosts.yml', 'w').write(inventory)
def create_test_subdomain(self, domain):
# exclusively when running from molecule
assert os.path.exists('molecule.yml')
d = f"{settings.CONFIG_DIR}/inventory/group_vars/all"
assert os.path.exists(d)
if 'bind-host' not in Stack(self.clouds_file).list():
return None
s = Stack(self.clouds_file, Heat.get_stack_definition('bind-host'))
s.set_public_key(f'{settings.CONFIG_DIR}/infrastructure_key.pub')
bind_host = s.create_or_update()
# reverse so the leftmost part varies, for human readability
s = str(int(time.time()))[::-1]
subdomain = base64.b32encode(s.encode('ascii')).decode('ascii').lower()
fqdn = f'{subdomain}.test.{domain}'
token = os.environ['ENOUGH_API_TOKEN']
r = requests.post(f'https://api.{domain}/delegate-test-dns/',
headers={'Authorization': f'Token {token}'},
json={
'name': fqdn,
'ip': bind_host['ipv4'],
})
r.raise_for_status()
open(f'{d}/domain.yml', 'w').write(textwrap.dedent(f"""\
---
domain: {fqdn}
"""))
return fqdn
class OpenStackLeftovers(Exception):
pass

54
molecule/infrastructure/create.yml

@ -6,10 +6,6 @@
vars:
molecule_file: "{{ lookup('env', 'MOLECULE_FILE') }}"
molecule_instance_config: "{{ lookup('env', 'MOLECULE_INSTANCE_CONFIG') }}"
#
# obtained manually from api.{{ production_domain }}
#
enough_api_token: "{{ lookup('env', 'ENOUGH_API_TOKEN') }}"
molecule_yml: "{{ lookup('file', molecule_file) | from_yaml }}"
tasks:
@ -46,53 +42,9 @@
{% endfor %}
]
- name: bind_host_ip
set_fact:
bind_host_ip: "{% for s in stacks %}{% if s.name == 'bind-host' %}{{ s.ip }}{% endif %}{% endfor %}"
- name: set the default domain to enough.community
copy:
content: |
domain: enough.community
dest: "../../inventory/group_vars/all/domain.yml"
- block:
- name: generate subdomain
shell: date +%s | rev | base32 | tr -d =
register: cmd
- set_fact:
subdomain: "{{ cmd.stdout|lower }}"
- set_fact:
domain: "{{ subdomain }}.test.enough.community"
- name: create DNS delegation for {{ domain }} (requires access to api.{{ production_domain }})
uri:
url: https://api.{{ production_domain }}/delegate-test-dns/
method: POST
headers:
Authorization: "Token {{ enough_api_token }}"
body_format: json
body: |
{
"name": "{{ subdomain }}",
"ip": "{{ bind_host_ip }}"
}
status_code: 201
register: delegate_dns
- debug:
var: delegate_dns.json
- name: save the test sub-domain
copy:
content: |
domain: {{ domain }}
dest: "../../inventory/group_vars/all/domain.yml"
when: bind_host_ip != '' and (letsencrypt_staging | default(false))
- name: if bind-host exists, create and delegate a new test subdomain
shell: |
python -m enough.internal.cmd --domain {{ production_domain }} create test subdomain
- name: Dump instance config
copy:

1
requirements-dev.in

@ -5,6 +5,7 @@ pip-tools==3.6.1
pytest-cov==2.6.1
pytest-mock==1.10.4
pytest-django==3.4.8
requests_mock==1.6.0
sphinx==1.8.2
tox==3.5
twine==1.13.0

5
requirements-dev.txt

@ -122,13 +122,14 @@ pyyaml==3.13 # via ansible, ansible-lint, cliff, docker-compose, mo
readme-renderer==24.0 # via twine
requests-oauthlib==1.2.0 # via django-allauth
requests-toolbelt==0.9.1 # via twine
requests==2.20.1 # via cookiecutter, django-allauth, docker, docker-compose, keystoneauth1, oslo.config, python-glanceclient, python-heatclient, python-keystoneclient, python-swiftclient, requests-oauthlib, requests-toolbelt, sphinx, twine
requests==2.20.1 # via cookiecutter, django-allauth, docker, docker-compose, keystoneauth1, oslo.config, python-glanceclient, python-heatclient, python-keystoneclient, python-swiftclient, requests-mock, requests-oauthlib, requests-toolbelt, sphinx, twine
requests_mock==1.6.0
requestsexceptions==1.4.0 # via openstacksdk
rfc3986==1.3.1 # via oslo.config
sh==1.12.14
shade==1.30.0
simplejson==3.16.0 # via osc-lib, python-cinderclient, python-novaclient
six==1.11.0 # via ansible-lint, bcrypt, bleach, click-completion, cliff, cmd2, cryptography, debtcollector, docker, docker-compose, docker-pycreds, dockerpty, fasteners, keystoneauth1, mock, molecule, more-itertools, munch, openstacksdk, osc-lib, oslo.config, oslo.i18n, oslo.serialization, oslo.utils, packaging, pip-tools, pynacl, pyopenssl, pytest, python-cinderclient, python-dateutil, python-glanceclient, python-heatclient, python-keystoneclient, python-novaclient, python-openstackclient, python-swiftclient, readme-renderer, sphinx, stevedore, testinfra, tox, warlock, websocket-client
six==1.11.0 # via ansible-lint, bcrypt, bleach, click-completion, cliff, cmd2, cryptography, debtcollector, docker, docker-compose, docker-pycreds, dockerpty, fasteners, keystoneauth1, mock, molecule, more-itertools, munch, openstacksdk, osc-lib, oslo.config, oslo.i18n, oslo.serialization, oslo.utils, packaging, pip-tools, pynacl, pyopenssl, pytest, python-cinderclient, python-dateutil, python-glanceclient, python-heatclient, python-keystoneclient, python-novaclient, python-openstackclient, python-swiftclient, readme-renderer, requests-mock, sphinx, stevedore, testinfra, tox, warlock, websocket-client
snowballstemmer==1.2.1 # via sphinx
soupsieve==1.9.1 # via beautifulsoup4
sphinx==1.8.2

1
setup.cfg

@ -54,6 +54,7 @@ enough.internal.cli =
build_image = enough.internal.cli.docker:Build
create_service = enough.internal.cli.docker:Create
install = enough.internal.cli.install:InstallScript
create_test_subdomain = enough.internal.cli.test:CreateTestSubdomain
host_create = enough.internal.cli.host:Create
host_delete = enough.internal.cli.host:Delete
host_inventory = enough.internal.cli.host:Inventory

30
tests/enough/common/test_openstack.py

@ -2,6 +2,9 @@ import os
import pytest
import sh
import yaml
import requests_mock as requests_mock_module
from tests.modified_environ import modified_environ
from enough.common.openstack import Stack, Heat, OpenStack
@ -59,6 +62,33 @@ def test_heat_definition():
assert definition['name'] == 'bind-host'
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('inventory/group_vars/all/clouds.yml')
assert h.create_test_subdomain('my.tld') is None
def test_create_test_subdomain_with_bind(tmpdir, mocker, requests_mock):
mocker.patch('enough.settings.CONFIG_DIR', str(tmpdir))
d = f'{tmpdir}/inventory/group_vars/all'
os.makedirs(d)
assert not os.path.exists(f'{d}/domain.yml')
mocker.patch('os.path.exists', return_value=True)
mocker.patch('enough.common.openstack.Stack.list', return_value=['bind-host'])
mocker.patch('enough.common.openstack.Stack.set_public_key')
mocker.patch('enough.common.openstack.Stack.create_or_update', return_value={
'ipv4': '1.2.3.4',
})
mocker.patch('enough.common.openstack.Heat.get_stack_definition')
requests_mock.post(requests_mock_module.ANY, status_code=201)
h = Heat('inventory/group_vars/all/clouds.yml')
with modified_environ(ENOUGH_API_TOKEN="TOKEN"):
fqdn = h.create_test_subdomain('my.tld')
assert '.test.my.tld' in fqdn
assert os.path.exists(f'{d}/domain.yml')
#
# OpenStack
#

Loading…
Cancel
Save