Scripting for parsing file names from a directory

I'm currently using the Seiso/Kafka plugin to stream each unique Zeek log type to a different topic in Kafka and it works great I've been using SSL configurations to specify the directory path + filename for my .crt, .key and .pem files so in the $config variable, my table looks like this:
$config = table(
    [""] = "broker1:9092",
    [""] = "/path/to/ca/file.pem",
    ["ssl.certificate.location"] = "/path/to/certificate/file.crt",
    ["ssl.key.location"] = "/path/to/key/file.key",
    ["security.protocol"] = "ssl"

Instead of manually entering the "/path/to/certificate/file.crt" along with ca and key, I'd like to use either a bif (but I can't find one specifically for this use case) or create a function to parse the file names. I only need to be able to grab the file names, not the full directory path.
Here's what I have so far:
@load base/utils/exec

redef exit_only_after_terminate=T;

global command: string = "ls -A";

function get_certificate(): string
    local cmd = Exec::Command($cmd=command);
    when (local res = Exec::run(cmd))
            local results = res$stdout;
            for ( i in results )
                 if ( ends_with(results[i], ".crt") )
                      local match = match_pattern(results[i], /^([^.]+)\.crt/);
                      return match$str;
event zeek_init()
     local certificate: string = get_certificate();
    print $certificate;
I'm attempting to assign the return of the function (match$str) because that gives me the file name I'm looking for. Once I have the string in a variable, I think I should be able to insert that into the Kafka $config table for ssl.certificate.location. This script currently fails though with this error.

warning: non-void function returning without a value: get_certificate
expression error in ./get_certs.zeek, line 28: value used but not set (certificate)
fatal error: errors occurred while initializing

If I change return match$str to print match$str, then just simply call get_certificate() in the zeek_init(), it successfully prints the file name I want. How can I get this function to return match$str so I can save it into a variable for later use?


First, sorry it took me quite a while to reply. I guess my new Discourse workflow isn’t doing what I had thought it was! :smirk:

The problem you’re running into is that the fact that: just because get_certificate() has a when statement in it doesn’t make get_certificate() itself asynchronous. So when you’re calling it, it sets up the when but then continues executing the next statement (which here is an implicit return, since there’s nothing after the when). That leads to the error of returning-without-a-value.

To fix this, you need to do two things. First, you have to make get_certificate() asynchronous by replacing the when with return when. Second, now that it’s asynchronous, you need to call it inside another when statement. In particular, change:

local certificate: string = get_certificate();


when ( local certificate = get_certificate() )

Finally, note that get_certificate() will never return if there isn’t a file ending in .crt. To address that possibility, after its for loop you should add something like return "no certificates found";.