-
Notifications
You must be signed in to change notification settings - Fork 2
section: Add kube_node_info_v1 #26
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
Open
bx9001
wants to merge
4
commits into
Checkmk:master
Choose a base branch
from
bx9001:CMK-36235-node-info
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 3 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -4,7 +4,10 @@ use std::sync::Arc; | |||||
|
|
||||||
| use crate::host_settings::HostSettings; | ||||||
| use crate::piggyback::{AggregationHost, Meta, PiggybackHost}; | ||||||
| use crate::section::writeable::{SectionError, WriteableSection}; | ||||||
| use crate::section::{ | ||||||
| node::KubeNodeInfoV1, | ||||||
| writeable::{SectionError, WriteableSection}, | ||||||
| }; | ||||||
| use crate::snapshot::Snapshot; | ||||||
|
|
||||||
| pub struct Node<'a> { | ||||||
|
|
@@ -52,6 +55,9 @@ impl PiggybackHost for Node<'_> { | |||||
| fn emit(&self) -> Vec<Result<WriteableSection, SectionError>> { | ||||||
| let me = self.meta.piggyback_hostname(&self.settings.cluster_name); | ||||||
| let mut out = Vec::new(); | ||||||
| if let Some(kube_node_info_v1) = KubeNodeInfoV1::from_node(self.api, self.settings) { | ||||||
| out.push(WriteableSection::of(&me, &kube_node_info_v1)); | ||||||
| }; | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Stray semicolon here
Suggested change
We have a few others in the repo, too, I just checked. Feel free to add this to |
||||||
| out.extend(self.aggregation_sections(&me)); | ||||||
| out | ||||||
| } | ||||||
|
|
||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| use k8s_openapi::api::core::v1::Node; | ||
| use serde::Serialize; | ||
| use std::collections::BTreeMap; | ||
|
|
||
| use crate::host_settings::HostSettings; | ||
| use crate::section::Section; | ||
| use crate::section::common::LabelRef; | ||
|
|
||
| /// One entry of a Node's `status.addresses`. | ||
| /// | ||
| /// Not `k8s_openapi`'s `NodeAddress`: that one serializes as `type`, while | ||
| /// Checkmk expects `type_`. | ||
| #[derive(Serialize)] | ||
| pub(crate) struct NodeAddressRef<'a> { | ||
| address: &'a str, | ||
| type_: &'a str, | ||
| } | ||
|
|
||
| /// Node info. (`kube_node_info_v1`) | ||
| #[derive(Serialize)] | ||
| pub(crate) struct KubeNodeInfoV1<'a> { | ||
| pub architecture: &'a str, | ||
| pub kernel_version: &'a str, | ||
| pub os_image: &'a str, | ||
| pub operating_system: &'a str, | ||
| pub container_runtime_version: &'a str, | ||
| pub name: &'a str, | ||
| pub creation_timestamp: Option<f64>, | ||
| pub labels: BTreeMap<&'a str, LabelRef<'a>>, | ||
| /// Annotations filtered with user input. | ||
| /// | ||
| /// After receiving the annotations from the Kubernetes API, we cannot | ||
| /// process all of them as HostLabels. FilteredAnnotations are those | ||
| /// annotations, which can be processed. This means that the annotations can | ||
| /// no longer be arbitrary json objects and that options from the | ||
| /// `Kubernetes` rule have been taken into account. | ||
| pub annotations: BTreeMap<&'a str, &'a str>, | ||
| pub addresses: Vec<NodeAddressRef<'a>>, | ||
| pub cluster: &'a str, | ||
| pub kubernetes_cluster_hostname: &'a str, | ||
| } | ||
|
|
||
| impl<'a> KubeNodeInfoV1<'a> { | ||
| pub fn from_node(node: &'a Node, settings: &'a HostSettings) -> Option<KubeNodeInfoV1<'a>> { | ||
| let status = node.status.as_ref()?; | ||
| let node_info = status.node_info.as_ref()?; | ||
| let node_section = KubeNodeInfoV1 { | ||
| architecture: &node_info.architecture, | ||
| kernel_version: &node_info.kernel_version, | ||
| os_image: &node_info.os_image, | ||
| operating_system: &node_info.operating_system, | ||
| container_runtime_version: &node_info.container_runtime_version, | ||
| name: node.metadata.name.as_deref()?, | ||
| creation_timestamp: node | ||
| .metadata | ||
| .creation_timestamp | ||
| .as_ref() | ||
| .map(|x| x.0.as_millisecond() as f64 / 1000.0), | ||
| labels: node | ||
| .metadata | ||
| .labels | ||
| .as_ref() | ||
| .map(LabelRef::from_map) | ||
| .unwrap_or_default(), | ||
| annotations: node | ||
| .metadata | ||
| .annotations | ||
| .as_ref() | ||
| .map(|x| settings.annotation_key_pattern.filter(x)) | ||
| .unwrap_or_default(), | ||
| addresses: status | ||
| .addresses | ||
| .iter() | ||
| .flatten() | ||
| .map(|x| NodeAddressRef { | ||
| address: &x.address, | ||
| type_: &x.type_, | ||
| }) | ||
| .collect(), | ||
| cluster: &settings.cluster_name, | ||
| kubernetes_cluster_hostname: &settings.cluster_host_name, | ||
| }; | ||
| Some(node_section) | ||
| } | ||
| } | ||
| impl Section for KubeNodeInfoV1<'_> { | ||
| const NAME: &'static str = "kube_node_info_v1"; | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
| use regex::Regex; | ||
|
|
||
| use crate::host_settings::AnnotationKeyPattern; | ||
| use crate::test_support::{host_settings, node, node_prefilled}; | ||
|
|
||
| #[test] | ||
| fn kube_node_info_v1() { | ||
| let node = node_prefilled("worker-1"); | ||
| let mut settings = host_settings(); | ||
| insta::assert_json_snapshot!(KubeNodeInfoV1::from_node(&node, &settings)); | ||
|
|
||
| // This pattern should only match one annotation | ||
| settings.annotation_key_pattern = | ||
| AnnotationKeyPattern::Pattern(Regex::new("^example").unwrap()); | ||
| assert_eq!( | ||
| KubeNodeInfoV1::from_node(&node, &settings) | ||
| .unwrap() | ||
| .annotations | ||
| .len(), | ||
| 1 | ||
| ); | ||
|
|
||
| // Ignore all annotations, emit 0 of them | ||
| settings.annotation_key_pattern = AnnotationKeyPattern::IgnoreAll; | ||
| assert_eq!( | ||
| KubeNodeInfoV1::from_node(&node, &settings) | ||
| .unwrap() | ||
| .annotations | ||
| .len(), | ||
| 0 | ||
| ); | ||
|
|
||
| // Import all annotations (fixture default, captured by insta above, but let's be explicit) | ||
| settings.annotation_key_pattern = AnnotationKeyPattern::ImportAll; | ||
| assert_eq!( | ||
| KubeNodeInfoV1::from_node(&node, &settings) | ||
| .unwrap() | ||
| .annotations | ||
| .len(), | ||
| 2 | ||
| ); | ||
| } | ||
|
|
||
| /// A Node without `status.nodeInfo` cannot fill the five mandatory fields | ||
| /// of the section, so we emit nothing rather than something unparseable. | ||
| #[test] | ||
| fn kube_node_info_v1_without_node_info() { | ||
| assert!(KubeNodeInfoV1::from_node(&node("worker-1"), &host_settings()).is_none()); | ||
| } | ||
| } |
39 changes: 39 additions & 0 deletions
39
...s-cache/src/section/snapshots/metrics_cache__section__node__tests__kube_node_info_v1.snap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| --- | ||
| source: metrics-cache/src/section/node.rs | ||
| expression: "KubeNodeInfoV1::from_node(&node, &settings)" | ||
| --- | ||
| { | ||
| "architecture": "amd64", | ||
| "kernel_version": "6.8.0-51-generic", | ||
| "os_image": "Ubuntu 22.04.5 LTS", | ||
| "operating_system": "linux", | ||
| "container_runtime_version": "containerd://1.7.24", | ||
| "name": "worker-1", | ||
| "creation_timestamp": 1786130565.0, | ||
| "labels": { | ||
| "kubernetes.io/arch": { | ||
| "name": "kubernetes.io/arch", | ||
| "value": "amd64" | ||
| }, | ||
| "kubernetes.io/hostname": { | ||
| "name": "kubernetes.io/hostname", | ||
| "value": "worker-1" | ||
| } | ||
| }, | ||
| "annotations": { | ||
| "checkmk.com/promote-to-host": "true", | ||
| "example.com/cool-animal": "monkeys" | ||
| }, | ||
| "addresses": [ | ||
| { | ||
| "address": "10.0.0.5", | ||
| "type_": "InternalIP" | ||
| }, | ||
| { | ||
| "address": "worker-1", | ||
| "type_": "Hostname" | ||
| } | ||
| ], | ||
| "cluster": "the-cluster", | ||
| "kubernetes_cluster_hostname": "cluster.host.tld" | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
By convention with the rest of the project, prefer to only group leaves of import trees:
But I know there are a few places lingering in the repo that break the convention.
(This would be nice to enforce with
rustfmtbut it's a nightly-only feature 😕)