def _create_records(self, context, zone_id, dnspython_zone): """ Creates the records """ for record_name in dnspython_zone.nodes.keys(): for rdataset in dnspython_zone.nodes[record_name]: record_type = rdatatype.to_text(rdataset.rdtype) if record_type == 'SOA': continue # Create the recordset values = { 'domain_id': zone_id, 'name': record_name.to_text(), 'type': record_type, } recordset = self.central_api.create_recordset( context, zone_id, RecordSet(**values)) for rdata in rdataset: if (record_type == 'NS' and record_name == dnspython_zone.origin): # Don't create NS records for the domain, they've been # taken care of as servers pass else: # Everything else, including delegation NS, gets # created values = self._record2json(record_type, rdata) self.central_api.create_record(context, zone_id, recordset['id'], Record(**values))
def _create(self, addresses, extra, managed=True, resource_type=None, resource_id=None): """ Create a a record from addresses :param addresses: Address objects like {'version': 4, 'ip': '10.0.0.1'} :param extra: Extra data to use when formatting the record :param managed: Is it a managed resource :param resource_type: The managed resource type :param resource_id: The managed resource ID """ LOG.debug('Using DomainID: %s' % cfg.CONF[self.name].domain_id) domain = self.get_domain(cfg.CONF[self.name].domain_id) LOG.debug('Domain: %r' % domain) data = extra.copy() LOG.debug('Event data: %s' % data) data['domain'] = domain['name'] context = DesignateContext.get_admin_context(all_tenants=True) for addr in addresses: event_data = data.copy() event_data.update(get_ip_data(addr)) recordset_values = { 'domain_id': domain['id'], 'name': self._get_format() % event_data, 'type': 'A' if addr['version'] == 4 else 'AAAA' } recordset = self._find_or_create_recordset(context, **recordset_values) record_values = {'data': addr['address']} if managed: record_values.update({ 'managed': managed, 'managed_plugin_name': self.get_plugin_name(), 'managed_plugin_type': self.get_plugin_type(), 'managed_resource_type': resource_type, 'managed_resource_id': resource_id }) LOG.debug('Creating record in %s / %s with values %r', domain['id'], recordset['id'], record_values) self.central_api.create_record(context, domain['id'], recordset['id'], Record(**record_values))
def _create_record(self, context, format, zone, event_data, addr, managed, resource_type, resource_id): recordset_values = { 'zone_id': zone['id'], 'name': format % event_data, 'type': 'A' if addr['version'] == 4 else 'AAAA' } recordset = self._find_or_create_recordset(context, **recordset_values) record_values = {'data': addr['address']} if managed: record_values.update({ 'managed': managed, 'managed_plugin_name': self.get_plugin_name(), 'managed_plugin_type': self.get_plugin_type(), 'managed_resource_type': resource_type, 'managed_resource_id': resource_id }) LOG.warn('Creating record in %s / %s with values %r', zone['id'], recordset['id'], record_values) central_api.create_record(context, zone['id'], recordset['id'], Record(**record_values))
def _create_reverse_record(self, context, managed, host_fqdn, interface): LOG.info('Create reverse record for interface: %s and address: %s', interface['label'], interface['address']) host_reverse_fqdn = self._get_reverse_fqdn(interface['address'], interface['version']) LOG.info('Create reverse record: %s', host_reverse_fqdn) reverse_domains = self._get_reverse_domains(host_reverse_fqdn) admin_context = DesignateContext.get_admin_context(all_tenants=True) for reverse_domain in reverse_domains: LOG.info('Create reverse record for domain: %s', reverse_domain.name) try: recordset = self.central_api.create_recordset( admin_context, reverse_domain.id, RecordSet(name=host_reverse_fqdn, type='PTR')) except exceptions.DuplicateRecordSet: LOG.warn('The reverse record: %s was already registered', host_reverse_fqdn) else: record_values = dict(managed, data=host_fqdn) LOG.debug('Creating reverse record in %s / %s with values %r', reverse_domain.id, recordset['id'], record_values) self.central_api.create_record(admin_context, reverse_domain.id, recordset['id'], Record(**record_values))
def process_notification(self, context, event_type, payload): # Do something with the notification.. e.g: zone_id = cfg.CONF[self.name].zone_id zone_name = cfg.CONF[self.name].zone_name record_name = '%s.%s' % (payload['instance_id'], zone_name) context = DesignateContext().elevated() context.all_tenants = True # context.edit_managed_records = True for fixed_ip in payload['fixed_ips']: recordset_values = { 'zone_id': zone_id, 'name': record_name, 'type': 'A' if fixed_ip['version'] == 4 else 'AAAA' } record_values = { 'data': fixed_ip['address'], } recordset = self._find_or_create_recordset(context, **recordset_values) self.central_api.create_record(context, zone_id, recordset['id'], Record(**record_values))
def post_all(self, zone_id, recordset_id): """ Create Record """ request = pecan.request response = pecan.response context = request.environ['context'] body = request.body_dict # Validate the request conforms to the schema self._resource_schema.validate(body) # Convert from APIv2 -> Central format values = self._view.load(context, request, body) # Create the records record = self.central_api.create_record(context, zone_id, recordset_id, Record(**values)) # Prepare the response headers if record['status'] == 'PENDING': response.status_int = 202 else: response.status_int = 201 response.headers['Location'] = self._view._get_resource_href( request, record, [zone_id, recordset_id]) # Prepare and return the response body return self._view.show(context, request, record)
def _extract_record_values(values): record_values = ( 'data', 'priority', 'comment', ) return Record(**dict((k, values[k]) for k in record_values if k in values))
def process_notification(self, context, event_type, payload): # Do something with the notification.. e.g: domain_id = cfg.CONF['handler:sample'].domain_id domain_name = cfg.CONF['handler:sample'].domain_name hostname = '%s.%s' % (payload['instance_id'], domain_name) for fixed_ip in payload['fixed_ips']: if fixed_ip['version'] == 4: values = dict(type='A', name=hostname, data=fixed_ip['address']) self.central_api.create_record(domain_id, Record(**values)) elif fixed_ip['version'] == 6: values = dict(type='AAAA', name=hostname, data=fixed_ip['address']) self.central_api.create_record(domain_id, Record(**values))
def _create(self, context, addresses, name_format, extra, domain_id, managed_extra, resource_type, resource_id): """ Create a a record from addresses :param addresses: Address objects like {'version': 4, 'ip': '10.0.0.1'} :param extra: Extra data to use when formatting the record :param resource_type: The managed resource type :param resource_id: The managed resource ID """ data = extra.copy() LOG.debug('Event data: %s' % data) names = [] for addr in addresses: event_data = data.copy() event_data.update(designate.notification_handler.base.get_ip_data(addr)) recordset_values = { 'domain_id': domain_id, 'name': name_format % event_data, 'type': 'A' if addr['version'] == 4 else 'AAAA' } recordset = self._find_or_create_recordset( context, **recordset_values) # If there is any existing A records for this name, then we don't # want to create additional ones, we throw an exception so the # caller can retry if appropriate. if len(recordset.records) > 0: raise CirrusRecordExists('Name already has an A record') record_values = { 'data': addr['address'], 'managed': True, 'managed_plugin_name': self.get_plugin_name(), 'managed_plugin_type': self.get_plugin_type(), 'managed_extra': managed_extra, 'managed_resource_type': resource_type, 'managed_resource_id': resource_id } LOG.debug('Creating record in %s / %s with values %r' % (domain_id, recordset['id'], record_values)) self.central_api.create_record(context, domain_id, recordset['id'], Record(**record_values)) names.append(recordset_values['name']) return names
def _create(self, addresses, extra, zone_id, resource_type=None, resource_id=None): """ Create a record from addresses :param addresses: Address objects like {'version': 4, 'ip': '10.0.0.1'} :param extra: Extra data to use when formatting the record :param zone_id: The ID of the designate zone. :param resource_type: The managed resource type :param resource_id: The managed resource ID """ LOG.debug('Using Zone ID: %s', zone_id) zone = self.get_zone(zone_id) LOG.debug('Domain: %r', zone) data = extra.copy() LOG.debug('Event data: %s', data) data['zone'] = zone['name'] context = DesignateContext().elevated() context.all_tenants = True context.edit_managed_records = True for addr in addresses: event_data = data.copy() event_data.update(self._get_ip_data(addr)) if addr['version'] == 4: format = self._get_formatv4() else: format = self._get_formatv6() for fmt in format: recordset_values = { 'zone_id': zone['id'], 'name': fmt % event_data, 'type': 'A' if addr['version'] == 4 else 'AAAA'} record_values = { 'data': addr['address'], 'managed': True, 'managed_plugin_name': self.get_plugin_name(), 'managed_plugin_type': self.get_plugin_type(), 'managed_resource_type': resource_type, 'managed_resource_id': resource_id } self._create_or_update_recordset( context, [Record(**record_values)], **recordset_values )
def _create_record(self, context, managed, domain, host_fqdn, interface): LOG.info('Create record for host: %s and interface: %s', host_fqdn, interface['label']) recordset_type = 'AAAA' if interface['version'] == 6 else 'A' try: recordset = self.central_api.create_recordset( context, domain['id'], RecordSet(name=host_fqdn, type=recordset_type)) except exceptions.DuplicateRecordSet: LOG.warn('The record: %s was already registered', host_fqdn) else: record_values = dict(managed, data=interface['address']) LOG.debug('Creating record in %s / %s with values %r', domain['id'], recordset['id'], record_values) self.central_api.create_record(context, domain['id'], recordset['id'], Record(**record_values))
def _create_record(self, context, format, zone, event_data, addr, resource_type, resource_id): recordset_values = { 'zone_id': zone['id'], 'name': format % event_data, 'type': 'A' if addr['version'] == 4 else 'AAAA' } record_values = { 'data': addr['address'], 'managed': True, 'managed_plugin_name': self.get_plugin_name(), 'managed_plugin_type': self.get_plugin_type(), 'managed_resource_type': resource_type, 'managed_resource_id': resource_id } LOG.warn('Creating record in %s with values %r', zone['id'], record_values) self._create_or_update_recordset(context, [Record(**record_values)], **recordset_values)
def _create(self, addresses, extra, managed=True, resource_type=None, resource_id=None): """ Create a a record from addresses :param addresses: Address objects like {'version': 4, 'ip': '10.0.0.1'} :param extra: Extra data to use when formatting the record :param managed: Is it a managed resource :param resource_type: The managed resource type :param resource_id: The managed resource ID """ LOG.debug('Using DomainID: %s' % cfg.CONF[self.name].domain_id) domain = self.get_domain(cfg.CONF[self.name].domain_id) LOG.debug('Domain: %r' % domain) data = extra.copy() LOG.debug('Event data: %s' % data) data['domain'] = domain['name'] context = DesignateContext.get_admin_context(all_tenants=True) # Extra magic! The event record contains a tenant id but not a tenant name. So # if our formats include project_name then we need to ask keystone for the name. need_project_name = False for fmt in cfg.CONF[self.name].get('format'): if 'project_name' in fmt: need_project_name = True break if 'project_name' in cfg.CONF[self.name].get('reverse_format'): need_project_name = True if need_project_name: project_name = self._resolve_project_name(data['tenant_id']) data['project_name'] = project_name for addr in addresses: event_data = data.copy() event_data.update(self._get_ip_data(addr)) if addr['version'] == 4: reverse_format = cfg.CONF[self.name].get('reverse_format') reverse_domain_id = cfg.CONF[self.name].get('reverse_domain_id') if reverse_format and reverse_domain_id: reverse_domain = self.get_domain(reverse_domain_id) LOG.debug('Reverse domain: %r' % reverse_domain) ip_digits = addr['address'].split('.') ip_digits.reverse() name = "%s.in-addr.arpa." % '.'.join(ip_digits) recordset_values = { 'domain_id': reverse_domain['id'], 'name': name, 'type': 'PTR', } recordset = self._find_or_create_recordset( context, **recordset_values) record_values = {'data': reverse_format % event_data} if managed: record_values.update({ 'managed': managed, 'managed_plugin_name': self.get_plugin_name(), 'managed_plugin_type': self.get_plugin_type(), 'managed_resource_type': resource_type, 'managed_resource_id': resource_id}) LOG.warn('Creating record in %s / %s with values %r', reverse_domain['id'], recordset['id'], record_values) central_api.create_record(context, reverse_domain['id'], recordset['id'], Record(**record_values)) for fmt in cfg.CONF[self.name].get('format'): recordset_values = { 'domain_id': domain['id'], 'name': fmt % event_data, 'type': 'A' if addr['version'] == 4 else 'AAAA'} recordset = self._find_or_create_recordset( context, **recordset_values) record_values = { 'data': addr['address']} if managed: record_values.update({ 'managed': managed, 'managed_plugin_name': self.get_plugin_name(), 'managed_plugin_type': self.get_plugin_type(), 'managed_resource_type': resource_type, 'managed_resource_id': resource_id}) LOG.warn('Creating record in %s / %s with values %r', domain['id'], recordset['id'], record_values) central_api.create_record(context, domain['id'], recordset['id'], Record(**record_values))
def process_notification(self, context, event_type, payload): LOG.debug('NeutronFloatingHandler: Event type received: %s', event_type) LOG.debug('NeutronFloatingHandler: Event body received: %s', payload) zone_id = cfg.CONF[self.name].zone_id zone = self.get_zone(zone_id) # Get a list all all zones owned by the zone tenant owner. # This is so we can find the reverse DNS zone. elevated_context = DesignateContext.get_admin_context( all_tenants=True, edit_managed_records=True) criterion = { "tenant_id": cfg.CONF[self.name].zone_owner_tenant_id, } zones = self.central_api.find_zones(elevated_context, criterion) if event_type.startswith('floatingip.delete'): self._delete(zone_id=zone_id, resource_id=payload['floatingip_id'], resource_type='instance') elif event_type.startswith('floatingip.update'): floatingip = payload['floatingip']['floating_ip_address'] # Calculate Reverse Address v4address = ipaddress.ip_address(floatingip) reverse_address = v4address.reverse_pointer + '.' reverse_network = '.'.join(reverse_address.split('.')[1:]) reverse_id = None # Loop through all zones and see if one matches the reverse zone reverse_id = None for i in zones: if i.name == reverse_network: reverse_id = i.id if payload['floatingip']['fixed_ip_address']: # Create a nova client username = cfg.CONF[self.name].admin_user password = cfg.CONF[self.name].admin_password tenant_name = cfg.CONF[self.name].admin_tenant_name auth_url = cfg.CONF[self.name].auth_url auth = v3.Password(username=username, password=password, project_name=tenant_name, project_domain_name='default', user_domain_name='default', auth_url=auth_url) sess = session.Session(auth=auth) nvc = nova_c.Client(2.1, session=sess) # Search for an instance with the matching fixed ip search_opts = { 'ip': payload['floatingip']['fixed_ip_address'], 'status': 'ACTIVE', 'all_tenants': True, 'tenant_id': payload['floatingip']['tenant_id'], } instances = nvc.servers.list(detailed=True, search_opts=search_opts) if len(instances) == 1: instance = instances[0] # Get the ec2 id of the instance and build the hostname from it ec2id = getattr(instance, 'OS-EXT-SRV-ATTR:instance_name') ec2id = ec2id.split('-', 1)[1].lstrip('0') hostname = '%s.%s' % (ec2id, zone['name']) # create a recordset record_type = 'A' recordset_values = { 'zone_id': zone_id, 'name': hostname, 'type': record_type } recordset = self._find_or_create_recordset( elevated_context, **recordset_values) record_values = { 'data': floatingip, 'managed': True, 'managed_plugin_name': self.get_plugin_name(), 'managed_plugin_type': self.get_plugin_type(), 'managed_resource_type': 'instance', 'managed_resource_id': payload['floatingip']['id'], 'managed_extra': 'instance:%s' % (getattr(instance, 'id')), } LOG.debug('Creating record in %s / %s with values %r' % (zone_id, recordset['id'], record_values)) self.central_api.create_record(elevated_context, zone_id, recordset['id'], Record(**record_values)) # create a reverse recordset record_type = 'PTR' if reverse_id == None: LOG.debug('UNABLE TO DETERMINE REVERSE ZONE: %s', payload['floatingip']) else: recordset_values = { 'zone_id': reverse_id, 'name': reverse_address, 'type': record_type } recordset = self._find_or_create_recordset( elevated_context, **recordset_values) record_values = { 'data': hostname, 'managed': True, 'managed_plugin_name': self.get_plugin_name(), 'managed_plugin_type': self.get_plugin_type(), 'managed_resource_type': 'instance', 'managed_resource_id': payload['floatingip']['id'], 'managed_extra': 'instance:%s' % (getattr(instance, 'id')), } LOG.debug('Creating record in %s / %s with values %r' % (reverse_id, recordset['id'], record_values)) self.central_api.create_record(elevated_context, reverse_id, recordset['id'], Record(**record_values)) else: LOG.debug('Deleting records for %s / %s' % (zone_id, payload['floatingip']['id'])) self._delete(zone_id=zone_id, resource_id=payload['floatingip']['id'], resource_type='instance') if reverse_id == None: LOG.debug('UNABLE TO DETERMINE REVERSE ZONE: %s', payload['floatingip']) else: LOG.debug('Deleting records for %s / %s' % (reverse_id, payload['floatingip']['id'])) self._delete(zone_id=reverse_id, resource_id=payload['floatingip']['id'], resource_type='instance')
def _create(self, addresses, extra, managed=True, resource_type=None, resource_id=None): """ Create a record from addresses :param addresses: Address objects like {'version': 4, 'ip': '10.0.0.1'} :param extra: Extra data to use when formatting the record :param managed: Is it a managed resource :param resource_type: The managed resource type :param resource_id: The managed resource ID """ LOG.debug('Using DomainID: %s' % cfg.CONF[self.name].domain_id) zone = self.get_zone(cfg.CONF[self.name].domain_id) LOG.debug('Domain: %r' % zone) data = extra.copy() LOG.debug('Event data: %s' % data) data['zone'] = zone['name'] context = DesignateContext.get_admin_context(all_tenants=True) # We have a hack elsewhere in keystone to ensure that tenant id == tenant name. # So... we can safely use the id in the fqdn. data['project_name'] = data['tenant_id'] for addr in addresses: event_data = data.copy() event_data.update(self._get_ip_data(addr)) if addr['version'] == 4: reverse_format = cfg.CONF[self.name].get('reverse_format') reverse_zone_id = cfg.CONF[self.name].get('reverse_domain_id') if reverse_format and reverse_zone_id: reverse_zone = self.get_zone(reverse_zone_id) LOG.debug('Reverse zone: %r' % reverse_zone) ip_digits = addr['address'].split('.') ip_digits.reverse() name = "%s.in-addr.arpa." % '.'.join(ip_digits) recordset_values = { 'zone_id': reverse_zone['id'], 'name': name, 'type': 'PTR', } recordset = self._find_or_create_recordset( context, **recordset_values) record_values = {'data': reverse_format % event_data} if managed: record_values.update({ 'managed': managed, 'managed_plugin_name': self.get_plugin_name(), 'managed_plugin_type': self.get_plugin_type(), 'managed_resource_type': resource_type, 'managed_resource_id': resource_id }) LOG.warn( 'Creating reverse record in %s / %s with values %r', reverse_zone['id'], recordset['id'], record_values) central_api.create_record(context, reverse_zone['id'], recordset['id'], Record(**record_values)) for fmt in cfg.CONF[self.name].get('format'): self._create_record(context, fmt, zone, event_data, addr, managed, resource_type, resource_id) legacy_zone_id = cfg.CONF[self.name].get('legacy_domain_id') if legacy_zone_id: legacy_zone = self.get_zone(legacy_zone_id) event_data['zone'] = legacy_zone['name'] for fmt in cfg.CONF[self.name].get('legacy_format'): self._create_record(context, fmt, legacy_zone, event_data, addr, managed, resource_type, resource_id)
def process_notification(self, context, event_type, payload): LOG.debug('FilteredHandler received notification - %s', event_type) context = DesignateContext().elevated() context.all_tenants = True zone_id = cfg.CONF[self.name].zone_id zone_name = cfg.CONF[self.name].zone_name LOG.debug('FilteredHandler zone_id - %s', zone_id) LOG.debug('FilteredHandler zone_name - %s', zone_name) if event_type == 'compute.instance.create.end': valid_address = lambda x: IP(x) in IP(cfg.CONF[self.name].address_filter) payload['project'] = getattr(context, 'tenant', None) record_name = '%s.%s' % (payload['host'], zone_name) LOG.debug('FilteredHandler record_name - %s', record_name) filtered_addresses = [] for address in payload['fixed_ips']: if valid_address(address['address']): filtered_addresses.append(address) if filtered_addresses: LOG.debug('FilteredHandler Before Filtered %d', len(payload['fixed_ips'])) LOG.debug('FilteredHandler After Filtered %d', len(filtered_addresses)) for address in filtered_addresses: recordset_values = { 'zone_id': zone_id, 'name': record_name, 'type': 'A' if address['version'] == 4 else 'AAAA' } record_values = { 'data': address['address'], } LOG.debug('FilteredHandler:recordset_values:zone_id:', recordset_values['zone_id']) LOG.debug('FilteredHandler:recordset_values:record_name:', recordset_values['name']) LOG.debug('FilteredHandler:recordset_values:type:', recordset_values['type']) LOG.debug('FilteredHandler:record_values:data:', record_values['data']) recordset = self._find_or_create_recordset(context, **recordset_values) LOG.debug('FilteredHandler:recordset:id:', recordset['id']) self.central_api.create_record(context, zone_id, recordset['id'], Record(**record_values)) else: LOG.debug('FilteredHandler No Results after filtering for %s', self.address_filter) elif event_type == 'compute.instance.delete.start': self._delete(zone_id=zone_id, resource_id=payload['instance_id'], resource_type='instance')
def put_one(self, zone_id, recordset_id): """Update RecordSet""" request = pecan.request context = request.environ['context'] body = request.body_dict response = pecan.response # Fetch the existing recordset recordset = self.central_api.get_recordset(context, zone_id, recordset_id) # SOA recordsets cannot be updated manually if recordset['type'] == 'SOA': raise exceptions.BadRequest( 'Updating SOA recordsets is not allowed') # NS recordsets at the zone root cannot be manually updated if recordset['type'] == 'NS': zone = self.central_api.get_domain(context, zone_id) if recordset['name'] == zone['name']: raise exceptions.BadRequest( 'Updating a root zone NS record is not allowed') # Convert to APIv2 Format recordset_data = self._view.show(context, request, recordset) recordset_data = utils.deep_dict_merge(recordset_data, body) new_recordset = self._view.load(context, request, body) # Validate the new set of data self._resource_schema.validate(recordset_data) # Get original list of Records original_records = set() for record in recordset.records: original_records.add(record.data) # Get new list of Records new_records = set() if 'records' in new_recordset: for record in new_recordset['records']: new_records.add(record.data) # Get differences of Records records_to_add = new_records.difference(original_records) records_to_rm = original_records.difference(new_records) # Update all items except records record_update = False if 'records' in new_recordset: record_update = True del new_recordset['records'] recordset.update(new_recordset) # Remove deleted records if we have provided a records array if record_update: recordset.records[:] = [ record for record in recordset.records if record.data not in records_to_rm ] # Add new records for record in records_to_add: recordset.records.append(Record(data=record)) # Persist the resource recordset = self.central_api.update_recordset(context, recordset) if recordset['status'] == 'PENDING': response.status_int = 202 else: response.status_int = 200 return self._view.show(context, request, recordset)
def _create(self, addresses, extra, zone_id, managed=True, resource_type=None, resource_id=None): """ Create a a record from addresses :param addresses: Address objects like {'version': 4, 'ip': '10.0.0.1'} :param extra: Extra data to use when formatting the record :param zone_id: The ID of the designate zone. :param managed: Is it a managed resource :param resource_type: The managed resource type :param resource_id: The managed resource ID """ if not managed: LOG.warning(_LW( 'Deprecation notice: Unmanaged designate-sink records are ' 'being deprecated please update the call ' 'to remove managed=False')) LOG.debug('Using Zone ID: %s', zone_id) zone = self.get_zone(zone_id) LOG.debug('Domain: %r', zone) data = extra.copy() LOG.debug('Event data: %s', data) data['zone'] = zone['name'] context = DesignateContext().elevated() context.all_tenants = True context.edit_managed_records = True for addr in addresses: event_data = data.copy() event_data.update(self._get_ip_data(addr)) if addr['version'] == 4: format = self._get_formatv4() else: format = self._get_formatv6() for fmt in format: recordset_values = { 'zone_id': zone['id'], 'name': fmt % event_data, 'type': 'A' if addr['version'] == 4 else 'AAAA'} recordset = self._find_or_create_recordset( context, **recordset_values) record_values = { 'data': addr['address']} if managed: record_values.update({ 'managed': managed, 'managed_plugin_name': self.get_plugin_name(), 'managed_plugin_type': self.get_plugin_type(), 'managed_resource_type': resource_type, 'managed_resource_id': resource_id}) LOG.debug('Creating record in %s / %s with values %r', zone['id'], recordset['id'], record_values) self.central_api.create_record(context, zone['id'], recordset['id'], Record(**record_values))
def process_notification(self, context, event_type, payload): # Take notification and create a record LOG.debug('FloatingV4Handler: Event type received: %s', event_type) zone = self.get_zone(cfg.CONF[self.name].zone_id) domain_id = zone['id'] # Gather extra information (need to compare payload['floating_ip'] and figure out which zone it fits in. # The domains are owned by admin so we need admin context? elevated_context = DesignateContext.get_admin_context( all_tenants=True, edit_managed_records=True) criterion = { "tenant_id": cfg.CONF[self.name].admin_tenant_id, } zones = self.central_api.find_zones(elevated_context, criterion) # Calculate Reverse Address v4address = ipaddress.ip_address(payload['floating_ip']) reverse_address = v4address.reverse_pointer + '.' reverse_id = None for i in zones: if i.name == reverse_address[4:]: reverse_id = i.id if event_type == 'network.floating_ip.associate': LOG.debug('FloatingV4Handler: Creating A record for %s on %s', payload['floating_ip'], payload['instance_id']) # Get ec2id for hostname (in user's context) kc = keystone_c.Client( token=context['auth_token'], tenant_id=context['tenant'], auth_url=cfg.CONF['handler:nova_floating'].auth_uri) nova_endpoint = kc.service_catalog.url_for( service_type='compute', endpoint_type='internalURL') nvc = nova_c.Client(auth_token=kc.auth_token, tenant_id=kc.auth_tenant_id, bypass_url=nova_endpoint) server_info = nvc.servers.get(payload['instance_id']) # Determine the hostname ec2id = getattr(server_info, 'OS-EXT-SRV-ATTR:instance_name') ec2id = ec2id.split('-', 1)[1].lstrip('0') hostname = '%s.%s' % (ec2id, zone['name']) record_type = 'A' recordset_values = { 'zone_id': domain_id, 'name': hostname, 'type': record_type } recordset = self._find_or_create_recordset(elevated_context, **recordset_values) record_values = { 'data': payload['floating_ip'], 'managed': True, 'managed_plugin_name': self.get_plugin_name(), 'managed_plugin_type': self.get_plugin_type(), 'managed_resource_type': 'instance', 'managed_resource_id': payload['instance_id'] } LOG.debug('Creating record in %s / %s with values %r' % (domain_id, recordset['id'], record_values)) self.central_api.create_record(elevated_context, domain_id, recordset['id'], Record(**record_values)) # Reverse Record record_type = 'PTR' if reverse_id == None: LOG.debug('UNABLE TO DETERMINE REVERSE ZONE: %s', payload['floating_ip']) else: recordset_values = { 'zone_id': reverse_id, 'name': reverse_address, 'type': record_type } recordset = self._find_or_create_recordset( elevated_context, **recordset_values) record_values = { 'data': hostname, 'managed': True, 'managed_plugin_name': self.get_plugin_name(), 'managed_plugin_type': self.get_plugin_type(), 'managed_resource_type': 'instance', 'managed_resource_id': payload['instance_id'] } LOG.debug('Creating record in %s / %s with values %r' % (reverse_id, recordset['id'], record_values)) self.central_api.create_record(elevated_context, reverse_id, recordset['id'], Record(**record_values)) elif event_type == 'network.floating_ip.disassociate': LOG.debug('FloatingV4Handler: Deleting A record for %s on %s', payload['floating_ip'], payload['instance_id']) self._delete(zone_id=domain_id, resource_id=payload['instance_id'], resource_type='instance') if reverse_id == None: LOG.debug('UNABLE TO DETERMINE REVERSE ZONE: %s', payload['floating_ip']) else: self._delete(zone_id=reverse_id, resource_id=payload['instance_id'], resource_type='instance')
def process_notification(self, context, event_type, payload): LOG.debug('NovaFixedV6Handler: Event type received %s', event_type) LOG.debug('NovaFixedV6Handler: Event body received %s', payload) zone = self.get_zone(cfg.CONF[self.name].zone_id) reverse_zone = self.get_zone(cfg.CONF[self.name].reverse_zone_id) domain_id = zone['id'] reverse_domain_id = reverse_zone['id'] if event_type == 'compute.instance.create.end': # Need admin context to get the ec2id. Otherwise using the normal context would have worked. username = cfg.CONF[self.name].admin_user password = cfg.CONF[self.name].admin_password tenant_name = cfg.CONF[self.name].admin_tenant_name auth_url = cfg.CONF[self.name].auth_url auth = v3.Password(username=username, password=password, project_name=tenant_name, project_domain_name='default', user_domain_name='default', auth_url=auth_url) sess = session.Session(auth=auth) nvc = nova_c.Client(2.1, session=sess) instance = nvc.servers.get(payload['instance_id']) # Determine the hostname ec2id = getattr(instance, 'OS-EXT-SRV-ATTR:instance_name') ec2id = ec2id.split('-', 1)[1].lstrip('0') hostname = '%s.%s' % (ec2id, zone['name']) LOG.debug('NovaFixedV6Handler creating AAAA record (%s) for - %s', hostname, payload['instance_id']) # Become Designate Admin to manage records context = DesignateContext.get_admin_context(all_tenants=True) # 1 recordset of an A and AAAA record for fixed_ip in payload['fixed_ips']: # Don't create an A record for the private address. if fixed_ip['version'] == 4: continue record_type = 'AAAA' recordset_values = { 'zone_id': domain_id, 'name': hostname, 'type': record_type } recordset = self._find_or_create_recordset( context, **recordset_values) record_values = { 'data': fixed_ip['address'], 'managed': True, 'managed_plugin_name': self.get_plugin_name(), 'managed_plugin_type': self.get_plugin_type(), 'managed_resource_type': 'instance', 'managed_resource_id': payload['instance_id'] } LOG.debug('Creating record in %s / %s with values %r' % (domain_id, recordset['id'], record_values)) self.central_api.create_record(context, domain_id, recordset['id'], Record(**record_values)) # Create PTR record_type = 'PTR' # Calculate reverse address v6address = ipaddress.ip_address(fixed_ip['address']) reverse_address = v6address.reverse_pointer + '.' recordset_values = { 'zone_id': reverse_domain_id, 'name': reverse_address, 'type': record_type } reverse_recordset = self._find_or_create_recordset( context, **recordset_values) record_values = { 'data': hostname, 'managed': True, 'managed_plugin_name': self.get_plugin_name(), 'managed_plugin_type': self.get_plugin_type(), 'managed_resource_type': 'instance', 'managed_resource_id': payload['instance_id'] } LOG.debug( 'NovaFixedV6Handler Creating record in %s / %s with values %r' % (reverse_domain_id, reverse_recordset['id'], record_values)) self.central_api.create_record(context, reverse_domain_id, reverse_recordset['id'], Record(**record_values)) nvc.servers.set_meta_item(instance, 'dns', hostname[:-1]) elif event_type == 'compute.instance.delete.start': # Nova Delete Event does not include fixed_ips. Hence why we had the instance ID in the records. LOG.debug('NovaFixedV6Handler delete A and AAAA record for - %s', payload['instance_id']) self._delete(zone_id=domain_id, resource_id=payload['instance_id'], resource_type='instance') self._delete(zone_id=reverse_domain_id, resource_id=payload['instance_id'], resource_type='instance') # search for and delete floating IPs elevated_context = DesignateContext.get_admin_context( all_tenants=True, edit_managed_records=True) criterion = { 'managed': True, 'managed_plugin_name': 'neutron_floating', 'managed_resource_type': 'instance', 'managed_extra': 'instance:%s' % (payload['instance_id']), } records = self.central_api.find_records(elevated_context, criterion) LOG.debug('Found %d floating ip records to delete for %s' % (len(records), payload['instance_id'])) for record in records: zones = self.central_api.find_zones(elevated_context) for zone in zones: try: recordset = self.central_api.get_recordset( elevated_context, zone['id'], record['recordset_id']) LOG.debug( 'Deleting record %s from %s / %s' % (record['id'], zone['id'], record['recordset_id'])) #self.central_api.delete_record(elevated_context, zone['id'], record['recordset_id'], record['id']) self.central_api.delete_recordset( elevated_context, zone['id'], record['recordset_id']) except: pass