#7178 cert-find command has poor performance
Opened 6 years ago by ftweedal. Modified 6 years ago

Analysis by @pvoborni:

What is the complexity of the operation?

I find code of this command poorly documented/commented. Which makes it hard to understand what individual subsearch does or why they are there. But let's look at it.

When looking at cert_find command. I see there iteration with 3 types of searches:

for sub_search in (self._cert_search,
                   self._ca_search,
                   self._ldap_search):
    sub_result, sub_truncated, sub_complete = sub_search(
        all=all,
        raw=raw,
        pkey_only=pkey_only,
        no_members=no_members,
        **options)
  • _ldap_search seems to do 1 LDAP search, get matching certificates, process it and add it to result list.
  • _ca_search gets Sub CAs' certs? i.e. also one LDAP search
  • _ cert_search parses cert and returns it.

OK, sot not a big issue - max 2 searches so far as Standa wrote.

But here, we can see that with all option, for every IPA issued cert we do an additional API call to dogtag. Which changes complexity form O(1) at least to O(n).

So with combination of sizelimit=0 and all=true will do at least 2000 ldap searches - probably more because I have a hunch that ra.get_certificate(str(serial_number) does more than one search.

if not pkey_only:
    ca_objs = {}
    ra = self.api.Backend.ra

    for key, obj in six.iteritems(result):
        if all and 'cacn' in obj:
            _issuer, serial_number = key
            cacn = obj['cacn']

            try:
                ca_obj = ca_objs[cacn]
            except KeyError:
                ca_obj = ca_objs[cacn] = (
                    self.api.Command.ca_show(cacn, all=True)['result'])

            obj.update(ra.get_certificate(str(serial_number)))

ra.get_certificate() calls the "classic" dogtag API using the RA cert. Any LDAP searches are performed by dogtag in this case.

Login to comment on this ticket.

Metadata