mirror of
https://github.com/replicatedhq/troubleshoot.git
synced 2026-02-14 10:19:54 +00:00
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
This commit is contained in:
@@ -7,7 +7,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/replicatedhq/troubleshoot/cmd/util"
|
||||
"github.com/replicatedhq/troubleshoot/internal/util"
|
||||
analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
@@ -10,10 +10,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/replicatedhq/troubleshoot/cmd/util"
|
||||
"github.com/replicatedhq/troubleshoot/internal/util"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
|
||||
troubleshootclientsetscheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/collect"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/docrewrite"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
|
||||
@@ -88,7 +87,6 @@ func runCollect(v *viper.Viper, arg string) error {
|
||||
|
||||
multidocs := strings.Split(string(collectorContent), "\n---\n")
|
||||
|
||||
troubleshootclientsetscheme.AddToScheme(scheme.Scheme)
|
||||
decode := scheme.Codecs.UniversalDeserializer().Decode
|
||||
|
||||
redactors, err := supportbundle.GetRedactorsFromURIs(v.GetStringSlice("redactors"))
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/replicatedhq/troubleshoot/cmd/util"
|
||||
"github.com/replicatedhq/troubleshoot/internal/util"
|
||||
analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/convert"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
ui "github.com/replicatedhq/termui/v3"
|
||||
"github.com/replicatedhq/termui/v3/widgets"
|
||||
"github.com/replicatedhq/troubleshoot/cmd/util"
|
||||
"github.com/replicatedhq/troubleshoot/internal/util"
|
||||
analyzerunner "github.com/replicatedhq/troubleshoot/pkg/analyze"
|
||||
)
|
||||
|
||||
|
||||
@@ -19,8 +19,6 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
|
||||
troubleshootclientsetscheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/convert"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/httputil"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
|
||||
@@ -79,7 +77,6 @@ func runTroubleshoot(v *viper.Viper, arg []string) error {
|
||||
|
||||
var mainBundle *troubleshootv1beta2.SupportBundle
|
||||
|
||||
troubleshootclientsetscheme.AddToScheme(scheme.Scheme)
|
||||
additionalRedactors := &troubleshootv1beta2.Redactor{}
|
||||
|
||||
// Defining `v` below will render using `v` in reference to Viper unusable.
|
||||
|
||||
@@ -40,3 +40,7 @@ func AppName(name string) string {
|
||||
|
||||
return strings.Join(casedWords, " ")
|
||||
}
|
||||
|
||||
func SplitYAML(doc string) []string {
|
||||
return strings.Split(doc, "\n---\n")
|
||||
}
|
||||
@@ -4,20 +4,23 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
|
||||
troubleshootclientsetscheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/docrewrite"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
var decoder runtime.Decoder
|
||||
|
||||
func init() {
|
||||
decoder = scheme.Codecs.UniversalDeserializer()
|
||||
}
|
||||
|
||||
func ParseCollectorFromDoc(doc []byte) (*troubleshootv1beta2.Collector, error) {
|
||||
doc, err := docrewrite.ConvertToV1Beta2(doc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to convert to v1beta2")
|
||||
}
|
||||
|
||||
troubleshootclientsetscheme.AddToScheme(scheme.Scheme)
|
||||
decode := scheme.Codecs.UniversalDeserializer().Decode
|
||||
|
||||
obj, _, err := decode(doc, nil, nil)
|
||||
obj, _, err := decoder.Decode(doc, nil, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse document")
|
||||
}
|
||||
@@ -36,10 +39,7 @@ func ParseHostCollectorFromDoc(doc []byte) (*troubleshootv1beta2.HostCollector,
|
||||
return nil, errors.Wrap(err, "failed to convert to v1beta2")
|
||||
}
|
||||
|
||||
troubleshootclientsetscheme.AddToScheme(scheme.Scheme)
|
||||
decode := scheme.Codecs.UniversalDeserializer().Decode
|
||||
|
||||
obj, _, err := decode(doc, nil, nil)
|
||||
obj, _, err := decoder.Decode(doc, nil, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse document")
|
||||
}
|
||||
@@ -58,10 +58,7 @@ func ParseRemoteCollectorFromDoc(doc []byte) (*troubleshootv1beta2.RemoteCollect
|
||||
return nil, errors.Wrap(err, "failed to convert to v1beta2")
|
||||
}
|
||||
|
||||
troubleshootclientsetscheme.AddToScheme(scheme.Scheme)
|
||||
decode := scheme.Codecs.UniversalDeserializer().Decode
|
||||
|
||||
obj, _, err := decode(doc, nil, nil)
|
||||
obj, _, err := decoder.Decode(doc, nil, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse document")
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ const (
|
||||
DEFAULT_LOGS_COLLECTOR_TIMEOUT = 60 * time.Second
|
||||
|
||||
// Tracing constants
|
||||
|
||||
LIB_TRACER_NAME = "github.com/replicatedhq/troubleshoot"
|
||||
TROUBLESHOOT_ROOT_SPAN_NAME = "ReplicatedTroubleshootRootSpan"
|
||||
EXCLUDED = "excluded"
|
||||
@@ -58,4 +57,12 @@ const (
|
||||
EXIT_CODE_SPEC_ISSUES = 2
|
||||
EXIT_CODE_FAIL = 3
|
||||
EXIT_CODE_WARN = 4
|
||||
|
||||
// Troubleshoot label constants
|
||||
SupportBundleKey = "support-bundle-spec"
|
||||
RedactorKey = "redactor-spec"
|
||||
PreflightKey = "preflight.yaml" // Shouldn't this be "preflight-spec"?
|
||||
|
||||
// Troubleshoot spec constants
|
||||
Troubleshootv1beta2Kind = "troubleshoot.sh/v1beta2"
|
||||
)
|
||||
|
||||
290
pkg/loader/loader.go
Normal file
290
pkg/loader/loader.go
Normal file
@@ -0,0 +1,290 @@
|
||||
package loader
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/replicatedhq/troubleshoot/internal/util"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/constants"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/docrewrite"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/types"
|
||||
"gopkg.in/yaml.v2"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
var decoder runtime.Decoder
|
||||
|
||||
func init() {
|
||||
// Allow serializing Secrets and ConfigMaps
|
||||
_ = v1.AddToScheme(scheme.Scheme)
|
||||
decoder = scheme.Codecs.UniversalDeserializer()
|
||||
}
|
||||
|
||||
type parsedDoc struct {
|
||||
Kind string `json:"kind" yaml:"kind"`
|
||||
APIVersion string `json:"apiVersion" yaml:"apiVersion"`
|
||||
Data map[string]any `json:"data" yaml:"data"`
|
||||
StringData map[string]string `json:"stringData" yaml:"stringData"`
|
||||
}
|
||||
|
||||
type LoadOptions struct {
|
||||
RawSpecs []string
|
||||
RawSpec string
|
||||
}
|
||||
|
||||
// LoadSpecs takes sources to load specs from and returns a TroubleshootKinds object
|
||||
// that contains all the parsed troubleshoot specs.
|
||||
//
|
||||
// The fetched specs need to be yaml documents. The documents can be a multidoc yaml
|
||||
// separated by "---" which get split and parsed one at a time. This function will
|
||||
// return an error if any of the documents are not valid yaml. If Secrets or ConfigMaps
|
||||
// are found, they will be parsed and the support bundle, redactor or preflight spec
|
||||
// will be extracted from them, else they will be ignored.
|
||||
// Any other yaml documents will be ignored.
|
||||
func LoadSpecs(ctx context.Context, opt LoadOptions) (*TroubleshootKinds, error) {
|
||||
opt.RawSpecs = append(opt.RawSpecs, opt.RawSpec)
|
||||
return loadFromStrings(opt.RawSpecs...)
|
||||
}
|
||||
|
||||
type TroubleshootKinds struct {
|
||||
AnalyzersV1Beta2 []troubleshootv1beta2.Analyzer
|
||||
CollectorsV1Beta2 []troubleshootv1beta2.Collector
|
||||
HostCollectorsV1Beta2 []troubleshootv1beta2.HostCollector
|
||||
HostPreflightsV1Beta2 []troubleshootv1beta2.HostPreflight
|
||||
PreflightsV1Beta2 []troubleshootv1beta2.Preflight
|
||||
RedactorsV1Beta2 []troubleshootv1beta2.Redactor
|
||||
RemoteCollectorsV1Beta2 []troubleshootv1beta2.RemoteCollector
|
||||
SupportBundlesV1Beta2 []troubleshootv1beta2.SupportBundle
|
||||
}
|
||||
|
||||
func (kinds *TroubleshootKinds) IsEmpty() bool {
|
||||
return len(kinds.AnalyzersV1Beta2) == 0 &&
|
||||
len(kinds.CollectorsV1Beta2) == 0 &&
|
||||
len(kinds.HostCollectorsV1Beta2) == 0 &&
|
||||
len(kinds.HostPreflightsV1Beta2) == 0 &&
|
||||
len(kinds.PreflightsV1Beta2) == 0 &&
|
||||
len(kinds.RedactorsV1Beta2) == 0 &&
|
||||
len(kinds.RemoteCollectorsV1Beta2) == 0 &&
|
||||
len(kinds.SupportBundlesV1Beta2) == 0
|
||||
}
|
||||
|
||||
func NewTroubleshootKinds() *TroubleshootKinds {
|
||||
return &TroubleshootKinds{}
|
||||
}
|
||||
|
||||
// loadFromStrings accepts a list of strings (exploded) which should be yaml documents
|
||||
func loadFromStrings(rawSpecs ...string) (*TroubleshootKinds, error) {
|
||||
splitdocs := []string{}
|
||||
multiRawDocs := []string{}
|
||||
|
||||
// 1. First split multidoc yaml documents.
|
||||
for _, rawSpec := range rawSpecs {
|
||||
multiRawDocs = append(multiRawDocs, strings.Split(rawSpec, "\n---\n")...)
|
||||
}
|
||||
|
||||
// 2. Go through each document to see if it is a configmap, secret or troubleshoot kind
|
||||
// For secrets and configmaps, extract support bundle, redactor or preflight specs
|
||||
// For troubleshoot kinds, pass them through
|
||||
for _, rawDoc := range multiRawDocs {
|
||||
var parsed parsedDoc
|
||||
|
||||
err := yaml.Unmarshal([]byte(rawDoc), &parsed)
|
||||
if err != nil {
|
||||
return nil, types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, errors.Wrapf(err, "failed to parse yaml: '%s'", string(rawDoc)))
|
||||
}
|
||||
|
||||
if isConfigMap(parsed) || isSecret(parsed) {
|
||||
// Extract specs from configmap or secret
|
||||
obj, _, err := decoder.Decode([]byte(rawDoc), nil, nil)
|
||||
if err != nil {
|
||||
return nil, types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES,
|
||||
errors.Wrapf(err, "failed to decode raw spec: '%s'", string(rawDoc)),
|
||||
)
|
||||
}
|
||||
|
||||
// 3. Extract the raw troubleshoot specs
|
||||
switch v := obj.(type) {
|
||||
case *v1.ConfigMap:
|
||||
specs, err := getSpecFromConfigMap(v)
|
||||
if err != nil {
|
||||
return nil, types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, err)
|
||||
}
|
||||
splitdocs = append(splitdocs, specs...)
|
||||
case *v1.Secret:
|
||||
specs, err := getSpecFromSecret(v)
|
||||
if err != nil {
|
||||
return nil, types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, err)
|
||||
}
|
||||
splitdocs = append(splitdocs, specs...)
|
||||
default:
|
||||
return nil, types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, errors.Errorf("%T type is not a Secret or ConfigMap", v))
|
||||
}
|
||||
} else if parsed.APIVersion == constants.Troubleshootv1beta2Kind {
|
||||
// If it's not a configmap or secret, just append it to the splitdocs
|
||||
splitdocs = append(splitdocs, rawDoc)
|
||||
} else {
|
||||
klog.V(1).Infof("skip loading %q kind", parsed.Kind)
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Then load the specs into the kinds struct
|
||||
return loadFromSplitDocs(splitdocs)
|
||||
}
|
||||
|
||||
func loadFromSplitDocs(splitdocs []string) (*TroubleshootKinds, error) {
|
||||
kinds := NewTroubleshootKinds()
|
||||
|
||||
for _, doc := range splitdocs {
|
||||
converted, err := docrewrite.ConvertToV1Beta2([]byte(doc))
|
||||
if err != nil {
|
||||
return nil, types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, errors.Wrapf(err, "failed to convert doc to troubleshoot.sh/v1beta2 kind: '%s'", doc))
|
||||
}
|
||||
|
||||
obj, _, err := decoder.Decode([]byte(converted), nil, nil)
|
||||
if err != nil {
|
||||
return nil, types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, errors.Wrapf(err, "failed to decode '%s'", converted))
|
||||
}
|
||||
|
||||
switch spec := obj.(type) {
|
||||
case *troubleshootv1beta2.Analyzer:
|
||||
kinds.AnalyzersV1Beta2 = append(kinds.AnalyzersV1Beta2, *spec)
|
||||
case *troubleshootv1beta2.Collector:
|
||||
kinds.CollectorsV1Beta2 = append(kinds.CollectorsV1Beta2, *spec)
|
||||
case *troubleshootv1beta2.HostCollector:
|
||||
kinds.HostCollectorsV1Beta2 = append(kinds.HostCollectorsV1Beta2, *spec)
|
||||
case *troubleshootv1beta2.HostPreflight:
|
||||
kinds.HostPreflightsV1Beta2 = append(kinds.HostPreflightsV1Beta2, *spec)
|
||||
case *troubleshootv1beta2.Preflight:
|
||||
kinds.PreflightsV1Beta2 = append(kinds.PreflightsV1Beta2, *spec)
|
||||
case *troubleshootv1beta2.Redactor:
|
||||
kinds.RedactorsV1Beta2 = append(kinds.RedactorsV1Beta2, *spec)
|
||||
case *troubleshootv1beta2.RemoteCollector:
|
||||
kinds.RemoteCollectorsV1Beta2 = append(kinds.RemoteCollectorsV1Beta2, *spec)
|
||||
case *troubleshootv1beta2.SupportBundle:
|
||||
kinds.SupportBundlesV1Beta2 = append(kinds.SupportBundlesV1Beta2, *spec)
|
||||
default:
|
||||
return nil, types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, errors.Errorf("unknown troubleshoot kind %T", obj))
|
||||
}
|
||||
}
|
||||
|
||||
klog.V(1).Info("loaded troubleshoot specs successfully")
|
||||
return kinds, nil
|
||||
}
|
||||
|
||||
func isSecret(parsedDocHead parsedDoc) bool {
|
||||
if parsedDocHead.Kind == "Secret" && parsedDocHead.APIVersion == "v1" {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func isConfigMap(parsedDocHead parsedDoc) bool {
|
||||
if parsedDocHead.Kind == "ConfigMap" && parsedDocHead.APIVersion == "v1" {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// getSpecFromConfigMap extracts multiple troubleshoot specs from a secret
|
||||
func getSpecFromConfigMap(cm *v1.ConfigMap) ([]string, error) {
|
||||
specs := []string{}
|
||||
|
||||
str, ok := cm.Data[constants.SupportBundleKey]
|
||||
if ok {
|
||||
spec, err := validateYaml(str)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
specs = append(specs, util.SplitYAML(spec)...)
|
||||
}
|
||||
str, ok = cm.Data[constants.RedactorKey]
|
||||
if ok {
|
||||
spec, err := validateYaml(str)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
specs = append(specs, util.SplitYAML(spec)...)
|
||||
}
|
||||
str, ok = cm.Data[constants.PreflightKey]
|
||||
if ok {
|
||||
spec, err := validateYaml(str)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
specs = append(specs, util.SplitYAML(spec)...)
|
||||
}
|
||||
|
||||
return specs, nil
|
||||
}
|
||||
|
||||
// getSpecFromSecret extracts multiple troubleshoot specs from a secret
|
||||
func getSpecFromSecret(secret *v1.Secret) ([]string, error) {
|
||||
specs := []string{}
|
||||
|
||||
specBytes, ok := secret.Data[constants.SupportBundleKey]
|
||||
if ok {
|
||||
spec, err := validateYaml(string(specBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
specs = append(specs, util.SplitYAML(spec)...)
|
||||
}
|
||||
specBytes, ok = secret.Data[constants.RedactorKey]
|
||||
if ok {
|
||||
spec, err := validateYaml(string(specBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
specs = append(specs, util.SplitYAML(spec)...)
|
||||
}
|
||||
specBytes, ok = secret.Data[constants.PreflightKey]
|
||||
if ok {
|
||||
spec, err := validateYaml(string(specBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
specs = append(specs, util.SplitYAML(spec)...)
|
||||
}
|
||||
str, ok := secret.StringData[constants.SupportBundleKey]
|
||||
if ok {
|
||||
spec, err := validateYaml(str)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
specs = append(specs, util.SplitYAML(spec)...)
|
||||
}
|
||||
str, ok = secret.StringData[constants.RedactorKey]
|
||||
if ok {
|
||||
spec, err := validateYaml(str)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
specs = append(specs, util.SplitYAML(spec)...)
|
||||
}
|
||||
str, ok = secret.StringData[constants.PreflightKey]
|
||||
if ok {
|
||||
spec, err := validateYaml(str)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
specs = append(specs, util.SplitYAML(spec)...)
|
||||
}
|
||||
return specs, nil
|
||||
}
|
||||
|
||||
func validateYaml(raw string) (string, error) {
|
||||
var parsed map[string]any
|
||||
err := yaml.Unmarshal([]byte(raw), &parsed)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "failed to parse yaml: '%s'", string(raw))
|
||||
}
|
||||
|
||||
return raw, nil
|
||||
}
|
||||
408
pkg/loader/loader_test.go
Normal file
408
pkg/loader/loader_test.go
Normal file
@@ -0,0 +1,408 @@
|
||||
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())
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/replicatedhq/troubleshoot/cmd/util"
|
||||
"github.com/replicatedhq/troubleshoot/internal/util"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/version"
|
||||
"oras.land/oras-go/pkg/auth"
|
||||
dockerauth "oras.land/oras-go/pkg/auth/docker"
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
ui "github.com/replicatedhq/termui/v3"
|
||||
"github.com/replicatedhq/termui/v3/widgets"
|
||||
"github.com/replicatedhq/troubleshoot/cmd/util"
|
||||
"github.com/replicatedhq/troubleshoot/internal/util"
|
||||
analyzerunner "github.com/replicatedhq/troubleshoot/pkg/analyze"
|
||||
)
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/replicatedhq/troubleshoot/cmd/util"
|
||||
"github.com/replicatedhq/troubleshoot/internal/util"
|
||||
analyzerunner "github.com/replicatedhq/troubleshoot/pkg/analyze"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/convert"
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package preflight
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -10,41 +10,15 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/replicatedhq/troubleshoot/cmd/util"
|
||||
"github.com/replicatedhq/troubleshoot/internal/util"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
troubleshootclientsetscheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/constants"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/docrewrite"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/loader"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/oci"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/specs"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/types"
|
||||
"gopkg.in/yaml.v2"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
)
|
||||
|
||||
type documentHead struct {
|
||||
Kind string `yaml:"kind"`
|
||||
Metadata documentMetadata `yaml:"metadata,omitempty"`
|
||||
Data documentData `yaml:"data,omitempty"`
|
||||
StringData documentStringData `yaml:"stringData,omitempty"`
|
||||
}
|
||||
|
||||
type documentMetadata struct {
|
||||
Labels documentMetadataLabels `yaml:"labels,omitempty"`
|
||||
}
|
||||
|
||||
type documentMetadataLabels struct {
|
||||
TroubleshootKind string `yaml:"troubleshoot.sh/kind,omitempty"`
|
||||
}
|
||||
|
||||
type documentData struct {
|
||||
PreflightYaml string `yaml:"preflight.yaml,omitempty"`
|
||||
}
|
||||
|
||||
type documentStringData struct {
|
||||
PreflightYaml string `yaml:"preflight.yaml,omitempty"`
|
||||
}
|
||||
|
||||
type PreflightSpecs struct {
|
||||
PreflightSpec *troubleshootv1beta2.Preflight
|
||||
HostPreflightSpec *troubleshootv1beta2.HostPreflight
|
||||
@@ -55,6 +29,7 @@ func (p *PreflightSpecs) Read(args []string) error {
|
||||
var preflightContent []byte
|
||||
var err error
|
||||
|
||||
// TODO: Earmarked for cleanup in favour of loader.LoadFromArgs(args []string)
|
||||
for _, v := range args {
|
||||
if strings.HasPrefix(v, "secret/") {
|
||||
// format secret/namespace-name/secret-name
|
||||
@@ -126,70 +101,24 @@ func (p *PreflightSpecs) Read(args []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
multidocs := strings.Split(string(preflightContent), "\n---\n")
|
||||
ctx := context.Background()
|
||||
kinds, err := loader.LoadSpecs(ctx, loader.LoadOptions{
|
||||
RawSpec: string(preflightContent),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, doc := range multidocs {
|
||||
var parsedDocHead documentHead
|
||||
|
||||
err := yaml.Unmarshal([]byte(doc), &parsedDocHead)
|
||||
if err != nil {
|
||||
return types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, errors.Wrap(err, "failed to parse yaml"))
|
||||
for _, v := range kinds.PreflightsV1Beta2 {
|
||||
if v.Spec.UploadResultsTo == "" {
|
||||
p.PreflightSpec = ConcatPreflightSpec(p.PreflightSpec, &v)
|
||||
} else {
|
||||
p.UploadResultSpecs = append(p.UploadResultSpecs, &v)
|
||||
}
|
||||
}
|
||||
|
||||
// We're going to look for either of "kind: Preflight" OR "kind: Secret" with the label "troubleshoot.sh/kind: preflight"
|
||||
|
||||
if parsedDocHead.Kind != "Preflight" && parsedDocHead.Kind != "Secret" {
|
||||
continue
|
||||
}
|
||||
|
||||
if parsedDocHead.Kind == "Secret" {
|
||||
if parsedDocHead.Metadata.Labels.TroubleshootKind == "preflight" {
|
||||
secretSpecDoc := ""
|
||||
// In a Secret, we need to get the document out of the data.`preflight.yaml` or stringData.`preflight.yaml` (stringData takes precedence)
|
||||
if len(parsedDocHead.Data.PreflightYaml) > 0 {
|
||||
b64DecPreflightYaml, err := base64.StdEncoding.DecodeString(parsedDocHead.Data.PreflightYaml)
|
||||
if err != nil {
|
||||
return types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, errors.Wrap(err, "failed to base64 decode preflight secret data"))
|
||||
}
|
||||
secretSpecDoc = strings.TrimSpace(string(b64DecPreflightYaml))
|
||||
}
|
||||
// Do stringData second, if found overwrite data (as per K8s docs)
|
||||
if len(parsedDocHead.StringData.PreflightYaml) > 0 {
|
||||
secretSpecDoc = parsedDocHead.StringData.PreflightYaml
|
||||
}
|
||||
//
|
||||
if len(secretSpecDoc) > 0 {
|
||||
doc = secretSpecDoc
|
||||
} else {
|
||||
return types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, errors.Wrap(err, "secret spec with preflight label found, but no preflight stringData or data?"))
|
||||
}
|
||||
} else {
|
||||
// Not a preflight spec, skip
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
preflightContent, err = docrewrite.ConvertToV1Beta2([]byte(doc))
|
||||
if err != nil {
|
||||
return types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, errors.Wrap(err, "failed to convert to v1beta2"))
|
||||
}
|
||||
|
||||
troubleshootclientsetscheme.AddToScheme(scheme.Scheme)
|
||||
decode := scheme.Codecs.UniversalDeserializer().Decode
|
||||
obj, _, err := decode([]byte(preflightContent), nil, nil)
|
||||
if err != nil {
|
||||
return types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, errors.Wrapf(err, "failed to parse %s", v))
|
||||
}
|
||||
|
||||
if spec, ok := obj.(*troubleshootv1beta2.Preflight); ok {
|
||||
if spec.Spec.UploadResultsTo == "" {
|
||||
p.PreflightSpec = ConcatPreflightSpec(p.PreflightSpec, spec)
|
||||
} else {
|
||||
p.UploadResultSpecs = append(p.UploadResultSpecs, spec)
|
||||
}
|
||||
} else if spec, ok := obj.(*troubleshootv1beta2.HostPreflight); ok {
|
||||
p.HostPreflightSpec = ConcatHostPreflightSpec(p.HostPreflightSpec, spec)
|
||||
}
|
||||
for _, v := range kinds.HostPreflightsV1Beta2 {
|
||||
p.HostPreflightSpec = ConcatHostPreflightSpec(p.HostPreflightSpec, &v)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ type PreflightSpecsReadTest struct {
|
||||
wantUploadResultSpecs []*troubleshootv1beta2.Preflight
|
||||
}
|
||||
|
||||
// TODO: Simplify tests and rely on the loader tests
|
||||
func TestPreflightSpecsRead(t *testing.T) {
|
||||
// NOTE: don't use t.Parallel(), these tests manipulate os.Stdin
|
||||
|
||||
@@ -46,7 +47,7 @@ func TestPreflightSpecsRead(t *testing.T) {
|
||||
Spec: troubleshootv1beta2.PreflightSpec{
|
||||
UploadResultsTo: "",
|
||||
Collectors: []*troubleshootv1beta2.Collect{
|
||||
&troubleshootv1beta2.Collect{
|
||||
{
|
||||
Data: &troubleshootv1beta2.Data{
|
||||
CollectorMeta: troubleshootv1beta2.CollectorMeta{
|
||||
CollectorName: "",
|
||||
@@ -72,7 +73,7 @@ func TestPreflightSpecsRead(t *testing.T) {
|
||||
},
|
||||
RemoteCollectors: []*troubleshootv1beta2.RemoteCollect(nil),
|
||||
Analyzers: []*troubleshootv1beta2.Analyze{
|
||||
&troubleshootv1beta2.Analyze{
|
||||
{
|
||||
JsonCompare: &troubleshootv1beta2.JsonCompare{
|
||||
AnalyzeMeta: troubleshootv1beta2.AnalyzeMeta{
|
||||
CheckName: "Compare JSON Example",
|
||||
@@ -83,13 +84,13 @@ func TestPreflightSpecsRead(t *testing.T) {
|
||||
Value: `123
|
||||
`,
|
||||
Outcomes: []*troubleshootv1beta2.Outcome{
|
||||
&troubleshootv1beta2.Outcome{
|
||||
{
|
||||
Fail: &troubleshootv1beta2.SingleOutcome{
|
||||
When: "false",
|
||||
Message: "The collected data does not match the value.",
|
||||
},
|
||||
},
|
||||
&troubleshootv1beta2.Outcome{
|
||||
{
|
||||
Pass: &troubleshootv1beta2.SingleOutcome{
|
||||
When: "true",
|
||||
Message: "The collected data matches the value.",
|
||||
@@ -131,19 +132,19 @@ func TestPreflightSpecsRead(t *testing.T) {
|
||||
UploadResultsTo: "",
|
||||
RemoteCollectors: []*troubleshootv1beta2.RemoteCollect(nil),
|
||||
Analyzers: []*troubleshootv1beta2.Analyze{
|
||||
&troubleshootv1beta2.Analyze{
|
||||
{
|
||||
NodeResources: &troubleshootv1beta2.NodeResources{
|
||||
AnalyzeMeta: troubleshootv1beta2.AnalyzeMeta{
|
||||
CheckName: "Node Count Check",
|
||||
},
|
||||
Outcomes: []*troubleshootv1beta2.Outcome{
|
||||
&troubleshootv1beta2.Outcome{
|
||||
{
|
||||
Fail: &troubleshootv1beta2.SingleOutcome{
|
||||
When: "count() < 3",
|
||||
Message: "The cluster needs a minimum of 3 nodes.",
|
||||
},
|
||||
},
|
||||
&troubleshootv1beta2.Outcome{
|
||||
{
|
||||
Pass: &troubleshootv1beta2.SingleOutcome{
|
||||
Message: "There are not enough nodes to run this application (3 or more)",
|
||||
},
|
||||
@@ -151,24 +152,24 @@ func TestPreflightSpecsRead(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
&troubleshootv1beta2.Analyze{
|
||||
{
|
||||
ClusterVersion: &troubleshootv1beta2.ClusterVersion{
|
||||
Outcomes: []*troubleshootv1beta2.Outcome{
|
||||
&troubleshootv1beta2.Outcome{
|
||||
{
|
||||
Fail: &troubleshootv1beta2.SingleOutcome{
|
||||
When: "< 1.16.0",
|
||||
Message: "The application requires at least Kubernetes 1.16.0, and recommends 1.18.0.",
|
||||
URI: "https://kubernetes.io",
|
||||
},
|
||||
},
|
||||
&troubleshootv1beta2.Outcome{
|
||||
{
|
||||
Warn: &troubleshootv1beta2.SingleOutcome{
|
||||
When: "< 1.18.0",
|
||||
Message: "Your cluster meets the minimum version of Kubernetes, but we recommend you update to 1.18.0 or later.",
|
||||
URI: "https://kubernetes.io",
|
||||
},
|
||||
},
|
||||
&troubleshootv1beta2.Outcome{
|
||||
{
|
||||
Pass: &troubleshootv1beta2.SingleOutcome{
|
||||
Message: "Your cluster meets the recommended and required versions of Kubernetes.",
|
||||
},
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/fatih/color"
|
||||
"github.com/pkg/errors"
|
||||
analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze"
|
||||
analyzerunner "github.com/replicatedhq/troubleshoot/pkg/analyze"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/constants"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
|
||||
@@ -122,12 +121,10 @@ func RunPreflights(interactive bool, output string, format string, args []string
|
||||
}
|
||||
}
|
||||
|
||||
if uploadAnalyzeResultsMap != nil {
|
||||
for k, v := range uploadAnalyzeResultsMap {
|
||||
err := uploadResults(k, v)
|
||||
if err != nil {
|
||||
progressCh <- err
|
||||
}
|
||||
for k, v := range uploadAnalyzeResultsMap {
|
||||
err := uploadResults(k, v)
|
||||
if err != nil {
|
||||
progressCh <- err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +158,7 @@ func RunPreflights(interactive bool, output string, format string, args []string
|
||||
// If all checks passed: 0
|
||||
// If 1 or more checks failed: 3
|
||||
// If no checks failed, but 1 or more warn: 4
|
||||
func checkOutcomesToExitCode(analyzeResults []*analyzerunner.AnalyzeResult) int {
|
||||
func checkOutcomesToExitCode(analyzeResults []*analyzer.AnalyzeResult) int {
|
||||
// Assume pass until they don't
|
||||
exitCode := 0
|
||||
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
package specs
|
||||
|
||||
import "github.com/replicatedhq/troubleshoot/pkg/constants"
|
||||
|
||||
const (
|
||||
SupportBundleKey = "support-bundle-spec"
|
||||
RedactorKey = "redactor-spec"
|
||||
// Preserved for backwards compatibility
|
||||
|
||||
// Deprecated: Use constants.SupportBundleKey instead
|
||||
SupportBundleKey = constants.SupportBundleKey
|
||||
// Deprecated: Use constants.RedactorKey instead
|
||||
RedactorKey = constants.RedactorKey
|
||||
)
|
||||
|
||||
@@ -9,10 +9,9 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/replicatedhq/troubleshoot/cmd/util"
|
||||
"github.com/replicatedhq/troubleshoot/internal/util"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
|
||||
troubleshootclientsetscheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/docrewrite"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/httputil"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/oci"
|
||||
@@ -43,7 +42,6 @@ func ParseSupportBundle(doc []byte, followURI bool) (*troubleshootv1beta2.Suppor
|
||||
return nil, errors.Wrap(err, "failed to convert to v1beta2")
|
||||
}
|
||||
|
||||
troubleshootclientsetscheme.AddToScheme(scheme.Scheme)
|
||||
decode := scheme.Codecs.UniversalDeserializer().Decode
|
||||
|
||||
obj, _, err := decode(doc, nil, nil)
|
||||
|
||||
403
testdata/yamldocs/helm-template.yaml
vendored
Normal file
403
testdata/yamldocs/helm-template.yaml
vendored
Normal file
@@ -0,0 +1,403 @@
|
||||
---
|
||||
# Source: wg-easy/templates/replicated-library.yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: sb-spec-1-secret
|
||||
labels:
|
||||
troubleshoot.io/kind: support-bundle
|
||||
stringData:
|
||||
support-bundle-spec: |-
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: SupportBundle
|
||||
metadata:
|
||||
name: sb-spec-1
|
||||
spec:
|
||||
collectors:
|
||||
- clusterResources: {}
|
||||
---
|
||||
# Source: wg-easy/templates/replicated-library.yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: sb-spec-2-configmap
|
||||
labels:
|
||||
troubleshoot.io/kind: support-bundle
|
||||
data:
|
||||
support-bundle-spec: |-
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: SupportBundle
|
||||
metadata:
|
||||
name: sb-spec-2
|
||||
spec:
|
||||
collectors:
|
||||
- logs:
|
||||
collectorName: wg-easy
|
||||
---
|
||||
# Source: wg-easy/templates/replicated-library.yaml
|
||||
kind: PersistentVolumeClaim
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: release-name-wg-easy-config
|
||||
labels:
|
||||
app.kubernetes.io/instance: release-name
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: wg-easy
|
||||
app.kubernetes.io/version: "7"
|
||||
helm.sh/chart: wg-easy-0.1.2
|
||||
annotations:
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 100Mi
|
||||
---
|
||||
# Source: wg-easy/templates/replicated-library.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: release-name-wg-easy-vpn
|
||||
labels:
|
||||
app.kubernetes.io/instance: release-name
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: wg-easy
|
||||
app.kubernetes.io/version: "7"
|
||||
helm.sh/chart: wg-easy-0.1.2
|
||||
annotations:
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- port: 51820
|
||||
targetPort: 51820
|
||||
protocol: UDP
|
||||
name: udp
|
||||
selector:
|
||||
app.kubernetes.io/name: wg-easy
|
||||
app.kubernetes.io/instance: release-name
|
||||
---
|
||||
# Source: wg-easy/templates/replicated-library.yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: redactor-spec-1-configmap
|
||||
labels:
|
||||
troubleshoot.io/kind: support-bundle
|
||||
data:
|
||||
redactor-spec: |
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: Redactor
|
||||
metadata:
|
||||
name: redactor-spec-1
|
||||
spec:
|
||||
redactors:
|
||||
- name: redact-text-1
|
||||
removals:
|
||||
values:
|
||||
- REDACT SECOND TEXT PLEASE
|
||||
---
|
||||
# Source: wg-easy/templates/replicated-library.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: release-name-wg-easy-web
|
||||
labels:
|
||||
app.kubernetes.io/instance: release-name
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: wg-easy
|
||||
app.kubernetes.io/version: "7"
|
||||
helm.sh/chart: wg-easy-0.1.2
|
||||
annotations:
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ipFamilyPolicy: SingleStack
|
||||
ports:
|
||||
- port: 51821
|
||||
targetPort: 51821
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app.kubernetes.io/name: wg-easy
|
||||
app.kubernetes.io/instance: release-name
|
||||
---
|
||||
# Source: wg-easy/templates/replicated-library.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: release-name-wg-easy-wg-easy
|
||||
labels:
|
||||
app.kubernetes.io/instance: release-name
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: wg-easy
|
||||
app.kubernetes.io/version: "7"
|
||||
helm.sh/chart: wg-easy-0.1.2
|
||||
spec:
|
||||
revisionHistoryLimit:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: wg-easy
|
||||
app.kubernetes.io/instance: release-name
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: wg-easy
|
||||
app.kubernetes.io/instance: release-name
|
||||
spec:
|
||||
|
||||
serviceAccountName:
|
||||
automountServiceAccountToken:
|
||||
dnsPolicy: ClusterFirst
|
||||
enableServiceLinks:
|
||||
containers:
|
||||
- name: wg-container
|
||||
image: "weejewel/wg-easy:7"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
add:
|
||||
- NET_ADMIN
|
||||
drop: []
|
||||
env:
|
||||
- name: WG_HOST
|
||||
value: vpn.example.com
|
||||
ports:
|
||||
- containerPort: 51821
|
||||
protocol: TCP
|
||||
- containerPort: 51820
|
||||
protocol: UDP
|
||||
volumeMounts:
|
||||
- mountPath: /etc/wireguard
|
||||
name: config
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 50Mi
|
||||
livenessProbe:
|
||||
failureThreshold: 5
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
tcpSocket:
|
||||
port: 51821
|
||||
terminationGracePeriodSeconds: 30
|
||||
timeoutSeconds: 5
|
||||
readinessProbe:
|
||||
failureThreshold: 5
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
tcpSocket:
|
||||
port: 51821
|
||||
timeoutSeconds: 1
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: release-name-wg-easy-config
|
||||
---
|
||||
# Source: wg-easy/templates/replicated-library.yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install, pre-upgrade
|
||||
"helm.sh/hook-weight": "-6"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed
|
||||
labels:
|
||||
app.kubernetes.io/managed-by: "Helm"
|
||||
app.kubernetes.io/instance: "release-name"
|
||||
app.kubernetes.io/version: 0.62.1
|
||||
helm.sh/chart: "troubleshoot-0.1.0"
|
||||
troubleshoot.io/kind: preflight
|
||||
name: "release-name-preflight-config"
|
||||
data:
|
||||
preflight.yaml: CmFwaVZlcnNpb246IHRyb3VibGVzaG9vdC5zaC92MWJldGEyCmtpbmQ6IFByZWZsaWdodAptZXRhZGF0YToKICBuYW1lOiBwcmVmbGlnaHQtc2FtcGxlCnNwZWM6CiAgCiAgYW5hbHl6ZXJzOgogICAgLSBub2RlUmVzb3VyY2VzOgogICAgICAgIGNoZWNrTmFtZTogTm9kZSBDb3VudCBDaGVjawogICAgICAgIG91dGNvbWVzOgogICAgICAgICAgLSBmYWlsOgogICAgICAgICAgICAgIHdoZW46ICdjb3VudCgpIDwgMycKICAgICAgICAgICAgICBtZXNzYWdlOiBUaGUgY2x1c3RlciBuZWVkcyBhIG1pbmltdW0gb2YgMyBub2Rlcy4KICAgICAgICAgIC0gcGFzczoKICAgICAgICAgICAgICBtZXNzYWdlOiBUaGVyZSBhcmUgbm90IGVub3VnaCBub2RlcyB0byBydW4gdGhpcyBhcHBsaWNhdGlvbiAoMyBvciBtb3JlKQogICAgLSBjbHVzdGVyVmVyc2lvbjoKICAgICAgICBvdXRjb21lczoKICAgICAgICAgIC0gZmFpbDoKICAgICAgICAgICAgICB3aGVuOiAiPCAxLjE2LjAiCiAgICAgICAgICAgICAgbWVzc2FnZTogVGhlIGFwcGxpY2F0aW9uIHJlcXVpcmVzIGF0IGxlYXN0IEt1YmVybmV0ZXMgMS4xNi4wLCBhbmQgcmVjb21tZW5kcyAxLjE4LjAuCiAgICAgICAgICAgICAgdXJpOiBodHRwczovL2t1YmVybmV0ZXMuaW8KICAgICAgICAgIC0gd2FybjoKICAgICAgICAgICAgICB3aGVuOiAiPCAxLjE4LjAiCiAgICAgICAgICAgICAgbWVzc2FnZTogWW91ciBjbHVzdGVyIG1lZXRzIHRoZSBtaW5pbXVtIHZlcnNpb24gb2YgS3ViZXJuZXRlcywgYnV0IHdlIHJlY29tbWVuZCB5b3UgdXBkYXRlIHRvIDEuMTguMCBvciBsYXRlci4KICAgICAgICAgICAgICB1cmk6IGh0dHBzOi8va3ViZXJuZXRlcy5pbwogICAgICAgICAgLSBwYXNzOgogICAgICAgICAgICAgIG1lc3NhZ2U6IFlvdXIgY2x1c3RlciBtZWV0cyB0aGUgcmVjb21tZW5kZWQgYW5kIHJlcXVpcmVkIHZlcnNpb25zIG9mIEt1YmVybmV0ZXMuCiAgICA=
|
||||
---
|
||||
# Source: wg-easy/templates/replicated-library.yaml
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: release-name-preflight-wg-preflights
|
||||
labels:
|
||||
helm.sh/chart: wg-easy-0.1.2
|
||||
app.kubernetes.io/name: wg-easy
|
||||
app.kubernetes.io/instance: release-name
|
||||
app.kubernetes.io/version: "7"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
troubleshoot.io/kind: preflight
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install, pre-upgrade
|
||||
"helm.sh/hook-weight": "-6"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed
|
||||
secrets:
|
||||
- name: release-name-wg-easy-preflight-wg-preflights
|
||||
---
|
||||
# Source: wg-easy/templates/replicated-library.yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: release-name-wg-easy-preflight-wg-preflights
|
||||
labels:
|
||||
helm.sh/chart: wg-easy-0.1.2
|
||||
app.kubernetes.io/name: wg-easy
|
||||
app.kubernetes.io/instance: release-name
|
||||
app.kubernetes.io/version: "7"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
troubleshoot.io/kind: preflight
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install, pre-upgrade
|
||||
"helm.sh/hook-weight": "-6"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed
|
||||
stringData:
|
||||
preflight.yaml: |-
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: Preflight
|
||||
metadata:
|
||||
name: preflight-1
|
||||
spec:
|
||||
collectors:
|
||||
- clusterResources:
|
||||
ignoreRBAC: true
|
||||
analyzers:
|
||||
- clusterVersion:
|
||||
outcomes:
|
||||
- pass:
|
||||
message: Your cluster meets the recommended and required versions of Kubernetes.
|
||||
---
|
||||
# Source: wg-easy/templates/replicated-library.yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: release-name-preflight-wg-preflights
|
||||
labels:
|
||||
helm.sh/chart: wg-easy-0.1.2
|
||||
app.kubernetes.io/name: wg-easy
|
||||
app.kubernetes.io/instance: release-name
|
||||
app.kubernetes.io/version: "7"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
troubleshoot.io/kind: preflight
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install, pre-upgrade
|
||||
"helm.sh/hook-weight": "-6"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- "namespaces"
|
||||
verbs:
|
||||
- "get"
|
||||
- "watch"
|
||||
- "list"
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- "nodes"
|
||||
verbs:
|
||||
- "get"
|
||||
- "watch"
|
||||
- "list"
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- "pods"
|
||||
verbs:
|
||||
- "get"
|
||||
- "watch"
|
||||
- "list"
|
||||
- "create"
|
||||
- apiGroups:
|
||||
- "apiextensions.k8s.io"
|
||||
resources:
|
||||
- "customresourcedefinitions"
|
||||
verbs:
|
||||
- "get"
|
||||
- "watch"
|
||||
- "list"
|
||||
- apiGroups:
|
||||
- "storage.k8s.io"
|
||||
resources:
|
||||
- "storageclasses"
|
||||
verbs:
|
||||
- "get"
|
||||
- "watch"
|
||||
- "list"
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- "pods/log"
|
||||
verbs:
|
||||
- "get"
|
||||
- "list"
|
||||
---
|
||||
# Source: wg-easy/templates/replicated-library.yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: "some-secret"
|
||||
stringData:
|
||||
somesecret: gibberish text
|
||||
---
|
||||
# Source: wg-easy/templates/replicated-library.yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: release-name-preflight-wg-preflights
|
||||
labels:
|
||||
helm.sh/chart: wg-easy-0.1.2
|
||||
app.kubernetes.io/name: wg-easy
|
||||
app.kubernetes.io/instance: release-name
|
||||
app.kubernetes.io/version: "7"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
troubleshoot.io/kind: preflight
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install, pre-upgrade
|
||||
"helm.sh/hook-weight": "-6"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: release-name-preflight-wg-preflights
|
||||
namespace: default
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: release-name-preflight-wg-preflights
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
---
|
||||
# Source: wg-easy/templates/replicated-library.yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: release-name-preflight-check
|
||||
labels:
|
||||
helm.sh/chart: wg-easy-0.1.2
|
||||
app.kubernetes.io/name: wg-easy
|
||||
app.kubernetes.io/instance: release-name
|
||||
app.kubernetes.io/version: "7"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
troubleshoot.io/kind: preflight
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install, pre-upgrade
|
||||
"helm.sh/show-output": "true"
|
||||
"helm.sh/hook-weight": "-5"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation, hook-succeeded, hook-failed
|
||||
"helm.sh/hook-output-log-policy": hook-failed, hook-succeeded
|
||||
spec:
|
||||
serviceAccountName: release-name-preflight-wg-preflights
|
||||
restartPolicy: Never
|
||||
volumes:
|
||||
- name: preflights
|
||||
secret:
|
||||
secretName: release-name-wg-easy-preflight-wg-preflights
|
||||
containers:
|
||||
- name: pre-install-job
|
||||
image: replicated/preflight:latest
|
||||
command:
|
||||
- "preflight"
|
||||
- "--interactive=false"
|
||||
- "/preflights/preflight.yaml"
|
||||
volumeMounts:
|
||||
- name: preflights
|
||||
mountPath: /preflights
|
||||
77
testdata/yamldocs/multidoc-spec-1.yaml
vendored
Normal file
77
testdata/yamldocs/multidoc-spec-1.yaml
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: Analyzer
|
||||
spec:
|
||||
analyzers:
|
||||
- clusterVersion: {}
|
||||
hostAnalyzers:
|
||||
- tcpLoadBalancer: {}
|
||||
---
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: Collector
|
||||
spec:
|
||||
collectors:
|
||||
- clusterResources:
|
||||
collectorName: my-cluster-resources
|
||||
---
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: HostCollector
|
||||
metadata:
|
||||
name: my-host-collector
|
||||
spec:
|
||||
collectors:
|
||||
- cpu: {}
|
||||
---
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: HostPreflight
|
||||
spec:
|
||||
remoteCollectors:
|
||||
- certificate:
|
||||
certificatePath: /etc/ssl/corp.crt
|
||||
keyPath: /etc/ssl/corp.key
|
||||
analyzers:
|
||||
- certificate:
|
||||
outcomes:
|
||||
- pass:
|
||||
message: Certificate key pair is valid
|
||||
---
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: Preflight
|
||||
spec:
|
||||
collectors:
|
||||
- data:
|
||||
data: "5"
|
||||
analyzers:
|
||||
- clusterVersion: {}
|
||||
---
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: Redactor
|
||||
spec:
|
||||
redactors:
|
||||
- name: replace password # names are not used internally, but are useful for recordkeeping
|
||||
fileSelector:
|
||||
file: data/my-password-dump # this targets a single file
|
||||
removals:
|
||||
values:
|
||||
- abc123 # this is a very good password, and I don't want it to be exposed
|
||||
---
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: RemoteCollector
|
||||
metadata:
|
||||
name: certificate
|
||||
spec:
|
||||
collectors:
|
||||
- cpu: {}
|
||||
---
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: SupportBundle
|
||||
metadata:
|
||||
name: my-support-bundle
|
||||
spec:
|
||||
collectors:
|
||||
- logs:
|
||||
name: all-logs
|
||||
hostCollectors:
|
||||
- hostOS: {}
|
||||
analyzers:
|
||||
- clusterVersion: {}
|
||||
35
testdata/yamldocs/multidoc-spec-2.yaml
vendored
Normal file
35
testdata/yamldocs/multidoc-spec-2.yaml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: multi-spec
|
||||
labels:
|
||||
troubleshoot.io/kind: support-bundle
|
||||
data:
|
||||
support-bundle-spec: |-
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: SupportBundle
|
||||
spec:
|
||||
collectors:
|
||||
- logs:
|
||||
name: all-logs
|
||||
redactor-spec: |
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: Redactor
|
||||
spec:
|
||||
redactors:
|
||||
- name: redact-text-1
|
||||
removals:
|
||||
values:
|
||||
- abc123
|
||||
preflight.yaml: |-
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: Preflight
|
||||
spec:
|
||||
collectors:
|
||||
- clusterResources:
|
||||
ignoreRBAC: true
|
||||
analyzers:
|
||||
- clusterVersion:
|
||||
outcomes:
|
||||
- pass:
|
||||
message: Cluster is up to date
|
||||
26
testdata/yamldocs/multidoc-spec-3.yaml
vendored
Normal file
26
testdata/yamldocs/multidoc-spec-3.yaml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: sb-spec
|
||||
labels:
|
||||
troubleshoot.io/kind: support-bundle
|
||||
data:
|
||||
support-bundle-spec: |-
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: SupportBundle
|
||||
spec:
|
||||
collectors:
|
||||
- logs:
|
||||
name: all-logs
|
||||
---
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: SupportBundle
|
||||
spec:
|
||||
collectors:
|
||||
- clusterResources: {}
|
||||
---
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: SupportBundle
|
||||
spec:
|
||||
collectors:
|
||||
- clusterInfo: {}
|
||||
Reference in New Issue
Block a user