add e2e tests

main
Hannaeko 2022-03-04 13:08:47 +01:00
parent 4a4362715c
commit 690987010d
2 changed files with 501 additions and 0 deletions

402
api.yml 100644
View File

@ -0,0 +1,402 @@
openapi: '3.0.0'
info:
description: ''
version: 0.1.0-dev
title: Nomilo
components:
securitySchemes:
ApiToken:
type: http
scheme: bearer
bearerFormat: JWT
parameters:
ZoneName:
name: zone
in: path
schema:
type: string
required: true
schemas:
UserRequest:
type: object
required:
- username
- password
- email
properties:
username:
type: string
password:
type: string
email:
type: string
role:
type: string
enum:
- admin
- zoneadmin
TokenRequest:
type: object
required:
- username
- password
properties:
username:
type: string
password:
type: string
TokenResponse:
type: object
required:
- token
properties:
token:
type: string
AddZoneMemberRequest:
type: object
required:
- id
properties:
id:
type: string
CreateZoneRequest:
type: object
required:
- name
properties:
name:
type: string
Zone:
type: object
required:
- name
properties:
name:
type: string
ZoneList:
type: array
items:
$ref: '#/components/schemas/Zone'
RecordBase:
type: object
required:
- Name
- Class
- TTL
- Type
properties:
Name:
type: string
Class:
type: string
enum:
- IN
- CH
- HS
- NONE
- ANY
TTL:
type: integer
Type:
type: string
RecordTypeA:
type: object
allOf:
- $ref: '#/components/schemas/RecordBase'
- type: object
required:
- Address
properties:
Address:
type: string
RecordTypeAAAA:
type: object
allOf:
- $ref: '#/components/schemas/RecordBase'
- type: object
required:
- Address
properties:
Address:
type: string
RecordTypeCAA:
type: object
allOf:
- $ref: '#/components/schemas/RecordBase'
required:
- IssuerCritical
- Value
- PropertyTag
properties:
IssuerCritical:
type: boolean
Value:
type: string
PropertyTag:
type: string
RecordTypeCNAME:
type: object
allOf:
- $ref: '#/components/schemas/RecordBase'
- type: object
required:
- Target
properties:
Target:
type: string
RecordTypeMX:
type: object
allOf:
- $ref: '#/components/schemas/RecordBase'
- type: object
required:
- Preference
- MailExchanger
properties:
Preference:
type: integer
MailExchanger:
type: string
RecordTypeNS:
type: object
allOf:
- $ref: '#/components/schemas/RecordBase'
- type: object
required:
- Target
properties:
Target:
type: string
RecordTypePTR:
type: object
allOf:
- $ref: '#/components/schemas/RecordBase'
- type: object
required:
- Target
properties:
Target:
type: string
RecordTypeSOA:
type: object
allOf:
- $ref: '#/components/schemas/RecordBase'
- type: object
required:
- MasterServerName
- MaintainerName
- Refresh
- Retry
- Expire
- Minimum
- Serial
properties:
MasterServerName:
type: string
MaintainerName:
type: string
Refresh:
type: integer
Retry:
type: integer
Expire:
type: integer
Minimum:
type: integer
Serial:
type: integer
RecordTypeSRV:
type: object
allOf:
- $ref: '#/components/schemas/RecordBase'
- type: object
required:
- Server
- Port
- Priority
- Weight
properties:
Server:
type: string
Port:
type: integer
Priority:
type: integer
Weight:
type: integer
RecordTypeSSHFP:
type: object
allOf:
- $ref: '#/components/schemas/RecordBase'
- type: object
required:
- Algorithm
- DigestType
- Fingerprint
properties:
Algorithm:
type: integer
DigestType:
type: integer
Fingerprint:
type: string
RecordTypeTXT:
type: object
allOf:
- $ref: '#/components/schemas/RecordBase'
- type: object
required:
- Text
properties:
Text:
type: string
Record:
type: object
oneOf:
- $ref: '#/components/schemas/RecordTypeA'
- $ref: '#/components/schemas/RecordTypeAAAA'
- $ref: '#/components/schemas/RecordTypeCAA'
- $ref: '#/components/schemas/RecordTypeCNAME'
- $ref: '#/components/schemas/RecordTypeMX'
- $ref: '#/components/schemas/RecordTypeNS'
- $ref: '#/components/schemas/RecordTypePTR'
- $ref: '#/components/schemas/RecordTypeSOA'
- $ref: '#/components/schemas/RecordTypeSRV'
- $ref: '#/components/schemas/RecordTypeSSHFP'
- $ref: '#/components/schemas/RecordTypeTXT'
discriminator:
propertyName: Type
mapping:
A: '#/components/schemas/RecordTypeA'
AAAA: '#/components/schemas/RecordTypeAAAA'
CAA: '#/components/schemas/RecordTypeCAA'
CNAME: '#/components/schemas/RecordTypeCNAME'
MX: '#/components/schemas/RecordTypeMX'
NS: '#/components/schemas/RecordTypeNS'
PTR: '#/components/schemas/RecordTypePTR'
SOA: '#/components/schemas/RecordTypeSOA'
SRV: '#/components/schemas/RecordTypeSRV'
SSHFP: '#/components/schemas/RecordTypeSSHFP'
TXT: '#/components/schemas/RecordTypeTXT'
RecordList:
type: array
items:
$ref: '#/components/schemas/Record'
paths:
'/users':
post:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UserRequest'
responses:
'201':
description: ''
'/users/me/token':
post:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/TokenRequest'
responses:
'200':
description: ''
content:
application/json:
schema:
$ref: '#/components/schemas/TokenResponse'
'/zones':
get:
security:
- ApiToken: []
responses:
'200':
description: ''
content:
application/json:
schema:
$ref: '#/components/schemas/ZoneList'
post:
security:
- ApiToken: []
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CreateZoneRequest'
responses:
'200':
description: ''
content:
application/json:
schema:
$ref: '#/components/schemas/Zone'
'/zones/{zone}/members':
parameters:
- $ref: '#/components/parameters/ZoneName'
post:
security:
- ApiToken: []
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AddZoneMemberRequest'
responses:
'201':
description: ''
'/zones/{zone}/records':
parameters:
- $ref: '#/components/parameters/ZoneName'
get:
security:
- ApiToken: []
responses:
'200':
description: ''
content:
application/json:
schema:
$ref: '#/components/schemas/RecordList'
post:
security:
- ApiToken: []
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/RecordList'
responses:
'200':
description: ''

