mirror of
				https://github.com/github/octodns.git
				synced 2024-05-11 05:55:00 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			403 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			403 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#
 | 
						|
#
 | 
						|
#
 | 
						|
 | 
						|
from __future__ import absolute_import, division, print_function, \
 | 
						|
    unicode_literals
 | 
						|
 | 
						|
from unittest import TestCase
 | 
						|
from six import text_type
 | 
						|
 | 
						|
import requests_mock
 | 
						|
 | 
						|
from octodns.provider.selectel import SelectelProvider
 | 
						|
from octodns.record import Record, Update
 | 
						|
from octodns.zone import Zone
 | 
						|
 | 
						|
 | 
						|
class TestSelectelProvider(TestCase):
 | 
						|
    API_URL = 'https://api.selectel.ru/domains/v1'
 | 
						|
 | 
						|
    api_record = []
 | 
						|
 | 
						|
    zone = Zone('unit.tests.', [])
 | 
						|
    expected = set()
 | 
						|
 | 
						|
    domain = [{"name": "unit.tests", "id": 100000}]
 | 
						|
 | 
						|
    # A, subdomain=''
 | 
						|
    api_record.append({
 | 
						|
        'type': 'A',
 | 
						|
        'ttl': 100,
 | 
						|
        'content': '1.2.3.4',
 | 
						|
        'name': 'unit.tests',
 | 
						|
        'id': 1
 | 
						|
    })
 | 
						|
    expected.add(Record.new(zone, '', {
 | 
						|
        'ttl': 100,
 | 
						|
        'type': 'A',
 | 
						|
        'value': '1.2.3.4',
 | 
						|
    }))
 | 
						|
 | 
						|
    # A, subdomain='sub'
 | 
						|
    api_record.append({
 | 
						|
        'type': 'A',
 | 
						|
        'ttl': 200,
 | 
						|
        'content': '1.2.3.4',
 | 
						|
        'name': 'sub.unit.tests',
 | 
						|
        'id': 2
 | 
						|
    })
 | 
						|
    expected.add(Record.new(zone, 'sub', {
 | 
						|
        'ttl': 200,
 | 
						|
        'type': 'A',
 | 
						|
        'value': '1.2.3.4',
 | 
						|
    }))
 | 
						|
 | 
						|
    # CNAME
 | 
						|
    api_record.append({
 | 
						|
        'type': 'CNAME',
 | 
						|
        'ttl': 300,
 | 
						|
        'content': 'unit.tests',
 | 
						|
        'name': 'www2.unit.tests',
 | 
						|
        'id': 3
 | 
						|
    })
 | 
						|
    expected.add(Record.new(zone, 'www2', {
 | 
						|
        'ttl': 300,
 | 
						|
        'type': 'CNAME',
 | 
						|
        'value': 'unit.tests.',
 | 
						|
    }))
 | 
						|
 | 
						|
    # MX
 | 
						|
    api_record.append({
 | 
						|
        'type': 'MX',
 | 
						|
        'ttl': 400,
 | 
						|
        'content': 'mx1.unit.tests',
 | 
						|
        'priority': 10,
 | 
						|
        'name': 'unit.tests',
 | 
						|
        'id': 4
 | 
						|
    })
 | 
						|
    expected.add(Record.new(zone, '', {
 | 
						|
        'ttl': 400,
 | 
						|
        'type': 'MX',
 | 
						|
        'values': [{
 | 
						|
            'preference': 10,
 | 
						|
            'exchange': 'mx1.unit.tests.',
 | 
						|
        }]
 | 
						|
    }))
 | 
						|
 | 
						|
    # NS
 | 
						|
    api_record.append({
 | 
						|
        'type': 'NS',
 | 
						|
        'ttl': 600,
 | 
						|
        'content': 'ns1.unit.tests',
 | 
						|
        'name': 'unit.tests.',
 | 
						|
        'id': 6
 | 
						|
    })
 | 
						|
    api_record.append({
 | 
						|
        'type': 'NS',
 | 
						|
        'ttl': 600,
 | 
						|
        'content': 'ns2.unit.tests',
 | 
						|
        'name': 'unit.tests',
 | 
						|
        'id': 7
 | 
						|
    })
 | 
						|
    expected.add(Record.new(zone, '', {
 | 
						|
        'ttl': 600,
 | 
						|
        'type': 'NS',
 | 
						|
        'values': ['ns1.unit.tests.', 'ns2.unit.tests.'],
 | 
						|
    }))
 | 
						|
 | 
						|
    # NS with sub
 | 
						|
    api_record.append({
 | 
						|
        'type': 'NS',
 | 
						|
        'ttl': 700,
 | 
						|
        'content': 'ns3.unit.tests',
 | 
						|
        'name': 'www3.unit.tests',
 | 
						|
        'id': 8
 | 
						|
    })
 | 
						|
    api_record.append({
 | 
						|
        'type': 'NS',
 | 
						|
        'ttl': 700,
 | 
						|
        'content': 'ns4.unit.tests',
 | 
						|
        'name': 'www3.unit.tests',
 | 
						|
        'id': 9
 | 
						|
    })
 | 
						|
    expected.add(Record.new(zone, 'www3', {
 | 
						|
        'ttl': 700,
 | 
						|
        'type': 'NS',
 | 
						|
        'values': ['ns3.unit.tests.', 'ns4.unit.tests.'],
 | 
						|
    }))
 | 
						|
 | 
						|
    # SRV
 | 
						|
    api_record.append({
 | 
						|
        'type': 'SRV',
 | 
						|
        'ttl': 800,
 | 
						|
        'target': 'foo-1.unit.tests',
 | 
						|
        'weight': 20,
 | 
						|
        'priority': 10,
 | 
						|
        'port': 30,
 | 
						|
        'id': 10,
 | 
						|
        'name': '_srv._tcp.unit.tests'
 | 
						|
    })
 | 
						|
    api_record.append({
 | 
						|
        'type': 'SRV',
 | 
						|
        'ttl': 800,
 | 
						|
        'target': 'foo-2.unit.tests',
 | 
						|
        'name': '_srv._tcp.unit.tests',
 | 
						|
        'weight': 50,
 | 
						|
        'priority': 40,
 | 
						|
        'port': 60,
 | 
						|
        'id': 11
 | 
						|
    })
 | 
						|
    expected.add(Record.new(zone, '_srv._tcp', {
 | 
						|
        'ttl': 800,
 | 
						|
        'type': 'SRV',
 | 
						|
        'values': [{
 | 
						|
            'priority': 10,
 | 
						|
            'weight': 20,
 | 
						|
            'port': 30,
 | 
						|
            'target': 'foo-1.unit.tests.',
 | 
						|
        }, {
 | 
						|
            'priority': 40,
 | 
						|
            'weight': 50,
 | 
						|
            'port': 60,
 | 
						|
            'target': 'foo-2.unit.tests.',
 | 
						|
        }]
 | 
						|
    }))
 | 
						|
 | 
						|
    # AAAA
 | 
						|
    aaaa_record = {
 | 
						|
        'type': 'AAAA',
 | 
						|
        'ttl': 200,
 | 
						|
        'content': '1:1ec:1::1',
 | 
						|
        'name': 'unit.tests',
 | 
						|
        'id': 15
 | 
						|
    }
 | 
						|
    api_record.append(aaaa_record)
 | 
						|
    expected.add(Record.new(zone, '', {
 | 
						|
        'ttl': 200,
 | 
						|
        'type': 'AAAA',
 | 
						|
        'value': '1:1ec:1::1',
 | 
						|
    }))
 | 
						|
 | 
						|
    # TXT
 | 
						|
    api_record.append({
 | 
						|
        'type': 'TXT',
 | 
						|
        'ttl': 300,
 | 
						|
        'content': 'little text',
 | 
						|
        'name': 'text.unit.tests',
 | 
						|
        'id': 16
 | 
						|
    })
 | 
						|
    expected.add(Record.new(zone, 'text', {
 | 
						|
        'ttl': 200,
 | 
						|
        'type': 'TXT',
 | 
						|
        'value': 'little text',
 | 
						|
    }))
 | 
						|
 | 
						|
    @requests_mock.Mocker()
 | 
						|
    def test_populate(self, fake_http):
 | 
						|
        zone = Zone('unit.tests.', [])
 | 
						|
        fake_http.get('{}/unit.tests/records/'.format(self.API_URL),
 | 
						|
                      json=self.api_record)
 | 
						|
        fake_http.get('{}/'.format(self.API_URL), json=self.domain)
 | 
						|
        fake_http.head('{}/unit.tests/records/'.format(self.API_URL),
 | 
						|
                       headers={'X-Total-Count': str(len(self.api_record))})
 | 
						|
        fake_http.head('{}/'.format(self.API_URL),
 | 
						|
                       headers={'X-Total-Count': str(len(self.domain))})
 | 
						|
 | 
						|
        provider = SelectelProvider(123, 'secret_token')
 | 
						|
        provider.populate(zone)
 | 
						|
 | 
						|
        self.assertEquals(self.expected, zone.records)
 | 
						|
 | 
						|
    @requests_mock.Mocker()
 | 
						|
    def test_populate_invalid_record(self, fake_http):
 | 
						|
        more_record = self.api_record
 | 
						|
        more_record.append({"name": "unit.tests",
 | 
						|
                            "id": 100001,
 | 
						|
                            "content": "support.unit.tests.",
 | 
						|
                            "ttl": 300, "ns": "ns1.unit.tests",
 | 
						|
                            "type": "SOA",
 | 
						|
                            "email": "support@unit.tests"})
 | 
						|
 | 
						|
        zone = Zone('unit.tests.', [])
 | 
						|
        fake_http.get('{}/unit.tests/records/'.format(self.API_URL),
 | 
						|
                      json=more_record)
 | 
						|
        fake_http.get('{}/'.format(self.API_URL), json=self.domain)
 | 
						|
        fake_http.head('{}/unit.tests/records/'.format(self.API_URL),
 | 
						|
                       headers={'X-Total-Count': str(len(self.api_record))})
 | 
						|
        fake_http.head('{}/'.format(self.API_URL),
 | 
						|
                       headers={'X-Total-Count': str(len(self.domain))})
 | 
						|
 | 
						|
        zone.add_record(Record.new(self.zone, 'unsup', {
 | 
						|
            'ttl': 200,
 | 
						|
            'type': 'NAPTR',
 | 
						|
            'value': {
 | 
						|
                'order': 40,
 | 
						|
                'preference': 70,
 | 
						|
                'flags': 'U',
 | 
						|
                'service': 'SIP+D2U',
 | 
						|
                'regexp': '!^.*$!sip:info@bar.example.com!',
 | 
						|
                'replacement': '.',
 | 
						|
            }
 | 
						|
        }))
 | 
						|
 | 
						|
        provider = SelectelProvider(123, 'secret_token')
 | 
						|
        provider.populate(zone)
 | 
						|
 | 
						|
        self.assertNotEqual(self.expected, zone.records)
 | 
						|
 | 
						|
    @requests_mock.Mocker()
 | 
						|
    def test_apply(self, fake_http):
 | 
						|
 | 
						|
        fake_http.get('{}/unit.tests/records/'.format(self.API_URL),
 | 
						|
                      json=list())
 | 
						|
        fake_http.get('{}/'.format(self.API_URL), json=self.domain)
 | 
						|
        fake_http.head('{}/unit.tests/records/'.format(self.API_URL),
 | 
						|
                       headers={'X-Total-Count': '0'})
 | 
						|
        fake_http.head('{}/'.format(self.API_URL),
 | 
						|
                       headers={'X-Total-Count': str(len(self.domain))})
 | 
						|
        fake_http.post('{}/100000/records/'.format(self.API_URL), json=list())
 | 
						|
 | 
						|
        provider = SelectelProvider(123, 'test_token')
 | 
						|
 | 
						|
        zone = Zone('unit.tests.', [])
 | 
						|
 | 
						|
        for record in self.expected:
 | 
						|
            zone.add_record(record)
 | 
						|
 | 
						|
        plan = provider.plan(zone)
 | 
						|
        self.assertEquals(8, len(plan.changes))
 | 
						|
        self.assertEquals(8, provider.apply(plan))
 | 
						|
 | 
						|
    @requests_mock.Mocker()
 | 
						|
    def test_domain_list(self, fake_http):
 | 
						|
        fake_http.get('{}/'.format(self.API_URL), json=self.domain)
 | 
						|
        fake_http.head('{}/'.format(self.API_URL),
 | 
						|
                       headers={'X-Total-Count': str(len(self.domain))})
 | 
						|
 | 
						|
        expected = {'unit.tests': self.domain[0]}
 | 
						|
        provider = SelectelProvider(123, 'test_token')
 | 
						|
 | 
						|
        result = provider.domain_list()
 | 
						|
        self.assertEquals(result, expected)
 | 
						|
 | 
						|
    @requests_mock.Mocker()
 | 
						|
    def test_authentication_fail(self, fake_http):
 | 
						|
        fake_http.get('{}/'.format(self.API_URL), status_code=401)
 | 
						|
        fake_http.head('{}/'.format(self.API_URL),
 | 
						|
                       headers={'X-Total-Count': str(len(self.domain))})
 | 
						|
 | 
						|
        with self.assertRaises(Exception) as ctx:
 | 
						|
            SelectelProvider(123, 'fail_token')
 | 
						|
        self.assertEquals(text_type(ctx.exception),
 | 
						|
                          'Authorization failed. Invalid or empty token.')
 | 
						|
 | 
						|
    @requests_mock.Mocker()
 | 
						|
    def test_not_exist_domain(self, fake_http):
 | 
						|
        fake_http.get('{}/'.format(self.API_URL), status_code=404, json='')
 | 
						|
        fake_http.head('{}/'.format(self.API_URL),
 | 
						|
                       headers={'X-Total-Count': str(len(self.domain))})
 | 
						|
 | 
						|
        fake_http.post('{}/'.format(self.API_URL),
 | 
						|
                       json={"name": "unit.tests",
 | 
						|
                             "create_date": 1507154178,
 | 
						|
                             "id": 100000})
 | 
						|
        fake_http.get('{}/unit.tests/records/'.format(self.API_URL),
 | 
						|
                      json=list())
 | 
						|
        fake_http.head('{}/unit.tests/records/'.format(self.API_URL),
 | 
						|
                       headers={'X-Total-Count': str(len(self.api_record))})
 | 
						|
        fake_http.post('{}/100000/records/'.format(self.API_URL),
 | 
						|
                       json=list())
 | 
						|
 | 
						|
        provider = SelectelProvider(123, 'test_token')
 | 
						|
 | 
						|
        zone = Zone('unit.tests.', [])
 | 
						|
 | 
						|
        for record in self.expected:
 | 
						|
            zone.add_record(record)
 | 
						|
 | 
						|
        plan = provider.plan(zone)
 | 
						|
        self.assertEquals(8, len(plan.changes))
 | 
						|
        self.assertEquals(8, provider.apply(plan))
 | 
						|
 | 
						|
    @requests_mock.Mocker()
 | 
						|
    def test_delete_no_exist_record(self, fake_http):
 | 
						|
        fake_http.get('{}/'.format(self.API_URL), json=self.domain)
 | 
						|
        fake_http.get('{}/100000/records/'.format(self.API_URL), json=list())
 | 
						|
        fake_http.head('{}/'.format(self.API_URL),
 | 
						|
                       headers={'X-Total-Count': str(len(self.domain))})
 | 
						|
        fake_http.head('{}/unit.tests/records/'.format(self.API_URL),
 | 
						|
                       headers={'X-Total-Count': '0'})
 | 
						|
 | 
						|
        provider = SelectelProvider(123, 'test_token')
 | 
						|
 | 
						|
        zone = Zone('unit.tests.', [])
 | 
						|
 | 
						|
        provider.delete_record('unit.tests', 'NS', zone)
 | 
						|
 | 
						|
    @requests_mock.Mocker()
 | 
						|
    def test_change_record(self, fake_http):
 | 
						|
        exist_record = [self.aaaa_record,
 | 
						|
                        {"content": "6.6.5.7",
 | 
						|
                         "ttl": 100,
 | 
						|
                         "type": "A",
 | 
						|
                         "id": 100001,
 | 
						|
                         "name": "delete.unit.tests"},
 | 
						|
                        {"content": "9.8.2.1",
 | 
						|
                         "ttl": 100,
 | 
						|
                         "type": "A",
 | 
						|
                         "id": 100002,
 | 
						|
                         "name": "unit.tests"}]  # exist
 | 
						|
        fake_http.get('{}/unit.tests/records/'.format(self.API_URL),
 | 
						|
                      json=exist_record)
 | 
						|
        fake_http.get('{}/'.format(self.API_URL), json=self.domain)
 | 
						|
        fake_http.get('{}/100000/records/'.format(self.API_URL),
 | 
						|
                      json=exist_record)
 | 
						|
        fake_http.head('{}/unit.tests/records/'.format(self.API_URL),
 | 
						|
                       headers={'X-Total-Count': str(len(exist_record))})
 | 
						|
        fake_http.head('{}/'.format(self.API_URL),
 | 
						|
                       headers={'X-Total-Count': str(len(self.domain))})
 | 
						|
        fake_http.head('{}/100000/records/'.format(self.API_URL),
 | 
						|
                       headers={'X-Total-Count': str(len(exist_record))})
 | 
						|
        fake_http.post('{}/100000/records/'.format(self.API_URL),
 | 
						|
                       json=list())
 | 
						|
        fake_http.delete('{}/100000/records/100001'.format(self.API_URL),
 | 
						|
                         text="")
 | 
						|
        fake_http.delete('{}/100000/records/100002'.format(self.API_URL),
 | 
						|
                         text="")
 | 
						|
 | 
						|
        provider = SelectelProvider(123, 'test_token')
 | 
						|
 | 
						|
        zone = Zone('unit.tests.', [])
 | 
						|
 | 
						|
        for record in self.expected:
 | 
						|
            zone.add_record(record)
 | 
						|
 | 
						|
        plan = provider.plan(zone)
 | 
						|
        self.assertEquals(8, len(plan.changes))
 | 
						|
        self.assertEquals(8, provider.apply(plan))
 | 
						|
 | 
						|
    @requests_mock.Mocker()
 | 
						|
    def test_include_change_returns_false(self, fake_http):
 | 
						|
        fake_http.get('{}/'.format(self.API_URL), json=self.domain)
 | 
						|
        fake_http.head('{}/'.format(self.API_URL),
 | 
						|
                       headers={'X-Total-Count': str(len(self.domain))})
 | 
						|
        provider = SelectelProvider(123, 'test_token')
 | 
						|
        zone = Zone('unit.tests.', [])
 | 
						|
 | 
						|
        exist_record = Record.new(zone, '', {
 | 
						|
            'ttl': 60,
 | 
						|
            'type': 'A',
 | 
						|
            'values': ['1.1.1.1', '2.2.2.2']
 | 
						|
        })
 | 
						|
        new = Record.new(zone, '', {
 | 
						|
            'ttl': 10,
 | 
						|
            'type': 'A',
 | 
						|
            'values': ['1.1.1.1', '2.2.2.2']
 | 
						|
        })
 | 
						|
        change = Update(exist_record, new)
 | 
						|
 | 
						|
        include_change = provider._include_change(change)
 | 
						|
 | 
						|
        self.assertFalse(include_change)
 |