diff --git a/changelog/fragments/1704994055-add-error-statements.yaml b/changelog/fragments/1704994055-add-error-statements.yaml new file mode 100644 index 00000000000..0be47eb9359 --- /dev/null +++ b/changelog/fragments/1704994055-add-error-statements.yaml @@ -0,0 +1,32 @@ +# Kind can be one of: +# - breaking-change: a change to previously-documented behavior +# - deprecation: functionality that is being removed in a later release +# - bug-fix: fixes a problem in a previous version +# - enhancement: extends functionality but does not break or fix existing behavior +# - feature: new functionality +# - known-issue: problems that we are aware of in a given version +# - security: impacts on the security of a product or a user’s deployment. +# - upgrade: important information for someone upgrading from a prior version +# - other: does not fit into any of the other categories +kind: enhancement + +# Change summary; a 80ish characters long description of the change. +summary: add error descriptors to inspect command, config methods + +# Long description; in case the summary is not enough to describe the change +# this field accommodate a description without length limits. +# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment. +#description: + +# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc. +component: config + +# PR URL; optional; the PR number that added the changeset. +# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added. +# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number. +# Please provide it if you are adding a fragment for a different PR. +#pr: https://github.com/owner/repo/1234 + +# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of). +# If not present is automatically filled by the tooling with the issue linked to the PR number. +#issue: https://github.com/owner/repo/1234 diff --git a/internal/pkg/agent/cmd/inspect.go b/internal/pkg/agent/cmd/inspect.go index 094d4584a06..24f1cc0bc79 100644 --- a/internal/pkg/agent/cmd/inspect.go +++ b/internal/pkg/agent/cmd/inspect.go @@ -130,20 +130,23 @@ type inspectConfigOpts struct { func inspectConfig(ctx context.Context, cfgPath string, opts inspectConfigOpts, streams *cli.IOStreams) error { l, err := newErrorLogger() if err != nil { - return err + return fmt.Errorf("error creating logger: %w", err) } if !opts.variables && !opts.includeMonitoring { fullCfg, err := operations.LoadFullAgentConfig(ctx, l, cfgPath, true) if err != nil { - return err + return fmt.Errorf("error loading agent config: %w", err) + } + err = printConfig(fullCfg, streams) + if err != nil { + return fmt.Errorf("error printing config: %w", err) } - return printConfig(fullCfg, streams) } cfg, lvl, err := getConfigWithVariables(ctx, l, cfgPath, opts.variablesWait) if err != nil { - return err + return fmt.Errorf("error fetching config with variables: %w", err) } agentInfo, err := info.NewAgentInfoWithLog(ctx, "error", false) @@ -212,12 +215,17 @@ func printMapStringConfig(mapStr map[string]interface{}, streams *cli.IOStreams) return err } +// convert the config object to a mapstr and print to the stream specified in in streams.Out func printConfig(cfg *config.Config, streams *cli.IOStreams) error { mapStr, err := cfg.ToMapStr() if err != nil { - return err + return fmt.Errorf("error parsing config as hashmap: %w", err) + } + err = printMapStringConfig(mapStr, streams) + if err != nil { + return fmt.Errorf("error printing config to output: %w", err) } - return printMapStringConfig(mapStr, streams) + return nil } type inspectComponentsOpts struct { diff --git a/internal/pkg/config/config.go b/internal/pkg/config/config.go index 05e0dd02c76..0f0f9a53dea 100644 --- a/internal/pkg/config/config.go +++ b/internal/pkg/config/config.go @@ -155,7 +155,7 @@ func (c *Config) ToMapStr(opts ...interface{}) (map[string]interface{}, error) { } ucfgOpts, local, err := getOptions(opts...) if err != nil { - return nil, err + return nil, fmt.Errorf("error unpacking logs: %w", err) } // remove and unpack each skip keys into its own map with no resolve @@ -166,21 +166,21 @@ func (c *Config) ToMapStr(opts ...interface{}) (map[string]interface{}, error) { if c.access().HasField(skip) { subCfg, err := c.access().Child(skip, -1) if err != nil { - return nil, err + return nil, fmt.Errorf("error accessing skip key %s: %w", skip, err) } var subUnpacked interface{} if subCfg.IsDict() { var subDict map[string]interface{} err = subCfg.Unpack(&subDict, ucfg.ResolveNOOP) if err != nil { - return nil, err + return nil, fmt.Errorf("error unpacking subdict object in config for skip key %s: %w", skip, err) } subUnpacked = subDict } else if subCfg.IsArray() { var subArr []interface{} err = subCfg.Unpack(&subArr, ucfg.ResolveNOOP) if err != nil { - return nil, err + return nil, fmt.Errorf("error unpacking subarray in config for skip key %s: %w ", skip, err) } subUnpacked = subArr } else { @@ -188,7 +188,7 @@ func (c *Config) ToMapStr(opts ...interface{}) (map[string]interface{}, error) { } _, err = c.access().Remove(skip, -1) if err != nil { - return nil, err + return nil, fmt.Errorf("error removing skip key %s: %w", skip, err) } skippedKeys[skip] = subUnpacked skippedKeysOrig[skip] = subCfg @@ -198,7 +198,7 @@ func (c *Config) ToMapStr(opts ...interface{}) (map[string]interface{}, error) { // perform unpack with the skip keys removed var m map[string]interface{} if err := c.access().Unpack(&m, ucfgOpts...); err != nil { - return nil, err + return nil, fmt.Errorf("error unpacking config to MapStr object: %w", err) } // add the skipped keys into the map and back into the config @@ -208,7 +208,7 @@ func (c *Config) ToMapStr(opts ...interface{}) (map[string]interface{}, error) { if len(skippedKeysOrig) > 0 { err := c.access().Merge(skippedKeysOrig, ucfg.ResolveNOOP) if err != nil { - return nil, err + return nil, fmt.Errorf("error merging config with skipped key config: %w", err) } } return m, nil diff --git a/internal/pkg/config/operations/inspector.go b/internal/pkg/config/operations/inspector.go index f1066c22531..55e78069292 100644 --- a/internal/pkg/config/operations/inspector.go +++ b/internal/pkg/config/operations/inspector.go @@ -29,12 +29,12 @@ var ( func LoadFullAgentConfig(ctx context.Context, logger *logger.Logger, cfgPath string, failOnFleetMissing bool) (*config.Config, error) { rawConfig, err := loadConfig(ctx, cfgPath) if err != nil { - return nil, err + return nil, fmt.Errorf("error loading raw config: %w", err) } cfg, err := configuration.NewFromConfig(rawConfig) if err != nil { - return nil, err + return nil, fmt.Errorf("error creating config object from raw agent config: %w", err) } if configuration.IsStandalone(cfg.Fleet) { @@ -57,7 +57,7 @@ func LoadFullAgentConfig(ctx context.Context, logger *logger.Logger, cfgPath str fleetConfig, err := loadFleetConfig(ctx, logger) if err != nil { - return nil, err + return nil, fmt.Errorf("error obtaining fleet config: %w", err) } else if fleetConfig == nil { if failOnFleetMissing { return nil, ErrNoFleetConfig @@ -78,7 +78,7 @@ func LoadFullAgentConfig(ctx context.Context, logger *logger.Logger, cfgPath str func loadConfig(ctx context.Context, configPath string) (*config.Config, error) { rawConfig, err := config.LoadFile(configPath) if err != nil { - return nil, err + return nil, fmt.Errorf("error loading config file %s: %w", configPath, err) } path := paths.AgentConfigFile() @@ -100,10 +100,13 @@ func loadConfig(ctx context.Context, configPath string) (*config.Config, error) } // merge local configuration and configuration persisted from fleet. - _ = rawConfig.Merge(config) + err = rawConfig.Merge(config) + if err != nil { + return nil, fmt.Errorf("error merging local and fleet config: %w", err) + } if err := info.InjectAgentConfig(rawConfig); err != nil { - return nil, err + return nil, fmt.Errorf("error injecting agent config: %w", err) } return rawConfig, nil