Remove designate v1 support

Remove support completely and map the v1 resources to
NoneResource.

Change-Id: I8252e7feb4c1b87497770bf045d844fe5975c2b9
This commit is contained in:
Rabi Mishra 2019-09-20 12:51:28 +05:30
parent 73f2cdef7a
commit a8fba21f23
6 changed files with 18 additions and 331 deletions

View File

@ -14,12 +14,6 @@
from designateclient import client from designateclient import client
from designateclient import exceptions from designateclient import exceptions
try:
from designateclient.v1 import domains
from designateclient.v1 import records
except ImportError:
pass
from heat.common import exception as heat_exception from heat.common import exception as heat_exception
from heat.engine.clients import client_plugin from heat.engine.clients import client_plugin
from heat.engine import constraints from heat.engine import constraints
@ -33,13 +27,9 @@ class DesignateClientPlugin(client_plugin.ClientPlugin):
service_types = [DNS] = ['dns'] service_types = [DNS] = ['dns']
supported_versions = [V1, V2] = ['1', '2'] def _create(self):
default_version = V2
def _create(self, version=default_version):
endpoint_type = self._get_client_option(CLIENT_NAME, 'endpoint_type') endpoint_type = self._get_client_option(CLIENT_NAME, 'endpoint_type')
return client.Client(version=version, return client.Client(version='2',
session=self.context.keystone_session, session=self.context.keystone_session,
endpoint_type=endpoint_type, endpoint_type=endpoint_type,
service_type=self.DNS, service_type=self.DNS,
@ -48,18 +38,6 @@ class DesignateClientPlugin(client_plugin.ClientPlugin):
def is_not_found(self, ex): def is_not_found(self, ex):
return isinstance(ex, exceptions.NotFound) return isinstance(ex, exceptions.NotFound)
def get_domain_id(self, domain_id_or_name):
try:
domain_obj = self.client().domains.get(domain_id_or_name)
return domain_obj.id
except exceptions.NotFound:
for domain in self.client().domains.list():
if domain.name == domain_id_or_name:
return domain.id
raise heat_exception.EntityNotFound(entity='Designate Domain',
name=domain_id_or_name)
def get_zone_id(self, zone_id_or_name): def get_zone_id(self, zone_id_or_name):
client = self.client(version=self.V2) client = self.client(version=self.V2)
try: try:
@ -73,51 +51,6 @@ class DesignateClientPlugin(client_plugin.ClientPlugin):
raise heat_exception.EntityNotFound(entity='Designate Zone', raise heat_exception.EntityNotFound(entity='Designate Zone',
name=zone_id_or_name) name=zone_id_or_name)
def domain_create(self, **kwargs):
domain = domains.Domain(**kwargs)
return self.client().domains.create(domain)
def domain_update(self, **kwargs):
# Designate mandates to pass the Domain object with updated properties
domain = self.client().domains.get(kwargs['id'])
for key in kwargs.keys():
setattr(domain, key, kwargs[key])
return self.client().domains.update(domain)
def record_create(self, **kwargs):
domain_id = self.get_domain_id(kwargs.pop('domain'))
record = records.Record(**kwargs)
return self.client().records.create(domain_id, record)
def record_update(self, **kwargs):
# Designate mandates to pass the Record object with updated properties
domain_id = self.get_domain_id(kwargs.pop('domain'))
record = self.client().records.get(domain_id, kwargs['id'])
for key in kwargs.keys():
setattr(record, key, kwargs[key])
return self.client().records.update(record.domain_id, record)
def record_delete(self, **kwargs):
try:
domain_id = self.get_domain_id(kwargs.pop('domain'))
except heat_exception.EntityNotFound:
return
return self.client().records.delete(domain_id,
kwargs.pop('id'))
def record_show(self, **kwargs):
domain_id = self.get_domain_id(kwargs.pop('domain'))
return self.client().records.get(domain_id,
kwargs.pop('id'))
class DesignateDomainConstraint(constraints.BaseCustomConstraint):
resource_client_name = CLIENT_NAME
resource_getter_name = 'get_domain_id'
class DesignateZoneConstraint(constraints.BaseCustomConstraint): class DesignateZoneConstraint(constraints.BaseCustomConstraint):
resource_client_name = CLIENT_NAME resource_client_name = CLIENT_NAME

View File

@ -10,128 +10,28 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import six
from heat.common.i18n import _ from heat.common.i18n import _
from heat.engine import attributes from heat.engine.resources.openstack.heat import none_resource
from heat.engine import constraints
from heat.engine import properties
from heat.engine import resource
from heat.engine import support from heat.engine import support
class DesignateDomain(resource.Resource): class DesignateDomain(none_resource.NoneResource):
"""Heat Template Resource for Designate Domain. """Heat Template Resource for Designate Domain.
Designate provides DNS-as-a-Service services for OpenStack. So, domain Designate provides DNS-as-a-Service services for OpenStack. So, domain
is a realm with an identification string, unique in DNS. is a realm with an identification string, unique in DNS.
""" """
support_status = support.SupportStatus( support_status = support.SupportStatus(
status=support.HIDDEN, status=support.HIDDEN,
version='10.0.0', version='10.0.0',
message=_('Use OS::Designate::Zone instead.'), message=_('This resource has been removed, use '
'OS::Designate::Zone instead.'),
previous_status=support.SupportStatus( previous_status=support.SupportStatus(
status=support.DEPRECATED, status=support.DEPRECATED,
version='8.0.0', version='8.0.0',
previous_status=support.SupportStatus(version='5.0.0'))) previous_status=support.SupportStatus(version='5.0.0')))
entity = 'domains'
default_client_name = 'designate'
PROPERTIES = (
NAME, TTL, DESCRIPTION, EMAIL
) = (
'name', 'ttl', 'description', 'email'
)
ATTRIBUTES = (
SERIAL,
) = (
'serial',
)
properties_schema = {
# Based on RFC 1035, length of name is set to max of 255
NAME: properties.Schema(
properties.Schema.STRING,
_('Domain name.'),
required=True,
constraints=[constraints.Length(max=255)]
),
# Based on RFC 1035, range for ttl is set to 1 to signed 32 bit number
TTL: properties.Schema(
properties.Schema.INTEGER,
_('Time To Live (Seconds).'),
update_allowed=True,
constraints=[constraints.Range(min=1,
max=2147483647)]
),
# designate mandates to the max length of 160 for description
DESCRIPTION: properties.Schema(
properties.Schema.STRING,
_('Description of domain.'),
update_allowed=True,
constraints=[constraints.Length(max=160)]
),
EMAIL: properties.Schema(
properties.Schema.STRING,
_('Domain email.'),
update_allowed=True,
required=True
)
}
attributes_schema = {
SERIAL: attributes.Schema(
_("DNS domain serial."),
type=attributes.Schema.STRING
),
}
def handle_create(self):
args = dict((k, v) for k, v in six.iteritems(self.properties) if v)
domain = self.client_plugin().domain_create(**args)
self.resource_id_set(domain.id)
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
args = dict()
if prop_diff.get(self.EMAIL):
args['email'] = prop_diff.get(self.EMAIL)
if prop_diff.get(self.TTL):
args['ttl'] = prop_diff.get(self.TTL)
if prop_diff.get(self.DESCRIPTION):
args['description'] = prop_diff.get(self.DESCRIPTION)
if len(args.keys()) > 0:
args['id'] = self.resource_id
self.client_plugin().domain_update(**args)
def _resolve_attribute(self, name):
if self.resource_id is None:
return
if name == self.SERIAL:
domain = self.client().domains.get(self.resource_id)
return domain.serial
# FIXME(kanagaraj-manickam) Remove this method once designate defect
# 1485552 is fixed.
def _show_resource(self):
return dict(self.client().domains.get(self.resource_id).items())
def parse_live_resource_data(self, resource_properties, resource_data):
domain_reality = {}
for key in self.PROPERTIES:
domain_reality.update({key: resource_data.get(key)})
return domain_reality
def resource_mapping(): def resource_mapping():
return { return {

View File

@ -11,16 +11,12 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import six
from heat.common.i18n import _ from heat.common.i18n import _
from heat.engine import constraints from heat.engine.resources.openstack.heat import none_resource
from heat.engine import properties
from heat.engine import resource
from heat.engine import support from heat.engine import support
class DesignateRecord(resource.Resource): class DesignateRecord(none_resource.NoneResource):
"""Heat Template Resource for Designate Record. """Heat Template Resource for Designate Record.
Designate provides DNS-as-a-Service services for OpenStack. Record is Designate provides DNS-as-a-Service services for OpenStack. Record is
@ -31,157 +27,13 @@ class DesignateRecord(resource.Resource):
support_status = support.SupportStatus( support_status = support.SupportStatus(
status=support.HIDDEN, status=support.HIDDEN,
version='10.0.0', version='10.0.0',
message=_('Use OS::Designate::RecordSet instead.'), message=_('This resource has been removed, use '
'OS::Designate::RecordSet instead.'),
previous_status=support.SupportStatus( previous_status=support.SupportStatus(
status=support.DEPRECATED, status=support.DEPRECATED,
version='8.0.0', version='8.0.0',
previous_status=support.SupportStatus(version='5.0.0'))) previous_status=support.SupportStatus(version='5.0.0')))
entity = 'records'
default_client_name = 'designate'
PROPERTIES = (
NAME, TTL, DESCRIPTION, TYPE, DATA, PRIORITY, DOMAIN
) = (
'name', 'ttl', 'description', 'type', 'data', 'priority', 'domain'
)
_ALLOWED_TYPES = (
A, AAAA, CNAME, MX, SRV, TXT, SPF,
NS, PTR, SSHFP, SOA
) = (
'A', 'AAAA', 'CNAME', 'MX', 'SRV', 'TXT', 'SPF',
'NS', 'PTR', 'SSHFP', 'SOA'
)
properties_schema = {
# Based on RFC 1035, length of name is set to max of 255
NAME: properties.Schema(
properties.Schema.STRING,
_('Record name.'),
required=True,
constraints=[constraints.Length(max=255)]
),
# Based on RFC 1035, range for ttl is set to 1 to signed 32 bit number
TTL: properties.Schema(
properties.Schema.INTEGER,
_('Time To Live (Seconds).'),
update_allowed=True,
constraints=[constraints.Range(min=1,
max=2147483647)]
),
# designate mandates to the max length of 160 for description
DESCRIPTION: properties.Schema(
properties.Schema.STRING,
_('Description of record.'),
update_allowed=True,
constraints=[constraints.Length(max=160)]
),
TYPE: properties.Schema(
properties.Schema.STRING,
_('DNS Record type.'),
update_allowed=True,
required=True,
constraints=[constraints.AllowedValues(
_ALLOWED_TYPES
)]
),
DATA: properties.Schema(
properties.Schema.STRING,
_('DNS record data, varies based on the type of record. For more '
'details, please refer rfc 1035.'),
update_allowed=True,
required=True
),
# Based on RFC 1035, range for priority is set to 0 to signed 16 bit
# number
PRIORITY: properties.Schema(
properties.Schema.INTEGER,
_('DNS record priority. It is considered only for MX and SRV '
'types, otherwise, it is ignored.'),
update_allowed=True,
constraints=[constraints.Range(min=0,
max=65536)]
),
DOMAIN: properties.Schema(
properties.Schema.STRING,
_('DNS Domain id or name.'),
required=True,
constraints=[constraints.CustomConstraint('designate.domain')]
),
}
def handle_create(self):
args = dict(
name=self.properties[self.NAME],
type=self.properties[self.TYPE],
description=self.properties[self.DESCRIPTION],
ttl=self.properties[self.TTL],
data=self.properties[self.DATA],
# priority is considered only for MX and SRV record.
priority=(self.properties[self.PRIORITY]
if self.properties[self.TYPE] in (self.MX, self.SRV)
else None),
domain=self.properties[self.DOMAIN]
)
domain = self.client_plugin().record_create(**args)
self.resource_id_set(domain.id)
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
args = dict()
if prop_diff.get(self.TTL):
args['ttl'] = prop_diff.get(self.TTL)
if prop_diff.get(self.DESCRIPTION):
args['description'] = prop_diff.get(self.DESCRIPTION)
if prop_diff.get(self.TYPE):
args['type'] = prop_diff.get(self.TYPE)
# priority is considered only for MX and SRV record.
if prop_diff.get(self.PRIORITY):
args['priority'] = (prop_diff.get(self.PRIORITY)
if (prop_diff.get(self.TYPE) or
self.properties[self.TYPE]) in
(self.MX, self.SRV)
else None)
if prop_diff.get(self.DATA):
args['data'] = prop_diff.get(self.DATA)
if len(args.keys()) > 0:
args['id'] = self.resource_id
args['domain'] = self.properties[self.DOMAIN]
self.client_plugin().record_update(**args)
def handle_delete(self):
if self.resource_id is not None:
with self.client_plugin().ignore_not_found:
self.client_plugin().record_delete(
id=self.resource_id,
domain=self.properties[self.DOMAIN]
)
# FIXME(kanagaraj-manickam) Remove this method once designate defect
# 1485552 is fixed.
def _show_resource(self):
kwargs = dict(domain=self.properties[self.DOMAIN],
id=self.resource_id)
return dict(six.iteritems(self.client_plugin().record_show(**kwargs)))
def parse_live_resource_data(self, resource_properties, resource_data):
record_reality = {}
properties_keys = list(set(self.PROPERTIES) - {self.NAME, self.DOMAIN})
for key in properties_keys:
record_reality.update({key: resource_data.get(key)})
return record_reality
def resource_mapping(): def resource_mapping():
return { return {

View File

@ -1,5 +0,0 @@
---
upgrade:
- |
Designate client already removed support for designate V1. We now switch
default version for designate client plugin from V1 to V2.

View File

@ -0,0 +1,8 @@
---
upgrade:
- |
Designate project had removed v1 api support since stable/queens.
Heat has now removed support for v1 resources ``OS::Designate::Domain``
and ``OS::Designate::Record`` completely and replaced them with
placeholders for existing templates with those resources. The
``designate.domain`` custom constraint has also been removed.

View File

@ -113,7 +113,6 @@ heat.constraints =
cinder.snapshot = heat.engine.clients.os.cinder:VolumeSnapshotConstraint cinder.snapshot = heat.engine.clients.os.cinder:VolumeSnapshotConstraint
cinder.volume = heat.engine.clients.os.cinder:VolumeConstraint cinder.volume = heat.engine.clients.os.cinder:VolumeConstraint
cinder.vtype = heat.engine.clients.os.cinder:VolumeTypeConstraint cinder.vtype = heat.engine.clients.os.cinder:VolumeTypeConstraint
designate.domain = heat.engine.clients.os.designate:DesignateDomainConstraint
designate.zone = heat.engine.clients.os.designate:DesignateZoneConstraint designate.zone = heat.engine.clients.os.designate:DesignateZoneConstraint
glance.image = heat.engine.clients.os.glance:ImageConstraint glance.image = heat.engine.clients.os.glance:ImageConstraint
keystone.domain = heat.engine.clients.os.keystone.keystone_constraints:KeystoneDomainConstraint keystone.domain = heat.engine.clients.os.keystone.keystone_constraints:KeystoneDomainConstraint