-
Notifications
You must be signed in to change notification settings - Fork 292
feat: generic objects #1996
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat: generic objects #1996
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,84 @@ | ||||||||||||||||||
| Generic resource tracking | ||||||||||||||||||
| =============== | ||||||||||||||||||
|
|
||||||||||||||||||
| Track changes to any Kubernetes resource | ||||||||||||||||||
|
|
||||||||||||||||||
| Track HTTPRoute Change | ||||||||||||||||||
| -------------------------------- | ||||||||||||||||||
|
|
||||||||||||||||||
| For example, get notified when an HTTPRoute resource changes. | ||||||||||||||||||
|
|
||||||||||||||||||
| **Setup Steps**: | ||||||||||||||||||
|
|
||||||||||||||||||
| 1. **Grant Permissions to Robusta**: By default, Robusta does not have permission to read it | ||||||||||||||||||
| 2. **Configure Kubewatch**: Set up Kubewatch to monitor HTTPRoute resources | ||||||||||||||||||
| 3. **Create Custom Playbook**: Define notification rules | ||||||||||||||||||
|
|
||||||||||||||||||
| **1. Grant Permissions to Robusta** | ||||||||||||||||||
|
|
||||||||||||||||||
| Create a YAML file named ``kubewatch-httproute-permissions.yaml`` with the following content: | ||||||||||||||||||
|
|
||||||||||||||||||
| .. code-block:: yaml | ||||||||||||||||||
| kind: ClusterRole | ||||||||||||||||||
| apiVersion: rbac.authorization.k8s.io/v1 | ||||||||||||||||||
| metadata: | ||||||||||||||||||
| name: kubewatch-custom-role | ||||||||||||||||||
| rules: | ||||||||||||||||||
| - apiGroups: | ||||||||||||||||||
| - "gateway.networking.k8s.io" | ||||||||||||||||||
| resources: | ||||||||||||||||||
| - httproutes | ||||||||||||||||||
| verbs: | ||||||||||||||||||
| - get | ||||||||||||||||||
| - list | ||||||||||||||||||
| - watch | ||||||||||||||||||
| --- | ||||||||||||||||||
| apiVersion: rbac.authorization.k8s.io/v1 | ||||||||||||||||||
| kind: ClusterRoleBinding | ||||||||||||||||||
| metadata: | ||||||||||||||||||
| name: kubewatch-custom-role-binding | ||||||||||||||||||
| roleRef: | ||||||||||||||||||
| kind: ClusterRole | ||||||||||||||||||
| name: kubewatch-custom-role | ||||||||||||||||||
| subjects: | ||||||||||||||||||
| - kind: ServiceAccount | ||||||||||||||||||
| name: robusta-forwarder-service-account | ||||||||||||||||||
| namespace: default | ||||||||||||||||||
|
Comment on lines
+44
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hardcoded namespace may not match actual deployment. The ServiceAccount namespace is hardcoded to 📝 Suggested fix subjects:
- kind: ServiceAccount
name: robusta-forwarder-service-account
- namespace: default
+ namespace: robusta # Adjust to match your Robusta installation namespace📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
| Apply the permissions: | ||||||||||||||||||
|
|
||||||||||||||||||
| .. code-block:: bash | ||||||||||||||||||
| kubectl apply -f kubewatch-httproute-permissions.yaml | ||||||||||||||||||
| **2. Configure Kubewatch to Monitor HTTPRoute** | ||||||||||||||||||
|
|
||||||||||||||||||
| Add the following to the ``kubewatch`` section in your ``generated_values.yaml``: | ||||||||||||||||||
|
|
||||||||||||||||||
| .. code-block:: yaml | ||||||||||||||||||
| kubewatch: | ||||||||||||||||||
| config: | ||||||||||||||||||
| customresources: | ||||||||||||||||||
| - group: gateway.networking.k8s.io | ||||||||||||||||||
| version: v1 | ||||||||||||||||||
| resource: httproutes | ||||||||||||||||||
| **3. Create Custom Playbook** | ||||||||||||||||||
|
|
||||||||||||||||||
| Add the following to the ``customPlaybooks`` section in your ``generated_values.yaml``: | ||||||||||||||||||
|
|
||||||||||||||||||
| .. code-block:: yaml | ||||||||||||||||||
| customPlaybooks: | ||||||||||||||||||
| - triggers: | ||||||||||||||||||
| - on_kubernetes_resource_operation: | ||||||||||||||||||
| namespace_prefix: "monitoring" | ||||||||||||||||||
| name_prefix: "grafana-" | ||||||||||||||||||
| actions: | ||||||||||||||||||
| - create_finding: # | ||||||||||||||||||
| title: "resource $name in namespace $namespace was modified" | ||||||||||||||||||
| aggregation_key: "resource_modified" | ||||||||||||||||||
|
Comment on lines
+74
to
+82
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Playbook example filters don't align with HTTPRoute context. The example uses 📝 Suggested fix customPlaybooks:
- triggers:
- on_kubernetes_resource_operation:
- namespace_prefix: "monitoring"
- name_prefix: "grafana-"
+ # Adjust these filters to match your HTTPRoute resources
+ namespace_prefix: ""
+ name_prefix: ""
actions:
- - create_finding: #
+ - create_finding:
title: "resource $name in namespace $namespace was modified"
aggregation_key: "resource_modified"🤖 Prompt for AI Agents |
||||||||||||||||||
| Then perform a :ref:`Helm Upgrade <Simple Upgrade>`. | ||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,7 +5,7 @@ | |||||||||||||||
|
|
||||||||||||||||
| from robusta.core.model.events import ExecutionBaseEvent | ||||||||||||||||
| from robusta.core.model.k8s_operation_type import K8sOperationType | ||||||||||||||||
| from robusta.core.reporting import Finding, FindingSource | ||||||||||||||||
| from robusta.core.reporting import Finding, FindingSource, FindingSubject, FindingSubjectType | ||||||||||||||||
|
|
||||||||||||||||
|
|
||||||||||||||||
| @dataclass | ||||||||||||||||
|
|
@@ -31,3 +31,39 @@ def create_default_finding(self) -> Finding: | |||||||||||||||
| @classmethod | ||||||||||||||||
| def get_source(cls) -> FindingSource: | ||||||||||||||||
| return FindingSource.KUBERNETES_API_SERVER | ||||||||||||||||
|
|
||||||||||||||||
| def get_subject(self) -> FindingSubject: | ||||||||||||||||
| """Get subject information from the Kubernetes object, including custom resources.""" | ||||||||||||||||
| if not self.obj: | ||||||||||||||||
| return FindingSubject(name="Unresolved", subject_type=FindingSubjectType.TYPE_NONE) | ||||||||||||||||
|
|
||||||||||||||||
| # Handle both Hikaru objects and GenericKubernetesObject | ||||||||||||||||
| if hasattr(self.obj, 'metadata') and self.obj.metadata: | ||||||||||||||||
| metadata = self.obj.metadata | ||||||||||||||||
| name = getattr(metadata, 'name', None) or 'Unresolved' | ||||||||||||||||
| namespace = getattr(metadata, 'namespace', None) | ||||||||||||||||
| labels = getattr(metadata, 'labels', {}) or {} | ||||||||||||||||
| annotations = getattr(metadata, 'annotations', {}) or {} | ||||||||||||||||
| else: | ||||||||||||||||
| name = 'Unresolved' | ||||||||||||||||
| namespace = None | ||||||||||||||||
| labels = {} | ||||||||||||||||
| annotations = {} | ||||||||||||||||
|
|
||||||||||||||||
| # Get the kind from the object | ||||||||||||||||
| kind = getattr(self.obj, 'kind', None) or 'Unknown' | ||||||||||||||||
|
|
||||||||||||||||
| # Determine the subject type from the kind | ||||||||||||||||
| try: | ||||||||||||||||
| subject_type = FindingSubjectType.from_kind(kind) | ||||||||||||||||
| except: | ||||||||||||||||
| # Fallback for unknown kinds | ||||||||||||||||
| subject_type = FindingSubjectType.TYPE_NONE | ||||||||||||||||
|
Comment on lines
+57
to
+61
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid bare The bare 📝 Suggested fix # Determine the subject type from the kind
- try:
- subject_type = FindingSubjectType.from_kind(kind)
- except:
- # Fallback for unknown kinds
- subject_type = FindingSubjectType.TYPE_NONE
+ subject_type = FindingSubjectType.from_kind(kind)If defensive handling is preferred: - except:
+ except Exception:📝 Committable suggestion
Suggested change
🧰 Tools🪛 Flake8 (7.3.0)[error] 59-59: do not use bare 'except' (E722) 🪛 Ruff (0.14.11)59-59: Do not use bare (E722) 🤖 Prompt for AI Agents |
||||||||||||||||
|
|
||||||||||||||||
| return FindingSubject( | ||||||||||||||||
| name=name, | ||||||||||||||||
| subject_type=subject_type, | ||||||||||||||||
| namespace=namespace, | ||||||||||||||||
| labels=labels, | ||||||||||||||||
| annotations=annotations, | ||||||||||||||||
| ) | ||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RST underline should match or exceed title length.
The underline
===============(15 characters) is shorter than the title "Generic resource tracking" (25 characters). In reStructuredText, the underline should be at least as long as the title text.📝 Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents