task

package
v0.0.0-...-9f7285a Latest Latest
Warning

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

Go to latest
Published: Jan 31, 2025 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Index

Constants

View Source
const ClusterNamePrefixTaskID = GCPPrefix + "cluster-name-prefix"

ClusterNamePrefixTaskID is the task ID for generating the cluster name prefix used in query. For GKE, it's just a task to return "" always. For Anthos on AWS, it should return "awsClusters/" because the `resource.labels.cluster_name` field would be `awsClusters/<cluster-name>` For Anthos on Azure, it will be "azureClusters/"

View Source
const FormBasePriority = 100000
View Source
const GCPPrefix = "cloud.google.com/"
View Source
const InputClusterNameTaskID = GCPPrefix + "input/cluster-name"
View Source
const InputDurationTaskID = GCPPrefix + "input/duration"
View Source
const InputEndTimeTaskID = GCPPrefix + "input/end-time"
View Source
const InputKindFilterTaskID = GCPPrefix + "input/kinds"
View Source
const InputLocationsTaskID = GCPPrefix + "input/location"
View Source
const InputNamespaceFilterTaskID = GCPPrefix + "input/namespaces"
View Source
const InputNodeNameFilterTaskID = GCPPrefix + "input/node-name-filter"
View Source
const InputProjectIdTaskID = GCPPrefix + "input/project-id"
View Source
const InputStartTimeTaskID = GCPPrefix + "input/start-time"
View Source
const K8sResourceMergeConfigTaskID = GCPPrefix + "merge-config"
View Source
const PriorityForK8sResourceFilterGroup = FormBasePriority + 30000
View Source
const PriorityForQueryTimeGroup = FormBasePriority + 50000
View Source
const PriorityForResourceIdentifierGroup = FormBasePriority + 40000

Variables

View Source
var AutocompleteClusterNamesTaskID = GCPPrefix + "autocomplete/cluster-names"
View Source
var GCPDefaultK8sResourceMergeConfigTask = inspection_task.NewInspectionProducer(K8sResourceMergeConfigTaskID+"#gcp", func(ctx context.Context, taskMode int, progress *progress.TaskProgress) (any, error) {
	return k8s.GenerateDefaultMergeConfig()
})
View Source
var InputClusterNameTask = form.NewInputFormDefinitionBuilder(InputClusterNameTaskID, PriorityForResourceIdentifierGroup+4000, "Cluster name").
	WithDependencies([]string{AutocompleteClusterNamesTaskID, ClusterNamePrefixTaskID}).
	WithDefaultValueFunc(func(ctx context.Context, variables *task.VariableSet, previousValues []string) (string, error) {
		clusters, err := GetAutocompleteClusterNamesFromTaskVariable(variables)
		if err != nil {
			return "", err
		}

		if len(previousValues) > 0 && slices.Index(clusters.ClusterNames, previousValues[0]) > -1 {
			return previousValues[0], nil
		}
		if len(clusters.ClusterNames) == 0 {
			return "", nil
		}
		return clusters.ClusterNames[0], nil
	}).
	WithSuggestionsFunc(func(ctx context.Context, value string, variables *task.VariableSet, previousValues []string) ([]string, error) {
		clusters, err := GetAutocompleteClusterNamesFromTaskVariable(variables)
		if err != nil {
			return []string{}, err
		}
		return common.SortForAutocomplete(value, clusters.ClusterNames), nil
	}).
	WithHintFunc(func(ctx context.Context, value string, convertedValue any, variables *task.VariableSet) (string, form_metadata.FormFieldHintType, error) {
		clusters, err := GetAutocompleteClusterNamesFromTaskVariable(variables)
		if err != nil {
			return "", form_metadata.HintTypeInfo, err
		}

		if clusters.Error != "" {
			return fmt.Sprintf("Failed to obtain the cluster list due to the error '%s'.\n The suggestion list won't popup", clusters.Error), form_metadata.HintTypeWarning, nil
		}
		prefix, err := GetClusterNamePrefixFromTaskVariable(variables)
		if err != nil {
			return "", form_metadata.HintTypeInfo, err
		}
		convertedWithoutPrefix := strings.TrimPrefix(convertedValue.(string), prefix)
		for _, suggestedCluster := range clusters.ClusterNames {
			if suggestedCluster == convertedWithoutPrefix {
				return "", form_metadata.HintTypeInfo, nil
			}
		}
		return fmt.Sprintf("Cluster `%s` was not found in the specified project at this time. It works for the clusters existed in the past but make sure the cluster name is right if you believe the cluster should be there.", value), form_metadata.HintTypeWarning, nil
	}).
	WithValidator(func(ctx context.Context, value string, variables *task.VariableSet) (string, error) {
		if !clusterNameValidator.Match([]byte(value)) {
			return "Cluster name must match `^[0-9a-z:\\-]+$`", nil
		}
		return "", nil
	}).
	WithConverter(func(ctx context.Context, value string, variables *task.VariableSet) (any, error) {

		prefix, err := GetClusterNamePrefixFromTaskVariable(variables)
		if err != nil {
			return nil, err
		}
		return prefix + strings.TrimSpace(value), nil
	}).
	Build()
