Exemple #1
0
    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))
Exemple #2
0
    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))
Exemple #3
0
    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))
Exemple #5
0
    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))
Exemple #6
0
    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)
Exemple #7
0
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))
Exemple #8
0
    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
Exemple #10
0
    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))
Exemple #12
0
    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)
Exemple #13
0
    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')
Exemple #15
0
    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)
Exemple #16
0
    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')
Exemple #17
0
    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)
Exemple #18
0
    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))
Exemple #19
0
    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')
Exemple #20
0
    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