Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ HolmesGPT integrates with popular observability and cloud platforms. The followi
| [<img src="images/integration_logos/confluence_logo.png" alt="Confluence" width="20" style="vertical-align: middle;"> **Confluence**](https://holmesgpt.dev/data-sources/builtin-toolsets/confluence/) | Private runbooks and documentation |
| [<img src="images/integration_logos/confluence_logo.png" alt="Confluence MCP" width="20" style="vertical-align: middle;"> **Confluence (MCP)**](https://holmesgpt.dev/data-sources/builtin-toolsets/confluence-mcp/) | Private runbooks and documentation (MCP) |
| [<img src="images/integration_logos/coralogix-icon.png" alt="Coralogix" width="20" style="vertical-align: middle;"> **Coralogix**](https://holmesgpt.dev/data-sources/builtin-toolsets/coralogix-logs/) | Retrieve logs for any resource |
| [<img src="images/integration_logos/crossplane-icon.png" alt="Crossplane" width="20" style="vertical-align: middle;"> **Crossplane**](https://holmesgpt.dev/data-sources/builtin-toolsets/crossplane/) | Troubleshoot Crossplane providers, compositions, claims, and managed resources |
| [<img src="images/integration_logos/datadog_logo.png" alt="Datadog" width="20" style="vertical-align: middle;"> **Datadog**](https://holmesgpt.dev/data-sources/builtin-toolsets/datadog/) | Query logs, metrics, and traces |
| [<img src="images/integration_logos/docker_logo.png" alt="Docker" width="20" style="vertical-align: middle;"> **Docker**](https://holmesgpt.dev/data-sources/builtin-toolsets/docker/) | Get images, logs, events, history and more |
| [<img src="images/integration_logos/opensearchserverless-icon.png" alt="Elasticsearch" width="20" style="vertical-align: middle;"> **Elasticsearch / OpenSearch**](https://holmesgpt.dev/data-sources/builtin-toolsets/elasticsearch/) | Query logs, cluster health, shard and index diagnostics |
Expand Down
1 change: 1 addition & 0 deletions docs/data-sources/builtin-toolsets/.nav.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ nav:
- Confluence (MCP): confluence-mcp.md
- Connectivity Check: connectivity-check.md
- Coralogix: coralogix-logs.md
- Crossplane: crossplane.md
- DataDog: datadog.md
- Docker: docker.md
- Elasticsearch / OpenSearch: elasticsearch.md
Expand Down
80 changes: 80 additions & 0 deletions docs/data-sources/builtin-toolsets/crossplane.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Crossplane

By enabling this toolset, HolmesGPT will be able to troubleshoot Crossplane-managed infrastructure by inspecting providers, compositions, claims, composite resources, and managed resources across the full resource hierarchy.

## Prerequisites

Crossplane must be installed on your Kubernetes cluster. HolmesGPT uses `kubectl` to query Crossplane custom resources, so no additional CLI tools are required.

HolmesGPT needs read access to Crossplane CRDs. If you use Kubernetes RBAC, ensure the service account has permissions to `get` and `list` the following API groups:

```yaml
# Add to your ClusterRole
- apiGroups: ["pkg.crossplane.io"]
resources: ["providers", "providerrevisions"]
verbs: ["get", "list"]
- apiGroups: ["apiextensions.crossplane.io"]
resources: ["compositeresourcedefinitions", "compositions"]
verbs: ["get", "list"]
# For managed resources, add the specific API groups used by your providers.
# Example for AWS provider:
- apiGroups: ["s3.aws.upbound.io", "rds.aws.upbound.io", "ec2.aws.upbound.io"]
resources: ["*"]
verbs: ["get", "list"]
```

## Configuration

=== "Holmes CLI"

Add the following to **~/.holmes/config.yaml**:

```yaml
toolsets:
crossplane/core:
enabled: true
```

--8<-- "snippets/toolset_refresh_warning.md"

To test, run:

```bash
holmes ask "Which Crossplane managed resources are failing and why?"
```

=== "Robusta Helm Chart"

```yaml
holmes:
customClusterRoleRules:
- apiGroups: ["pkg.crossplane.io"]
resources: ["providers", "providerrevisions"]
verbs: ["get", "list"]
- apiGroups: ["apiextensions.crossplane.io"]
resources: ["compositeresourcedefinitions", "compositions"]
verbs: ["get", "list"]
toolsets:
crossplane/core:
enabled: true
```

--8<-- "snippets/helm_upgrade_command.md"

## Common Use Cases

```bash
holmes ask "Which Crossplane managed resources are failing and why?"
```

```bash
holmes ask "Are all Crossplane providers healthy?"
```

```bash
holmes ask "Trace the claim my-database in namespace production and find which managed resource is broken"
```

```bash
holmes ask "Why is my S3 bucket not becoming ready?"
```
1 change: 1 addition & 0 deletions docs/data-sources/builtin-toolsets/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ HolmesGPT includes pre-built integrations for popular monitoring and observabili
- [:simple-kubernetes:{ .lg .middle } **Kubectl Run**](kubectl-run.md)
- [:simple-argo:{ .lg .middle } **ArgoCD**](argocd.md)
- [:simple-cilium:{ .lg .middle } **Cilium**](cilium.md)
- [:material-cloud-sync:{ .lg .middle } **Crossplane**](crossplane.md)
- [:material-magnify:{ .lg .middle } **Inspektor Gadget**](inspektor-gadget.md)
- [:material-microsoft-azure:{ .lg .middle } **Azure Kubernetes Service**](aks.md)
- [:material-heart-pulse:{ .lg .middle } **AKS Node Health**](aks-node-health.md)
Expand Down
2 changes: 1 addition & 1 deletion docs/why-holmesgpt.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ HolmesGPT ships with read-only integrations for every major observability vendor
- **Logs**: Loki, Elasticsearch/OpenSearch, Datadog, Coralogix, Splunk
- **Traces**: Tempo, Datadog, NewRelic
- **Dashboards**: Grafana
- **Infrastructure**: Kubernetes, Docker, Helm, ArgoCD, OpenShift, Cilium, KubeVela
- **Infrastructure**: Kubernetes, Docker, Helm, ArgoCD, Crossplane, OpenShift, Cilium, KubeVela
- **CI/CD**: Jenkins
- **Cloud**: AWS RDS, Azure SQL, Azure AKS, GCP
- **Databases**: PostgreSQL, MySQL, ClickHouse, MariaDB, SQL Server, MongoDB Atlas
Expand Down
101 changes: 101 additions & 0 deletions holmes/plugins/toolsets/crossplane.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
toolsets:
crossplane/core:
description: "Tools for troubleshooting Crossplane managed resources, compositions, providers, and claims"
docs_url: "https://holmesgpt.dev/data-sources/builtin-toolsets/crossplane/"
icon_url: "https://raw.githubusercontent.com/crossplane/crossplane/master/docs/media/logo.svg"
llm_instructions: |
You have tools to debug Crossplane-managed infrastructure-as-code resources.
Crossplane uses a resource hierarchy: Claims -> Composite Resources (XRs) -> Managed Resources.
Providers are controllers that reconcile managed resources against cloud APIs.

ALWAYS follow this investigation order:
1. Check provider health with crossplane_list_providers - a broken provider causes all its managed resources to fail
2. If investigating a specific resource, trace its hierarchy from claim down to managed resources
3. Check status.conditions on each resource level:
- Synced=False usually means a provider/API error (wrong credentials, quota exceeded, invalid config)
- Ready=False but Synced=True means the resource is still provisioning or waiting for a dependency
- Installed/Healthy conditions on providers indicate controller health
4. Look at events for detailed error messages
5. Compare spec vs status for drift detection

When a managed resource fails:
- First check if its provider is healthy
- Then check the ProviderConfig for credential/connectivity issues
- Then look at the managed resource's conditions and events for the specific API error

{% if tool_names|list|length > 0 %}
The following Crossplane tools are available: {{ ", ".join(tool_names) }}
{% endif %}

DO NOT tell the user to check resources manually. Investigate on their behalf using the available tools and report your findings with specific details.
tags:
- core
prerequisites:
- command: "kubectl api-resources --api-group=pkg.crossplane.io --no-headers 2>/dev/null | grep -q providers"

tools:
- name: "crossplane_list_providers"
description: "List all installed Crossplane providers with their health status, installed version, and package reference"
command: "kubectl get providers.pkg.crossplane.io -o wide 2>&1"

- name: "crossplane_get_provider"
description: "Get detailed status of a specific Crossplane provider including conditions (Installed, Healthy), revision, and package info"
command: "kubectl get providers.pkg.crossplane.io {{ provider_name }} -o yaml 2>&1"

- name: "crossplane_list_provider_revisions"
description: "List provider revisions to check for version rollout issues or stuck upgrades"
command: "kubectl get providerrevisions.pkg.crossplane.io -o wide 2>&1"

- name: "crossplane_list_provider_configs"
description: "List ProviderConfigs of a specific type to check credential configurations. The provider_config_kind should be the full CRD kind (e.g., providerconfigs.aws.upbound.io, providerconfigs.gcp.upbound.io)"
command: "kubectl get {{ provider_config_kind }} -o wide 2>&1"

- name: "crossplane_get_provider_config"
description: "Get detailed ProviderConfig including credential source and configuration"
command: "kubectl get {{ provider_config_kind }} {{ config_name }} -o yaml 2>&1"

- name: "crossplane_list_xrds"
description: "List all CompositeResourceDefinitions (XRDs) which define the schema for composite resources and claims"
command: "kubectl get compositeresourcedefinitions.apiextensions.crossplane.io -o wide 2>&1"

- name: "crossplane_get_xrd"
description: "Get details of a specific CompositeResourceDefinition including its schema, claim names, and offered versions"
command: "kubectl get compositeresourcedefinitions.apiextensions.crossplane.io {{ xrd_name }} -o yaml 2>&1"

- name: "crossplane_list_compositions"
description: "List all Compositions which define how composite resources map to managed resources"
command: "kubectl get compositions.apiextensions.crossplane.io -o wide 2>&1"

- name: "crossplane_get_composition"
description: "Get details of a specific Composition including its resource templates and patch sets"
command: "kubectl get compositions.apiextensions.crossplane.io {{ composition_name }} -o yaml 2>&1"

- name: "crossplane_get_claim"
description: "Get a Crossplane claim's full status including conditions, composite resource reference, and connection details. The claim_kind is the plural form (e.g., postgresqlinstances, buckets)"
command: "kubectl get {{ claim_kind }} {{ claim_name }} -n {{ namespace }} -o yaml 2>&1"

- name: "crossplane_get_composite_resource"
description: "Get a composite resource (XR) including its status, conditions, composed resource references, and connection details. The xr_kind is the plural form (e.g., xpostgresqlinstances, xbuckets)"
command: "kubectl get {{ xr_kind }} {{ xr_name }} -o yaml 2>&1"

- name: "crossplane_list_managed_resources"
description: "List managed resources of a specific kind with their sync and ready status. The resource_kind is the plural form (e.g., buckets.s3.aws.upbound.io, instances.rds.aws.upbound.io)"
command: "kubectl get {{ resource_kind }} -o wide 2>&1"

- name: "crossplane_get_managed_resource"
description: "Get full details of a specific managed resource including conditions (Synced, Ready, LastAsyncOperation), external name, and provider config reference"
script: |
#!/bin/bash
echo "=== Resource Status ==="
kubectl get {{ resource_kind }} {{ resource_name }} -o yaml 2>&1
echo ""
echo "=== Events ==="
kubectl get events --field-selector involvedObject.name={{ resource_name }} --sort-by='.lastTimestamp' 2>&1

- name: "crossplane_get_resource_events"
description: "Get Kubernetes events for a specific Crossplane resource to find error messages and status transitions"
command: "kubectl get events --field-selector involvedObject.name={{ resource_name }} --sort-by='.lastTimestamp' 2>&1"

- name: "crossplane_list_managed_by_composite"
description: "List all managed resources owned by a specific composite resource by label selector"
command: "kubectl get managed -l crossplane.io/composite={{ composite_name }} -o wide 2>&1"
Binary file added images/integration_logos/crossplane-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading