diff --git a/.changelog/2612.txt b/.changelog/2612.txt new file mode 100644 index 0000000000..41a44644cd --- /dev/null +++ b/.changelog/2612.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +Added `conditions` attribute to `kubernetes_nodes` data source, which will provide detailed node health and status information +``` \ No newline at end of file diff --git a/docs/data-sources/nodes.md b/docs/data-sources/nodes.md index 54d5ec792a..3e5b9e41f6 100644 --- a/docs/data-sources/nodes.md +++ b/docs/data-sources/nodes.md @@ -82,7 +82,7 @@ Read-Only: - `allocatable` (Map of String) - `capacity` (Map of String) - `node_info` (List of Object) (see [below for nested schema](#nestedobjatt--nodes--status--node_info)) - +- `conditions` (List of Object) (see [below for nested schema](#nestedobjatt--nodes--status--conditions)) ### Nested Schema for `nodes.status.addresses` @@ -108,7 +108,17 @@ Read-Only: - `os_image` (String) - `system_uuid` (String) + +### Nested Schema for `nodes.status.conditions` + +Read-Only: +- `type` (String) +- `status` (String) +- `last_heartbeat_time` (String) +- `last_transition_time` (String) +- `reason` (String) +- `message` (String) diff --git a/kubernetes/data_source_kubernetes_nodes_test.go b/kubernetes/data_source_kubernetes_nodes_test.go index d733fa1105..68cd84723c 100644 --- a/kubernetes/data_source_kubernetes_nodes_test.go +++ b/kubernetes/data_source_kubernetes_nodes_test.go @@ -33,6 +33,13 @@ func TestAccKubernetesDataSourceNodes_basic(t *testing.T) { resource.TestCheckResourceAttrWith(dataSourceName, "nodes.0.status.0.capacity.memory", checkParsableQuantity), resource.TestCheckResourceAttrSet(dataSourceName, "nodes.0.status.0.node_info.0.architecture"), resource.TestCheckResourceAttrSet(dataSourceName, "nodes.0.status.0.addresses.0.address"), + resource.TestMatchResourceAttr(dataSourceName, "nodes.0.status.0.conditions.#", oneOrMore), + resource.TestCheckResourceAttrSet(dataSourceName, "nodes.0.status.0.conditions.0.type"), + resource.TestCheckResourceAttrSet(dataSourceName, "nodes.0.status.0.conditions.0.status"), + resource.TestCheckResourceAttrSet(dataSourceName, "nodes.0.status.0.conditions.0.last_heartbeat_time"), + resource.TestCheckResourceAttrSet(dataSourceName, "nodes.0.status.0.conditions.0.last_transition_time"), + resource.TestCheckResourceAttrSet(dataSourceName, "nodes.0.status.0.conditions.0.reason"), + resource.TestCheckResourceAttrSet(dataSourceName, "nodes.0.status.0.conditions.0.message"), ) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, diff --git a/kubernetes/schema_node_spec.go b/kubernetes/schema_node_spec.go index d87186039c..cf445f124c 100644 --- a/kubernetes/schema_node_spec.go +++ b/kubernetes/schema_node_spec.go @@ -124,6 +124,39 @@ func nodeStatusFields() map[string]*schema.Schema { }, }, }, + "conditions": { + Type: schema.TypeList, + Computed: true, + Description: "List of conditions describing each node's health and operational status.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "last_heartbeat_time": { + Type: schema.TypeString, + Computed: true, + }, + "last_transition_time": { + Type: schema.TypeString, + Computed: true, + }, + "reason": { + Type: schema.TypeString, + Computed: true, + }, + "message": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, } } diff --git a/kubernetes/structures_node.go b/kubernetes/structures_node.go index 24dd1f06fe..fade3ad564 100644 --- a/kubernetes/structures_node.go +++ b/kubernetes/structures_node.go @@ -71,12 +71,29 @@ func flattenNodeInfo(in v1.NodeSystemInfo) []interface{} { return []interface{}{att} } +func flattenNodeConditions(conditions []v1.NodeCondition) []interface{} { + out := make([]interface{}, len(conditions)) + for i, condition := range conditions { + m := make(map[string]interface{}) + m["type"] = condition.Type + m["status"] = condition.Status + m["last_heartbeat_time"] = condition.LastHeartbeatTime.String() + m["last_transition_time"] = condition.LastTransitionTime.String() + m["reason"] = condition.Reason + m["message"] = condition.Message + out[i] = m + } + return out +} + func flattenNodeStatus(in v1.NodeStatus) []interface{} { att := make(map[string]interface{}) att["addresses"] = flattenAddresses(in.Addresses...) att["allocatable"] = flattenResourceList(in.Allocatable) att["capacity"] = flattenResourceList(in.Capacity) att["node_info"] = flattenNodeInfo(in.NodeInfo) + att["conditions"] = flattenNodeConditions(in.Conditions) + return []interface{}{att} }