View Source
var InputDurationTask = form.NewInputFormDefinitionBuilder(InputDurationTaskID, PriorityForQueryTimeGroup+4000, "Duration").
	WithDependencies([]string{
		common_task.InspectionTimeTaskID,
		InputEndTimeTaskID,
		TimeZoneShiftInputTaskID,
	}).
	WithDefaultValueFunc(func(ctx context.Context, variables *task.VariableSet, previousValues []string) (string, error) {
		if len(previousValues) > 0 {
			return previousValues[0], nil
		} else {
			return "1h", nil
		}
	}).
	WithHintFunc(func(ctx context.Context, value string, convertedValue any, variables *task.VariableSet) (string, form_metadata.FormFieldHintType, error) {
		inspectionTime, err := common_task.GetInspectionTimeFromTaskVariable(variables)
		if err != nil {
			return "", form_metadata.HintTypeInfo, err
		}
		endTime, err := GetInputEndTimeFromTaskVariable(variables)
		if err != nil {
			return "", form_metadata.HintTypeInfo, err
		}
		timezoneShift, err := GetTimezoneShiftInput(variables)
		if err != nil {
			return "", form_metadata.HintTypeInfo, err
		}
		duration := convertedValue.(time.Duration)
		startTime := endTime.Add(-duration)
		startToNow := inspectionTime.Sub(startTime)
		hintString := ""
		if startToNow > time.Hour*24*30 {
			hintString += "Specified time range starts from over than 30 days ago, maybe some logs are missing and the generated result could be incomplete.\n"
		}
		if duration > time.Hour*3 {
			hintString += "This duration can be too long for big clusters and lead OOM. Please retry with shorter duration when your machine crashed.\n"
		}
		hintString += fmt.Sprintf("Query range:\n%s\n", toTimeDurationWithTimezone(startTime, endTime, timezoneShift, true))
		hintString += fmt.Sprintf("(UTC: %s)\n", toTimeDurationWithTimezone(startTime, endTime, time.UTC, false))
		hintString += fmt.Sprintf("(PDT: %s)", toTimeDurationWithTimezone(startTime, endTime, time.FixedZone("PDT", -7*3600), false))
		return hintString, form_metadata.HintTypeInfo, nil
	}).
	WithSuggestionsConstant([]string{"1m", "10m", "1h", "3h", "12h", "24h"}).
	WithValidator(func(ctx context.Context, value string, variables *task.VariableSet) (string, error) {
		d, err := time.ParseDuration(value)
		if err != nil {
			return err.Error(), nil
		}
		if d <= 0 {
			return "duration must be positive", nil
		}
		return "", nil
	}).
	WithConverter(func(ctx context.Context, value string, variables *task.VariableSet) (any, error) {
		d, err := time.ParseDuration(value)
		if err != nil {
			return nil, err
		}
		return d, nil
	}).
	Build()
View Source
var InputEndTimeTask = form.NewInputFormDefinitionBuilder(InputEndTimeTaskID, PriorityForQueryTimeGroup+5000, "End time").
	WithDependencies([]string{
		common_task.InspectionTimeTaskID,
		TimeZoneShiftInputTaskID,
	}).
	WithDescription(`The endtime of query. Please input it in the format of RFC3339
(example: 2006-01-02T15:04:05-07:00)`).
	WithSuggestionsFunc(func(ctx context.Context, value string, variables *task.VariableSet, previousValues []string) ([]string, error) {
		return previousValues, nil
	}).
	WithDefaultValueFunc(func(ctx context.Context, variables *task.VariableSet, previousValues []string) (string, error) {
		if len(previousValues) > 0 {
			return previousValues[0], nil
		}
		inspectionTime, err := common_task.GetInspectionTimeFromTaskVariable(variables)
		if err != nil {
			return "", err
		}
		timezoneShift, err := GetTimezoneShiftInput(variables)
		if err != nil {
			return "", err
		}
		return inspectionTime.In(timezoneShift).Format(time.RFC3339), nil
	}).
	WithHintFunc(func(ctx context.Context, value string, convertedValue any, variables *task.VariableSet) (string, form_metadata.FormFieldHintType, error) {
		inspectionTime, err := common_task.GetInspectionTimeFromTaskVariable(variables)
		if err != nil {
			return "", form_metadata.HintTypeInfo, err
		}
		specifiedTime := convertedValue.(time.Time)
		if inspectionTime.Sub(specifiedTime) < 0 {
			return fmt.Sprintf("Specified time `%s` is pointing the future. Please make sure if you specified the right value", value), form_metadata.HintTypeWarning, nil
		}
		return "", form_metadata.HintTypeInfo, nil
	}).
	WithValidator(func(ctx context.Context, value string, variables *task.VariableSet) (string, error) {
		_, err := common.ParseTime(value)
		if err != nil {
			return "invalid time format. Please specify in the format of `2006-01-02T15:04:05-07:00`(RFC3339)", nil
		}
		return "", nil
	}).
	WithConverter(func(ctx context.Context, value string, variables *task.VariableSet) (any, error) {
		return common.ParseTime(value)
	}).
	Build()