99
e2e/zones.py 100644
View File

@ -0,0 +1,99 @@
from nomilo_client import ApiClient, Configuration
from nomilo_client.api.default_api import DefaultApi
from nomilo_client.models import (
TokenRequest,
RecordTypeSOA,
RecordTypeAAAA,
RecordTypeCNAME,
RecordTypeNS,
RecordTypeTXT,
RecordList
)
import logging
import string
import random
import unittest
import warnings
logging.basicConfig(level=logging.DEBUG)
HOST = 'http://localhost:8000/api/v1'
USER='toto'
PASSWORD='supersecure'
def build_api(host: str):
conf = Configuration(host=HOST)
api_client = ApiClient(configuration=conf)
return DefaultApi(api_client)
def build_authenticated_api(host: str, token: TokenRequest):
auth_conf = Configuration(host=host, access_token=token.token)
api_client = ApiClient(configuration=auth_conf)
return DefaultApi(api_client)
def random_string(length):
return ''.join(random.choice(string.ascii_lowercase) for x in range(length))
def random_name(zone):
return '%s.%s' % (random_string(16), zone)
class TestZones(unittest.TestCase):
@classmethod
def setUpClass(cls):
# Ignore warning about unclosed socket
warnings.filterwarnings(action="ignore", message="unclosed", category=ResourceWarning)
api = build_api(HOST)
token = api.users_me_token_post(token_request=TokenRequest(username=USER,password=PASSWORD))
cls.api = build_authenticated_api(HOST, token)
def test_get_zones(self):
zones = self.api.zones_get()
zone_name = zones.value[0].name
self.assertEqual(zone_name, 'example.com.')
def test_get_records(self):
records = self.api.zones_zone_records_get(zone='example.com.')
for record in records.value:
if type(record) is RecordTypeSOA:
with self.subTest(type='soa'):
self.assertEqual(record.name, 'example.com.')
if type(record) is RecordTypeAAAA:
with self.subTest(type='ns'):
self.assertEqual(record.name, 'srv1.example.com.')
self.assertEqual(record.address, '2001:db8:cafe:bc68::2')
if type(record) is RecordTypeCNAME:
with self.subTest(type='cname'):
self.assertEqual(record.name, 'www.example.com.')
self.assertEqual(record.target, 'srv1.example.com.')
if type(record) is RecordTypeNS:
with self.subTest(type='ns'):
self.assertEqual(record.name, 'example.com.')
self.assertEqual(record.target, 'ns.example.com.')
def test_create_records(self):
new_record = RecordTypeTXT(
_class='IN',
ttl=300,
name=random_name('example.com.'),
text=random_string(32),
type='TXT'
)
self.api.zones_zone_records_post(zone='example.com.', record_list=RecordList(value=[new_record]))
records = self.api.zones_zone_records_get(zone='example.com.')
found = False
for record in records.value:
if type(record) is RecordTypeTXT and record.name == new_record.name:
self.assertEqual(record.text, new_record.text, msg='New record does not have the expected value')
found = True
self.assertTrue(found, msg='New record not found in zone records')