npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@burna-org/ansible-client

v0.0.1

Published

Ansible client library

Readme

@burna-org/ansible-client

Ansible workflow helpers built on top of @burna-org/awx-client.

This library composes:

  • Full AWX client API pass-through
  • Higher-level helpers for pagination, job polling, cached job reuse, and template auto-provisioning

Install

npm install @burna-org/ansible-client @burna-org/awx-client

Quick start (server)

const AWXClient = require('@burna-org/awx-client');
const {createAnsibleWorkflows} = require('@burna-org/ansible-client');

const awxClient = new AWXClient({
  host: process.env.AWX_HOST,
  username: process.env.AWX_USERNAME,
  password: process.env.AWX_PASSWORD,
});

const ansible = createAnsibleWorkflows({
  awxClient,
  config: {
    jobResultExpirySeconds: 3600,
    pollInitialDelay: 5000,
    pollInterval: 2000,
  },
});

Factory

createAnsibleWorkflows({ awxClient, config })

  • awxClient (required): an initialized AWXClient instance
  • config.jobResultExpirySeconds (default 3600)
  • config.pollInitialDelay (default 5000 ms)
  • config.pollInterval (default 2000 ms)
  • config.runtimeMock (default false): when true, use built-in mock AWX responses and avoid real HTTP calls.

If awxClient is missing, it throws awxClient is required unless config.runtimeMock is enabled. If required AWX methods are missing, it throws awxClient method "<name>" is required.

Returned API

The returned object includes:

  1. All AWX methods from @burna-org/awx-client
  2. Workflow helper methods below

AWX pass-through methods

All of these are directly delegated to awxClient:

  • getAccessToken
  • listInventories, listInventoryHosts, createInventory, manageInventoryHost
  • listJobs, retrieveJob, retrieveJobStdout, listJobEvents
  • listJobTemplates, createJobTemplate, updateJobTemplate, launchJobTemplate, listJobsForTemplate, manageJobTemplateCredential
  • listAdhocCommands, retrieveAdhocCommand, retrieveAdhocCommandStdout, createAdhocCommand
  • listProjects, createProject
  • listCredentials, createCredential
  • listOrganizations, createOrganization
  • updateHost, listHosts, listHostGroups
  • createGroup, updateGroup, listGroups, listGroupHosts, manageGroupHost
  • listExecutionEnvironments
  • listSettingCategories, listSettings, updateSettings

Helper API reference

getGroups({ inventoryName })

Returns all groups for inventory name, handling pagination.

Response:

{ groups: Array, error: '' }

getHosts({ inventoryName })

Finds inventory by name, then returns all hosts with pagination.

Response:

{ hosts: Array, error: '' }

If inventory is not found:

{ hosts: [], error: 'Failed to found inventory "<name>"' }

findJobTemplateId({ jobTemplateName })

Response:

{ jobTemplateId: number | null, error: string }

getLastJobResult({ jobTemplateName, limit })

Returns latest non-failed job result if not expired.

Uses configured jobResultExpirySeconds.

Response:

{ job: Object | null, error: string }

handleJob({ jobTemplateName, limit, options, useLastJobResult })

Flow:

  1. Optionally reuse valid previous job
  2. Else launch new job template run
  3. Poll until finished

useLastJobResult defaults to true.

Response:

{ job: Object | null, error: string }

handleJobEvents({ jobTemplateName, limit, options, urlParams, useLastJobResult })

Runs/reuses job via handleJob, then fetches all events with pagination.

Response:

{ jobEvents: Array, error: string }

getJobEventsByJobId({ jobId, urlParams })

Polls job by ID until completion, then returns all events.

Response:

{ jobEvents: Array, error: '' }
// or
{ job: null, error: string }

waitForJobToFinish({ jobId })

Polls AWX until job finishes.

Response:

{ job: Object | null, error: string }

ensureJobTemplate({ ... })

Ensures template exists and returns template ID. If missing, it creates template and attaches credentials.

Params:

  • slug (required): logical template key (for example deploy_app)
  • templateNamePrefix (optional): prefix for generated name
  • projectName (required)
  • inventoryName (required)
  • executionEnvironmentName (required)
  • credentialNames (required): comma-separated string or array
  • playbook (required)
  • extraVars (optional object)
  • options (optional AWX template options)

Notes:

  • Template display name is generated from prefix+slug and title-cased
  • Uses in-memory cache for template IDs
  • Throws on resolution/create failures

clearTemplateCache(slug, templateNamePrefix)

  • With slug, clears one cached entry
  • With no args, clears all cache

getTemplateCacheStats()

Returns:

{ size: number, keys: string[] }

Practical examples

1) Use helper APIs

const {groups, error} = await ansible.getGroups({inventoryName: 'production'});
if (error) throw new Error(error);

const hostsResult = await ansible.getHosts({inventoryName: 'production'});

2) Run job with cache fallback

const result = await ansible.handleJob({
  jobTemplateName: 'Deploy App',
  limit: 'web-01',
  options: {
    extra_vars: {release: '2026.02'},
  },
  useLastJobResult: true,
});

if (result.error) {
  throw new Error(result.error);
}

console.log('Job ID:', result.job.id);

3) Run and collect all events

const events = await ansible.handleJobEvents({
  jobTemplateName: 'Deploy App',
  urlParams: {
    event: 'runner_on_ok',
    page_size: 200,
  },
});

if (events.error) {
  throw new Error(events.error);
}

console.log(events.jobEvents.length);

4) Ensure template exists (auto-create)

const templateId = await ansible.ensureJobTemplate({
  slug: 'deploy_app',
  templateNamePrefix: 'kolla-',
  projectName: 'infra-project',
  inventoryName: 'prod-inventory',
  executionEnvironmentName: 'default-ee',
  credentialNames: ['machine-cred', 'vault-cred'],
  playbook: 'site.yml',
  extraVars: {kolla_action: 'deploy'},
  options: {verbosity: 2},
});

console.log('Template ID:', templateId);

5) Cache inspection/cleanup

console.log(ansible.getTemplateCacheStats());
ansible.clearTemplateCache('deploy_app', 'kolla-');
ansible.clearTemplateCache();

Example server wrapper (Express)

const express = require('express');
const app = express();

app.use(express.json());

app.post('/api/ansible/job', async (req, res) => {
  const {jobTemplateName, limit, options} = req.body;

  const result = await ansible.handleJob({
    jobTemplateName,
    limit,
    options,
    useLastJobResult: true,
  });

  if (result.error) {
    return res.status(400).json(result);
  }

  return res.json(result);
});

app.get('/api/ansible/job/:id/events', async (req, res) => {
  const result = await ansible.getJobEventsByJobId({
    jobId: Number(req.params.id),
    urlParams: req.query,
  });

  if (result.error) {
    return res.status(400).json(result);
  }

  return res.json(result);
});

Error handling model

  • Most helpers return {..., error: ''} on success and a non-empty error string on failures
  • ensureJobTemplate throws when required dependencies/resources cannot be resolved

Development

npm test
npm run typecheck
npm run build:types