Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

eosl.lifecycle — hardware end-of-life data for Ansible

ci licence: GPL-3.0-or-later

Answer one question from a playbook, down to the part number: is this hardware still supported by its manufacturer, and when does that stop?

Every date this collection returns comes from the manufacturer's own end-of-life bulletin, and the URL of that bulletin is returned alongside it. Nothing is estimated, modelled or inferred. Data comes from EOSL.ai, which tracks 1,100+ hardware families and 6,000+ part numbers across 10 manufacturers, refreshed weekly.

  • No API key, no account, no rate limit.
  • No Python dependencies beyond ansible-core itself.
  • One HTTP request per run, however many part numbers you check.
  • Data is CC BY 4.0; the collection is GPL-3.0-or-later, the standard licence for Ansible modules.

Install

ansible-galaxy collection install eosl.lifecycle

Quick start

- hosts: localhost
  tasks:
    - name: Check some hardware
      eosl.lifecycle.part_info:
        part_numbers:
          - WS-C3850-24T-L
          - N9K-C93180YC-EX
      register: eosl

    - name: Show what is past vendor support
      ansible.builtin.debug:
        msg: "{{ eosl.summary.unsupported_part_numbers }}"
ok: [localhost] => {
    "msg": ["WS-C3850-24T-L"]
}

The actual use case: audit an inventory

One request covers the whole fleet, so this scales to thousands of devices.

- name: Gather model numbers from network devices
  hosts: switches
  gather_facts: false
  tasks:
    - cisco.ios.ios_facts:
        gather_subset: hardware

- name: Check every gathered model against vendor lifecycle data
  hosts: localhost
  gather_facts: false
  tasks:
    - eosl.lifecycle.part_info:
        part_numbers: >-
          {{ groups['switches'] | map('extract', hostvars, 'ansible_net_model')
             | select('string') | unique | list }}
      register: audit

    - ansible.builtin.debug:
        msg: >-
          {{ audit.summary.counts.unsupported }} of {{ audit.summary.counts.total }} models
          are past end of service life

Contents

eosl.lifecycle.part_info — module

Option Type Default Description
part_numbers list required Part numbers to look up
vendor str Enables vendor-specific SKU alias expansion (see below)
api_url str https://eosl.ai/data/lookup.json Override to use a mirror or pinned copy
timeout int 30 HTTP timeout in seconds
validate_certs bool true TLS certificate validation

Returns parts (part number → record, or null), unmatched (list), and summary (counts plus unsupported_part_numbers). Read-only, so it supports --check.

The map is called parts, not results — Ansible reserves results for loop output and will silently rename any module return that uses it.

Each record:

part_number: WS-C3850-24T-L
family: Catalyst 3850 Series
vendor: Cisco
slug: cisco-catalyst-3850
end_of_sale: "2020-10"
end_of_service_life: "2025-10"
status: unsupported          # active | supported | unsupported | unknown
active: false                # true = manufacturer has announced no end of life
support_runway_score: 23     # higher = more remaining support runway
support_runway_band: Little or no runway
source_url: https://www.cisco.com/...eos-eol-notice-c51-743072.html
cisa_bod_26_02_scope: true   # networked edge device category, derived from public vendor data
url: https://eosl.ai/system/cisco-catalyst-3850/

eosl.lifecycle.eosl — lookup plugin

- ansible.builtin.debug:
    msg: "{{ lookup('eosl.lifecycle.eosl', 'WS-C3850-24T-L').end_of_service_life }}"

- ansible.builtin.assert:
    that: lookup('eosl.lifecycle.eosl', model, vendor='Cisco').status != 'unsupported'
    fail_msg: "{{ model }} is past vendor end of service life"

Options: vendor, api_url, timeout, validate_certs, and on_missing (null — default, skip, or error).

How part numbers are matched

Deterministic and conservative, in this order:

  1. Exact match on the part number.
  2. Loose match ignoring case and punctuation — FortiGate-60E, fortigate 60e and FORTIGATE60E are the same part.
  3. Vendor-gated alias expansion — Fortinet publishes FortiGate-60E where inventories often carry FG-60E. This step only runs when you pass a matching vendor, so it cannot map one manufacturer's part number onto another's record.

There is no fuzzy or substring matching. WS-C3850 does not match WS-C3850-24T-L. A part number the database does not carry is returned as null and listed in unmatched — it is never resolved to a near neighbour, because a wrong lifecycle date is worse than no lifecycle date.

This is the same logic as the NetBox plugin, deliberately, so both integrations resolve a given part number identically.

Reading the results honestly

  • status: unknown does not mean supported. It means this database holds no end-of-service-life date for that part.
  • unmatched is not "this hardware is fine". It means the database does not track that part.
  • Dates describe what the manufacturer published, not what it will do. Vendors sometimes extend support, and paid extensions exist that this data does not see. Check source_url before acting on anything load-bearing.
  • One part number resolves to one record. Where the same part appears in more than one product family with different dates, the lookup document serves a single answer. For those cases consult the family page at url, which shows the conflict.
  • cisa_bod_26_02_scope flags a category of networked edge device derived from public vendor data. CISA's own device list is not public, so this never claims presence on it.

Requirements

ansible-core 2.15 or newer. No collections or Python packages beyond it.

Outbound HTTPS to eosl.ai is needed. For air-gapped use, mirror https://eosl.ai/data/lookup.json and point api_url at your copy — the data is CC BY 4.0.

Links

Not affiliated with, endorsed by, or sponsored by any hardware manufacturer named in the data, nor by Red Hat or the Ansible project.

About

Ansible collection: source-backed hardware end-of-life (EOL/EOSL) dates from EOSL.ai. Part-number matched, one HTTP request per inventory, every date linked to the manufacturer's own bulletin.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages