diff --git a/novajoin/ipa.py b/novajoin/ipa.py index 780c86f..b4f0a42 100644 --- a/novajoin/ipa.py +++ b/novajoin/ipa.py @@ -62,6 +62,7 @@ class IPANovaJoinBase(object): self.ntries = CONF.connect_retries self.initial_backoff = CONF.connect_backoff self.ccache = "MEMORY:" + str(uuid.uuid4()) + LOG.debug("cache: %s", self.ccache) os.environ['KRB5CCNAME'] = self.ccache if self._ipa_client_configured() and not api.isdone('finalize'): (hostname, realm) = self.get_host_and_realm() @@ -126,23 +127,24 @@ class IPANovaJoinBase(object): return (hostname, realm) - def __backoff(self): - LOG.debug("Backing off %s seconds", self.backoff) + def __backoff(self, message_id): + LOG.debug("[%s] Backing off %s seconds", message_id, self.backoff) time.sleep(self.backoff) if self.backoff < 512: self.backoff = self.backoff * 2 - def __reset_backoff(self): + def __reset_backoff(self, message_id): if self.backoff > self.initial_backoff: - LOG.debug("Resetting backoff to %d", self.initial_backoff) + LOG.debug("[%s] Resetting backoff to %d", + message_id, self.initial_backoff) self.backoff = self.initial_backoff - def __get_connection(self): + def __get_connection(self, message_id): """Make a connection to IPA or raise an error.""" tries = 0 while (tries <= self.ntries): - LOG.debug("Attempt %d of %d", tries, self.ntries) + LOG.debug("[%s] Attempt %d of %d", message_id, tries, self.ntries) if api.Backend.rpcclient.isconnected(): api.Backend.rpcclient.disconnect() try: @@ -154,7 +156,7 @@ class IPANovaJoinBase(object): errors.TicketExpired, errors.KerberosError) as e: tries += 1 - LOG.debug("kinit again: %s", e) + LOG.debug("[%s] kinit again: %s", message_id, e) # pylint: disable=no-member try: kinit_keytab(str('nova/%s@%s' % @@ -162,35 +164,37 @@ class IPANovaJoinBase(object): CONF.keytab, self.ccache) except GSSError as e: - LOG.debug("kinit failed: %s", e) + LOG.debug("[%s] kinit failed: %s", message_id, e) if self.backoff: - self.__backoff() + self.__backoff(message_id) except errors.NetworkError: tries += 1 if self.backoff: - self.__backoff() + self.__backoff(message_id) except http_client.ResponseNotReady: # NOTE(xek): This means that the server closed the socket, # so keep-alive ended and we can't use that connection. api.Backend.rpcclient.disconnect() tries += 1 if self.backoff: - self.__backoff() + self.__backoff(message_id) else: # successful connection - self.__reset_backoff() + self.__reset_backoff(message_id) return - LOG.error("Failed to connect to IPA after %d attempts", self.ntries) + LOG.error("[%s] Failed to connect to IPA after %d attempts", + message_id, self.ntries) raise exception.IPAConnectionError(tries=self.ntries) - def start_batch_operation(self): + def start_batch_operation(self, message_id=0): """Start a batch operation. IPA method calls will be collected in a batch job and submitted to IPA once all the operations have collected by a call to _flush_batch_operation(). """ + LOG.debug("[%s] start batch operation", message_id) self.batch_args = list() def _add_batch_operation(self, command, *args, **kw): @@ -200,21 +204,21 @@ class IPANovaJoinBase(object): "params": [args, kw], }) - def flush_batch_operation(self): + def flush_batch_operation(self, message_id=0): """Make an IPA batch call.""" - LOG.debug("flush_batch_operation") + LOG.debug("[%] flush_batch_operation", message_id) if not self.batch_args: return None kw = {} - LOG.debug(self.batch_args) + LOG.debug("[%s] %s", message_id, self.batch_args) - return self._call_ipa('batch', *self.batch_args, **kw) + return self._call_ipa(message_id, 'batch', *self.batch_args, **kw) - def _call_ipa(self, command, *args, **kw): + def _call_ipa(self, message_id, command, *args, **kw): """Make an IPA call.""" if not api.Backend.rpcclient.isconnected(): - self.__get_connection() + self.__get_connection(message_id) if 'version' not in kw: kw['version'] = u'2.146' # IPA v4.2.0 for compatibility @@ -226,11 +230,11 @@ class IPANovaJoinBase(object): except (errors.CCacheError, errors.TicketExpired, errors.KerberosError): - LOG.debug("Refresh authentication") - self.__get_connection() + LOG.debug("[%s] Refresh authentication", message_id) + self.__get_connection(message_id) except errors.NetworkError: if self.backoff: - self.__backoff() + self.__backoff(message_id) else: raise except http_client.ResponseNotReady: @@ -238,7 +242,7 @@ class IPANovaJoinBase(object): # so keep-alive ended and we can't use that connection. api.Backend.rpcclient.disconnect() if self.backoff: - self.__backoff() + self.__backoff(message_id) else: raise @@ -259,7 +263,8 @@ class IPAClient(IPANovaJoinBase): host_cache = cachetools.TTLCache(maxsize=512, ttl=30) service_cache = cachetools.TTLCache(maxsize=512, ttl=30) - def add_host(self, hostname, ipaotp, metadata=None, image_metadata=None): + def add_host(self, hostname, ipaotp, metadata=None, image_metadata=None, + message_id=0): """Add a host to IPA. If requested in the metadata, add a host to IPA. The assumption @@ -270,10 +275,10 @@ class IPAClient(IPANovaJoinBase): and if that fails due to NotFound the host is added. """ - LOG.debug('Adding ' + hostname + ' to IPA.') + LOG.debug("[%s] Adding %s to IPA.", message_id, hostname) if not self._ipa_client_configured(): - LOG.debug('IPA is not configured') + LOG.debug('[%s] IPA is not configured', message_id) return False # There's no use in doing any operations if ipalib hasn't been @@ -287,7 +292,7 @@ class IPAClient(IPANovaJoinBase): image_metadata = {} if hostname in self.host_cache: - LOG.debug('Host ' + hostname + ' found in cache.') + LOG.debug("[%s] Host %s found in cache.", message_id, hostname) return self.host_cache[hostname] params = [hostname] @@ -316,11 +321,11 @@ class IPAClient(IPANovaJoinBase): } try: - self._call_ipa('host_mod', *params, **modargs) + self._call_ipa(message_id, 'host_mod', *params, **modargs) self.host_cache[hostname] = six.text_type(ipaotp) except errors.NotFound: try: - self._call_ipa('host_add', *params, **hostargs) + self._call_ipa(message_id, 'host_add', *params, **hostargs) self.host_cache[hostname] = six.text_type(ipaotp) except errors.DuplicateEntry: # We have no idea what the OTP is for the existing host. @@ -337,30 +342,30 @@ class IPAClient(IPANovaJoinBase): return self.host_cache.get(hostname, False) - def add_subhost(self, hostname): + def add_subhost(self, hostname, message_id=0): """Add a subhost to IPA. Servers can have multiple network interfaces, and therefore can have multiple aliases. Moreover, they can part of a service using a virtual host (VIP). These aliases are denoted 'subhosts', """ - LOG.debug('Adding subhost: ' + hostname) + LOG.debug('[%s] Adding subhost: %s', message_id, hostname) if hostname not in self.host_cache: params = [hostname] hostargs = {'force': True} self._add_batch_operation('host_add', *params, **hostargs) self.host_cache[hostname] = True else: - LOG.debug('subhost ' + hostname + ' found in cache.') + LOG.debug("[%s] subhost %s found in cache.", message_id, hostname) - def delete_subhost(self, hostname, batch=True): + def delete_subhost(self, hostname, batch=True, message_id=0): """Delete a subhost from IPA. Servers can have multiple network interfaces, and therefore can have multiple aliases. Moreover, they can part of a service using a virtual host (VIP). These aliases are denoted 'subhosts', """ - LOG.debug('Deleting subhost: ' + hostname) + LOG.debug(" [%s] Deleting subhost: %s", message_id, hostname) host_params = [hostname] (hn, domain) = self.split_hostname(hostname) @@ -381,19 +386,20 @@ class IPAClient(IPANovaJoinBase): else: if hostname in self.host_cache: del self.host_cache[hostname] - self._call_ipa('host_del', *host_params, **host_kw) + self._call_ipa(message_id, 'host_del', *host_params, **host_kw) try: - self._call_ipa('dnsrecord_del', *dns_params, **dns_kw) + self._call_ipa(message_id, 'dnsrecord_del', + *dns_params, **dns_kw) except (errors.NotFound, errors.ACIError): # Ignore DNS deletion errors pass - def delete_host(self, hostname, metadata=None): + def delete_host(self, hostname, metadata=None, message_id=0): """Delete a host from IPA and remove all related DNS entries.""" - LOG.debug('Deleting ' + hostname + ' from IPA.') + LOG.debug("[%s] Deleting %s from IPA", message_id, hostname) if not self._ipa_client_configured(): - LOG.debug('IPA is not configured') + LOG.debug('[%s] IPA is not configured', message_id) return if metadata is None: @@ -409,7 +415,7 @@ class IPAClient(IPANovaJoinBase): try: if hostname in self.host_cache: del self.host_cache[hostname] - self._call_ipa('host_del', *params, **kw) + self._call_ipa(message_id, 'host_del', *params, **kw) except (errors.NotFound, errors.ACIError): # Trying to delete a host that doesn't exist will raise an ACIError # to hide whether the entry exists or not @@ -422,27 +428,28 @@ class IPAClient(IPANovaJoinBase): dns_kw = {'del_all': True, } try: - self._call_ipa('dnsrecord_del', *dns_params, **dns_kw) + self._call_ipa(message_id, 'dnsrecord_del', *dns_params, **dns_kw) except (errors.NotFound, errors.ACIError): # Ignore DNS deletion errors pass - def add_service(self, principal): + def add_service(self, principal, message_id=0): if principal not in self.service_cache: try: (service, hostname, realm) = self.split_principal(principal) except errors.MalformedServicePrincipal as e: - LOG.error("Unable to split principal %s: %s", principal, e) + LOG.error("[%s] Unable to split principal %s: %s", + message_id, principal, e) raise - LOG.debug('Adding service: ' + principal) + LOG.debug("[%s] Adding service: %s", message_id, principal) params = [principal] service_args = {'force': True} self._add_batch_operation('service_add', *params, **service_args) self.service_cache[principal] = [hostname] else: - LOG.debug('Service ' + principal + ' found in cache.') + LOG.debug("[%s] Service %s found in cache", message_id, principal) - def service_add_host(self, service_principal, host): + def service_add_host(self, service_principal, host, message_id=0): """Add a host to a service. In IPA there is a relationship between a host and the services for @@ -454,8 +461,8 @@ class IPAClient(IPANovaJoinBase): in IPA this is done using the service-add-host API. """ if host not in self.service_cache.get(service_principal, []): - LOG.debug('Adding principal ' + service_principal + - ' to host ' + host) + LOG.debug("[%s] Adding principal %s to host %s", + message_id, service_principal, host) params = [service_principal] service_args = {'host': (host,)} self._add_batch_operation('service_add_host', *params, @@ -463,17 +470,19 @@ class IPAClient(IPANovaJoinBase): self.service_cache[service_principal] = self.service_cache.get( service_principal, []) + [host] else: - LOG.debug('Host ' + host + ' managing ' + service_principal + - ' found in cache.') + LOG.debug("[%s] Host %s managing %s found in cache", + message_id, host, service_principal) - def service_has_hosts(self, service_principal): + def service_has_hosts(self, service_principal, message_id=0): """Return True if hosts other than parent manages this service""" - LOG.debug('Checking if principal ' + service_principal + ' has hosts') + LOG.debug("[%s] Checking if principal %s has hosts", + message_id, service_principal) params = [service_principal] service_args = {} try: - result = self._call_ipa('service_show', *params, **service_args) + result = self._call_ipa(message_id, 'service_show', + *params, **service_args) except errors.NotFound: raise KeyError serviceresult = result['result'] @@ -483,7 +492,8 @@ class IPAClient(IPANovaJoinBase): service_principal ) except errors.MalformedServicePrincipal as e: - LOG.error("Unable to split principal %s: %s", service_principal, e) + LOG.error("[%s] Unable to split principal %s: %s", + message_id, service_principal, e) raise for candidate in serviceresult.get('managedby_host', []): @@ -491,28 +501,30 @@ class IPAClient(IPANovaJoinBase): return True return False - def host_get_services(self, service_host): + def host_get_services(self, service_host, message_id=0): """Return list of services this host manages""" - LOG.debug('Checking host ' + service_host + ' services') + LOG.debug("[%s] Checking host %s services", message_id, service_host) params = [] service_args = {'man_by_host': six.text_type(service_host)} - result = self._call_ipa('service_find', *params, **service_args) + result = self._call_ipa(message_id, 'service_find', + *params, **service_args) return [service['krbprincipalname'][0] for service in result['result']] - def host_has_services(self, service_host): + def host_has_services(self, service_host, message_id=0): """Return True if this host manages any services""" - return len(self.host_get_services(service_host)) > 0 + return len(self.host_get_services(service_host, message_id)) > 0 - def find_host(self, hostname): + def find_host(self, hostname, message_id=0): """Return True if this host exists""" - LOG.debug('Checking if host ' + hostname + ' exists') + LOG.debug("[%s] Checking if host %s exists", message_id, hostname) params = [] service_args = {'fqdn': six.text_type(hostname)} - result = self._call_ipa('host_find', *params, **service_args) + result = self._call_ipa(message_id, 'host_find', + *params, **service_args) return result['count'] > 0 - def delete_service(self, principal, batch=True): - LOG.debug('Deleting service: ' + principal) + def delete_service(self, principal, batch=True, message_id=0): + LOG.debug("[%s] Deleting service: %s", message_id, principal) params = [principal] service_args = {} if batch: @@ -522,14 +534,15 @@ class IPAClient(IPANovaJoinBase): else: if principal in self.service_cache: del self.service_cache[principal] - return self._call_ipa('service_del', *params, **service_args) + return self._call_ipa(message_id, 'service_del', + *params, **service_args) - def add_ip(self, hostname, floating_ip): + def add_ip(self, hostname, floating_ip, message_id=0): """Add a floating IP to a given hostname.""" - LOG.debug('In add_ip') + LOG.debug("[%s] In add_ip", message_id) if not self._ipa_client_configured(): - LOG.debug('IPA is not configured') + LOG.debug('[%s] IPA is not configured', message_id) return params = [six.text_type(get_domain() + '.'), @@ -537,35 +550,39 @@ class IPAClient(IPANovaJoinBase): kw = {'a_part_ip_address': six.text_type(floating_ip)} try: - self._call_ipa('dnsrecord_add', *params, **kw) + self._call_ipa(message_id, 'dnsrecord_add', *params, **kw) except (errors.DuplicateEntry, errors.ValidationError): pass - def find_record(self, floating_ip): + def find_record(self, floating_ip, message_id=0): """Find DNS A record for floating IP address""" - LOG.debug('looking up host for floating ip' + floating_ip) + LOG.debug("[%s] looking up host for floating ip %s", + message_id, floating_ip) params = [six.text_type(get_domain() + '.')] service_args = {'arecord': six.text_type(floating_ip)} - result = self._call_ipa('dnsrecord_find', *params, **service_args) + result = self._call_ipa(message_id, 'dnsrecord_find', + *params, **service_args) if result['count'] == 0: return assert(result['count'] == 1) return result['result'][0]['idnsname'][0].to_unicode() - def remove_ip(self, floating_ip): + def remove_ip(self, floating_ip, message_id=0): """Remove a floating IP from a given hostname.""" - LOG.debug('In remove_ip') + LOG.debug("[%s] In remove_ip", message_id) if not self._ipa_client_configured(): - LOG.debug('IPA is not configured') + LOG.debug("[%s] IPA is not configured", message_id) return - hostname = self.find_record(floating_ip) + hostname = self.find_record(floating_ip, message_id) if not hostname: - LOG.debug('floating IP record not found') + LOG.debug("[%s] floating IP record not found for %s", + message_id, floating_ip) return params = [six.text_type(get_domain() + '.'), hostname] service_args = {'arecord': six.text_type(floating_ip)} - self._call_ipa('dnsrecord_del', *params, **service_args) + self._call_ipa(message_id, 'dnsrecord_del', + *params, **service_args) diff --git a/novajoin/join.py b/novajoin/join.py index 3ed43e8..cd65469 100644 --- a/novajoin/join.py +++ b/novajoin/join.py @@ -108,6 +108,12 @@ class JoinController(Controller): Options passed in but as yet-unused are and user-data. """ + + # Set message id to zero for now. + # We could set it to the request_id in the python-request, + # but this is already logged as part of the server logs. + message_id = 0 + if not body: LOG.error('No body in create request') raise base.Fault(webob.exc.HTTPBadRequest()) @@ -191,7 +197,8 @@ class JoinController(Controller): try: data['ipaotp'] = self.ipaclient.add_host(data['hostname'], ipaotp, - metadata, image_metadata) + metadata, image_metadata, + message_id) if not data['ipaotp']: # OTP was not added to host, don't return one del data['ipaotp'] @@ -199,24 +206,26 @@ class JoinController(Controller): LOG.error('adding host failed %s', e) LOG.error(traceback.format_exc()) - self.ipaclient.start_batch_operation() + self.ipaclient.start_batch_operation(message_id) # key-per-service managed_services = [metadata[key] for key in metadata.keys() if key.startswith('managed_service_')] if managed_services: - self.add_managed_services(data['hostname'], managed_services) + self.add_managed_services( + data['hostname'], managed_services, message_id) compact_services = util.get_compact_services(metadata) if compact_services: - self.add_compact_services(hostname_short, compact_services) + self.add_compact_services( + hostname_short, compact_services, message_id) - self.ipaclient.flush_batch_operation() + self.ipaclient.flush_batch_operation(message_id) return data - def add_managed_services(self, base_host, services): + def add_managed_services(self, base_host, services, message_id=0): """Make any host/principal assignments passed into metadata.""" - LOG.debug("In add_managed_services") + LOG.debug("[%s] In add_managed_services", message_id) hosts_found = list() services_found = list() @@ -226,17 +235,18 @@ class JoinController(Controller): # add host if not present if principal_host not in hosts_found: - self.ipaclient.add_subhost(principal_host) + self.ipaclient.add_subhost(principal_host, message_id) hosts_found.append(principal_host) # add service if not present if principal not in services_found: - self.ipaclient.add_service(principal) + self.ipaclient.add_service(principal, message_id) services_found.append(principal) - self.ipaclient.service_add_host(principal, base_host) + self.ipaclient.service_add_host(principal, base_host, message_id) - def add_compact_services(self, base_host_short, service_repr): + def add_compact_services(self, base_host_short, service_repr, + message_id=0): """Make any host/principal assignments passed from metadata This takes a dictionary representation of the services and networks @@ -270,7 +280,7 @@ class JoinController(Controller): This attempts to do a more compact representation since the nova metadta entries have a limit of 255 characters. """ - LOG.debug("In add_compact_services") + LOG.debug("[%s] In add_compact_services", message_id) hosts_found = list() services_found = list() @@ -284,12 +294,13 @@ class JoinController(Controller): # add host if not present if principal_host not in hosts_found: - self.ipaclient.add_subhost(principal_host) + self.ipaclient.add_subhost(principal_host, message_id) hosts_found.append(principal_host) # add service if not present if principal not in services_found: - self.ipaclient.add_service(principal) + self.ipaclient.add_service(principal, message_id) services_found.append(principal) - self.ipaclient.service_add_host(principal, base_host) + self.ipaclient.service_add_host( + principal, base_host, message_id) diff --git a/novajoin/notifications.py b/novajoin/notifications.py index 0725e29..bf89e3f 100644 --- a/novajoin/notifications.py +++ b/novajoin/notifications.py @@ -65,9 +65,10 @@ class Registry(dict): def __call__(self, name, version=None, service='nova'): def register_event(fun): if version: - def check_event(sself, payload): + def check_event(sself, payload, message_id): self.check_version(payload, version, service) - return fun(sself, payload[service + '_object.data']) + return fun(sself, payload[service + '_object.data'], + message_id) self[name] = check_event return check_event self[name] = fun @@ -124,19 +125,22 @@ class NotificationEndpoint(object): LOG.debug("publisher: %s, event: %s, metadata: %s", publisher_id, event_type, metadata) + message_id = metadata['message_id'] + event_handler = self.event_handlers.get( event_type, lambda payload: LOG.error("Status update or unknown")) # run event handler for received notification type - event_handler(self, payload) + event_handler(self, payload, message_id) @event_handlers('compute.instance.create.end') - def compute_instance_create(self, payload): + def compute_instance_create(self, payload, message_id): hostname = self._generate_hostname(payload.get('hostname')) instance_id = payload['instance_id'] - LOG.info("Add new host %s (%s)", instance_id, hostname) + LOG.info("[%s] Add new host %s (%s)", + message_id, instance_id, hostname) @event_handlers('compute.instance.update') - def compute_instance_update(self, payload): + def compute_instance_update(self, payload, message_id): ipa = ipaclient() join_controller = join.JoinController(ipa) hostname_short = payload['hostname'] @@ -149,33 +153,37 @@ class NotificationEndpoint(object): enroll = payload_metadata.get('ipa_enroll', '') image_enroll = image_metadata.get('ipa_enroll', '') if enroll.lower() != 'true' and image_enroll.lower() != 'true': - LOG.info('IPA enrollment not requested, skipping update of %s', - hostname) + LOG.info( + '[%s] IPA enrollment not requested, skipping update of %s', + message_id, hostname) return # Ensure this instance exists in nova instance = get_instance(instance_id) if instance is None: - msg = 'No such instance-id, %s' % instance_id + msg = '[%s] No such instance-id, %s' % (message_id, instance_id) LOG.error(msg) return - ipa.start_batch_operation() + LOG.info("[%s] compute instance update for %s", message_id, hostname) + + ipa.start_batch_operation(message_id) # key-per-service managed_services = [ payload_metadata[key] for key in payload_metadata.keys() if key.startswith('managed_service_')] if managed_services: - join_controller.add_managed_services(hostname, managed_services) + join_controller.add_managed_services( + hostname, managed_services, message_id) compact_services = util.get_compact_services(payload_metadata) if compact_services: join_controller.add_compact_services( - hostname_short, compact_services) + hostname_short, compact_services, message_id) - ipa.flush_batch_operation() + ipa.flush_batch_operation(message_id) @event_handlers('compute.instance.delete.end') - def compute_instance_delete(self, payload): + def compute_instance_delete(self, payload, message_id): hostname_short = payload['hostname'] instance_id = payload['instance_id'] payload_metadata = payload['metadata'] @@ -187,49 +195,51 @@ class NotificationEndpoint(object): image_enroll = image_metadata.get('ipa_enroll', '') if enroll.lower() != 'true' and image_enroll.lower() != 'true': - LOG.info('IPA enrollment not requested, skipping delete of %s', - hostname) + LOG.info( + '[%s] IPA enrollment not requested, skipping delete of %s', + message_id, hostname) return - LOG.info("Delete host %s (%s)", instance_id, hostname) + LOG.info("[%s] Delete host %s (%s)", message_id, instance_id, hostname) try: ipa = ipaclient() - ipa.delete_host(hostname, {}) + ipa.delete_host(hostname, {}, message_id) self.delete_subhosts(ipa, hostname_short, payload_metadata) except exception.IPAConnectionError: - LOG.error("IPA Connection Error when deleting host %s (%s). " + LOG.error("[%s] IPA Connection Error when deleting host %s (%s). " "Manual cleanup may be required in the IPA server.", - instance_id, hostname) + message_id, instance_id, hostname) @event_handlers('network.floating_ip.associate') - def floaitng_ip_associate(self, payload): + def floaitng_ip_associate(self, payload, message_id): floating_ip = payload['floating_ip'] - LOG.info("Associate floating IP %s" % floating_ip) + LOG.info("[%s] Associate floating IP %s" % (message_id, floating_ip)) ipa = ipaclient() nova = novaclient() server = nova.servers.get(payload['instance_id']) if server: - ipa.add_ip(server.name, floating_ip) + ipa.add_ip(server.name, floating_ip, message_id) else: - LOG.error("Could not resolve %s into a hostname", - payload['instance_id']) + LOG.error("[%s] Could not resolve %s into a hostname", + message_id, payload['instance_id']) @event_handlers('network.floating_ip.disassociate') - def floating_ip_disassociate(self, payload): + def floating_ip_disassociate(self, payload, message_id): floating_ip = payload['floating_ip'] - LOG.info("Disassociate floating IP %s" % floating_ip) + LOG.info("[%s] Disassociate floating IP %s", message_id, floating_ip) ipa = ipaclient() - ipa.remove_ip(floating_ip) + ipa.remove_ip(floating_ip, message_id) @event_handlers('floatingip.update.end') - def floating_ip_update(self, payload): + def floating_ip_update(self, payload, message_id): """Neutron event""" floatingip = payload['floatingip'] floating_ip = floatingip['floating_ip_address'] port_id = floatingip['port_id'] ipa = ipaclient() if port_id: - LOG.info("Neutron floating IP associate: %s" % floating_ip) + LOG.info("[%s] Neutron floating IP associate: %s", + message_id, floating_ip) nova = novaclient() neutron = neutronclient() search_opts = {'id': port_id} @@ -239,14 +249,16 @@ class NotificationEndpoint(object): if device_id: server = nova.servers.get(device_id) if server: - ipa.add_ip(server.name, floating_ip) + ipa.add_ip(server.name, floating_ip, message_id) else: - LOG.error("Expected 1 port, got %d", len(ports)) + LOG.error("[%s] Expected 1 port, got %d", + message_id, len(ports)) else: - LOG.info("Neutron floating IP disassociate: %s" % floating_ip) - ipa.remove_ip(floating_ip) + LOG.info("[%s] Neutron floating IP disassociate: %s", + message_id, floating_ip) + ipa.remove_ip(floating_ip, message_id) - def delete_subhosts(self, ipa, hostname_short, metadata): + def delete_subhosts(self, ipa, hostname_short, metadata, message_id): """Delete subhosts and remove VIPs if possible. Servers can have multiple network interfaces, and therefore can @@ -269,13 +281,15 @@ class NotificationEndpoint(object): compact_services = util.get_compact_services(metadata) if compact_services: self.delete_compact_services(ipa, hostname_short, - compact_services) + compact_services, + message_id) managed_services = [metadata[key] for key in metadata.keys() if key.startswith('managed_service_')] if managed_services: - self.delete_managed_services(ipa, managed_services) + self.delete_managed_services(ipa, managed_services, message_id) - def delete_compact_services(self, ipa, host_short, service_repr): + def delete_compact_services(self, ipa, host_short, service_repr, + message_id): """Reconstructs and removes subhosts for compact services. Data looks like this: @@ -289,10 +303,10 @@ class NotificationEndpoint(object): services to be automatically deleted through IPA referential integrity. """ - LOG.debug("In delete compact services") + LOG.debug("[%s] In delete compact services", message_id) hosts_found = list() - ipa.start_batch_operation() + ipa.start_batch_operation(message_id) for service_name, net_list in service_repr.items(): for network in net_list: host = "%s.%s" % (host_short, network) @@ -302,15 +316,15 @@ class NotificationEndpoint(object): if principal_host not in hosts_found: ipa.delete_subhost(principal_host) hosts_found.append(principal_host) - ipa.flush_batch_operation() + ipa.flush_batch_operation(message_id) - def delete_managed_services(self, ipa, services): + def delete_managed_services(self, ipa, services, message_id): """Delete any managed services if possible. Checks to see if the managed service subhost has no managed hosts associations and if so, deletes the host. """ - LOG.debug("In delete_managed_services") + LOG.debug("[%s] In delete_managed_services", message_id) hosts_deleted = list() services_deleted = list() @@ -353,15 +367,15 @@ class VersionedNotificationEndpoint(NotificationEndpoint): event_handlers = Registry(NotificationEndpoint.event_handlers) @event_handlers('instance.create.end', '1.10') - def instance_create(self, payload): + def instance_create(self, payload, message_id): newpayload = { 'hostname': payload['host_name'], 'instance_id': payload['uuid'], } - self.compute_instance_create(newpayload) + self.compute_instance_create(newpayload, message_id) @event_handlers('instance.update', '1.8') - def instance_update(self, payload): + def instance_update(self, payload, message_id): glance = glanceclient() newpayload = { 'hostname': payload['host_name'], @@ -369,10 +383,10 @@ class VersionedNotificationEndpoint(NotificationEndpoint): 'metadata': payload['metadata'], 'image_meta': glance.images.get(payload['image_uuid']) } - self.compute_instance_update(newpayload) + self.compute_instance_update(newpayload, message_id) @event_handlers('instance.delete.end', '1.7') - def instance_delete(self, payload): + def instance_delete(self, payload, message_id): glance = glanceclient() newpayload = { 'hostname': payload['host_name'], @@ -380,7 +394,7 @@ class VersionedNotificationEndpoint(NotificationEndpoint): 'metadata': payload['metadata'], 'image_meta': glance.images.get(payload['image_uuid']) } - self.compute_instance_delete(newpayload) + self.compute_instance_delete(newpayload, message_id) def main():