View Source
var InputKindFilterTask = form.NewInputFormDefinitionBuilder(InputKindFilterTaskID, PriorityForK8sResourceFilterGroup+5000, "Kind").
	WithDefaultValueConstant("@default", true).
	WithValidator(func(ctx context.Context, value string, variables *task.VariableSet) (string, error) {
		if value == "" {
			return "kind filter can't be empty", nil
		}
		result, err := queryutil.ParseSetFilter(value, inputKindNameAliasMap, true, true, true)
		if err != nil {
			return "", err
		}
		return result.ValidationError, nil
	}).
	WithConverter(func(ctx context.Context, value string, variables *task.VariableSet) (any, error) {
		result, err := queryutil.ParseSetFilter(value, inputKindNameAliasMap, true, true, true)
		if err != nil {
			return "", err
		}
		return result, nil
	}).
	Build()
View Source
var InputLocationsTask = form.NewInputFormDefinitionBuilder(InputLocationsTaskID, PriorityForResourceIdentifierGroup+4500, "Location").WithDescription(
	"A location(regions) containing the environments to inspect",
).Build()
View Source
var InputNamespaceFilterTask = form.NewInputFormDefinitionBuilder(InputNamespaceFilterTaskID, PriorityForK8sResourceFilterGroup+4000, "Namespaces").
	WithDefaultValueConstant("@all_cluster_scoped @all_namespaced", true).
	WithValidator(func(ctx context.Context, value string, variables *task.VariableSet) (string, error) {
		if value == "" {
			return "namespace filter can't be empty", nil
		}
		result, err := queryutil.ParseSetFilter(value, inputNamespacesAliasMap, false, false, true)
		if err != nil {
			return "", err
		}
		return result.ValidationError, nil
	}).
	WithConverter(func(ctx context.Context, value string, variables *task.VariableSet) (any, error) {
		result, err := queryutil.ParseSetFilter(value, inputNamespacesAliasMap, false, false, true)
		if err != nil {
			return "", err
		}
		return result, nil
	}).
	Build()
View Source
var InputNodeNameFilterTask = form.NewInputFormDefinitionBuilder(InputNodeNameFilterTaskID, PriorityForK8sResourceFilterGroup+3000, "Node names").
	WithDefaultValueConstant("", true).
	WithDescription("A space-separated list of node name substrings used to collect node-related logs. If left blank, KHI gathers logs from all nodes in the cluster.").
	WithValidator(func(ctx context.Context, value string, variables *task.VariableSet) (string, error) {
		nodeNameSubstrings := getNodeNameSubstringsFromRawInput(value)
		for _, name := range nodeNameSubstrings {
			if !nodeNameSubstringValidator.Match([]byte(name)) {
				return fmt.Sprintf("substring `%s` is not valid as a substring of node name", name), nil
			}
		}
		return "", nil
	}).WithConverter(func(ctx context.Context, value string, variables *task.VariableSet) (any, error) {
	return getNodeNameSubstringsFromRawInput(value), nil
}).Build()

InputNodeNameFilterTask is a task to collect list of substrings of node names. This input value is used in querying k8s_node or serialport logs.

View Source
var InputProjectIdTask = form.NewInputFormDefinitionBuilder(InputProjectIdTaskID, PriorityForResourceIdentifierGroup+5000, "Project ID").
	WithDescription("A project ID containing the cluster to inspect").
	WithDependencies([]string{}).
	WithValidator(func(ctx context.Context, value string, variables *task.VariableSet) (string, error) {
		if !projectIdValidator.Match([]byte(value)) {
			return "Project ID must match `^*[0-9a-z\\.:\\-]+$`", nil
		}
		return "", nil
	}).
	WithAllowEditFunc(func(ctx context.Context, variables *task.VariableSet) (bool, error) {
		if parameters.Auth.FixedProjectID == nil {
			return true, nil
		}
		return *parameters.Auth.FixedProjectID == "", nil
	}).
	WithDefaultValueFunc(func(ctx context.Context, variables *task.VariableSet, previousValues []string) (string, error) {
		if parameters.Auth.FixedProjectID != nil && *parameters.Auth.FixedProjectID != "" {
			return *parameters.Auth.FixedProjectID, nil
		}
		if len(previousValues) > 0 {
			return previousValues[0], nil
		}
		return "", nil
	}).
	WithConverter(func(ctx context.Context, value string, variables *task.VariableSet) (any, error) {
		return strings.TrimSpace(value), nil
	}).
	Build()
View Source
var InputStartTimeTask = common_task.NewInspectionProcessor(InputStartTimeTaskID, []string{
	InputEndTimeTaskID,
	InputDurationTaskID,
}, func(ctx context.Context, taskMode int, v *task.VariableSet, progress *progress.TaskProgress) (any, error) {
	endTime, err := GetInputEndTimeFromTaskVariable(v)
	if err != nil {
		return nil, err
	}
	duration, err := GetInputDurationFromTaskVariable(v)
	if err != nil {
		return nil, err
	}
	startTime := endTime.Add(-duration)

	metadataSet, err := common_task.GetMetadataSetFromVariable(v)
	if err != nil {
		return nil, err
	}
	header := metadataSet.LoadOrStore(header.HeaderMetadataKey, &header.HeaderMetadataFactory{}).(*header.Header)
	header.StartTimeUnixSeconds = startTime.Unix()
	header.EndTimeUnixSeconds = endTime.Unix()
	return startTime, nil
})
View Source
var TimeZoneShiftInputTask = inspection_task.NewInspectionProcessor(TimeZoneShiftInputTaskID, []string{}, func(ctx context.Context, taskMode int, v *task.VariableSet, progress *progress.TaskProgress) (any, error) {
	req, err := inspection_task.GetInspectionRequestFromVariable(v)
	if err != nil {
		return nil, err
	}
	if tzShiftAny, found := req.Values["timezoneShift"]; found {
		if tzShiftFloat, convertible := tzShiftAny.(float64); convertible {
			return time.FixedZone("Unknown", int(tzShiftFloat*3600)), nil
		} else {
			return time.UTC, nil
		}
	} else {
		return time.UTC, nil
	}
})
View Source
var TimeZoneShiftInputTaskID = GCPPrefix + "input/timezone-shift"

Functions

func GetClusterNamePrefixFromTaskVariable

func GetClusterNamePrefixFromTaskVariable(v *task.VariableSet) (string, error)

func GetInputClusterNameFromTaskVariable

func GetInputClusterNameFromTaskVariable(tv *task.VariableSet) (string, error)

func GetInputDurationFromTaskVariable

func GetInputDurationFromTaskVariable(tv *task.VariableSet) (time.Duration, error)

func GetInputEndTimeFromTaskVariable

func GetInputEndTimeFromTaskVariable(tv *task.VariableSet) (time.Time, error)

func GetInputKindNameFromTaskVariable

func GetInputKindNameFromTaskVariable(tv *task.VariableSet) (*queryutil.SetFilterParseResult, error)

func GetInputLocationsFromTaskVariable

func GetInputLocationsFromTaskVariable(tv *task.VariableSet) (string, error)

func GetInputNamespaceFilterFromTaskVariable

func GetInputNamespaceFilterFromTaskVariable(tv *task.VariableSet) (*queryutil.SetFilterParseResult, error)

func GetInputProjectIdFromTaskVariable

func GetInputProjectIdFromTaskVariable(tv *task.VariableSet) (string, error)

func GetInputStartTimeFromTaskVariable

func GetInputStartTimeFromTaskVariable(tv *task.VariableSet) (time.Time, error)

func GetK8sResourceMergeConfigFromTaskVariable

func GetK8sResourceMergeConfigFromTaskVariable(v *task.VariableSet) (*k8s.MergeConfigRegistry, error)

func GetNodeNameFilterFromTaskVaraible

func GetNodeNameFilterFromTaskVaraible(tv *task.VariableSet) ([]string, error)

func GetTimezoneShiftInput

func GetTimezoneShiftInput(tv *task.VariableSet) (*time.Location, error)

Types

type AutocompleteClusterNameList

type AutocompleteClusterNameList struct {
	ClusterNames []string
	Error        string
}

func GetAutocompleteClusterNamesFromTaskVariable

func GetAutocompleteClusterNamesFromTaskVariable(v *task.VariableSet) (*AutocompleteClusterNameList, error)

Jump to

Keyboard shortcuts

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