-
Notifications
You must be signed in to change notification settings - Fork 19
OTA-1963: skills: Add cluster-update skills (update-advisor, product-lifecycle) #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,165 @@ | ||
| --- | ||
| name: product-lifecycle | ||
| description: Query Red Hat Product Life Cycle data for support phases, end-of-life dates, and OpenShift version compatibility. Use when evaluating whether installed operators or layered products are supported on a given OCP version, approaching end of life, or need upgrading before a cluster upgrade. Also use when the user asks about product support status, EOL dates, or lifecycle phases for any Red Hat product. | ||
| --- | ||
|
|
||
| # Red Hat Product Life Cycle | ||
|
|
||
| Query the Red Hat Product Life Cycle API to check support status, EOL dates, and OpenShift compatibility for Red Hat products and layered operators. | ||
|
|
||
| ## API Overview | ||
|
|
||
| - **Base URL**: `https://access.redhat.com/product-life-cycles/api/v1/products` | ||
| - **Authentication**: None required — the API is public. | ||
| - **Query parameter**: `?name=<substring>` — case-insensitive substring match on product name. | ||
| - **Response**: `{ "data": [ { product }, ... ] }` — array of matching products. | ||
|
|
||
| ## Quick Start | ||
|
|
||
| ```bash | ||
| # Search for a product by name (substring match) | ||
| curl -s "https://access.redhat.com/product-life-cycles/api/v1/products?name=logging+for+Red+Hat+OpenShift" | jq . | ||
|
|
||
| # List all products with "OpenShift" in the name | ||
| curl -s "https://access.redhat.com/product-life-cycles/api/v1/products?name=OpenShift" | jq -r '.data[].name' | ||
| ``` | ||
|
|
||
| ## Response Structure | ||
|
|
||
| Each product in `data[]` has: | ||
|
|
||
| ```json | ||
| { | ||
| "name": "logging for Red Hat OpenShift", | ||
| "former_names": ["Red Hat OpenShift Logging"], | ||
| "all_phases": [{"name": "General availability", ...}, ...], | ||
| "versions": [ | ||
| { | ||
| "name": "6.5", | ||
| "type": "Full Support", | ||
| "openshift_compatibility": "4.19, 4.20, 4.21", | ||
| "phases": [ | ||
| { | ||
| "name": "General availability", | ||
| "end_date": "2026-04-01T00:00:00.000Z", | ||
| "date_format": "date" | ||
| }, | ||
| { | ||
| "name": "Full support", | ||
| "end_date": "Release of Logging 6.6 + 1 month", | ||
| "date_format": "string" | ||
| }, | ||
| { | ||
| "name": "Maintenance support", | ||
| "end_date": "Release of Logging 6.7", | ||
| "date_format": "string" | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| For full field descriptions, type enumerations, and phase name details, see `references/api-details.md`. | ||
|
|
||
| ## Common Queries | ||
|
|
||
| ### Check support status for a specific product version | ||
|
|
||
| ```bash | ||
| curl -s "https://access.redhat.com/product-life-cycles/api/v1/products?name=logging+for+Red+Hat+OpenShift" \ | ||
| | jq -r '.data[] | "\(.name)", (.versions[] | " \(.name) - \(.type) (OCP: \(.openshift_compatibility // "N/A"))")' | ||
| ``` | ||
|
|
||
| ### Check if a product version is compatible with a target OCP version | ||
|
|
||
| ```bash | ||
| TARGET_OCP="4.21" | ||
| PRODUCT="logging+for+Red+Hat+OpenShift" | ||
|
|
||
| curl -s "https://access.redhat.com/product-life-cycles/api/v1/products?name=$PRODUCT" \ | ||
| | jq -r --arg target "$TARGET_OCP" ' | ||
| .data[] | .name as $prod | | ||
| .versions[] | | ||
| .name as $ver | .type as $type | | ||
| (.openshift_compatibility // "" | split(", ")) as $compat | | ||
| (if ($compat | index($target)) then "COMPATIBLE" else "NOT COMPATIBLE" end) as $status | | ||
| "\($prod) \($ver) (\($type)) - \($status) with OCP \($target)"' | ||
| ``` | ||
|
|
||
| ### Get EOL dates for OCP itself | ||
|
|
||
| ```bash | ||
| curl -s "https://access.redhat.com/product-life-cycles/api/v1/products?name=OpenShift+Container+Platform" \ | ||
| | jq -r '.data[0].versions[] | | ||
| "OCP \(.name) - \(.type) (maintenance ends: \( | ||
| [.phases[] | select(.name == "Maintenance support") | .end_date] | first // "N/A" | ||
| ))"' | ||
| ``` | ||
|
|
||
| ### Cross-reference OLM operators with Product Life Cycle data | ||
|
|
||
| Products that are OLM operators have a `package` field that maps directly to the | ||
| OLM Subscription's `spec.name`. This is an **exact match key** — more reliable than name | ||
| matching. The `is_operator` field confirms the product is OLM-managed. | ||
|
|
||
| When the upgrade advisor readiness JSON includes `olm_operator_lifecycle` data: | ||
|
|
||
| 1. Extract the `package` name from each operator in readiness data | ||
| 2. Search the Product Life Cycle API using that package name | ||
| 3. Match by comparing `product.package` == operator's `package` | ||
| 4. Check if the installed version's `openshift_compatibility` includes the target OCP version | ||
| 5. Check the `type` field for support status | ||
|
|
||
| ```bash | ||
| # Look up Product Life Cycle data for an OLM operator by its package name | ||
| OLM_PACKAGE="cluster-logging" | ||
| TARGET_OCP="4.21" | ||
|
|
||
| curl -s "https://access.redhat.com/product-life-cycles/api/v1/products?name=logging" \ | ||
| | jq -r --arg pkg "$OLM_PACKAGE" --arg target "$TARGET_OCP" ' | ||
| [.data[] | select(.package == $pkg)] | | ||
| if length == 0 then "No Product Life Cycle entry with package=\($pkg)" | ||
| else .[0] | | ||
| "\(.name) (package: \(.package))", | ||
| (.versions[] | | ||
| .name as $ver | .type as $type | | ||
| (.openshift_compatibility // "" | split(", ")) as $compat | | ||
| (if ($compat | index($target)) then "YES" else "NO" end) as $ok | | ||
| " \($ver) - \($type) - OCP \($target) compatible: \($ok)") | ||
| end' | ||
| ``` | ||
|
|
||
| If the `?name=` search doesn't return the operator, try searching by `csv_display_name` | ||
| from the readiness data as a fallback. | ||
|
|
||
| **Not all operators have Product Life Cycle entries.** If a search returns no results, that's expected — | ||
| it means the product isn't tracked in the Product Life Cycle API. Report this as "lifecycle data unavailable" | ||
| rather than an error. | ||
|
|
||
| ### Batch lookup for multiple OLM operators | ||
|
|
||
| When cross-referencing several operators, avoid N+1 API calls. Fetch `?name=OpenShift` | ||
| once (~14 products covering most Red Hat layered operators), then make individual calls | ||
| only for operators not found in that initial batch. | ||
|
|
||
| ```bash | ||
| TARGET_OCP="4.21" | ||
|
|
||
| # Single call covers most Red Hat operator products | ||
| curl -s "https://access.redhat.com/product-life-cycles/api/v1/products?name=OpenShift" \ | ||
| | jq -r --arg target "$TARGET_OCP" ' | ||
| .data[] | select(.is_operator) | | ||
| (.package // "") as $pkg | .name as $prod | | ||
| .versions[] | | ||
| .name as $ver | .type as $type | | ||
| (.openshift_compatibility // "" | split(", ")) as $compat | | ||
| (if ($compat | index($target)) then "YES" else "NO" end) as $ok | | ||
| "\($pkg): \($prod) \($ver) (\($type)) - OCP \($target): \($ok)"' | ||
| ``` | ||
|
|
||
| ## Important | ||
|
|
||
| - **Always use `?name=`** to filter — never fetch the unfiltered `/products` endpoint. | ||
| - `openshift_compatibility` is only present on **layered product** versions, not on OCP itself. | ||
| - When cross-referencing with OLM data, a missing Product Life Cycle entry is normal — report "lifecycle data unavailable" and move on. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| # Product Life Cycle API Reference | ||
|
|
||
| ## Endpoint | ||
|
|
||
| ``` | ||
| GET https://access.redhat.com/product-life-cycles/api/v1/products?name=<substring> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: there's now a v2 lifecycle API at https://access.redhat.com/product-life-cycles/api/v2/products . It has a slightly different schema, e.g.: $ diff -u3 <(curl -s 'https://access.redhat.com/product-life-cycles/api/v1/products?name=OpenShift+Container+Platform' | jq -S .) <(curl -s 'https://access.redhat.com/product-life-cycles/api/v2/products?name=OpenShift+Container+Platform' | jq -S .) | head -n30
--- /dev/fd/63 2026-04-21 13:36:54.495565201 -0700
+++ /dev/fd/62 2026-04-21 13:36:54.495565201 -0700
@@ -61,27 +61,23 @@
"is_retired": false,
"link": "https://access.redhat.com/support/policy/updates/openshift/",
"name": "Red Hat OpenShift Container Platform",
+ "opl_uuid": null,
"package": null,
"policies": "https://access.redhat.com/site/support/policy/updates/openshift/policies/",
"release_cadence": "4 months ",
"show_final_minor_release": false,
- "show_last_minor_release": false,
"show_openshift_compatibility": false,
"uuid": "9bbc4758-50e0-4b73-89dc-2bae80f1d394",
"versions": [
{
"additional_text": "",
"extra_dependences": [],
- "extra_header_value": null,
"final_minor_release": null,
- "last_minor_release": null,
"name": "4.21",
"openshift_compatibility": null,
"phases": [
{
"additional_text": "",
- "date": "2026-02-03T00:00:00.000Z",
- "date_format": "date",
"end_date": "2026-02-03T00:00:00.000Z",
"end_date_format": "date",We probably want the skill to use the v2 API, but I'm agnostic about whether we port from v1 to v2 in this pull or, after merging this as it stands, in follow-up pulls.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, we will introduce v2 usage in #13 |
||
| ``` | ||
|
|
||
| No authentication required. The `name` parameter is a case-insensitive substring match. | ||
|
|
||
| ## Product Object | ||
|
|
||
| | Field | Type | Description | | ||
| |---|---|---| | ||
| | `name` | string | Current product name | | ||
| | `former_names` | string[] | Previous product names (useful for search fallback) | | ||
| | `is_operator` | bool | Whether this product is an OLM-managed operator | | ||
| | `is_layered_product` | bool | Whether this product is layered on OpenShift | | ||
| | `is_retired` | bool | Whether the entire product has been retired | | ||
| | `package` | string\|null | **OLM package name** — maps to Subscription `spec.name` | | ||
| | `versions` | object[] | Per-version lifecycle data | | ||
|
|
||
| ### The `package` field | ||
|
|
||
| The `package` field is the OLM package name and provides an **exact match key** to correlate | ||
| Product Life Cycle products with OLM Subscriptions. This is more reliable than name matching. | ||
|
|
||
| Mapping: `product.package` == `subscription.spec.name` | ||
|
|
||
| ## Version Object | ||
|
|
||
| | Field | Type | Description | | ||
| |---|---|---| | ||
| | `name` | string | Version number (e.g., `"6.5"`, `"4.21"`) | | ||
| | `type` | string | **Current support status** — see table below | | ||
| | `openshift_compatibility` | string\|null | Comma-separated OCP versions (e.g., `"4.19, 4.20, 4.21"`) — only on layered products | | ||
| | `phases` | object[] | Lifecycle phase details with dates | | ||
|
|
||
| ### Support status (`type`) | ||
|
|
||
| | Value | Meaning | | ||
| |---|---| | ||
| | `"Full Support"` | Active development, bug fixes, security patches | | ||
| | `"Maintenance Support"` | Critical/security fixes only, no new features | | ||
| | `"End of Maintenance"` | Maintenance support has ended; no EUS/ELS applies to this version | | ||
| | `"Extended Support"` | Past maintenance, currently in a paid Extended Life Cycle Support (ELS) phase | | ||
| | `"End of life"` | No fixes, no support — must upgrade | | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. $ curl -s https://access.redhat.com/product-life-cycles/api/v1/products | jq -r '.data[].versions[].type' | sort | uniq -c | sort -n
12
39 End of Maintenance
119 Extended Support
156 Maintenance Support
257 Full Support
875 End of lifeI'm not clear on what
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch. I've updated the table to include all six Agreed on the OpenAPI schemas, I'm not aware of any either.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| | `""` (empty) | Status not yet determined (e.g., version has incomplete lifecycle data) | | ||
|
|
||
| ## Phase Object | ||
|
|
||
| | Field | Type | Description | | ||
| |---|---|---| | ||
| | `name` | string | Phase name (e.g., `"General availability"`, `"Full support"`, `"Maintenance support"`) | | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. $ curl -s https://access.redhat.com/product-life-cycles/api/v1/products | jq -r '.data[].versions[].phases[].name' | sort | uniq -c | sort -n
3 Migration support
5 Retired
18 Extended life cycle support (ELS) Term 3 add-on
18 Third-party certification period
26 Maintenance support 2
29 Extended life cycle support (ELS) Term 2 add-on
36 Maintenance Support 1
38 Extended life cycle support (ELS) 2
75 Extended life cycle support (ELS) add-on
85 Extended life cycle support (ELS) 1
125 Extended life phase
298 Extended update support Term 3
331 End of Life
453 Extended update support Term 2
583 Extended update support
1161 Maintenance support
1289 Full support
1458 General availabilityMaybe the API needs a link from each phase to docs about what that phase means for that product? Because that seems like a lot of phases that aren't all that clear to me as someone not terribly familiar with a bunch of these products.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agree, I will update that file. Thanks.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| | `start_date` | string | Phase start — ISO 8601 date or descriptive string | | ||
| | `end_date` | string | Phase end — ISO 8601 date or descriptive string | | ||
| | `date_format` | string | `"date"` (ISO 8601) or `"string"` (relative/TBD) | | ||
|
|
||
| Phase names vary by product. Common categories: | ||
|
|
||
| | Category | Phase names | Meaning | | ||
| |---|---|---| | ||
| | Release | `General availability` | When the version was first released | | ||
| | Active support | `Full support` | Active development, bug fixes, security patches | | ||
| | Reduced support | `Maintenance support`, `Maintenance Support 1`, `Maintenance support 2` | Critical/security fixes only | | ||
| | Extended support | `Extended update support`, `Extended update support Term 2`, `Extended update support Term 3` | EUS — available for select versions, may require add-on purchase | | ||
| | Extended lifecycle | `Extended life phase`, `Extended life cycle support (ELS) 1`/`2`, `Extended life cycle support (ELS) add-on`/`Term 2 add-on`/`Term 3 add-on` | Paid extended support beyond normal EOL | | ||
| | End | `End of Life`, `Retired` | No further updates or support | | ||
| | Other | `Migration support`, `Third-party certification period` | Product-specific transitional phases | | ||
|
|
||
| Phase names are not standardized across products. Use the `start_date` and `end_date` fields | ||
| to determine whether a phase is current, rather than relying on the phase name alone. | ||
|
|
||
| For detailed lifecycle policy definitions, see the [Red Hat product lifecycle policies](https://access.redhat.com/support/policy/updates/openshift#dates). | ||
|
|
||
| ## Search Tips | ||
|
|
||
| 1. **Be specific with `?name=`** — `"logging+for+Red+Hat+OpenShift"` is better than `"logging"` | ||
| 2. **Check `former_names`** — products may appear under a previous name in the `former_names` field | ||
| 3. **Use `is_operator: true`** to filter for OLM operators in results | ||
| 4. **Use `package` for OLM correlation** — more reliable than name matching | ||
| 5. **Never omit `?name=`** — the unfiltered response is very large | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like it overlaps with
api-details.md? Is the goal here just to cover some of the highlights of the response format, without swamping with context? Maybe we should suggest using a sub-agent that has read the wholeapi-details.mdfile, to try to preserve that context capacity, at the cost of restricting use to agents that can launch sub-agents? Or offload PLC queries to an MCP tool, instead of using a Skill? Or...?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, you're right. There was genuine duplication here and it was already causing drift (the
typefield table in SKILL.md was stale). I've removed the duplicated Key fields and Phase date formats sections from SKILL.md, keeping just the JSON example and a pointer toapi-details.md.The intent is progressive disclosure. I want to give the agent just enough to work with for typical queries without loading the full schema into context. If the agent needs the full field details, type enumerations, or phase name breakdown, it can read
api-details.mdon demand.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved by 23c5759 -> 804b96b dropping the "Key fields" and "Phase date formats" sections from
SKILL.md; thanks 👍