Files
troubleshoot/pkg/loader/loader_test.go
Diamon Wiggins 8105fa00e9 Refactor Remote Host Collection (#1633)
* refactor remote collectors

* add remotecollect params struct

* remove commented checkrbac function

* removed unused function

* add temp comments

* refactor to not require RemoteCollect method per collector

* removed unneeded param

* removed unneeded param

* more refactor

* more refactor

* remove unneeded function

* remove debug print

* fix analyzer results

* move rbac to separate file

* be more specific with rbac function name

* fix imports

* fix node list file

* make k8s rest client config consistent with in cluster collection

* add ctx and otel tracing

* add test for allCollectedData

* move runHostCollectorsInPod to spec instead of metadata

* make generate

* fix broken references to supportbundle metadata

* add e2e tests

* update loader tests

* fix tests

* fix hostos remote collector spec

* update remoteHostCollectrs.yaml

---------

Co-authored-by: Dexter Yan <yanshaocong@gmail.com>
2024-10-09 18:38:49 +13:00

638 lines
16 KiB
Go

package loader
import (
"context"
"testing"
"github.com/replicatedhq/troubleshoot/internal/testutils"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func TestLoadingHelmTemplate_Succeeds(t *testing.T) {
s := testutils.GetTestFixture(t, "yamldocs/helm-template.yaml")
l := specLoader{}
kinds, err := l.loadFromStrings(s)
require.NoError(t, err)
require.NotNil(t, kinds)
assert.Len(t, kinds.AnalyzersV1Beta2, 0)
assert.Len(t, kinds.CollectorsV1Beta2, 0)
assert.Len(t, kinds.HostCollectorsV1Beta2, 0)
assert.Len(t, kinds.HostPreflightsV1Beta2, 0)
assert.Len(t, kinds.RemoteCollectorsV1Beta2, 0)
require.Len(t, kinds.PreflightsV1Beta2, 2)
require.Len(t, kinds.RedactorsV1Beta2, 1)
require.Len(t, kinds.SupportBundlesV1Beta2, 3)
// Assert a few fields from the loaded troubleshoot specs
assert.Equal(t, "redactor-spec-1", kinds.RedactorsV1Beta2[0].ObjectMeta.Name)
assert.Equal(t, "REDACT SECOND TEXT PLEASE", kinds.RedactorsV1Beta2[0].Spec.Redactors[0].Removals.Values[0])
assert.Equal(t, "sb-spec-1", kinds.SupportBundlesV1Beta2[0].Name)
assert.Equal(t, "sb-spec-2", kinds.SupportBundlesV1Beta2[1].Name)
assert.Equal(t, "sb-spec-3", kinds.SupportBundlesV1Beta2[2].Name)
assert.Equal(t, false, kinds.SupportBundlesV1Beta2[0].Spec.RunHostCollectorsInPod)
assert.Equal(t, true, kinds.SupportBundlesV1Beta2[2].Spec.RunHostCollectorsInPod)
assert.Equal(t, "wg-easy", kinds.SupportBundlesV1Beta2[1].Spec.Collectors[0].Logs.CollectorName)
assert.Equal(t, "Node Count Check", kinds.PreflightsV1Beta2[0].Spec.Analyzers[0].NodeResources.CheckName)
assert.Len(t, kinds.PreflightsV1Beta2[0].Spec.Collectors, 0)
assert.Equal(t, true, kinds.PreflightsV1Beta2[1].Spec.Collectors[0].ClusterResources.IgnoreRBAC)
}
func TestLoadingRandomValidYaml_IgnoreDoc(t *testing.T) {
tests := []string{
"",
"---",
"configVersion: v1",
`
array:
- 1
- 2
`,
}
for _, ts := range tests {
ctx := context.Background()
kinds, err := LoadSpecs(ctx, LoadOptions{RawSpecs: []string{ts}})
assert.NoError(t, err)
assert.Equal(t, NewTroubleshootKinds(), kinds)
}
}
func TestLoadingInvalidYaml_ReturnError(t *testing.T) {
tests := []string{
"@",
"-",
`
array:- 1
- 2
`,
}
for _, ts := range tests {
t.Run(ts, func(t *testing.T) {
ctx := context.Background()
kinds, err := LoadSpecs(ctx, LoadOptions{RawSpec: ts, Strict: true})
assert.Error(t, err)
assert.Nil(t, kinds)
kinds, err = LoadSpecs(ctx, LoadOptions{RawSpec: ts, Strict: false})
assert.NoError(t, err)
assert.Equal(t, NewTroubleshootKinds(), kinds)
})
}
}
func TestLoadingInvalidYaml_IgnoreDocs(t *testing.T) {
s := testutils.GetTestFixture(t, "yamldocs/multidoc-spec-with-invalids.yaml")
ctx := context.Background()
kinds, err := LoadSpecs(ctx, LoadOptions{RawSpec: s})
require.NoError(t, err)
require.NotNil(t, kinds)
assert.Equal(t, &TroubleshootKinds{
CollectorsV1Beta2: []troubleshootv1beta2.Collector{
{
TypeMeta: metav1.TypeMeta{
Kind: "Collector",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.CollectorSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
ClusterResources: &troubleshootv1beta2.ClusterResources{
CollectorMeta: troubleshootv1beta2.CollectorMeta{
CollectorName: "my-cluster-resources",
},
},
},
},
},
},
},
SupportBundlesV1Beta2: []troubleshootv1beta2.SupportBundle{
{
TypeMeta: metav1.TypeMeta{
Kind: "SupportBundle",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.SupportBundleSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
Logs: &troubleshootv1beta2.Logs{
Name: "all-logs",
},
},
},
},
},
{
TypeMeta: metav1.TypeMeta{
Kind: "SupportBundle",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.SupportBundleSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
ClusterInfo: &troubleshootv1beta2.ClusterInfo{},
},
},
},
},
},
PreflightsV1Beta2: []troubleshootv1beta2.Preflight{
{
TypeMeta: metav1.TypeMeta{
Kind: "Preflight",
APIVersion: "troubleshoot.sh/v1beta2",
},
ObjectMeta: metav1.ObjectMeta{
Name: "preflight-1",
},
Spec: troubleshootv1beta2.PreflightSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
ClusterResources: &troubleshootv1beta2.ClusterResources{},
},
},
},
},
{
TypeMeta: metav1.TypeMeta{
Kind: "Preflight",
APIVersion: "troubleshoot.sh/v1beta2",
},
ObjectMeta: metav1.ObjectMeta{
Name: "preflight-2",
},
Spec: troubleshootv1beta2.PreflightSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
ClusterResources: &troubleshootv1beta2.ClusterResources{},
},
},
},
},
},
}, kinds)
}
func TestLoadingMultidocsWithTroubleshootSpecs(t *testing.T) {
s := testutils.GetTestFixture(t, "yamldocs/multidoc-spec-1.yaml")
ctx := context.Background()
kinds, err := LoadSpecs(ctx, LoadOptions{RawSpec: s})
require.NoError(t, err)
require.NotNil(t, kinds)
assert.Equal(t, []troubleshootv1beta2.Analyzer{
{
TypeMeta: metav1.TypeMeta{
Kind: "Analyzer",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.AnalyzerSpec{
Analyzers: []*troubleshootv1beta2.Analyze{
{
ClusterVersion: &troubleshootv1beta2.ClusterVersion{},
},
},
HostAnalyzers: []*troubleshootv1beta2.HostAnalyze{
{
TCPLoadBalancer: &troubleshootv1beta2.TCPLoadBalancerAnalyze{},
},
},
},
},
}, kinds.AnalyzersV1Beta2)
assert.Equal(t, []troubleshootv1beta2.Collector{
{
TypeMeta: metav1.TypeMeta{
Kind: "Collector",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.CollectorSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
ClusterResources: &troubleshootv1beta2.ClusterResources{
CollectorMeta: troubleshootv1beta2.CollectorMeta{
CollectorName: "my-cluster-resources",
},
},
},
},
},
},
}, kinds.CollectorsV1Beta2)
assert.Equal(t, []troubleshootv1beta2.HostCollector{
{
TypeMeta: metav1.TypeMeta{
Kind: "HostCollector",
APIVersion: "troubleshoot.sh/v1beta2",
},
ObjectMeta: metav1.ObjectMeta{
Name: "my-host-collector",
},
Spec: troubleshootv1beta2.HostCollectorSpec{
Collectors: []*troubleshootv1beta2.HostCollect{
{
CPU: &troubleshootv1beta2.CPU{},
},
},
},
},
}, kinds.HostCollectorsV1Beta2)
assert.Equal(t, []troubleshootv1beta2.HostPreflight{
{
TypeMeta: metav1.TypeMeta{
Kind: "HostPreflight",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.HostPreflightSpec{
RemoteCollectors: []*troubleshootv1beta2.RemoteCollect{
{
Certificate: &troubleshootv1beta2.RemoteCertificate{
CertificatePath: "/etc/ssl/corp.crt",
KeyPath: "/etc/ssl/corp.key",
},
},
},
Analyzers: []*troubleshootv1beta2.HostAnalyze{
{
Certificate: &troubleshootv1beta2.CertificateAnalyze{
Outcomes: []*troubleshootv1beta2.Outcome{
{
Pass: &troubleshootv1beta2.SingleOutcome{
Message: "Certificate key pair is valid",
},
},
},
},
},
},
},
},
}, kinds.HostPreflightsV1Beta2)
assert.Equal(t, []troubleshootv1beta2.Preflight{
{
TypeMeta: metav1.TypeMeta{
Kind: "Preflight",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.PreflightSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
Data: &troubleshootv1beta2.Data{
Data: "5",
},
},
},
Analyzers: []*troubleshootv1beta2.Analyze{
{
ClusterVersion: &troubleshootv1beta2.ClusterVersion{},
},
},
},
},
}, kinds.PreflightsV1Beta2)
assert.Equal(t, []troubleshootv1beta2.Redactor{
{
TypeMeta: metav1.TypeMeta{
Kind: "Redactor",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.RedactorSpec{
Redactors: []*troubleshootv1beta2.Redact{
{
Name: "replace password",
FileSelector: troubleshootv1beta2.FileSelector{
File: "data/my-password-dump",
},
Removals: troubleshootv1beta2.Removals{
Values: []string{"abc123"},
},
},
},
},
},
}, kinds.RedactorsV1Beta2)
assert.Equal(t, []troubleshootv1beta2.RemoteCollector{
{
TypeMeta: metav1.TypeMeta{
Kind: "RemoteCollector",
APIVersion: "troubleshoot.sh/v1beta2",
},
ObjectMeta: metav1.ObjectMeta{
Name: "certificate",
},
Spec: troubleshootv1beta2.RemoteCollectorSpec{
Collectors: []*troubleshootv1beta2.RemoteCollect{
{
CPU: &troubleshootv1beta2.RemoteCPU{},
},
},
},
},
}, kinds.RemoteCollectorsV1Beta2)
assert.Equal(t, []troubleshootv1beta2.SupportBundle{
{
TypeMeta: metav1.TypeMeta{
Kind: "SupportBundle",
APIVersion: "troubleshoot.sh/v1beta2",
},
ObjectMeta: metav1.ObjectMeta{
Name: "my-support-bundle",
},
Spec: troubleshootv1beta2.SupportBundleSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
Logs: &troubleshootv1beta2.Logs{
Name: "all-logs",
},
},
},
HostCollectors: []*troubleshootv1beta2.HostCollect{
{
HostOS: &troubleshootv1beta2.HostOS{},
},
},
Analyzers: []*troubleshootv1beta2.Analyze{
{
ClusterVersion: &troubleshootv1beta2.ClusterVersion{},
},
},
},
},
}, kinds.SupportBundlesV1Beta2)
}
func TestLoadingV1Beta1CollectorSpec(t *testing.T) {
kinds, err := LoadSpecs(context.Background(), LoadOptions{RawSpec: `kind: Collector
apiVersion: troubleshoot.replicated.com/v1beta1
metadata:
name: collector-sample
spec:
collectors:
- clusterInfo: {}
`})
require.NoError(t, err)
require.NotNil(t, kinds)
assert.Equal(t, []troubleshootv1beta2.Collector{
{
TypeMeta: metav1.TypeMeta{
Kind: "Collector",
APIVersion: "troubleshoot.sh/v1beta2",
},
ObjectMeta: metav1.ObjectMeta{
Name: "collector-sample",
},
Spec: troubleshootv1beta2.CollectorSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
ClusterInfo: &troubleshootv1beta2.ClusterInfo{},
},
},
},
},
}, kinds.CollectorsV1Beta2)
}
func TestLoadingConfigMapWithMultipleSpecs_PreflightSupportBundleAndRedactorDataKeys(t *testing.T) {
s := testutils.GetTestFixture(t, "yamldocs/multidoc-spec-2.yaml")
l := specLoader{}
kinds, err := l.loadFromStrings(s)
require.NoError(t, err)
require.NotNil(t, kinds)
assert.Equal(t, &TroubleshootKinds{
SupportBundlesV1Beta2: []troubleshootv1beta2.SupportBundle{
{
TypeMeta: metav1.TypeMeta{
Kind: "SupportBundle",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.SupportBundleSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
Logs: &troubleshootv1beta2.Logs{
Name: "all-logs",
},
},
},
},
},
},
RedactorsV1Beta2: []troubleshootv1beta2.Redactor{
{
TypeMeta: metav1.TypeMeta{
Kind: "Redactor",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.RedactorSpec{
Redactors: []*troubleshootv1beta2.Redact{
{
Name: "redact-text-1",
Removals: troubleshootv1beta2.Removals{
Values: []string{"abc123"},
},
},
},
},
},
},
PreflightsV1Beta2: []troubleshootv1beta2.Preflight{
{
TypeMeta: metav1.TypeMeta{
Kind: "Preflight",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.PreflightSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
ClusterResources: &troubleshootv1beta2.ClusterResources{
IgnoreRBAC: true,
},
},
},
Analyzers: []*troubleshootv1beta2.Analyze{
{
ClusterVersion: &troubleshootv1beta2.ClusterVersion{
Outcomes: []*troubleshootv1beta2.Outcome{
{
Pass: &troubleshootv1beta2.SingleOutcome{
Message: "Cluster is up to date",
},
},
},
},
},
},
},
},
},
}, kinds)
}
func TestLoadingConfigMapWithMultipleSpecs_SupportBundleMultidoc(t *testing.T) {
s := testutils.GetTestFixture(t, "yamldocs/multidoc-spec-3.yaml")
l := specLoader{}
kinds, err := l.loadFromStrings(s)
require.NoError(t, err)
require.NotNil(t, kinds)
assert.Equal(t, &TroubleshootKinds{
SupportBundlesV1Beta2: []troubleshootv1beta2.SupportBundle{
{
TypeMeta: metav1.TypeMeta{
Kind: "SupportBundle",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.SupportBundleSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
Logs: &troubleshootv1beta2.Logs{
Name: "all-logs",
},
},
},
},
},
{
TypeMeta: metav1.TypeMeta{
Kind: "SupportBundle",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.SupportBundleSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
ClusterResources: &troubleshootv1beta2.ClusterResources{},
},
},
},
},
{
TypeMeta: metav1.TypeMeta{
Kind: "SupportBundle",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.SupportBundleSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
ClusterInfo: &troubleshootv1beta2.ClusterInfo{},
},
},
},
},
},
}, kinds)
}
func TestKindsIsEmpty(t *testing.T) {
assert.True(t, NewTroubleshootKinds().IsEmpty())
kinds := NewTroubleshootKinds()
kinds.AnalyzersV1Beta2 = append(kinds.AnalyzersV1Beta2, troubleshootv1beta2.Analyzer{})
assert.False(t, kinds.IsEmpty())
}
func TestAddingKinds(t *testing.T) {
a := troubleshootv1beta2.Analyzer{
Spec: troubleshootv1beta2.AnalyzerSpec{},
}
k1 := NewTroubleshootKinds()
k1.Add(&TroubleshootKinds{
AnalyzersV1Beta2: []troubleshootv1beta2.Analyzer{a},
})
k2 := &TroubleshootKinds{
AnalyzersV1Beta2: []troubleshootv1beta2.Analyzer{a},
}
assert.Equal(t, k2, k1)
}
func TestToYaml(t *testing.T) {
k := &TroubleshootKinds{
AnalyzersV1Beta2: []troubleshootv1beta2.Analyzer{
{
TypeMeta: metav1.TypeMeta{
Kind: "Analyzer",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.AnalyzerSpec{
Analyzers: []*troubleshootv1beta2.Analyze{
{
ClusterVersion: &troubleshootv1beta2.ClusterVersion{
Outcomes: []*troubleshootv1beta2.Outcome{
{
Pass: &troubleshootv1beta2.SingleOutcome{
Message: "Cluster is up to date",
},
},
},
},
},
},
},
},
},
SupportBundlesV1Beta2: []troubleshootv1beta2.SupportBundle{
{
TypeMeta: metav1.TypeMeta{
Kind: "SupportBundle",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.SupportBundleSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
ClusterResources: &troubleshootv1beta2.ClusterResources{
IgnoreRBAC: true,
},
},
},
},
},
},
}
y, err := k.ToYaml()
require.NoError(t, err)
assert.Contains(t, string(y), `apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
metadata:
creationTimestamp: null
spec:
collectors:
- clusterResources:
ignoreRBAC: true`)
assert.Contains(t, string(y), "message: Cluster is up to date")
}
func TestLoadingEmptySpec(t *testing.T) {
s := testutils.GetTestFixture(t, "supportbundle/empty.yaml")
kinds, err := LoadSpecs(context.Background(), LoadOptions{RawSpec: s})
require.NoError(t, err)
require.NotNil(t, kinds)
assert.Equal(t, &TroubleshootKinds{
SupportBundlesV1Beta2: []troubleshootv1beta2.SupportBundle{
{
TypeMeta: metav1.TypeMeta{
Kind: "SupportBundle",
APIVersion: "troubleshoot.sh/v1beta2",
},
ObjectMeta: metav1.ObjectMeta{
Name: "empty",
},
},
},
}, kinds)
}