diff --git a/cmd/catalogd/main.go b/cmd/catalogd/main.go index 2b6f81b4ab..2cd491ba45 100644 --- a/cmd/catalogd/main.go +++ b/cmd/catalogd/main.go @@ -351,7 +351,10 @@ func run(ctx context.Context) error { } var localStorage storage.Instance - metrics.Registry.MustRegister(catalogdmetrics.RequestDurationMetric) + metrics.Registry.MustRegister( + catalogdmetrics.RequestDurationMetric, + catalogdmetrics.NewClusterCatalogCollector(mgr.GetCache()), + ) storeDir := filepath.Join(cfg.cacheDir, storageDir) if err := os.MkdirAll(storeDir, 0700); err != nil { diff --git a/cmd/operator-controller/main.go b/cmd/operator-controller/main.go index 2fcea83ef0..5639e6be45 100644 --- a/cmd/operator-controller/main.go +++ b/cmd/operator-controller/main.go @@ -54,6 +54,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/manager" + crmetrics "sigs.k8s.io/controller-runtime/pkg/metrics" "sigs.k8s.io/controller-runtime/pkg/metrics/filters" "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/predicate" @@ -68,6 +69,7 @@ import ( "github.com/operator-framework/operator-controller/internal/operator-controller/controllers" "github.com/operator-framework/operator-controller/internal/operator-controller/features" "github.com/operator-framework/operator-controller/internal/operator-controller/finalizers" + operatormetrics "github.com/operator-framework/operator-controller/internal/operator-controller/metrics" "github.com/operator-framework/operator-controller/internal/operator-controller/resolve" "github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/preflights/crdupgradesafety" "github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/render" @@ -357,6 +359,9 @@ func run() error { setupLog.Error(err, "unable to start manager") return err } + if err := crmetrics.Registry.Register(operatormetrics.NewClusterExtensionCollector(mgr.GetCache())); err != nil { + return fmt.Errorf("registering ClusterExtension metrics: %w", err) + } cpwCatalogd, err := httputil.NewCertPoolWatcher(cfg.catalogdCasDir, ctrl.Log.WithName("catalogd-ca-pool")) if err != nil { diff --git a/docs/designs/clusterextension-metrics.md b/docs/designs/clusterextension-metrics.md new file mode 100644 index 0000000000..03f02a123a --- /dev/null +++ b/docs/designs/clusterextension-metrics.md @@ -0,0 +1,160 @@ +# OLM inventory and status metrics spike + +## Goal + +Prototype kube-state-metrics-style metrics for the current catalog and extension state. The spike intentionally models the useful data first; observed series count and churn will determine what is suitable for long-term in-cluster use or a separate bounded Telemeter metric. + +The metrics are generated on scrape from each component's controller-runtime cache. They are not updated from reconcile code, so deleted objects and obsolete label sets disappear from subsequent collections without explicit cleanup. + +A cache list failure is returned as an invalid Prometheus metric rather than silently reporting an empty inventory. + +## ClusterExtension metrics + +Operator-controller exposes these metrics. + +### `olm_clusterextension_info` + +One gauge with value `1` is emitted per `ClusterExtension`: + +```text +olm_clusterextension_info{ + name="example", + package="example-operator", + channels="preview,stable", + catalog="community-operators", + installed_version="1.2.3" +} 1 +``` + +| Label | Source | Empty value | +| --- | --- | --- | +| `name` | `.metadata.name` | never | +| `package` | `.spec.source.catalog.packageName` | no catalog source | +| `channels` | sorted `.spec.source.catalog.channels`, comma-joined | no channel constraint | +| `catalog` | `.spec.source.catalog.selector.matchLabels[MetadataNameLabel]` | selector does not pin one named catalog | +| `installed_version` | `.status.install.bundle.version` | nothing installed | + +`name` is retained as the technical series identity. Two `ClusterExtension` objects can request the same package and otherwise have identical labels; omitting `name` would make the collector emit duplicate Prometheus series. + +Channels remain one deterministic label value so the info metric emits one active series per extension. This avoids multiplying series by the number of requested channels, at the cost of treating every channel combination as its own label value. + +### `olm_clusterextension_condition` + +One gauge with value `1` is emitted for each present `Installed` and `Progressing` condition: + +```text +olm_clusterextension_condition{ + package="example-operator", + name="example", + type="Progressing", + status="False", + reason="Blocked" +} 1 +``` + +Raw condition values are retained instead of deriving a lossy health classification. This distinguishes a healthy installed version that is retrying an update from an extension with no successful installation. + +Keeping conditions separate prevents every readiness transition from also creating a new inventory-series combination. An absent condition emits no condition series. + +## ClusterCatalog metrics + +Catalogd exposes these metrics because it is authoritative for the content being served. + +### `olm_cluster_catalog_serving` + +One gauge is emitted per `ClusterCatalog`: + +```text +olm_cluster_catalog_serving{ + name="community-operators", + digest="sha256:e3b0c44298fc...", + reason="Available" +} 1 +``` + +| State | Value | `digest` | `reason` | +| --- | ---: | --- | --- | +| `Serving=True` | `1` | Digest extracted from `.status.resolvedSource.image.ref` | Serving condition reason | +| `Serving=False` or `Unknown` | `0` | empty | Serving condition reason | +| Serving condition absent | `0` | empty | empty | + +The digest identifies the complete catalog snapshot, not an individual package. A new catalog image can add or remove versions for one package or change many packages at once. + +During a failed catalog refresh, catalogd continues serving the previous content. The metric therefore remains `1` with the previous digest while the `Progressing` condition reports the refresh failure. After a successful switch, the old digest label set disappears from new scrapes and a series with the new digest appears. Prometheus marks the old series stale but retains its historical samples. + +Deleting a `ClusterCatalog` removes its series; deletion does not emit a final zero. + +### `olm_cluster_catalog_condition` + +One gauge with value `1` is emitted for each present `Serving` and `Progressing` condition: + +```text +olm_cluster_catalog_condition{ + name="community-operators", + type="Progressing", + status="True", + reason="Retrying" +} 1 +``` + +This condition metric explains states that the serving metric intentionally does not, including a failed attempt to replace catalog content that is still available to clients. + +## Catalog selection limitation + +`ClusterExtension` does not record the catalog that supplied its installed bundle. Its `catalog` label is truthful only when the source selector has an exact `MetadataNameLabel` match. It is empty for broad or expression-based selectors and must not claim that the selector is the resolved source. + +The resolver retains the catalog name alongside each candidate and selects a single winning bundle, but its current result discards the catalog name. Truthfully answering "which catalog supplied this installed bundle?" requires returning the winning catalog and recording it in `ClusterExtension` status. + +That is an API/status change, not a metric-layer tweak. It requires upstream API review and the normal generated-code, CRD, reference-documentation, and API-diff workflow. It is outside this prototype. + +## Updates and transitions + +The metrics describe current state: + +```text +catalog digest changes + -> new package metadata becomes available + -> ClusterExtension resolves a bundle + -> installed version changes +``` + +They can show the catalog digest and installed version before and after an update, but they cannot truthfully encode a durable event containing `from version`, `to version`, transition time, and outcome. A reconcile-time counter would reset with the process and create unbounded version-pair labels. Durable update transitions remain an Events, audit, or Insights/CCX concern. + +## Cardinality and churn + +For `N` extensions and `C` catalogs, the maximum active series represented here is approximately: + +```text +N extension info ++ 2N extension conditions ++ C catalog serving ++ 2C catalog conditions += 3N + 3C +``` + +Missing conditions reduce the actual count. Label values do not form a cross-product because the collectors emit concrete object and condition records. + +Prometheus creates a new historical time series whenever any label changes. Expected churn comes from installed versions, requested channel sets, resolved catalog digests, and condition transitions. Removing constant labels reduces payload size but does not reduce active series while `name` remains unique; removing changing labels reduces historical churn. A Telemeter-safe design will require bounded aggregation rather than exporting these identity-rich series. + +## Local visualization + +After deploying the prototype with `make run`, run: + +```shell +uv run --script hack/watch-clusterextension-metrics.py +``` + +The terminal view follows all four spike metrics, scraping extension metrics from operator-controller and catalog metrics from catalogd. Each metric has independent active-series, cumulative-series, gauge-value, sparkline, and per-label cardinality output. A label change increases that metric's cumulative count even when its active count stays constant. History is process-local and resets when the script exits. + +Use `--once` for one scrape, `--interval` to change the polling period, and `--self-test` to check the exposition parser. The script obtains an operator-controller service-account token and manages local port-forwards for operator-controller on `18443` and catalogd on `17443`; use `--port` or `--catalog-port` if either port is occupied. + +## Evaluation + +Use a representative cluster to measure: + +1. active series per metric; +2. cumulative series churn during catalog refreshes, installs, upgrades, failures, and recovery; +3. distinct and changing values per label; +4. which labels answer actual inventory and operational questions. + +Then remove labels or split out bounded aggregate metrics based on evidence rather than treating this spike's contracts as stable APIs. diff --git a/enhancement.md b/enhancement.md new file mode 100644 index 0000000000..781c6e2250 --- /dev/null +++ b/enhancement.md @@ -0,0 +1,288 @@ +--- +title: olm-v1-metrics +authors: + - @theobarberbany +reviewers: + - @joelanford +approvers: [] +api-approvers: + - @joelspeed +creation-date: 2026-09-04 +last-updated: 2026-09-10 +status: provisional +tracking-link: + - https://issues.redhat.com/browse/OCPSTRAT-3069 +--- + +# OLM v1 Metrics + +## Summary + +OLM v1 does not currently provide the fleet inventory and health data available +for OLM v0, or the near-real-time catalog signals needed to investigate +incidents such as HPSTRAT-277. This enhancement makes detailed OLM v1 package, +version, resolved catalog, configured channel constraints, and condition data +available through Insights with approximately two-hour freshness, while +forwarding only bounded catalog digest and aggregate ClusterExtension health +series through Telemeter for approximately five-minute incident detection. It +also adds resolved catalog attribution to ClusterExtension status and exposes +detailed in-cluster metrics +for cluster-level troubleshooting, providing the required visibility without +exceeding the Telemeter cardinality budget. + +## Motivation + +OLM v1 resources are not represented in existing OLM v0 fleet reporting, so +adoption, version distribution, and health cannot be measured consistently. + +Product analysis needs detailed data with approximately two-hour freshness; +SRE incident detection needs bounded signals within approximately five minutes. +Detailed dimensions belong in Insights, while only catalog digest and aggregate +health belong in Telemeter. + +ClusterExtension status must also record the catalog selected for the installed +bundle. Channel analysis uses the requested constraints from the specification +because OLM v1 does not select a single channel during resolution. + +### User Stories + +**Product managers** need OLM v1 inventory and health data to measure adoption, +composition, versions, upgrades, and migration from OLM v0. + +**SREs** need to correlate catalog digest changes with abnormal extensions to +identify the blast radius of a bad catalog push. + +**Cluster administrators and support engineers** need detailed in-cluster state +to diagnose affected extensions and catalogs. + +### Goals + +- Provide detailed OLM v1 inventory and health data through Insights. +- Provide bounded catalog and aggregate health signals through Telemeter. +- Expose detailed ClusterExtension and ClusterCatalog metrics in-cluster. +- Record the resolved catalog for each installed extension. + +### Non-Goals + +- Building Insights/CCX reports or lifecycle-data joins. +- Sending per-extension, package, version, channel, or reason data through Telemeter. +- Recording durable update lineage or adding an update-event counter. + +## Proposal + +Deliver four linked changes: + +1. Add resolved catalog attribution to `ClusterExtension.status`. +2. Expose detailed ClusterExtension and ClusterCatalog metrics in-cluster, plus + bounded total and abnormal recording rules. +3. Add OLM v1 ClusterExtension and ClusterCatalog data to the Insights archive. +4. Allowlist only catalog serving `{name,digest}`, total, and abnormal series + for Telemeter. + +### Workflow Description + +Operator-controller and catalogd expose current resource state as metrics. +Insights gathers detailed inventory approximately every two hours. Cluster +monitoring evaluates the bounded recording rules and forwards the three +allowlisted series to Telemeter approximately every five minutes. + +Product analysis uses Insights, SRE fleet investigation uses Telemeter, and +cluster administrators use the detailed in-cluster metrics. + +### API Extensions + +`ClusterExtension.status.install` currently identifies only the installed bundle's +name, version, and optional release. It will also record the catalog selected for +that bundle. Channels remain zero-or-more requested resolution constraints in +the specification; OLM v1 does not select a single channel. + +This is an additive, controller-populated status change. It does not change the +specification, admission, or finalizers. During a failed upgrade, the catalog +continues to describe the bundle that remains installed. + +### Topology Considerations + +#### Hypershift / Hosted Control Planes + +OLM v1 does not currently support hosted control plane clusters. This proposal +does not add that support. + +#### Standalone Clusters + +The API fields and in-cluster metrics apply normally. Insights and Telemeter +data is available on connected clusters using the existing remote-health paths. + +#### Single-node Deployments or MicroShift + +SNO uses the same collectors and bounded recording rules without additional +components. Resource use scales with the number of ClusterExtensions and +ClusterCatalogs. + +OLM v1 does not currently support MicroShift. This proposal does not add that +support. + +#### OpenShift Kubernetes Engine + +The change applies where OLM v1 and the existing cluster monitoring and +remote-health capabilities are available. It adds no OKE-specific behavior. + +### Implementation Details/Notes/Constraints + +#### Data routing + +| Ask | Path | Freshness | +| --- | --- | --- | +| Adoption, packages, versions, configured channel constraints, resolved catalogs, detailed health, installed-version and condition snapshots, and lifecycle inputs | Insights | Approximately two hours | +| Cluster troubleshooting | In-cluster metrics | Current scrape | +| Fleet aggregate health | Insights and bounded Telemeter aggregates | Two hours / five minutes | +| Catalog digest blast radius and digest-change correlation | Telemeter | Approximately five minutes | + +#### Metrics data model + +```text +olm_clusterextension_info{ + name="example", + package="example-operator", + channels="stable", + catalog="community-operators", + installed_version="1.2.3" +} 1 + +olm_clusterextension_condition{ + name="example", + package="example-operator", + type="Progressing", + status="False", + reason="Blocked" +} 1 + +olm_cluster_catalog_serving{ + name="community-operators", + digest="sha256:abc123", + reason="Available" +} 1 + +olm_cluster_catalog_condition{ + name="community-operators", + type="Progressing", + status="True", + reason="Retrying" +} 1 + +cluster:olm_clusterextension_total 12 +cluster:olm_clusterextension_abnormal 2 +``` + +The `channels` label contains the sorted, comma-separated constraints from +`ClusterExtension.spec.source.catalog.channels` and is empty when resolution is +unconstrained. The `catalog` label comes from the resolved catalog recorded in +status. A failed catalog refresh continues to expose the digest of the content +still being served. + +Only `olm_cluster_catalog_serving{name,digest}` and the two unlabeled aggregate +series are forwarded through Telemeter. Detailed metric series remain +in-cluster; equivalent API fields are gathered through Insights. + +For upgrade use cases, SREs correlate catalog digest changes with abnormal +counts; PM analysis uses Insights history. No separate update-event counter is +required. + +### Risks and Mitigations + +- Telemeter cardinality is limited to `C+2` active series per cluster, where + `C` is the number of ClusterCatalogs. OCP provides three catalogs by default, + but administrators can add more and digest changes create historical churn; + representative clusters will be measured before allowlisting. +- Resolved catalog attribution could become inconsistent during upgrades; the + status value remains tied to the bundle that is actually installed. + +### Drawbacks + +As OLM is a package manager, package, version, catalog, and channel values are +inherently unbounded; exporting them fleet-wide as metric labels would create +unbounded series. This design therefore trades fine-grained, real-time fleet +attribution for bounded cardinality. Telemeter can show that a catalog digest +change correlates with abnormal extensions, but package-level attribution +requires Insights or in-cluster investigation. + +## Alternatives (Not Implemented) + +- Forward detailed per-extension metrics through Telemeter: rejected because + package, version, catalog, channel, and reason labels are unbounded. +- Infer the selected catalog from the `ClusterExtension` specification: rejected + because a selector does not identify which catalog won resolution. Configured + channel constraints are read directly from the specification. +- Add an update-event counter: rejected because the existing catalog digest, + aggregate health, Insights history, and in-cluster metrics cover the agreed + SRE and PM use cases. + +## Open Questions [optional] + +- Should resolved catalog be a scalar field on `status.install`, or part of a + nested source structure? +- Do existing Insights/CCX reports consume the new archive data automatically, or + is a separate backend/reporting work item required? + +## Test Plan + +- Unit and controller tests cover resolved catalog status across installs, + upgrades, failed upgrades, and objects without provenance. +- Collector and recording-rule tests cover expected labels, missing status, + deletion, cache failures, zero totals, and abnormal-state aggregation. +- Insights archive output and Telemeter allowlisting are validated with + representative resources and cardinality measurements. + +## Graduation Criteria + +This proposal targets GA. It is complete when: + +- The status API change is reviewed, documented, and shipped. +- The four in-cluster metrics and two recording rules are available by default + with unit and end-to-end coverage. +- Insights archive collection and the three Telemeter series are verified. +- Representative cardinality measurements remain within the agreed budget. + +## Upgrade / Downgrade Strategy + +No user action is required. Existing ClusterExtensions remain valid but may lack +resolved catalog provenance until a successful install or upgrade records it. +Metrics appear when the updated components are deployed. + +Older components ignore the additive status field. Downgrading removes the new +observability data but does not change installed extensions or catalog serving +behavior. + +TODO: Document upgrade, downgrade, and telemetry behavior while OLM v0 and OLM v1 +coexist during the migration period. + +## Version Skew Strategy + +The updated ClusterExtension CRD must be applied before the updated +operator-controller Deployment. CVO payload manifest ordering will place the +CRD before the controller within the existing OLM component/run level. + +During rollout, metrics and Insights tolerate ClusterExtensions without the new +resolved catalog field. Recording rules and the Telemeter allowlist +also tolerate their source metrics being temporarily absent; data begins flowing +when the updated collectors are available. + +There is no node or kubelet impact. + +## Operational Aspects of API Extensions + +Not applicable beyond adding a controller-populated field to an existing CRD +status. This introduces no webhook, aggregated API server, finalizer, or new +dependency affecting API availability or throughput. + +## Support Procedures + +No special support procedures are required. Failures are visible through the +existing OLM v1 resource status, operator logs, and monitoring tools. The +additive status field cannot be disabled independently; removing the CRD is +unsupported and would remove existing custom resources. + +## Infrastructure Needed [optional] + +No new infrastructure is required. The proposal uses the existing +operator-controller, catalogd, cluster monitoring, Insights, and Telemeter +infrastructure. diff --git a/hack/watch-clusterextension-metrics.py b/hack/watch-clusterextension-metrics.py new file mode 100755 index 0000000000..dbc311aa10 --- /dev/null +++ b/hack/watch-clusterextension-metrics.py @@ -0,0 +1,251 @@ +#!/usr/bin/env python3 + +"""Watch active and cumulative cardinality of the OLM metrics spike.""" + +import argparse +import datetime +import subprocess +import sys +import time + +METRICS = ( + "olm_clusterextension_info", + "olm_clusterextension_condition", + "olm_cluster_catalog_serving", + "olm_cluster_catalog_condition", +) +BLOCKS = "▁▂▃▄▅▆▇█" + + +def parse_labels(value): + labels = {} + i = 0 + while i < len(value): + equals = value.find("=", i) + if equals < 0 or equals + 1 >= len(value) or value[equals + 1] != '"': + raise ValueError(f"invalid label set near {value[i:]!r}") + name = value[i:equals] + i = equals + 2 + chars = [] + while i < len(value) and value[i] != '"': + if value[i] == "\\": + i += 1 + if i >= len(value): + raise ValueError("unterminated label escape") + chars.append("\n" if value[i] == "n" else value[i]) + else: + chars.append(value[i]) + i += 1 + if i >= len(value): + raise ValueError("unterminated label value") + labels[name] = "".join(chars) + i += 1 + if i < len(value): + if value[i] != ",": + raise ValueError(f"invalid label separator {value[i]!r}") + i += 1 + return labels + + +def samples(text, metric_names=METRICS): + result = {name: [] for name in metric_names} + for line in text.splitlines(): + name, separator, remainder = line.partition("{") + if not separator or name not in result: + continue + label_end = remainder.rfind("}") + if label_end < 0: + raise ValueError(f"missing closing brace in {line!r}") + try: + value = float(remainder[label_end + 1 :].strip().split()[0]) + except (IndexError, ValueError) as error: + raise ValueError(f"invalid sample value in {line!r}") from error + result[name].append({"labels": parse_labels(remainder[:label_end]), "value": value}) + return result + + +def sparkline(values, width=60): + values = values[-width:] + if not values: + return "" + low, high = min(values), max(values) + if low == high: + return BLOCKS[0] * len(values) + return "".join(BLOCKS[round((value - low) * (len(BLOCKS) - 1) / (high - low))] for value in values) + + +def create_token(namespace, service_account): + try: + return subprocess.run( + ["kubectl", "create", "token", service_account, "-n", namespace], + check=True, + capture_output=True, + text=True, + ).stdout.strip() + except subprocess.CalledProcessError as error: + raise SystemExit(f"kubectl could not create a token for {service_account}: {error.stderr.strip()}") from error + + +def start_forward(namespace, service, local_port, remote_port): + return subprocess.Popen( + ["kubectl", "port-forward", "-n", namespace, f"svc/{service}", f"{local_port}:{remote_port}"], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + ) + + +def fetch(port, token): + return subprocess.run( + [ + "curl", + "--fail", + "--silent", + "--show-error", + "--insecure", + "--config", + "-", + f"https://127.0.0.1:{port}/metrics", + ], + check=True, + input=f'header = "Authorization: Bearer {token}"\n', + capture_output=True, + text=True, + timeout=3, + ).stdout + + +def update_state(state, current): + fingerprints = {tuple(sorted(sample["labels"].items())) for sample in current} + new = fingerprints - state["seen"] + state["seen"].update(fingerprints) + for sample in current: + for name, value in sample["labels"].items(): + state["seen_values"].setdefault(name, set()).add(value) + state["active_history"].append(len(fingerprints)) + state["seen_history"].append(len(state["seen"])) + return fingerprints, new + + +def print_metric(name, current, state): + fingerprints, new = update_state(state, current) + values = sorted({sample["value"] for sample in current}) + print(f"\n{name}") + print(f"active: {len(fingerprints):<5} unique seen: {len(state['seen']):<5} new: +{len(new):<4} values: {values}") + print(f"active {sparkline(state['active_history'])}") + print(f"seen {sparkline(state['seen_history'])}") + if not current: + print("No series found. Rebuild/redeploy with `make run` and verify the resource exists.") + return + + print("label active distinct seen distinct") + print("-" * 65) + label_names = sorted({label for sample in current for label in sample["labels"]}) + for label in label_names: + active_values = {sample["labels"].get(label, "") for sample in current} + print(f"{label:<32} {len(active_values):>8} {len(state['seen_values'][label]):>15}") + + +def self_test(): + parsed = samples( + '# HELP ignored\n' + 'olm_clusterextension_info{name="example",channels="preview,stable"} 1\n' + 'olm_cluster_catalog_serving{name="catalog",digest="",reason="Unavailable"} 0\n' + ) + assert parsed["olm_clusterextension_info"] == [ + {"labels": {"name": "example", "channels": "preview,stable"}, "value": 1.0} + ] + assert parsed["olm_cluster_catalog_serving"][0]["value"] == 0 + assert sparkline([1, 2, 3]) == "▁▅█" + print("self-test passed") + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--interval", type=float, default=2, help="seconds between scrapes (default: 2)") + parser.add_argument("--port", type=int, default=18443, help="operator-controller local port (default: 18443)") + parser.add_argument("--catalog-port", type=int, default=17443, help="catalogd local port (default: 17443)") + parser.add_argument("--namespace", default="olmv1-system") + parser.add_argument("--once", action="store_true", help="scrape once without clearing the terminal") + parser.add_argument("--self-test", action="store_true") + args = parser.parse_args() + + if args.self_test: + self_test() + return + + token = create_token(args.namespace, "operator-controller-controller-manager") + endpoints = ( + { + "name": "operator-controller", + "port": args.port, + "remote_port": 8443, + "service": "operator-controller-service", + "token": token, + "metrics": METRICS[:2], + }, + { + "name": "catalogd", + "port": args.catalog_port, + "remote_port": 7443, + "service": "catalogd-service", + "token": token, + "metrics": METRICS[2:], + }, + ) + forwards = [ + start_forward(args.namespace, endpoint["service"], endpoint["port"], endpoint["remote_port"]) + for endpoint in endpoints + ] + + # ponytail: cumulative history is intentionally in-memory; use Prometheus when persistence is needed. + states = { + metric: {"seen": set(), "seen_values": {}, "active_history": [], "seen_history": []} + for metric in METRICS + } + scrape_count = 0 + + try: + while True: + try: + current = {} + for endpoint in endpoints: + current.update(samples(fetch(endpoint["port"], endpoint["token"]), endpoint["metrics"])) + except Exception as error: + stopped = [ + (endpoint, forward) + for endpoint, forward in zip(endpoints, forwards, strict=True) + if forward.poll() is not None + ] + if stopped: + endpoint, forward = stopped[0] + output = forward.stdout.read() if forward.stdout else "" + raise RuntimeError(f"{endpoint['name']} port-forward exited:\n{output}") from error + print(f"waiting for metrics endpoints: {error}", file=sys.stderr) + time.sleep(0.5) + continue + + scrape_count += 1 + if not args.once and sys.stdout.isatty(): + print("\033[2J\033[H", end="") + print(f"OLM metrics cardinality — {datetime.datetime.now().astimezone().strftime('%H:%M:%S %Z')} — scrape {scrape_count}") + for metric in METRICS: + print_metric(metric, current[metric], states[metric]) + + if args.once: + return + time.sleep(args.interval) + except KeyboardInterrupt: + pass + finally: + for forward in forwards: + forward.terminate() + for forward in forwards: + try: + forward.wait(timeout=3) + except subprocess.TimeoutExpired: + forward.kill() + + +if __name__ == "__main__": + main() diff --git a/internal/catalogd/metrics/collector.go b/internal/catalogd/metrics/collector.go new file mode 100644 index 0000000000..0c1f32f899 --- /dev/null +++ b/internal/catalogd/metrics/collector.go @@ -0,0 +1,115 @@ +/* +Copyright 2026. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "context" + "strings" + + "github.com/prometheus/client_golang/prometheus" + apimeta "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + + ocv1 "github.com/operator-framework/operator-controller/api/v1" +) + +const ( + ClusterCatalogServingMetricName = "olm_cluster_catalog_serving" + ClusterCatalogConditionMetricName = "olm_cluster_catalog_condition" +) + +var clusterCatalogConditions = []string{ocv1.TypeServing, ocv1.TypeProgressing} + +type clusterCatalogCollector struct { + reader client.Reader + servingDesc *prometheus.Desc + conditionDesc *prometheus.Desc +} + +func NewClusterCatalogCollector(reader client.Reader) prometheus.Collector { + return &clusterCatalogCollector{ + reader: reader, + servingDesc: prometheus.NewDesc( + ClusterCatalogServingMetricName, + "Whether a ClusterCatalog is serving content and the digest currently served.", + []string{"name", "digest", "reason"}, + nil, + ), + conditionDesc: prometheus.NewDesc( + ClusterCatalogConditionMetricName, + "Current Serving and Progressing conditions for a ClusterCatalog.", + []string{"name", "type", "status", "reason"}, + nil, + ), + } +} + +func (c *clusterCatalogCollector) Describe(ch chan<- *prometheus.Desc) { + ch <- c.servingDesc + ch <- c.conditionDesc +} + +func (c *clusterCatalogCollector) Collect(ch chan<- prometheus.Metric) { + var catalogs ocv1.ClusterCatalogList + if err := c.reader.List(context.Background(), &catalogs); err != nil { + ch <- prometheus.NewInvalidMetric(c.servingDesc, err) + ch <- prometheus.NewInvalidMetric(c.conditionDesc, err) + return + } + + for i := range catalogs.Items { + catalog := &catalogs.Items[i] + serving := apimeta.FindStatusCondition(catalog.Status.Conditions, ocv1.TypeServing) + value, digest, reason := float64(0), "", "" + if serving != nil { + reason = serving.Reason + if serving.Status == metav1.ConditionTrue { + value = 1 + digest = servedCatalogDigest(catalog) + } + } + ch <- prometheus.MustNewConstMetric(c.servingDesc, prometheus.GaugeValue, value, catalog.Name, digest, reason) + + for _, conditionType := range clusterCatalogConditions { + condition := apimeta.FindStatusCondition(catalog.Status.Conditions, conditionType) + if condition == nil { + continue + } + ch <- prometheus.MustNewConstMetric( + c.conditionDesc, + prometheus.GaugeValue, + 1, + catalog.Name, + condition.Type, + string(condition.Status), + condition.Reason, + ) + } + } +} + +func servedCatalogDigest(catalog *ocv1.ClusterCatalog) string { + if catalog.Status.ResolvedSource == nil || catalog.Status.ResolvedSource.Image == nil { + return "" + } + _, digest, ok := strings.Cut(catalog.Status.ResolvedSource.Image.Ref, "@") + if !ok { + return "" + } + return digest +} diff --git a/internal/operator-controller/metrics/metrics.go b/internal/operator-controller/metrics/metrics.go new file mode 100644 index 0000000000..30b8fe4b15 --- /dev/null +++ b/internal/operator-controller/metrics/metrics.go @@ -0,0 +1,127 @@ +/* +Copyright 2026. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "context" + "sort" + "strings" + + "github.com/prometheus/client_golang/prometheus" + apimeta "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + + ocv1 "github.com/operator-framework/operator-controller/api/v1" +) + +const ( + ClusterExtensionInfoMetricName = "olm_clusterextension_info" + ClusterExtensionConditionMetricName = "olm_clusterextension_condition" +) + +var ( + clusterExtensionInfoLabels = []string{"name", "package", "channels", "catalog", "installed_version"} + clusterExtensionConditions = []string{ocv1.TypeInstalled, ocv1.TypeProgressing} + conditionLabels = []string{"name", "type", "status", "reason"} +) + +type clusterExtensionCollector struct { + reader client.Reader + infoDesc *prometheus.Desc + conditionDesc *prometheus.Desc +} + +func NewClusterExtensionCollector(reader client.Reader) prometheus.Collector { + return &clusterExtensionCollector{ + reader: reader, + infoDesc: prometheus.NewDesc( + ClusterExtensionInfoMetricName, + "Information about a ClusterExtension and its current installation.", + clusterExtensionInfoLabels, + nil, + ), + conditionDesc: prometheus.NewDesc( + ClusterExtensionConditionMetricName, + "Current Installed and Progressing conditions for a ClusterExtension.", + append([]string{"package"}, conditionLabels...), + nil, + ), + } +} + +func (c *clusterExtensionCollector) Describe(ch chan<- *prometheus.Desc) { + ch <- c.infoDesc + ch <- c.conditionDesc +} + +func (c *clusterExtensionCollector) Collect(ch chan<- prometheus.Metric) { + var extensions ocv1.ClusterExtensionList + if err := c.reader.List(context.Background(), &extensions); err != nil { + ch <- prometheus.NewInvalidMetric(c.infoDesc, err) + ch <- prometheus.NewInvalidMetric(c.conditionDesc, err) + return + } + + for i := range extensions.Items { + extension := &extensions.Items[i] + packageName, channels, catalogName := extensionSourceValues(extension) + installedVersion := "" + if extension.Status.Install != nil { + installedVersion = extension.Status.Install.Bundle.Version + } + ch <- prometheus.MustNewConstMetric( + c.infoDesc, + prometheus.GaugeValue, + 1, + extension.Name, + packageName, + channels, + catalogName, + installedVersion, + ) + collectConditions(ch, c.conditionDesc, extension.Status.Conditions, clusterExtensionConditions, packageName, extension.Name) + } +} + +func extensionSourceValues(extension *ocv1.ClusterExtension) (packageName, channels, catalogName string) { + catalog := extension.Spec.Source.Catalog + if catalog == nil { + return "", "", "" + } + requestedChannels := append([]string(nil), catalog.Channels...) + sort.Strings(requestedChannels) + if catalog.Selector != nil { + catalogName = catalog.Selector.MatchLabels[ocv1.MetadataNameLabel] + } + return catalog.PackageName, strings.Join(requestedChannels, ","), catalogName +} + +func collectConditions(ch chan<- prometheus.Metric, desc *prometheus.Desc, conditions []metav1.Condition, conditionTypes []string, labels ...string) { + for _, conditionType := range conditionTypes { + condition := apimeta.FindStatusCondition(conditions, conditionType) + if condition == nil { + continue + } + ch <- prometheus.MustNewConstMetric( + desc, + prometheus.GaugeValue, + 1, + append(labels, condition.Type, string(condition.Status), condition.Reason)..., + ) + } +} diff --git a/metrics_debug/example_scrape b/metrics_debug/example_scrape new file mode 100644 index 0000000000..899747efe4 --- /dev/null +++ b/metrics_debug/example_scrape @@ -0,0 +1,48 @@ +olm_clusterextension_condition{name="ack-acm-controller",package="ack-acm-controller",reason="Succeeded",status="True",type="Installed"} 1 +olm_clusterextension_condition{name="ack-acm-controller",package="ack-acm-controller",reason="Succeeded",status="True",type="Progressing"} 1 +olm_clusterextension_condition{name="ack-acmpca-controller",package="ack-acmpca-controller",reason="Succeeded",status="True",type="Installed"} 1 +olm_clusterextension_condition{name="ack-bedrock-controller",package="ack-bedrock-controller",reason="Succeeded",status="True",type="Progressing"} 1 +olm_clusterextension_condition{name="ack-bedrockagent-controller",package="ack-bedrockagent-controller",reason="Succeeded",status="True",type="Installed"} 1 +olm_clusterextension_condition{name="ack-bedrockagent-controller",package="ack-bedrockagent-controller",reason="Succeeded",status="True",type="Progressing"} 1 +olm_clusterextension_condition{name="ack-bedrockagentcorecontrol-controller",package="ack-bedrockagentcorecontrol-controller",reason="Succeeded",status="True",type="Installed"} 1 +olm_clusterextension_condition{name="ack-bedrockagentcorecontrol-controller",package="ack-bedrockagentcorecontrol-controller",reason="Succeeded",status="True",type="Progressing"} 1 +olm_clusterextension_condition{name="ack-cloudfront-controller",package="ack-cloudfront-controller",reason="Succeeded",status="True",type="Installed"} 1 +olm_clusterextension_condition{name="ack-cloudfront-controller",package="ack-cloudfront-controller",reason="Succeeded",status="True",type="Progressing"} 1 +olm_clusterextension_condition{name="ack-cloudtrail-controller",package="ack-cloudtrail-controller",reason="Succeeded",status="True",type="Installed"} 1 +olm_clusterextension_condition{name="ack-cloudtrail-controller",package="ack-cloudtrail-controller",reason="Succeeded",status="True",type="Progressing"} 1 +olm_clusterextension_condition{name="ack-cloudwatch-controller",package="ack-cloudwatch-controller",reason="Succeeded",status="True",type="Installed"} 1 +olm_clusterextension_condition{name="ack-cloudwatch-controller",package="ack-cloudwatch-controller",reason="Succeeded",status="True",type="Progressing"} 1 +olm_clusterextension_condition{name="ack-cloudwatchlogs-controller",package="ack-cloudwatchlogs-controller",reason="Succeeded",status="True",type="Installed"} 1 +olm_clusterextension_condition{name="ack-cloudwatchlogs-controller",package="ack-cloudwatchlogs-controller",reason="Succeeded",status="True",type="Progressing"} 1 +olm_clusterextension_condition{name="ack-codeartifact-controller",package="ack-codeartifact-controller",reason="Succeeded",status="True",type="Installed"} 1 +olm_clusterextension_condition{name="ack-codeartifact-controller",package="ack-codeartifact-controller",reason="Succeeded",status="True",type="Progressing"} 1 +olm_clusterextension_condition{name="ack-cognitoidentityprovider-controller",package="ack-cognitoidentityprovider-controller",reason="Succeeded",status="True",type="Installed"} 1 +olm_clusterextension_condition{name="ack-cognitoidentityprovider-controller",package="ack-cognitoidentityprovider-controller",reason="Succeeded",status="True",type="Progressing"} 1 +olm_clusterextension_condition{name="ack-dms-controller",package="ack-dms-controller",reason="Succeeded",status="True",type="Installed"} 1 +olm_clusterextension_condition{name="ack-dms-controller",package="ack-dms-controller",reason="Succeeded",status="True",type="Progressing"} 1 +olm_clusterextension_condition{name="ack-documentdb-controller",package="ack-documentdb-controller",reason="Succeeded",status="True",type="Installed"} 1 +olm_clusterextension_condition{name="ack-documentdb-controller",package="ack-documentdb-controller",reason="Succeeded",status="True",type="Progressing"} 1 +olm_clusterextension_condition{name="ack-dsql-controller",package="ack-dsql-controller",reason="Succeeded",status="True",type="Installed"} 1 +olm_clusterextension_condition{name="ack-dsql-controller",package="ack-dsql-controller",reason="Succeeded",status="True",type="Progressing"} 1 +olm_clusterextension_info{catalog="",channels="",installed_version="1.6.0",name="ack-pipes-controller",package="ack-pipes-controller"} 1 +olm_clusterextension_info{catalog="",channels="",installed_version="1.6.0",name="ack-route53-controller",package="ack-route53-controller"} 1 +olm_clusterextension_info{catalog="",channels="",installed_version="1.6.0",name="ack-s3control-controller",package="ack-s3control-controller"} 1 +olm_clusterextension_info{catalog="",channels="",installed_version="1.6.0",name="ack-sfn-controller",package="ack-sfn-controller"} 1 +olm_clusterextension_info{catalog="",channels="",installed_version="1.6.0",name="ack-ssm-controller",package="ack-ssm-controller"} 1 +olm_clusterextension_info{catalog="",channels="",installed_version="1.6.0",name="ack-wafv2-controller",package="ack-wafv2-controller"} 1 +olm_clusterextension_info{catalog="",channels="",installed_version="1.7.0",name="ack-applicationautoscaling-controller",package="ack-applicationautoscaling-controller"} 1 +olm_clusterextension_info{catalog="",channels="",installed_version="1.7.0",name="ack-cloudtrail-controller",package="ack-cloudtrail-controller"} 1 +olm_clusterextension_info{catalog="",channels="",installed_version="1.8.0",name="ack-athena-controller",package="ack-athena-controller"} 1 +olm_clusterextension_info{catalog="",channels="",installed_version="1.8.0",name="ack-cloudfront-controller",package="ack-cloudfront-controller"} 1 +olm_clusterextension_info{catalog="",channels="",installed_version="1.8.1",name="ack-acm-controller",package="ack-acm-controller"} 1 +olm_clusterextension_info{catalog="",channels="",installed_version="1.9.0",name="ack-apigateway-controller",package="ack-apigateway-controller"} 1 +olm_clusterextension_info{catalog="",channels="",installed_version="1.9.0",name="ack-cloudwatch-controller",package="ack-cloudwatch-controller"} 1 +olm_clusterextension_info{catalog="",channels="",installed_version="1.9.0",name="ack-ecr-controller",package="ack-ecr-controller"} 1 +olm_clusterextension_info{catalog="",channels="",installed_version="1.9.0",name="ack-elasticache-controller",package="ack-elasticache-controller"} 1 +olm_clusterextension_info{catalog="",channels="",installed_version="1.9.0",name="ack-route53resolver-controller",package="ack-route53resolver-controller"} 1 + +catalog side: + +olm_cluster_catalog_condition{name="operatorhubio",reason="Available",status="True",type="Serving"} 1 +olm_cluster_catalog_condition{name="operatorhubio",reason="Succeeded",status="True",type="Progressing"} 1 +olm_cluster_catalog_serving{digest="sha256:74efb1a5f8c770b506becf343c8630889f95fed86a22bf48129ad8b0a3aca551",name="operatorhubio",reason="Available"} 1 diff --git a/metrics_debug/install.yaml b/metrics_debug/install.yaml new file mode 100644 index 0000000000..3f981e7b77 --- /dev/null +++ b/metrics_debug/install.yaml @@ -0,0 +1,843 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: ack-system +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-acm-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-acm-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-acmpca-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-acmpca-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-apigateway-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-apigateway-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-apigatewayv2-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-apigatewayv2-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-applicationautoscaling-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-applicationautoscaling-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-athena-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-athena-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-autoscaling-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-autoscaling-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-backup-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-backup-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-bedrock-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-bedrock-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-bedrockagent-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-bedrockagent-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-bedrockagentcorecontrol-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-bedrockagentcorecontrol-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-cloudfront-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-cloudfront-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-cloudtrail-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-cloudtrail-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-cloudwatch-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-cloudwatch-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-cloudwatchlogs-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-cloudwatchlogs-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-codeartifact-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-codeartifact-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-cognitoidentityprovider-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-cognitoidentityprovider-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-dms-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-dms-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-documentdb-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-documentdb-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-dsql-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-dsql-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-dynamodb-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-dynamodb-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-ec2-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-ec2-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-ecr-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-ecr-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-ecrpublic-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-ecrpublic-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-ecs-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-ecs-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-efs-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-efs-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-eks-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-eks-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-elasticache-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-elasticache-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-elbv2-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-elbv2-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-emr-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-emr-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-emrcontainers-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-emrcontainers-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-emrserverless-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-emrserverless-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-eventbridge-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-eventbridge-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-firehose-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-firehose-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-glue-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-glue-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-iam-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-iam-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-kafka-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-kafka-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-keyspaces-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-keyspaces-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-kinesis-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-kinesis-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-kms-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-kms-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-lambda-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-lambda-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-lambdamicrovms-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-lambdamicrovms-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-memorydb-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-memorydb-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-mq-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-mq-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-mwaa-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-mwaa-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-networkfirewall-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-networkfirewall-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-opensearchserverless-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-opensearchserverless-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-opensearchservice-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-opensearchservice-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-organizations-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-organizations-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-pipes-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-pipes-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-prometheusservice-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-prometheusservice-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-quicksight-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-quicksight-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-ram-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-ram-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-rds-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-rds-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-recyclebin-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-recyclebin-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-route53-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-route53-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-route53resolver-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-route53resolver-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-s3-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-s3-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-s3control-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-s3control-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-s3files-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-s3files-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-s3tables-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-s3tables-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-s3vectors-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-s3vectors-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-sagemaker-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-sagemaker-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-secretsmanager-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-secretsmanager-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-ses-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-ses-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-sfn-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-sfn-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-sns-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-sns-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-sqs-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-sqs-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-ssm-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-ssm-controller + +--- +apiVersion: olm.operatorframework.io/v1 +kind: ClusterExtension +metadata: + name: ack-wafv2-controller +spec: + namespace: ack-system + source: + sourceType: Catalog + catalog: + packageName: ack-wafv2-controller diff --git a/status_metrics_wip.json b/status_metrics_wip.json new file mode 100644 index 0000000000..bab12df066 --- /dev/null +++ b/status_metrics_wip.json @@ -0,0 +1,2590 @@ +{ + "name": "ack-acm-controller", + "pkg": "ack-acm-controller", + "ver": "1.8.1", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-acmpca-controller", + "pkg": "ack-acmpca-controller", + "ver": "1.5.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-apigateway-controller", + "pkg": "ack-apigateway-controller", + "ver": "1.9.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-apigatewayv2-controller", + "pkg": "ack-apigatewayv2-controller", + "ver": "1.5.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-applicationautoscaling-controller", + "pkg": "ack-applicationautoscaling-controller", + "ver": "1.7.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-athena-controller", + "pkg": "ack-athena-controller", + "ver": "1.8.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-autoscaling-controller", + "pkg": "ack-autoscaling-controller", + "ver": "1.2.1", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-backup-controller", + "pkg": "ack-backup-controller", + "ver": "1.2.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-bedrock-controller", + "pkg": "ack-bedrock-controller", + "ver": "1.4.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-bedrockagent-controller", + "pkg": "ack-bedrockagent-controller", + "ver": "1.3.1", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-bedrockagentcorecontrol-controller", + "pkg": "ack-bedrockagentcorecontrol-controller", + "ver": "1.15.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-cloudfront-controller", + "pkg": "ack-cloudfront-controller", + "ver": "1.8.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-cloudtrail-controller", + "pkg": "ack-cloudtrail-controller", + "ver": "1.7.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-cloudwatch-controller", + "pkg": "ack-cloudwatch-controller", + "ver": "1.9.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-cloudwatchlogs-controller", + "pkg": "ack-cloudwatchlogs-controller", + "ver": "1.6.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-codeartifact-controller", + "pkg": "ack-codeartifact-controller", + "ver": "1.7.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-cognitoidentityprovider-controller", + "pkg": "ack-cognitoidentityprovider-controller", + "ver": "1.6.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-dms-controller", + "pkg": "ack-dms-controller", + "ver": "0.2.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-documentdb-controller", + "pkg": "ack-documentdb-controller", + "ver": "1.7.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-dsql-controller", + "pkg": "ack-dsql-controller", + "ver": "1.2.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-dynamodb-controller", + "pkg": "ack-dynamodb-controller", + "ver": "1.12.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-ec2-controller", + "pkg": "ack-ec2-controller", + "ver": "1.21.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-ecr-controller", + "pkg": "ack-ecr-controller", + "ver": "1.9.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-ecrpublic-controller", + "pkg": "ack-ecrpublic-controller", + "ver": "1.5.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-ecs-controller", + "pkg": "ack-ecs-controller", + "ver": null, + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "Unknown", + "reason": "Absent" + }, + { + "type": "Installed", + "status": "False", + "reason": "Failed" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Retrying" + } + ] +} +{ + "name": "ack-efs-controller", + "pkg": "ack-efs-controller", + "ver": "1.5.1", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-eks-controller", + "pkg": "ack-eks-controller", + "ver": "1.21.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-elasticache-controller", + "pkg": "ack-elasticache-controller", + "ver": "1.9.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-elbv2-controller", + "pkg": "ack-elbv2-controller", + "ver": "1.7.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-emr-controller", + "pkg": "ack-emr-controller", + "ver": "0.2.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-emrcontainers-controller", + "pkg": "ack-emrcontainers-controller", + "ver": "1.7.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-emrserverless-controller", + "pkg": "ack-emrserverless-controller", + "ver": "1.2.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-eventbridge-controller", + "pkg": "ack-eventbridge-controller", + "ver": "1.7.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-firehose-controller", + "pkg": "ack-firehose-controller", + "ver": "0.5.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-glue-controller", + "pkg": "ack-glue-controller", + "ver": "1.2.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-iam-controller", + "pkg": "ack-iam-controller", + "ver": null, + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "Unknown", + "reason": "Absent" + }, + { + "type": "Installed", + "status": "False", + "reason": "Failed" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Retrying" + } + ] +} +{ + "name": "ack-kafka-controller", + "pkg": "ack-kafka-controller", + "ver": "1.12.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-keyspaces-controller", + "pkg": "ack-keyspaces-controller", + "ver": "1.6.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-kinesis-controller", + "pkg": "ack-kinesis-controller", + "ver": "1.5.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-kms-controller", + "pkg": "ack-kms-controller", + "ver": "1.5.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-lambda-controller", + "pkg": "ack-lambda-controller", + "ver": "1.17.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-lambdamicrovms-controller", + "pkg": "ack-lambdamicrovms-controller", + "ver": "0.3.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-memorydb-controller", + "pkg": "ack-memorydb-controller", + "ver": "1.7.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-mq-controller", + "pkg": "ack-mq-controller", + "ver": "1.6.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-mwaa-controller", + "pkg": "ack-mwaa-controller", + "ver": "1.2.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-networkfirewall-controller", + "pkg": "ack-networkfirewall-controller", + "ver": "1.5.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-opensearchserverless-controller", + "pkg": "ack-opensearchserverless-controller", + "ver": "1.2.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-opensearchservice-controller", + "pkg": "ack-opensearchservice-controller", + "ver": "1.6.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-organizations-controller", + "pkg": "ack-organizations-controller", + "ver": "1.5.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-pipes-controller", + "pkg": "ack-pipes-controller", + "ver": "1.6.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-prometheusservice-controller", + "pkg": "ack-prometheusservice-controller", + "ver": "1.7.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-quicksight-controller", + "pkg": "ack-quicksight-controller", + "ver": "1.1.2", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-ram-controller", + "pkg": "ack-ram-controller", + "ver": "1.5.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-rds-controller", + "pkg": "ack-rds-controller", + "ver": "1.12.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-recyclebin-controller", + "pkg": "ack-recyclebin-controller", + "ver": "1.5.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-route53-controller", + "pkg": "ack-route53-controller", + "ver": "1.6.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-route53resolver-controller", + "pkg": "ack-route53resolver-controller", + "ver": "1.9.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-s3-controller", + "pkg": "ack-s3-controller", + "ver": "1.11.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-s3control-controller", + "pkg": "ack-s3control-controller", + "ver": "1.6.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-s3files-controller", + "pkg": "ack-s3files-controller", + "ver": "1.2.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-s3tables-controller", + "pkg": "ack-s3tables-controller", + "ver": "1.2.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-s3vectors-controller", + "pkg": "ack-s3vectors-controller", + "ver": "1.2.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-sagemaker-controller", + "pkg": "ack-sagemaker-controller", + "ver": "1.10.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-secretsmanager-controller", + "pkg": "ack-secretsmanager-controller", + "ver": null, + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "Unknown", + "reason": "Absent" + }, + { + "type": "Installed", + "status": "False", + "reason": "Failed" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Retrying" + } + ] +} +{ + "name": "ack-ses-controller", + "pkg": "ack-ses-controller", + "ver": "1.5.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-sfn-controller", + "pkg": "ack-sfn-controller", + "ver": "1.6.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-sns-controller", + "pkg": "ack-sns-controller", + "ver": "1.10.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-sqs-controller", + "pkg": "ack-sqs-controller", + "ver": "1.7.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-ssm-controller", + "pkg": "ack-ssm-controller", + "ver": "1.6.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +} +{ + "name": "ack-wafv2-controller", + "pkg": "ack-wafv2-controller", + "ver": "1.6.0", + "conds": [ + { + "type": "Deprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "PackageDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "ChannelDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "BundleDeprecated", + "status": "False", + "reason": "NotDeprecated" + }, + { + "type": "Installed", + "status": "True", + "reason": "Succeeded" + }, + { + "type": "Progressing", + "status": "True", + "reason": "Succeeded" + } + ] +}