Files
troubleshoot/pkg/loader/loader_test.go
Evans Mungai 401dfe2c57 feat: add loader APIs to load specs from raw troubleshoot spec (#1202)
* feat: add loader APIs to load specs from a list of yaml docs

The change introduces a loader package that will contain loader
public APIs. The aim of these APIs will be to, given any source of
troubleshoot specs, the loaders will fetch the specs and parse out
all troubleshoot objects that can be extracted.

* Some refactoring

* Some more changes

* More changes caught when testing vendor portal

* Add tests and rename Troubleshoot kinds struct

* Additional test

* Handle ConfigMap and Secrets with multiple specs in them

* Fix failing test

* Revert multidoc split implementation

* Fix merge conflict

* Change LoadFromXXX functions to a single LoadSpecs function
2023-06-06 16:48:29 -04:00

409 lines
10 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")
kinds, err := 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, 2)
// 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].ObjectMeta.Name)
assert.Equal(t, "sb-spec-2", kinds.SupportBundlesV1Beta2[1].ObjectMeta.Name)
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})
assert.Error(t, err)
assert.Nil(t, 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 TestLoadingConfigMapWithMultipleSpecs_PreflightSupportBundleAndRedactorDataKeys(t *testing.T) {
s := testutils.GetTestFixture(t, "yamldocs/multidoc-spec-2.yaml")
kinds, err := 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")
kinds, err := 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())
}