troubleshooter

package
v2.11.26 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 3, 2024 License: Apache-2.0 Imports: 25 Imported by: 0

Documentation

Overview

Package troubleshooter holds logic for debugging individual Kubernetes objects.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Cause

type Cause struct {
	// Description is a markdown description of the cause.
	Description string

	// Filter returns True if the problem is caused by this cause.
	// If nil, it will match all objects and the recommendation will be at the
	// WARN level.
	Filter TroubleshootingTest

	// Recommendation is a markdown description of what the user should do to
	// resolve the problem.
	Recommendation string
}

Cause represents a single technical issue that may be causing an undesired observed behavior.

type Component

type Component struct {
	// Type contains the Kubernetes type represented by this component.
	Type genericcli.Type

	// Problems contains a list of possible problems that can occur with the
	// object.
	Problems []Problem
}

Component contains troubleshooting information for a single Kubernetes component.

func AppComponent

func AppComponent() Component

AppComponent specifies troubleshooting for a Kf App.

func BuildComponent

func BuildComponent() Component

BuildComponent specifies troubleshooting for a Kf Build.

func ClusterServiceBrokerComponent

func ClusterServiceBrokerComponent() Component

ClusterServiceBrokerComponent specifies troubleshooting for a Kf ClusterServiceBroker.

func CustomResourceComponents

func CustomResourceComponents() []Component

CustomResourceComponents returns a list containing Kf's components.

func RouteComponent

func RouteComponent() Component

RouteComponent specifies troubleshooting for a Kf Route.

func ServiceBrokerComponent

func ServiceBrokerComponent() Component

ServiceBrokerComponent specifies troubleshooting for a Kf ServiceBroker.

func ServiceInstanceBindingComponent

func ServiceInstanceBindingComponent() Component

ServiceInstanceBindingComponent specifies troubleshooting for a Kf Binding.

func ServiceInstanceComponent

func ServiceInstanceComponent() Component

ServiceInstanceComponent specifies troubleshooting for a Kf Service.

func SourcePackageComponent

func SourcePackageComponent() Component

SourcePackageComponent specifies troubleshooting for a Kf SourcePackage.

func SpaceComponent

func SpaceComponent() Component

SpaceComponent specifies troubleshooting for a Kf Space.

func TaskComponent

func TaskComponent() Component

TaskComponent specifies troubleshooting for a Kf Task.

func (*Component) DiagnoseSingle

func (c *Component) DiagnoseSingle(ctx context.Context, d *doctor.Diagnostic, obj *unstructured.Unstructured)

DiagnoseSingle diagnoses a single Kubernetes object.

Example
c := Component{
	Type: &genericcli.KubernetesType{
		KfName: "test",
	},
	Problems: []Problem{
		{
			Description: "Some problem.",
			Filter: func(_ *unstructured.Unstructured) bool {
				return true
			},
			Causes: []Cause{
				{
					Description: "Not the cause.",
					Filter: func(_ *unstructured.Unstructured) bool {
						return false
					},
				},
				{
					Description:    "Possible cause.",
					Filter:         nil,
					Recommendation: "Check your inputs.",
				},
				{
					Description: "Definite cause.",
					Filter: func(_ *unstructured.Unstructured) bool {
						return true
					},
					Recommendation: "Do XYZ.",
				},
			},
		},
	},
}

obj := &unstructured.Unstructured{}
obj.SetName("test-obj")
obj.SetNamespace("test-ns")

c.DiagnoseSingle(context.Background(), doctor.NewDefaultDiagnostic(), obj)
Output:

=== RUN	doctor/namespace="test-ns",name="test-obj"
=== RUN	doctor/namespace="test-ns",name="test-obj"/Symptom: Some problem.
=== RUN	doctor/namespace="test-ns",name="test-obj"/Symptom: Some problem./Cause: Not the cause.
=== RUN	doctor/namespace="test-ns",name="test-obj"/Symptom: Some problem./Cause: Possible cause.
=== LOG	doctor/namespace="test-ns",name="test-obj"/Symptom: Some problem./Cause: Possible cause.
Cause: Possible cause.
Recommendation: Check your inputs.

