From 3d4d570734c98aa70574abddba7f49eedc6b525d Mon Sep 17 00:00:00 2001 From: ikakeru Date: Mon, 3 Aug 2026 17:37:11 +0900 Subject: [PATCH] feat(inspection): add NodeNameDiscoveryTask for k8snode and k8scontainer log parsers - Add NodeNameDiscoveryTask for googlecloudlogk8snode to discover node names from K8sNodeLogCommonFieldSet.NodeName - Add NodeNameDiscoveryTask for googlecloudlogk8scontainer to discover node names from GCPContainerLogNodeNameLabelFieldSet.NodeName - Register NodeNameDiscoveryTask to each TailTask dependencies to include them in the inspection task graph - Update dry-run query placeholder comments in googlecloudlogcomputeapiaudit and googlecloudlogserialport --- .../impl/query_task.go | 2 +- .../impl/query_task_test.go | 2 +- .../contract/taskid.go | 3 + .../impl/nodename_discovery_task.go | 55 +++++++++++ .../impl/nodename_discovery_task_test.go | 98 +++++++++++++++++++ .../impl/parser_task.go | 1 + .../impl/registration.go | 1 + .../googlecloudlogk8snode/contract/taskid.go | 3 + .../googlecloudlogk8snode/impl/common_task.go | 1 + .../impl/nodename_discovery_task.go | 55 +++++++++++ .../impl/nodename_discovery_task_test.go | 98 +++++++++++++++++++ .../impl/registration.go | 1 + .../impl/query_task.go | 2 +- .../impl/query_task_test.go | 2 +- 14 files changed, 320 insertions(+), 4 deletions(-) create mode 100644 pkg/task/inspection/googlecloudlogk8scontainer/impl/nodename_discovery_task.go create mode 100644 pkg/task/inspection/googlecloudlogk8scontainer/impl/nodename_discovery_task_test.go create mode 100644 pkg/task/inspection/googlecloudlogk8snode/impl/nodename_discovery_task.go create mode 100644 pkg/task/inspection/googlecloudlogk8snode/impl/nodename_discovery_task_test.go diff --git a/pkg/task/inspection/googlecloudlogcomputeapiaudit/impl/query_task.go b/pkg/task/inspection/googlecloudlogcomputeapiaudit/impl/query_task.go index 4c0361338..e94c14107 100644 --- a/pkg/task/inspection/googlecloudlogcomputeapiaudit/impl/query_task.go +++ b/pkg/task/inspection/googlecloudlogcomputeapiaudit/impl/query_task.go @@ -34,7 +34,7 @@ import ( func GenerateComputeAPIQuery(taskMode inspectioncore_contract.InspectionTaskModeType, nodeNames []string) []string { if taskMode == inspectioncore_contract.TaskModeDryRun { return []string{ - generateComputeAPIQueryWithInstanceNameFilter("-- instance name filters to be determined after audit log query"), + generateComputeAPIQueryWithInstanceNameFilter("-- instance name filters to be determined after node name discovery"), } } else { result := []string{} diff --git a/pkg/task/inspection/googlecloudlogcomputeapiaudit/impl/query_task_test.go b/pkg/task/inspection/googlecloudlogcomputeapiaudit/impl/query_task_test.go index 98997e4d9..ae2f85797 100644 --- a/pkg/task/inspection/googlecloudlogcomputeapiaudit/impl/query_task_test.go +++ b/pkg/task/inspection/googlecloudlogcomputeapiaudit/impl/query_task_test.go @@ -35,7 +35,7 @@ func TestGenerateComputeAPIQuery(t *testing.T) { NodeNames: []string{}, // No nodes specified for dry run Expected: []string{`resource.type="gce_instance" -protoPayload.methodName:("list" OR "get" OR "watch") --- instance name filters to be determined after audit log query +-- instance name filters to be determined after node name discovery `}, }, { diff --git a/pkg/task/inspection/googlecloudlogk8scontainer/contract/taskid.go b/pkg/task/inspection/googlecloudlogk8scontainer/contract/taskid.go index 1f0416123..50ce83b74 100644 --- a/pkg/task/inspection/googlecloudlogk8scontainer/contract/taskid.go +++ b/pkg/task/inspection/googlecloudlogk8scontainer/contract/taskid.go @@ -53,3 +53,6 @@ var PodPhaseTimelineMapperTaskID = taskid.NewDefaultImplementationID[inspectiont // TailTaskID is a nop task just to require all container log mappers. var TailTaskID = taskid.NewDefaultImplementationID[struct{}](TaskIDPrefix + "tail") + +// NodeNameDiscoveryTaskID is the discovery task ID for extracting node names from Container log labels. +var NodeNameDiscoveryTaskID = taskid.NewDefaultImplementationID[[]string](TaskIDPrefix + "node-name-discovery") diff --git a/pkg/task/inspection/googlecloudlogk8scontainer/impl/nodename_discovery_task.go b/pkg/task/inspection/googlecloudlogk8scontainer/impl/nodename_discovery_task.go new file mode 100644 index 000000000..1701b8e81 --- /dev/null +++ b/pkg/task/inspection/googlecloudlogk8scontainer/impl/nodename_discovery_task.go @@ -0,0 +1,55 @@ +// Copyright 2026 Google LLC +// +// 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 googlecloudlogk8scontainer_impl + +import ( + "context" + + inspectionmetadata "github.com/GoogleCloudPlatform/khi/pkg/core/inspection/metadata" + coretask "github.com/GoogleCloudPlatform/khi/pkg/core/task" + "github.com/GoogleCloudPlatform/khi/pkg/core/task/taskid" + "github.com/GoogleCloudPlatform/khi/pkg/model/log" + commonlogk8saudit_contract "github.com/GoogleCloudPlatform/khi/pkg/task/inspection/commonlogk8saudit/contract" + googlecloudlogk8scontainer_contract "github.com/GoogleCloudPlatform/khi/pkg/task/inspection/googlecloudlogk8scontainer/contract" + inspectioncore_contract "github.com/GoogleCloudPlatform/khi/pkg/task/inspection/inspectioncore/contract" +) + +// NodeNameDiscoveryTask extracts node names from Kubernetes Container log labels and registers them to NodeNameInventoryTask. +var NodeNameDiscoveryTask = commonlogk8saudit_contract.NodeNameInventoryBuilder.DiscoveryTask( + googlecloudlogk8scontainer_contract.NodeNameDiscoveryTaskID, + []taskid.UntypedTaskReference{ + googlecloudlogk8scontainer_contract.FieldSetReaderTaskID.Ref(), + }, + func(ctx context.Context, taskMode inspectioncore_contract.InspectionTaskModeType, progress *inspectionmetadata.TaskProgressMetadata) ([]string, error) { + if taskMode == inspectioncore_contract.TaskModeDryRun { + return nil, nil + } + + foundNodeNames := map[string]struct{}{} + logs := coretask.GetTaskResult(ctx, googlecloudlogk8scontainer_contract.FieldSetReaderTaskID.Ref()) + for _, l := range logs { + fs, err := log.GetFieldSet(l, &googlecloudlogk8scontainer_contract.GCPContainerLogNodeNameLabelFieldSet{}) + if err == nil && fs.NodeName != "" { + foundNodeNames[fs.NodeName] = struct{}{} + } + } + + var result []string + for k := range foundNodeNames { + result = append(result, k) + } + return result, nil + }, +) diff --git a/pkg/task/inspection/googlecloudlogk8scontainer/impl/nodename_discovery_task_test.go b/pkg/task/inspection/googlecloudlogk8scontainer/impl/nodename_discovery_task_test.go new file mode 100644 index 000000000..414ce7bf0 --- /dev/null +++ b/pkg/task/inspection/googlecloudlogk8scontainer/impl/nodename_discovery_task_test.go @@ -0,0 +1,98 @@ +// Copyright 2026 Google LLC +// +// 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 googlecloudlogk8scontainer_impl + +import ( + "sort" + "testing" + + inspectiontest "github.com/GoogleCloudPlatform/khi/pkg/core/inspection/test" + tasktest "github.com/GoogleCloudPlatform/khi/pkg/core/task/test" + "github.com/GoogleCloudPlatform/khi/pkg/model/log" + googlecloudlogk8scontainer_contract "github.com/GoogleCloudPlatform/khi/pkg/task/inspection/googlecloudlogk8scontainer/contract" + inspectioncore_contract "github.com/GoogleCloudPlatform/khi/pkg/task/inspection/inspectioncore/contract" + "github.com/google/go-cmp/cmp" +) + +func TestNodeNameDiscoveryTask(t *testing.T) { + tests := []struct { + name string + logs []*log.Log + taskMode inspectioncore_contract.InspectionTaskModeType + want []string + }{ + { + name: "valid container logs with node name labels", + logs: []*log.Log{ + log.NewLogWithFieldSetsForTest(&googlecloudlogk8scontainer_contract.GCPContainerLogNodeNameLabelFieldSet{ + NodeName: "gke-test-cluster-default-pool-node-1", + }), + log.NewLogWithFieldSetsForTest(&googlecloudlogk8scontainer_contract.GCPContainerLogNodeNameLabelFieldSet{ + NodeName: "gke-test-cluster-default-pool-node-2", + }), + log.NewLogWithFieldSetsForTest(&googlecloudlogk8scontainer_contract.GCPContainerLogNodeNameLabelFieldSet{ + NodeName: "gke-test-cluster-default-pool-node-1", + }), + }, + taskMode: inspectioncore_contract.TaskModeRun, + want: []string{ + "gke-test-cluster-default-pool-node-1", + "gke-test-cluster-default-pool-node-2", + }, + }, + { + name: "empty node name label is ignored", + logs: []*log.Log{ + log.NewLogWithFieldSetsForTest(&googlecloudlogk8scontainer_contract.GCPContainerLogNodeNameLabelFieldSet{ + NodeName: "", + }), + log.NewLogWithFieldSetsForTest(&googlecloudlogk8scontainer_contract.GCPContainerLogNodeNameLabelFieldSet{ + NodeName: "gke-test-cluster-default-pool-node-1", + }), + }, + taskMode: inspectioncore_contract.TaskModeRun, + want: []string{ + "gke-test-cluster-default-pool-node-1", + }, + }, + { + name: "dry run returns nil", + logs: []*log.Log{ + log.NewLogWithFieldSetsForTest(&googlecloudlogk8scontainer_contract.GCPContainerLogNodeNameLabelFieldSet{ + NodeName: "gke-test-cluster-default-pool-node-1", + }), + }, + taskMode: inspectioncore_contract.TaskModeDryRun, + want: nil, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + ctx := inspectiontest.WithDefaultTestInspectionTaskContext(t.Context()) + result, _, err := inspectiontest.RunInspectionTask(ctx, NodeNameDiscoveryTask, tc.taskMode, map[string]any{}, + tasktest.NewTaskDependencyValuePair(googlecloudlogk8scontainer_contract.FieldSetReaderTaskID.Ref(), tc.logs), + ) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + sort.Strings(result) + sort.Strings(tc.want) + if diff := cmp.Diff(tc.want, result); diff != "" { + t.Errorf("result mismatch (-want +got):\n%s", diff) + } + }) + } +} diff --git a/pkg/task/inspection/googlecloudlogk8scontainer/impl/parser_task.go b/pkg/task/inspection/googlecloudlogk8scontainer/impl/parser_task.go index 8ae184c58..73e48d881 100644 --- a/pkg/task/inspection/googlecloudlogk8scontainer/impl/parser_task.go +++ b/pkg/task/inspection/googlecloudlogk8scontainer/impl/parser_task.go @@ -335,6 +335,7 @@ var TailTask = inspectiontaskbase.NewInspectionTask( []taskid.UntypedTaskReference{ googlecloudlogk8scontainer_contract.LogToTimelineMapperTaskID.Ref(), googlecloudlogk8scontainer_contract.PodPhaseTimelineMapperTaskID.Ref(), + googlecloudlogk8scontainer_contract.NodeNameDiscoveryTaskID.Ref(), }, func(ctx context.Context, taskMode inspectioncore_contract.InspectionTaskModeType) (struct{}, error) { return struct{}{}, nil diff --git a/pkg/task/inspection/googlecloudlogk8scontainer/impl/registration.go b/pkg/task/inspection/googlecloudlogk8scontainer/impl/registration.go index 590957657..17f3c9d3b 100644 --- a/pkg/task/inspection/googlecloudlogk8scontainer/impl/registration.go +++ b/pkg/task/inspection/googlecloudlogk8scontainer/impl/registration.go @@ -50,5 +50,6 @@ func Register(registry coreinspection.InspectionTaskRegistry) error { LogToTimelineMapperTask, PodPhaseTimelineMapperTask, TailTask, + NodeNameDiscoveryTask, ) } diff --git a/pkg/task/inspection/googlecloudlogk8snode/contract/taskid.go b/pkg/task/inspection/googlecloudlogk8snode/contract/taskid.go index 27e358d5b..b5e9c9c31 100644 --- a/pkg/task/inspection/googlecloudlogk8snode/contract/taskid.go +++ b/pkg/task/inspection/googlecloudlogk8snode/contract/taskid.go @@ -75,3 +75,6 @@ var OtherLogLogToTimelineMapperTaskID = taskid.NewDefaultImplementationID[inspec var TailTaskID = taskid.NewDefaultImplementationID[struct{}](TaskIDPrefix + "tail") var ContainerIDDiscoveryTaskID = taskid.NewDefaultImplementationID[commonlogk8saudit_contract.ContainerIDToContainerIdentity](TaskIDPrefix + "container-id-discovery") + +// NodeNameDiscoveryTaskID is the task ID for extracting node names from Kubernetes node logs. +var NodeNameDiscoveryTaskID = taskid.NewDefaultImplementationID[[]string](TaskIDPrefix + "node-name-discovery") diff --git a/pkg/task/inspection/googlecloudlogk8snode/impl/common_task.go b/pkg/task/inspection/googlecloudlogk8snode/impl/common_task.go index 51b2db309..71e2ca73a 100644 --- a/pkg/task/inspection/googlecloudlogk8snode/impl/common_task.go +++ b/pkg/task/inspection/googlecloudlogk8snode/impl/common_task.go @@ -191,6 +191,7 @@ var TailTask = inspectiontaskbase.NewInspectionTask(googlecloudlogk8snode_contra googlecloudlogk8snode_contract.OtherLogLogToTimelineMapperTaskID.Ref(), googlecloudlogk8snode_contract.ContainerIDDiscoveryTaskID.Ref(), + googlecloudlogk8snode_contract.NodeNameDiscoveryTaskID.Ref(), }, func(ctx context.Context, taskMode inspectioncore_contract.InspectionTaskModeType) (struct{}, error) { return struct{}{}, nil diff --git a/pkg/task/inspection/googlecloudlogk8snode/impl/nodename_discovery_task.go b/pkg/task/inspection/googlecloudlogk8snode/impl/nodename_discovery_task.go new file mode 100644 index 000000000..5a25f8597 --- /dev/null +++ b/pkg/task/inspection/googlecloudlogk8snode/impl/nodename_discovery_task.go @@ -0,0 +1,55 @@ +// Copyright 2026 Google LLC +// +// 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 googlecloudlogk8snode_impl + +import ( + "context" + + inspectionmetadata "github.com/GoogleCloudPlatform/khi/pkg/core/inspection/metadata" + coretask "github.com/GoogleCloudPlatform/khi/pkg/core/task" + "github.com/GoogleCloudPlatform/khi/pkg/core/task/taskid" + "github.com/GoogleCloudPlatform/khi/pkg/model/log" + commonlogk8saudit_contract "github.com/GoogleCloudPlatform/khi/pkg/task/inspection/commonlogk8saudit/contract" + googlecloudlogk8snode_contract "github.com/GoogleCloudPlatform/khi/pkg/task/inspection/googlecloudlogk8snode/contract" + inspectioncore_contract "github.com/GoogleCloudPlatform/khi/pkg/task/inspection/inspectioncore/contract" +) + +// NodeNameDiscoveryTask extracts node names from Kubernetes Node component logs and registers them to NodeNameInventoryTask. +var NodeNameDiscoveryTask = commonlogk8saudit_contract.NodeNameInventoryBuilder.DiscoveryTask( + googlecloudlogk8snode_contract.NodeNameDiscoveryTaskID, + []taskid.UntypedTaskReference{ + googlecloudlogk8snode_contract.CommonFieldsetReaderTaskID.Ref(), + }, + func(ctx context.Context, taskMode inspectioncore_contract.InspectionTaskModeType, progress *inspectionmetadata.TaskProgressMetadata) ([]string, error) { + if taskMode == inspectioncore_contract.TaskModeDryRun { + return nil, nil + } + + foundNodeNames := map[string]struct{}{} + logs := coretask.GetTaskResult(ctx, googlecloudlogk8snode_contract.CommonFieldsetReaderTaskID.Ref()) + for _, l := range logs { + fs, err := log.GetFieldSet(l, &googlecloudlogk8snode_contract.K8sNodeLogCommonFieldSet{}) + if err == nil && fs.NodeName != "" { + foundNodeNames[fs.NodeName] = struct{}{} + } + } + + var result []string + for k := range foundNodeNames { + result = append(result, k) + } + return result, nil + }, +) diff --git a/pkg/task/inspection/googlecloudlogk8snode/impl/nodename_discovery_task_test.go b/pkg/task/inspection/googlecloudlogk8snode/impl/nodename_discovery_task_test.go new file mode 100644 index 000000000..758d4f576 --- /dev/null +++ b/pkg/task/inspection/googlecloudlogk8snode/impl/nodename_discovery_task_test.go @@ -0,0 +1,98 @@ +// Copyright 2026 Google LLC +// +// 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 googlecloudlogk8snode_impl + +import ( + "sort" + "testing" + + inspectiontest "github.com/GoogleCloudPlatform/khi/pkg/core/inspection/test" + tasktest "github.com/GoogleCloudPlatform/khi/pkg/core/task/test" + "github.com/GoogleCloudPlatform/khi/pkg/model/log" + googlecloudlogk8snode_contract "github.com/GoogleCloudPlatform/khi/pkg/task/inspection/googlecloudlogk8snode/contract" + inspectioncore_contract "github.com/GoogleCloudPlatform/khi/pkg/task/inspection/inspectioncore/contract" + "github.com/google/go-cmp/cmp" +) + +func TestNodeNameDiscoveryTask(t *testing.T) { + tests := []struct { + name string + logs []*log.Log + taskMode inspectioncore_contract.InspectionTaskModeType + want []string + }{ + { + name: "valid node logs with node names", + logs: []*log.Log{ + log.NewLogWithFieldSetsForTest(&googlecloudlogk8snode_contract.K8sNodeLogCommonFieldSet{ + NodeName: "gke-test-cluster-default-pool-node-1", + }), + log.NewLogWithFieldSetsForTest(&googlecloudlogk8snode_contract.K8sNodeLogCommonFieldSet{ + NodeName: "gke-test-cluster-default-pool-node-2", + }), + log.NewLogWithFieldSetsForTest(&googlecloudlogk8snode_contract.K8sNodeLogCommonFieldSet{ + NodeName: "gke-test-cluster-default-pool-node-1", + }), + }, + taskMode: inspectioncore_contract.TaskModeRun, + want: []string{ + "gke-test-cluster-default-pool-node-1", + "gke-test-cluster-default-pool-node-2", + }, + }, + { + name: "empty node name field is ignored", + logs: []*log.Log{ + log.NewLogWithFieldSetsForTest(&googlecloudlogk8snode_contract.K8sNodeLogCommonFieldSet{ + NodeName: "", + }), + log.NewLogWithFieldSetsForTest(&googlecloudlogk8snode_contract.K8sNodeLogCommonFieldSet{ + NodeName: "gke-test-cluster-default-pool-node-1", + }), + }, + taskMode: inspectioncore_contract.TaskModeRun, + want: []string{ + "gke-test-cluster-default-pool-node-1", + }, + }, + { + name: "dry run returns nil", + logs: []*log.Log{ + log.NewLogWithFieldSetsForTest(&googlecloudlogk8snode_contract.K8sNodeLogCommonFieldSet{ + NodeName: "gke-test-cluster-default-pool-node-1", + }), + }, + taskMode: inspectioncore_contract.TaskModeDryRun, + want: nil, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + ctx := inspectiontest.WithDefaultTestInspectionTaskContext(t.Context()) + result, _, err := inspectiontest.RunInspectionTask(ctx, NodeNameDiscoveryTask, tc.taskMode, map[string]any{}, + tasktest.NewTaskDependencyValuePair(googlecloudlogk8snode_contract.CommonFieldsetReaderTaskID.Ref(), tc.logs), + ) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + sort.Strings(result) + sort.Strings(tc.want) + if diff := cmp.Diff(tc.want, result); diff != "" { + t.Errorf("result mismatch (-want +got):\n%s", diff) + } + }) + } +} diff --git a/pkg/task/inspection/googlecloudlogk8snode/impl/registration.go b/pkg/task/inspection/googlecloudlogk8snode/impl/registration.go index 6936bc0b9..d3d404a30 100644 --- a/pkg/task/inspection/googlecloudlogk8snode/impl/registration.go +++ b/pkg/task/inspection/googlecloudlogk8snode/impl/registration.go @@ -138,5 +138,6 @@ func Register(registry coreinspection.InspectionTaskRegistry) error { OtherLogLogToTimelineMapperTask, TailTask, ContainerIDDiscoveryTask, + NodeNameDiscoveryTask, ) } diff --git a/pkg/task/inspection/googlecloudlogserialport/impl/query_task.go b/pkg/task/inspection/googlecloudlogserialport/impl/query_task.go index 84b6b2fad..76b0e12da 100644 --- a/pkg/task/inspection/googlecloudlogserialport/impl/query_task.go +++ b/pkg/task/inspection/googlecloudlogserialport/impl/query_task.go @@ -35,7 +35,7 @@ const MaxNodesPerQuery = 30 func GenerateSerialPortQuery(taskMode inspectioncore_contract.InspectionTaskModeType, foundNodeNames []string, nodeNameSubstrings []string) []string { if taskMode == inspectioncore_contract.TaskModeDryRun { return []string{ - generateSerialPortQueryWithInstanceNameFilter("-- instance name filters to be determined after audit log query", generateNodeNameSubstringLogFilter(nodeNameSubstrings)), + generateSerialPortQueryWithInstanceNameFilter("-- instance name filters to be determined after node name discovery", generateNodeNameSubstringLogFilter(nodeNameSubstrings)), } } else { result := []string{} diff --git a/pkg/task/inspection/googlecloudlogserialport/impl/query_task_test.go b/pkg/task/inspection/googlecloudlogserialport/impl/query_task_test.go index c117f5621..55c8df183 100644 --- a/pkg/task/inspection/googlecloudlogserialport/impl/query_task_test.go +++ b/pkg/task/inspection/googlecloudlogserialport/impl/query_task_test.go @@ -42,7 +42,7 @@ LOG_ID("serialconsole.googleapis.com%2Fserial_port_2_output") OR LOG_ID("serialconsole.googleapis.com%2Fserial_port_3_output") OR LOG_ID("serialconsole.googleapis.com%2Fserial_port_debug_output") --- instance name filters to be determined after audit log query +-- instance name filters to be determined after node name discovery -- No node name substring filters are specified.`, },