Fix Trove CI failure

- Remove Designate v1 support. python-designateclient removed v1 support
  in
  093d8d7170
- Fix get port IP address error in devstack script.

Change-Id: I08916ddfba85c0218aeab5bfbad58ce3222521f3
This commit is contained in:
Lingxian Kong 2019-09-17 11:08:00 +12:00
parent b43248be79
commit f771e939eb
3 changed files with 75 additions and 235 deletions

View File

@ -285,6 +285,8 @@ EOF
# install_trove() - Collect source and prepare
function install_trove {
install_package jq
echo "Changing stack user sudoers"
echo "stack ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/60_stack_sh_allow_all
@ -541,6 +543,79 @@ manage_etc_hosts: "localhost"
EOF
}
# Set up Trove management network and make configuration change.
function config_trove_network {
echo "Finalizing Neutron networking for Trove"
echo "Dumping current network parameters:"
echo " SERVICE_HOST: $SERVICE_HOST"
echo " BRIDGE_IP: $BRIDGE_IP"
echo " PUBLIC_NETWORK_GATEWAY: $PUBLIC_NETWORK_GATEWAY"
echo " NETWORK_GATEWAY: $NETWORK_GATEWAY"
echo " IPV4_ADDRS_SAFE_TO_USE: $IPV4_ADDRS_SAFE_TO_USE"
echo " IPV6_ADDRS_SAFE_TO_USE: $IPV6_ADDRS_SAFE_TO_USE"
echo " FIXED_RANGE: $FIXED_RANGE"
echo " FLOATING_RANGE: $FLOATING_RANGE"
echo " SUBNETPOOL_PREFIX_V4: $SUBNETPOOL_PREFIX_V4"
echo " SUBNETPOOL_SIZE_V4: $SUBNETPOOL_SIZE_V4"
echo " SUBNETPOOL_V4_ID: $SUBNETPOOL_V4_ID"
echo " ROUTER_GW_IP: $ROUTER_GW_IP"
echo " TROVE_MGMT_SUBNET_RANGE: ${TROVE_MGMT_SUBNET_RANGE}"
# Save xtrace setting
local XTRACE
XTRACE=$(set +o | grep xtrace)
set -x
echo "Creating Trove management network/subnet for Trove service project."
trove_service_project_id=$(openstack project show $SERVICE_PROJECT_NAME -c id -f value)
setup_mgmt_network ${trove_service_project_id} ${TROVE_MGMT_NETWORK_NAME} ${TROVE_MGMT_SUBNET_NAME} ${TROVE_MGMT_SUBNET_RANGE}
mgmt_net_id=$(openstack network show ${TROVE_MGMT_NETWORK_NAME} -c id -f value)
echo "Created Trove management network ${TROVE_MGMT_NETWORK_NAME}(${mgmt_net_id})"
# Share the private network to other projects for testing purpose. We make
# the private network accessible to control plane below so that we could
# reach the private network for integration tests without floating ips
# associated, no matter which user the tests are using.
shared=$(openstack network show ${PRIVATE_NETWORK_NAME} -c shared -f value)
if [[ "$shared" == "False" ]]; then
openstack network set ${PRIVATE_NETWORK_NAME} --share
fi
sudo ip route replace ${IPV4_ADDRS_SAFE_TO_USE} via $ROUTER_GW_IP
# Make sure we can reach the management port of the service VM, this
# configuration is only for testing purpose. In production, it's
# recommended to config the router in the cloud infrastructure for the
# communication between Trove control plane and service VMs.
INTERFACE=trove-mgmt
MGMT_PORT_ID=$(openstack port create --project ${trove_service_project_id} --security-group ${TROVE_MGMT_SECURITY_GROUP} --device-owner trove --network ${TROVE_MGMT_NETWORK_NAME} --host=$(hostname) -c id -f value ${INTERFACE}-port)
MGMT_PORT_MAC=$(openstack port show -c mac_address -f value $MGMT_PORT_ID)
MGMT_PORT_IP=$(openstack port show -f value -c fixed_ips $MGMT_PORT_ID)
MGMT_PORT_IP=${MGMT_PORT_IP//u\'/\'}
MGMT_PORT_IP=$(echo ${MGMT_PORT_IP//\'/\"} | jq -r '.[0].ip_address')
sudo ovs-vsctl -- --may-exist add-port ${OVS_BRIDGE:-br-int} $INTERFACE -- set Interface $INTERFACE type=internal -- set Interface $INTERFACE external-ids:iface-status=active -- set Interface $INTERFACE external-ids:attached-mac=$MGMT_PORT_MAC -- set Interface $INTERFACE external-ids:iface-id=$MGMT_PORT_ID -- set Interface $INTERFACE external-ids:skip_cleanup=true
sudo ip link set dev $INTERFACE address $MGMT_PORT_MAC
mask=$(echo ${TROVE_MGMT_SUBNET_RANGE} | awk -F'/' '{print $2}')
sudo ip addr add ${MGMT_PORT_IP}/${mask} dev $INTERFACE
sudo ip link set $INTERFACE up
echo "Neutron network list:"
openstack network list
echo "Neutron subnet list:"
openstack subnet list
echo "ip route:"
sudo ip route
# Now make sure the conf settings are right
iniset $TROVE_CONF DEFAULT network_label_regex ${PRIVATE_NETWORK_NAME}
iniset $TROVE_CONF DEFAULT ip_regex ""
iniset $TROVE_CONF DEFAULT black_list_regex ""
iniset $TROVE_CONF DEFAULT management_networks ${mgmt_net_id}
iniset $TROVE_CONF DEFAULT network_driver trove.network.neutron.NeutronDriver
# Restore xtrace setting
$XTRACE
}
function config_nova_keypair {
export SSH_DIR=${SSH_DIR:-"$HOME/.ssh"}

View File

@ -21,7 +21,6 @@ import base64
import hashlib
from designateclient import client
from designateclient.v1.records import Record
from keystoneauth1 import loading
from keystoneauth1 import session
from oslo_log import log as logging
@ -38,9 +37,6 @@ CONF = cfg.CONF
DNS_TENANT_ID = CONF.dns_account_id
DNS_AUTH_URL = CONF.dns_auth_url
DNS_ENDPOINT_URL = CONF.dns_endpoint_url
DNS_SERVICE_TYPE = CONF.dns_service_type
DNS_REGION = CONF.dns_region
DNS_USERNAME = CONF.dns_username
DNS_PASSKEY = CONF.dns_passkey
DNS_TTL = CONF.dns_ttl
@ -52,18 +48,6 @@ DNS_PROJECT_DOMAIN_ID = CONF.dns_project_domain_id
LOG = logging.getLogger(__name__)
class DesignateObjectConverter(object):
@staticmethod
def domain_to_zone(domain):
return DesignateDnsZone(id=domain.id, name=domain.name)
def record_to_entry(self, record, dns_zone):
return driver.DnsEntry(name=record.name, content=record.data,
type=record.type, ttl=record.ttl,
priority=record.priority, dns_zone=dns_zone)
def create_designate_client(api_version='2'):
"""Creates a Designate DNSaaS client."""
loader = loading.get_plugin_loader('password')
@ -77,74 +61,6 @@ def create_designate_client(api_version='2'):
return client.Client(api_version, session=sesh)
class DesignateDriver(driver.DnsDriver):
def __init__(self):
self.dns_client = create_designate_client(api_version='1')
self.converter = DesignateObjectConverter()
self.default_dns_zone = DesignateDnsZone(id=DNS_DOMAIN_ID,
name=DNS_DOMAIN_NAME)
def create_entry(self, entry, content):
"""Creates the entry in the driver at the given dns zone."""
dns_zone = entry.dns_zone or self.default_dns_zone
if not dns_zone.id:
raise TypeError(_("The entry's dns_zone must have an ID "
"specified."))
name = entry.name
LOG.debug("Creating DNS entry %s.", name)
client = self.dns_client
# Record name has to end with a '.' by dns standard
record = Record(name=entry.name + '.',
type=entry.type,
data=content,
ttl=entry.ttl,
priority=entry.priority)
client.records.create(dns_zone.id, record)
def delete_entry(self, name, type, dns_zone=None):
"""Deletes an entry with the given name and type from a dns zone."""
dns_zone = dns_zone or self.default_dns_zone
records = self._get_records(dns_zone)
matching_record = [rec for rec in records
if rec.name == name + '.' and rec.type == type]
if not matching_record:
raise exception.DnsRecordNotFound(name=name)
LOG.debug("Deleting DNS entry %s.", name)
self.dns_client.records.delete(dns_zone.id, matching_record[0].id)
def get_entries_by_content(self, content, dns_zone=None):
"""Retrieves all entries in a DNS zone with matching content field."""
records = self._get_records(dns_zone)
return [self.converter.record_to_entry(record, dns_zone)
for record in records if record.data == content]
def get_entries_by_name(self, name, dns_zone):
records = self._get_records(dns_zone)
return [self.converter.record_to_entry(record, dns_zone)
for record in records if record.name == name]
def get_dns_zones(self, name=None):
"""Returns all dns zones (optionally filtered by the name argument."""
domains = self.dns_client.domains.list()
return [self.converter.domain_to_zone(domain)
for domain in domains if not name or domain.name == name]
def modify_content(self, name, content, dns_zone):
# We dont need this in trove for now
raise NotImplementedError(_("Not implemented for Designate DNS."))
def rename_entry(self, content, name, dns_zone):
# We dont need this in trove for now
raise NotImplementedError(_("Not implemented for Designate DNS."))
def _get_records(self, dns_zone):
dns_zone = dns_zone or self.default_dns_zone
if not dns_zone:
raise TypeError(_('DNS domain is must be specified'))
return self.dns_client.records.list(dns_zone.id)
class DesignateDriverV2(driver.DnsDriver):
def __init__(self):

View File

@ -14,8 +14,6 @@
import base64
import hashlib
from designateclient.v1.domains import Domain
from designateclient.v1.records import Record
from mock import MagicMock
from mock import patch
import six
@ -26,155 +24,6 @@ from trove.dns import driver as base_driver
from trove.tests.unittests import trove_testtools
class DesignateObjectConverterTest(trove_testtools.TestCase):
def setUp(self):
super(DesignateObjectConverterTest, self).setUp()
def tearDown(self):
super(DesignateObjectConverterTest, self).tearDown()
def test_convert_domain_to_zone(self):
name = 'www.example.com'
id = '39413651-3b9e-41f1-a4df-e47d5e9f67be'
email = 'john.smith@openstack.com'
domain = Domain(name=name, id=id, email=email)
converter = driver.DesignateObjectConverter()
converted_domain = converter.domain_to_zone(domain)
self.assertEqual(name, converted_domain.name)
self.assertEqual(id, converted_domain.id)
def test_convert_record_to_entry(self):
name = 'test.example.com'
id = '4f3439ef-fc8b-4098-a1aa-a66ed01102b9'
domain_id = '39413651-3b9e-41f1-a4df-e47d5e9f67be'
domain_name = 'example.com'
type = 'CNAME'
data = '127.0.0.1'
ttl = 3600
priority = 1
zone = driver.DesignateDnsZone(domain_id, domain_name)
record = Record(name=name, id=id, domain_id=domain_id, type=type,
data=data, priority=priority, ttl=ttl)
converter = driver.DesignateObjectConverter()
converted_record = converter.record_to_entry(record, zone)
self.assertEqual(name, converted_record.name)
self.assertEqual(data, converted_record.content)
self.assertEqual(type, converted_record.type)
self.assertEqual(priority, converted_record.priority)
self.assertEqual(ttl, converted_record.ttl)
self.assertEqual(zone, converted_record.dns_zone)
class DesignateDriverTest(trove_testtools.TestCase):
def setUp(self):
super(DesignateDriverTest, self).setUp()
self.domains = [Domain(name='www.example.com',
id='11111111-1111-1111-1111-111111111111',
email='test@example.com'),
Domain(name='www.trove.com',
id='22222222-2222-2222-2222-222222222222',
email='test@trove.com'),
Domain(name='www.openstack.com',
id='33333333-3333-3333-3333-333333333333',
email='test@openstack.com')]
self.records = [Record(name='record1', type='A', data='10.0.0.1',
ttl=3600, priority=1),
Record(name='record2', type='CNAME', data='10.0.0.2',
ttl=1800, priority=2),
Record(name='record3', type='A', data='10.0.0.3',
ttl=3600, priority=1)]
self.create_des_client_patch = patch.object(
driver, 'create_designate_client', MagicMock(return_value=None))
self.create_des_client_mock = self.create_des_client_patch.start()
self.addCleanup(self.create_des_client_patch.stop)
def tearDown(self):
super(DesignateDriverTest, self).tearDown()
def test_get_entries_by_name(self):
zone = driver.DesignateDnsZone('123', 'www.example.com')
with patch.object(driver.DesignateDriver, '_get_records',
MagicMock(return_value=self.records)):
dns_driver = driver.DesignateDriver()
entries = dns_driver.get_entries_by_name('record2', zone)
self.assertEqual(1, len(entries), 'More than one record found')
entry = entries[0]
self.assertEqual('record2', entry.name)
self.assertEqual('CNAME', entry.type)
self.assertEqual('10.0.0.2', entry.content)
self.assertEqual(1800, entry.ttl)
self.assertEqual(2, entry.priority)
zone = entry.dns_zone
self.assertEqual('123', zone.id)
self.assertEqual('www.example.com', zone.name)
def test_get_entries_by_name_not_found(self):
zone = driver.DesignateDnsZone('123', 'www.example.com')
with patch.object(driver.DesignateDriver, '_get_records',
MagicMock(return_value=self.records)):
dns_driver = driver.DesignateDriver()
entries = dns_driver.get_entries_by_name('record_not_found', zone)
self.assertEqual(0, len(entries), 'Some records were returned')
def test_get_entries_by_content(self):
zone = driver.DesignateDnsZone('123', 'www.example.com')
with patch.object(driver.DesignateDriver, '_get_records',
MagicMock(return_value=self.records)):
dns_driver = driver.DesignateDriver()
entries = dns_driver.get_entries_by_content('10.0.0.1', zone)
self.assertEqual(1, len(entries), 'More than one record found')
entry = entries[0]
self.assertEqual('record1', entry.name)
self.assertEqual('A', entry.type)
self.assertEqual('10.0.0.1', entry.content)
self.assertEqual(3600, entry.ttl)
self.assertEqual(1, entry.priority)
zone = entry.dns_zone
self.assertEqual('123', zone.id)
self.assertEqual('www.example.com', zone.name)
def test_get_entries_by_content_not_found(self):
zone = driver.DesignateDnsZone('123', 'www.example.com')
with patch.object(driver.DesignateDriver, '_get_records',
MagicMock(return_value=self.records)):
dns_driver = driver.DesignateDriver()
entries = dns_driver.get_entries_by_content('127.0.0.1', zone)
self.assertEqual(0, len(entries), 'Some records were returned')
def test_get_dnz_zones(self):
client = MagicMock()
self.create_des_client_mock.return_value = client
client.domains.list = MagicMock(return_value=self.domains)
dns_driver = driver.DesignateDriver()
zones = dns_driver.get_dns_zones()
self.assertEqual(3, len(zones))
for x in range(0, 3):
self.assertDomainsAreEqual(self.domains[x], zones[x])
def test_get_dnz_zones_by_name(self):
client = MagicMock()
self.create_des_client_mock.return_value = client
client.domains.list = MagicMock(return_value=self.domains)
dns_driver = driver.DesignateDriver()
zones = dns_driver.get_dns_zones('www.trove.com')
self.assertEqual(1, len(zones))
self.assertDomainsAreEqual(self.domains[1], zones[0])
def test_get_dnz_zones_not_found(self):
client = MagicMock()
self.create_des_client_mock.return_value = client
client.domains.list = MagicMock(return_value=self.domains)
dns_driver = driver.DesignateDriver()
zones = dns_driver.get_dns_zones('www.notfound.com')
self.assertEqual(0, len(zones))
def assertDomainsAreEqual(self, expected, actual):
self.assertEqual(expected.name, actual.name)
self.assertEqual(expected.id, actual.id)
class DesignateDriverV2Test(trove_testtools.TestCase):
def setUp(self):