Forum Discussion

tadams9145's avatar
tadams9145
Icon for Nimbostratus rankNimbostratus
Jul 19, 2025

Struggling with Node.js API for Searching Profiles Across Multiple F5 Devices

Hey everyone,

 

I’m working on a Node.js API that connects to my frontend and allows users to search for an SSL or LTM profile by name and get back all the relevant details. The twist is that the profile could live on any one of 40+ F5 devices (different mgmt IPs).

 

Here’s what I’ve done so far:

  • I’m using the F5 REST API and creating a session token for each mgmt IP to avoid basic auth on every call.
  • I built a loop to query each device, aggregate results, and return the profile details if it exists.

 

The problem:

  • It’s not consistent. Sometimes the profile is found; other times it’s missed—even though it’s definitely there.
  • I’m getting timeouts pretty frequently, which adds to the frustration.
  • Feels like I’m doing too many sequential calls and maybe hitting performance or token issues.

 

Has anyone tackled something similar?

  • How do you structure your calls to make them reliable across multiple devices?
  • Is there a recommended pattern for handling large-scale F5 REST calls in Node.js (parallelization, rate limits, caching)?
  • Should I stick to session tokens or consider another auth pattern?
  • Any tricks for minimizing timeouts when calling multiple mgmt IPs?

 

Any examples, best practices, or lessons learned would be hugely appreciated. At this point, I’m looking for a clean way to make this work reliably before I refactor again.

 

Thanks 

1 Reply

  • Hello,

     

    For Node.js have you considered parallel execution using async/await with Promise.all/Promise.allSettled ?  This will query all you BIG-IP devices concurrently which should help with keeping response time down.  You could also leverage axios-retry for retries depending upon the error codes.  On the BIG-IP side you will likely have to increase some of the restjavad settings refer here --> restjavad memory issues

    Here is a sample code snippet to work off of:  

    const axios = require('axios');
    const retry = require('axios-retry');
    const pLimit = require('p-limit');
    
    retry(axios, { retries: 3, retryDelay: (retryCount) => retryCount * 1000 });
    
    const mgmtIPs = ['10.0.0.1', '10.0.0.2', /* ... up to 40+ */];
    const profileName = 'your-profile-name'; // From user input
    const limit = pLimit(10); // Concurrency limit
    
    async function queryDevice(ip) {
      try {
        // Create session token (POST /mgmt/shared/authn/login)
        const tokenRes = await axios.post(`https://${ip}/mgmt/shared/authn/login`, {
          username: 'admin', password: 'your-password' // Use env vars or secrets manager
        }, { timeout: 5000 });
        const token = tokenRes.data.token.token;
    
        // Query SSL or LTM profile (adjust endpoint: /mgmt/tm/ltm/profile/client-ssl or server-ssl for SSL, /mgmt/tm/ltm/profile for LTM)
        const profileRes = await axios.get(`https://${ip}/mgmt/tm/ltm/profile/client-ssl/${profileName}`, {
          headers: { 'X-F5-Auth-Token': token },
          timeout: 10000 // Custom timeout
        });
        return { ip, details: profileRes.data }; // Aggregate if found
      } catch (err) {
        console.error(`Error on ${ip}: ${err.message}`);
        return { ip, error: err.message }; // Don't throw; collect failures
      }
    }
    
    // In your API endpoint
    async function searchProfiles(req, res) {
      const promises = mgmtIPs.map(ip => limit(() => queryDevice(ip)));
      const results = await Promise.allSettled(promises);
      const foundProfiles = results
        .filter(r => r.status === 'fulfilled' && !r.value.error)
        .map(r => r.value);
      
      res.json(foundProfiles); // Return aggregated list
    }