=== RUN	doctor/namespace="test-ns",name="test-obj"/Symptom: Some problem./Cause: Definite cause.
=== LOG	doctor/namespace="test-ns",name="test-obj"/Symptom: Some problem./Cause: Definite cause.
Cause: Definite cause.
Recommendation: Do XYZ.

=== LOG	doctor/namespace="test-ns",name="test-obj"/Symptom: Some problem.
=== LOG	doctor/namespace="test-ns",name="test-obj"
--- FAIL: doctor/namespace="test-ns",name="test-obj"
    --- FAIL: doctor/namespace="test-ns",name="test-obj"/Symptom: Some problem.
        --- PASS: doctor/namespace="test-ns",name="test-obj"/Symptom: Some problem./Cause: Not the cause.
        --- WARN: doctor/namespace="test-ns",name="test-obj"/Symptom: Some problem./Cause: Possible cause.
        --- FAIL: doctor/namespace="test-ns",name="test-obj"/Symptom: Some problem./Cause: Definite cause.

type Problem

type Problem struct {
	// Description is a markdown description of the problem. This should be
	// a single sentence.
	Description string

	// Filter returns True if the problem is happening.
	Filter TroubleshootingTest

	// Causes contains a list of possible causes for the problem that can be
	// tested.
	Causes []Cause
}

Problem represents a high-level observable issue with the object that can be caused by one or more issues.

type TroubleshootingCloser

type TroubleshootingCloser struct {
	// contains filtered or unexported fields
}

TroubleshootingCloser creates closures binding Components to Kubernetes clusters.

func NewTroubleshootingCloser

func NewTroubleshootingCloser(p *config.KfParams) *TroubleshootingCloser

NewTroubleshootingCloser creates a new object that can bind Components to a Kubernetes cluster so troubleshooters can be executed against it.

func (*TroubleshootingCloser) Close

func (tc *TroubleshootingCloser) Close(component Component, resourceName string) doctor.Diagnosable

Close creates reifies the component with the informaiton necessary to actuate its test against the currently targeted cluster.

type TroubleshootingTest

type TroubleshootingTest func(obj *unstructured.Unstructured) bool

TroubleshootingTest returns true if the object might be affected by some condition or false otherwise.

Example (FilterBackingResourceDeprovisionFailedError)
obj1 := &unstructured.Unstructured{}
obj1.Object = map[string]interface{}{
	"status": map[string]interface{}{
		"conditions": []interface{}{
			map[string]interface{}{
				"type":    "BackingResourceReady",
				"status":  "False",
				"message": "backing resource DeprovisionFailed",
			},
		},
	},
}

obj2 := &unstructured.Unstructured{}
obj2.Object = map[string]interface{}{
	"status": map[string]interface{}{
		"conditions": []interface{}{
			map[string]interface{}{
				"type":    "BackingResourceReady",
				"status":  "False",
				"message": "backing resource deprovision failed",
			},
		},
	},
}
fmt.Println("Obj1 has DeprovisionFailed error:", filterBackingResourceDeprovisionFailedError(obj1))
fmt.Println("Obj2 has DeprovisionFailed error:", filterBackingResourceDeprovisionFailedError(obj2))
Output:

Obj1 has DeprovisionFailed error: true
Obj2 has DeprovisionFailed error: true
Example (FilterBackingResourceReconcilationError)
obj := &unstructured.Unstructured{}
obj.Object = map[string]interface{}{
	"status": map[string]interface{}{
		"conditions": []interface{}{
			map[string]interface{}{
				"type":   "BackingResourceReady",
				"status": "False",
				"reason": "ReconciliationError",
			},
		},
	},
}

fmt.Println("Obj has BackingResourceReady error:", filterBackingResourceReconcilationError(obj))
Output:

Obj has BackingResourceReady error: true
Example (FilterChildNotOwnedSet)
obj := &unstructured.Unstructured{}
obj.Object = map[string]interface{}{
	"status": map[string]interface{}{
		"conditions": []interface{}{
			map[string]interface{}{
				"type":   "Ready",
				"status": "False",
				"reason": "NotOwned",
			},
		},
	},
}

fmt.Println("Obj has NotOwned error:", filterChildNotOwnedSet(obj))
Output:

Obj has NotOwned error: true
Example (FilterDeletionMayBeInFuture)
obj := &unstructured.Unstructured{}

obj.SetDeletionTimestamp(MetaTime(time.Now()))
fmt.Println("Deleted recently:", filterDeletionMayBeInFuture(obj))

obj.SetDeletionTimestamp(MetaTime(time.Now().Add(-2 * time.Minute)))
fmt.Println("Deleted in past:", filterDeletionMayBeInFuture(obj))
Output:

Deleted recently: true
Deleted in past: false
Example (FilterDeletionSet)
obj := &unstructured.Unstructured{}
fmt.Println("Not deleted:", filterDeletionSet(obj))

obj.SetDeletionTimestamp(MetaTime(time.Now()))
fmt.Println("Deleted:", filterDeletionSet(obj))
Output:

Not deleted: false
Deleted: true
Example (FilterGenerationStateDriftSet)
obj1 := &unstructured.Unstructured{}

obj1.Object = map[string]interface{}{
	"status": map[string]interface{}{
		"observedGeneration": obj1.GetGeneration(),
	},
}

obj2 := &unstructured.Unstructured{}

obj2.Object = map[string]interface{}{
	"status": map[string]interface{}{
		"observedGeneration": obj2.GetGeneration() + 1,
	},
}

fmt.Println("Obj1 Generation drifted:", filterGenerationStateDriftSet(obj1))
fmt.Println("Obj2 Generation drifted:", filterGenerationStateDriftSet(obj2))
Output:

Obj1 Generation drifted: false
Obj2 Generation drifted: true
Example (FilterHasFinalizers)
obj := &unstructured.Unstructured{}

fmt.Println("No finalizers:", filterHasFinalizers(obj))

obj.SetFinalizers([]string{"foo", "bar"})
fmt.Println("With finalizers:", filterHasFinalizers(obj))
Output:

No finalizers: false
With finalizers: true
Example (FilterReconliationErrorSet)
obj := &unstructured.Unstructured{}
obj.Object = map[string]interface{}{
	"status": map[string]interface{}{
		"conditions": []interface{}{
			map[string]interface{}{
				"type":   "Ready",
				"status": "False",
				"reason": "ReconciliationError",
			},
		},
	},
}

fmt.Println("Obj has ReconciliationError:", filterReconliationErrorSet(obj))
Output:

Obj has ReconciliationError: true
Example (FilterStatusFalseSet)
obj1 := &unstructured.Unstructured{}
obj1.Object = map[string]interface{}{
	"status": map[string]interface{}{
		"conditions": []interface{}{
			map[string]interface{}{
				"type":   "Ready",
				"status": "False",
			},
		},
	},
}

obj2 := &unstructured.Unstructured{}
obj2.Object = map[string]interface{}{
	"status": map[string]interface{}{
		"conditions": []interface{}{
			map[string]interface{}{
				"type":   "Succeeded",
				"status": "False",
			},
		},
	},
}

fmt.Println("Obj1 is matched:", filterStatusFalseSet(obj1))
fmt.Println("Obj2 is matched:", filterStatusFalseSet(obj2))
Output:

Obj1 is matched: true
Obj2 is matched: true
Example (FilterTemplateErrorSet)
obj := &unstructured.Unstructured{}
obj.Object = map[string]interface{}{
	"status": map[string]interface{}{
		"conditions": []interface{}{
			map[string]interface{}{
				"type":   "Ready",
				"status": "False",
				"reason": "TemplateError",
			},
		},
	},
}

fmt.Println("Obj has TemplateError:", filterTemplateErrorSet(obj))
Output:

Obj has TemplateError: true

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL