Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
var APICallOptionsInjectorTask = inspectiontaskbase.NewInspectionTask( gcpcommon.APIClientCallOptionsInjectorTaskID, []coretask.Dependency{}, func(ctx context.Context, taskMode inspectioncore.InspectionTaskModeType) (*googlecloud.CallOptionInjector, error) { var options []googlecloud.CallOptionInjectorOption optionsFromContext, err := khictx.GetValue(ctx, gcpcommon.APICallOptionsInjectorContextKey) if err != nil && !errors.Is(err, khierrors.ErrNotFound) { return nil, err } if optionsFromContext != nil { options = *optionsFromContext } return googlecloud.NewCallOptionInjector(options...), nil }, coretask.WithSelectionPriority(gcpcommon.DefaultAPIClientOptionTasksPriority), )
APICallOptionsInjectorTask is the default implementation to provide the CallOptionInjector. Each APIClient use must call this injector method before to supply parameters correctly.
var APIClientFactoryOptionsTask = inspectiontaskbase.NewInspectionTask( gcpcommon.APIClientFactoryOptionsTaskID, []coretask.Dependency{}, func(ctx context.Context, taskMode inspectioncore.InspectionTaskModeType) ([]googlecloud.ClientFactoryOption, error) { var options []googlecloud.ClientFactoryOption optionsFromContext, err := khictx.GetValue(ctx, gcpcommon.APIClientFactoryOptionsContextKey) if err != nil && !errors.Is(err, khierrors.ErrNotFound) { return nil, err } if optionsFromContext != nil { options = *optionsFromContext } if parameters.RateLimit.LoggingAdaptiveRateLimitEnabled == nil || *parameters.RateLimit.LoggingAdaptiveRateLimitEnabled { quotaProjectID := "" if parameters.Auth.QuotaProjectID != nil { quotaProjectID = *parameters.Auth.QuotaProjectID } cfg := ratelimit.DefaultAdaptiveRateLimiterConfig() if parameters.RateLimit.LoggingInitialQPS != nil { cfg.InitialQPS = *parameters.RateLimit.LoggingInitialQPS } if parameters.RateLimit.LoggingMinQPS != nil { cfg.MinQPS = *parameters.RateLimit.LoggingMinQPS } if parameters.RateLimit.LoggingMaxQPS != nil { cfg.MaxQPS = *parameters.RateLimit.LoggingMaxQPS } limiterPool := ratelimit.NewPool(cfg, quotaProjectID) options = append(options, optionspkg.AdaptiveRateLimiter(limiterPool)) } return options, nil }, coretask.WithSelectionPriority(gcpcommon.DefaultAPIClientOptionTasksPriority), )
APIClientFactoryOptionsTask is the default implementation to provide the list of googlecloud.ClientFactoryOption. User can extend this behavior with defining new task for gcpcommon.APIClientFactoryOptionsTaskID with higher selection priority.
var APIClientFactoryTask = inspectiontaskbase.NewInspectionCachedTask(gcpcommon.APIClientFactoryTaskID, []coretask.Dependency{ gcpcommon.APIClientFactoryOptionsTaskID.Ref(), }, func(ctx context.Context, prevValue inspectiontaskbase.CacheableTaskResult[*googlecloud.ClientFactory]) (inspectiontaskbase.CacheableTaskResult[*googlecloud.ClientFactory], error) { if prevValue.DependencyDigest != "" { return prevValue, nil } opts := coretask.GetTaskResult(ctx, gcpcommon.APIClientFactoryOptionsTaskID.Ref()) clientFactory, err := googlecloud.NewClientFactory(opts...) if err != nil { return inspectiontaskbase.CacheableTaskResult[*googlecloud.ClientFactory]{}, err } inspectionContext := khictx.MustGetValue(ctx, inspectioncore.InspectionContext) context.AfterFunc(inspectionContext, func() { if err := clientFactory.Close(); err != nil { slog.ErrorContext(inspectionContext, "failed to close client factory", "error", err) } }) return inspectiontaskbase.CacheableTaskResult[*googlecloud.ClientFactory]{ DependencyDigest: "singleton", Value: clientFactory, }, nil })
APIClientFactoryTask is a task to inject googlecloud.ClientFactory to the later tasks. The instance is singleton in an inspection and the instance is cached on inspection cache after the first generation.
var AutocompleteLocationTask = inspectiontaskbase.NewGlobalCachedTask(gcpcommon.AutocompleteLocationTaskID, []coretask.Dependency{ gcpcommon.InputProjectIdTaskID.Ref(), gcpcommon.LocationFetcherTaskID.Ref(), }, func(ctx context.Context, prevValue inspectiontaskbase.CacheableTaskResult[*inspectioncore.AutocompleteResult[string]]) (inspectiontaskbase.CacheableTaskResult[*inspectioncore.AutocompleteResult[string]], error) { projectID := coretask.GetTaskResult(ctx, gcpcommon.InputProjectIdTaskID.Ref()) dependencyDigest := fmt.Sprintf("location-%s", projectID) if prevValue.DependencyDigest == dependencyDigest { return prevValue, nil } defaultResult := inspectiontaskbase.CacheableTaskResult[*inspectioncore.AutocompleteResult[string]]{ DependencyDigest: dependencyDigest, Value: &inspectioncore.AutocompleteResult[string]{ Values: []string{}, Error: "", Hint: "", }, } if projectID == "" { return defaultResult, nil } locationFetcher := coretask.GetTaskResult(ctx, gcpcommon.LocationFetcherTaskID.Ref()) regions, err := locationFetcher.FetchRegions(ctx, projectID) if err != nil { return defaultResult, nil } result := defaultResult result.Value.Values = regions return result, nil })
AutocompleteLocationTask is a task that provides a list of available locations for autocomplete. This serves as the default fallback implementation for generic Google Cloud environments. When an inspection type specific implementation is available (e.g. Kubernetes cluster or Cloud Composer), this implementation is shadowed by the higher-priority task.
var InputDurationTask = formtask.NewTextFormTaskBuilder(gcpcommon.InputDurationTaskID, gcpcommon.PriorityForQueryTimeGroup+4000, "Duration"). WithDependencies([]coretask.Dependency{ inspectioncore.InspectionTimeTaskID.Ref(), gcpcommon.InputEndTimeTaskID.Ref(), inspectioncore.TimeZoneShiftInputTaskID.Ref(), }). WithDescription("The duration of time range to gather logs. Supported time units are `h`,`m` or `s`. (Example: `3h30m`)"). WithDefaultValueFunc(func(ctx context.Context, 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) (string, inspectionmetadata.ParameterHintType, error) { inspectionTime := coretask.GetTaskResult(ctx, inspectioncore.InspectionTimeTaskID.Ref()) endTime := coretask.GetTaskResult(ctx, gcpcommon.InputEndTimeTaskID.Ref()) timezoneShift := coretask.GetTaskResult(ctx, inspectioncore.TimeZoneShiftInputTaskID.Ref()) 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, inspectionmetadata.Info, nil }). WithSuggestionsConstant([]string{"1m", "10m", "1h", "3h", "12h", "24h"}). WithValidator(func(ctx context.Context, value string) (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) (time.Duration, error) { d, err := time.ParseDuration(value) if err != nil { return 0, err } return d, nil }). Build()
InputDurationTask defines a form task to input the duration for log queries.
var InputEndTimeTask = formtask.NewTextFormTaskBuilder(gcpcommon.InputEndTimeTaskID, gcpcommon.PriorityForQueryTimeGroup+5000, "End time"). WithDependencies([]coretask.Dependency{ inspectioncore.TimeZoneShiftInputTaskID.Ref(), }). 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, previousValues []string) ([]string, error) { return previousValues, nil }). WithDefaultValueFunc(func(ctx context.Context, previousValues []string) (string, error) { if len(previousValues) > 0 { return previousValues[0], nil } creationTime := khictx.MustGetValue(ctx, inspectioncore.InspectionCreationTime) timezoneShift := coretask.GetTaskResult(ctx, inspectioncore.TimeZoneShiftInputTaskID.Ref()) return creationTime.In(timezoneShift).Format(time.RFC3339), nil }). WithHintFunc(func(ctx context.Context, value string, convertedValue any) (string, inspectionmetadata.ParameterHintType, error) { creationTime := khictx.MustGetValue(ctx, inspectioncore.InspectionCreationTime) specifiedTime := convertedValue.(time.Time) if creationTime.Sub(specifiedTime) < 0 { return fmt.Sprintf("Specified time `%s` is pointing the future. Please make sure if you specified the right value", value), inspectionmetadata.Warning, nil } return "", inspectionmetadata.Info, nil }). WithValidator(func(ctx context.Context, value string) (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) (time.Time, error) { return common.ParseTime(value) }). Build()
InputEndTimeTask defines a form task to input the end time for log queries.
var InputLocationsTask = formtask.NewTextFormTaskBuilder(gcpcommon.InputLocationsTaskID, gcpcommon.PriorityForResourceIdentifierGroup+3000, "Location"). WithDependencies([]coretask.Dependency{gcpcommon.AutocompleteLocationTaskID.Ref()}). WithDescription( "The location(region) to specify the resource exist(s|ed)", ). WithDefaultValueFunc(func(ctx context.Context, previousValues []string) (string, error) { locations := coretask.GetTaskResult(ctx, gcpcommon.AutocompleteLocationTaskID.Ref()) if len(previousValues) > 0 && slices.Contains(locations.Values, previousValues[0]) { return previousValues[0], nil } if len(locations.Values) == 0 { return "", nil } return locations.Values[0], nil }). WithSuggestionsFunc(func(ctx context.Context, value string, previousValues []string) ([]string, error) { regions := coretask.GetTaskResult(ctx, gcpcommon.AutocompleteLocationTaskID.Ref()) return common.SortForAutocomplete(value, regions.Values), nil }). WithValidator(func(ctx context.Context, value string) (string, error) { if value == "" { return "location is required", nil } return "", nil }). Build()
InputLocationsTask defines a form task for inputting the resource location.
var InputLoggingFilterResourceNameTask = inspectiontaskbase.NewInspectionTask(gcpcommon.InputLoggingFilterResourceNameTaskID, []coretask.Dependency{}, func(ctx context.Context, taskMode inspectioncore.InspectionTaskModeType) (*gcpcommon.ResourceNamesInput, error) { taskRunner := khictx.MustGetValue(ctx, inspectioncore.TaskRunner) currentActiveResourceNameInputRequests := getCurrentActiveQueryIDsForResourceName(taskRunner) sharedMap := khictx.MustGetValue(ctx, inspectioncore.InspectionSharedMap) resourceNamesInput := typedmap.GetOrSetFunc(sharedMap, resourceNamesInputKey, gcpcommon.NewResourceNamesInput) metadata := khictx.MustGetValue(ctx, inspectionmetadata.MapContextKey) formFields, found := typedmap.Get(metadata, inspectionmetadata.FormFieldSetMetadataKey) if !found { return nil, fmt.Errorf("failed to get form fields from run metadata") } requestInput := khictx.MustGetValue(ctx, inspectioncore.InspectionTaskInput) queryForms := []inspectionmetadata.ParameterFormField{} for _, request := range currentActiveResourceNameInputRequests { queryInfo := resourceNamesInput.GetResourceNamesForQuery(ctx, request) defaultValue := strings.Join(queryInfo.DefaultResourceNames, " ") formFieldBase := inspectionmetadata.ParameterFormFieldBase{ Priority: 0, ID: queryInfo.GetInputID(), Type: inspectionmetadata.Text, Label: queryInfo.QueryID, Description: "", HintType: inspectionmetadata.None, Hint: "", } formInput, found := requestInput[queryInfo.GetInputID()] if found { resourceNamesFromInput := strings.Split(formInput.(string), " ") for i, resourceNameFromInput := range resourceNamesFromInput { resourceNameWithoutSurroundingSpace := strings.TrimSpace(resourceNameFromInput) err := googlecloud.ValidateResourceNameOnLogEntriesList(resourceNameWithoutSurroundingSpace) if err != nil { formFieldBase.HintType = inspectionmetadata.Error formFieldBase.Hint = fmt.Sprintf("%d: %s", i, err.Error()) break } } } queryForms = append(queryForms, inspectionmetadata.TextParameterFormField{ ParameterFormFieldBase: formFieldBase, Default: defaultValue, Suggestions: queryInfo.DefaultResourceNames, ValidationTiming: inspectionmetadata.Change, }) } groupForm := inspectionmetadata.GroupParameterFormField{ ParameterFormFieldBase: inspectionmetadata.ParameterFormFieldBase{ Priority: -1000000, ID: gcpcommon.InputLoggingFilterResourceNameTaskID.ReferenceIDString(), Type: inspectionmetadata.Group, Label: "Logging filter resource names (advanced)", Description: "Override these parameters when your logs are not on the same project of the cluster, or customize the log filter target resources.", HintType: inspectionmetadata.None, Hint: "", }, Children: queryForms, Collapsible: true, CollapsedByDefault: true, } err := formFields.SetField(groupForm) if err != nil { return nil, err } return resourceNamesInput, nil })
InputLoggingFilterResourceNameTask defines an inspection task that creates a form group for overriding log filter resource names for advanced users.
var InputProjectIdTask = formtask.NewTextFormTaskBuilder(gcpcommon.InputProjectIdTaskID, gcpcommon.PriorityForResourceIdentifierGroup+5000, "Project ID"). WithDescription("The project ID containing logs of the cluster to query"). WithValidatingTiming(inspectionmetadata.Blur). WithValidator(func(ctx context.Context, value string) (string, error) { if !projectIdValidator.Match([]byte(value)) { return "Project ID must match `^*[0-9a-z\\.:\\-]+$`", nil } return "", nil }). WithReadonlyFunc(func(ctx context.Context) (bool, error) { if parameters.Auth.FixedProjectID == nil { return false, nil } return *parameters.Auth.FixedProjectID != "", nil }). WithDefaultValueFunc(func(ctx context.Context, 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) (string, error) { return strings.TrimSpace(value), nil }). Build()
InputProjectIdTask defines a form task for inputting the Google Cloud project ID.
var InputStartTimeTask = inspectiontaskbase.NewInspectionTask(gcpcommon.InputStartTimeTaskID, []coretask.Dependency{ gcpcommon.InputEndTimeTaskID.Ref(), gcpcommon.InputDurationTaskID.Ref(), }, func(ctx context.Context, taskMode inspectioncore.InspectionTaskModeType) (time.Time, error) { endTime := coretask.GetTaskResult(ctx, gcpcommon.InputEndTimeTaskID.Ref()) duration := coretask.GetTaskResult(ctx, gcpcommon.InputDurationTaskID.Ref()) startTime := endTime.Add(-duration) metadataSet := khictx.MustGetValue(ctx, inspectionmetadata.MapContextKey) header, found := typedmap.Get(metadataSet, inspectionmetadata.HeaderMetadataKey) if !found { return time.Time{}, fmt.Errorf("header metadata not found") } header.StartTimeUnixSeconds = startTime.Unix() header.EndTimeUnixSeconds = endTime.Unix() return startTime, nil })
InputStartTimeTask defines an inspection task that calculates the start time of a query from the end time and duration.
var LocationFetcherTask = coretask.NewTask(gcpcommon.LocationFetcherTaskID, []coretask.Dependency{ gcpcommon.InputProjectIdTaskID.Ref(), gcpcommon.APIClientFactoryTaskID.Ref(), gcpcommon.APIClientCallOptionsInjectorTaskID.Ref(), }, func(ctx context.Context) (gcpcommon.LocationFetcher, error) { clientFactory := coretask.GetTaskResult(ctx, gcpcommon.APIClientFactoryTaskID.Ref()) callOptionInjector := coretask.GetTaskResult(ctx, gcpcommon.APIClientCallOptionsInjectorTaskID.Ref()) projectID := coretask.GetTaskResult(ctx, gcpcommon.InputProjectIdTaskID.Ref()) regionClient, err := clientFactory.RegionsClient(ctx, googlecloud.Project(projectID)) if err != nil { return nil, err } return gcpcommon.NewLocationFetcher(regionClient, callOptionInjector), nil })
LocationFetcherTask is the task to inject the reference to LocationFetcher. This is primarily utilized by the default fallback AutocompleteLocationTask.
var LoggingFetcherTask = coretask.NewTask(gcpcommon.LoggingFetcherTaskID, []coretask.Dependency{ gcpcommon.APIClientFactoryTaskID.Ref(), gcpcommon.APIClientCallOptionsInjectorTaskID.Ref(), }, func(ctx context.Context) (gcpcommon.LogFetcher, error) { clientFactory := coretask.GetTaskResult(ctx, gcpcommon.APIClientFactoryTaskID.Ref()) callOptionInjector := coretask.GetTaskResult(ctx, gcpcommon.APIClientCallOptionsInjectorTaskID.Ref()) return gcpcommon.NewLogFetcher(clientFactory, callOptionInjector, 1000), nil })
LoggingFetcherTask is a task to inject the reference to LogFetcher.
Functions ¶
func Register ¶
func Register(registry coreinspection.InspectionTaskRegistry) error
Register registers all googlecloudcommon inspection tasks to the registry.
Types ¶
This section is empty.