feat(crawl): improved logs; add partial credential overriding

The order of precedence is:

1. --username/--password
2. URI-specific credentials in store
3. Default credentials in store

The "partial" overriding means that specifying only one of --username or
--password will cause the crawl command to fetch the specific node
credentials for the BMC (falling back to the default) but override the
result with the value of the passed flag.

For instance,

magellan crawl <uri> --username foo

will fetch the username and password for <uri> in the secret store, but
override the username being sent to 'foo'. This does not change the
username stored in the secret store.
This commit is contained in:
Devon Bautista 2025-04-14 16:37:34 -06:00
parent 63dc2c07a6
commit 88bd791718
No known key found for this signature in database
GPG key ID: E1AAD3D4444A3DA0

View file

@ -40,41 +40,69 @@ var CrawlCmd = &cobra.Command{
store secrets.SecretStore store secrets.SecretStore
err error err error
) )
// try and load credentials from local store first
store, err = secrets.OpenStore(secretsFile) if username != "" && password != "" {
if err != nil { // First, try and load credentials from --username and --password if both are set.
log.Warn().Err(err).Msg("failed to open local store...falling back to provided arguments") log.Debug().Str("uri", uri).Msgf("--username and --password specified, using them for BMC credentials")
// try and use the `username` and `password` arguments instead
store = secrets.NewStaticStore(username, password) store = secrets.NewStaticStore(username, password)
} else {
// Alternatively, locate specific credentials (falling back to default) and override those
// with --username or --password if either are passed.
log.Debug().Str("uri", uri).Msgf("one or both of --username and --password NOT passed, attempting to obtain missing credentials from secret store at %s", secretsFile)
if store, err = secrets.OpenStore(secretsFile); err != nil {
log.Error().Str("uri", uri).Err(err).Msg("failed to open local secrets store")
} }
// found the store so try to load the creds // Either none of the flags were passed or only one of them were; get
_, err = store.GetSecretByID(uri) // credentials from secrets store to fill in the gaps.
//
// Attempt to get URI-specific credentials.
var nodeCreds secrets.StaticStore
if uriCreds, err := store.GetSecretByID(uri); err != nil {
// Specific credentials for URI not found, fetch default.
log.Warn().Str("uri", uri).Msg("specific credentials not found, falling back to default")
defaultSecret, err := store.GetSecretByID(secrets.DEFAULT_KEY)
if err != nil { if err != nil {
log.Warn().Err(err).Msgf("failed to get secrets for '%s'...", uri) // We've exhausted all options, the credentials will be blank unless
// if we have CLI flags set, then we want to override default stored creds // overridden by a CLI flag.
if username != "" && password != "" { log.Warn().Str("uri", uri).Err(err).Msg("no default credentials were set, they will be blank unless overridden by CLI flags")
// finally, use the CLI arguments passed instead
log.Info().Msg("...using provided arguments for credentials")
store = secrets.NewStaticStore(username, password)
} else { } else {
// try and get a default *stored* username/password // Default credentials found, use them.
log.Info().Msg("...using default stored secrets for credentials")
secret, err := store.GetSecretByID(secrets.DEFAULT_KEY)
if err != nil {
// no default found, so use CLI arguments
log.Warn().Err(err).Msg("no default credentials found")
} else {
// found default values in local store so use them
var creds crawler.BMCUsernamePassword var creds crawler.BMCUsernamePassword
err = json.Unmarshal([]byte(secret), &creds) if err = json.Unmarshal([]byte(defaultSecret), &creds); err != nil {
if err != nil { log.Warn().Str("uri", uri).Err(err).Msg("failed to unmarshal default secrets store credentials")
log.Warn().Err(err).Msg("failed to unmarshal default store credentials") } else {
log.Info().Str("uri", uri).Msg("default credentials found, using")
nodeCreds.Username = creds.Username
nodeCreds.Password = creds.Password
} }
} }
} else {
// Specific URI credentials found, use them.
var creds crawler.BMCUsernamePassword
if err = json.Unmarshal([]byte(uriCreds), &creds); err != nil {
log.Warn().Str("uri", uri).Err(err).Msg("failed to unmarshal uri credentials")
} else {
nodeCreds.Username = creds.Username
nodeCreds.Password = creds.Password
log.Info().Str("uri", uri).Msg("specific credentials found, using")
} }
} }
// If either of the flags were passed, override the fetched
// credentials with them.
if username != "" {
log.Info().Str("uri", uri).Msg("--username was set, overriding username for this BMC")
nodeCreds.Username = username
}
if password != "" {
log.Info().Str("uri", uri).Msg("--password was set, overriding password for this BMC")
nodeCreds.Password = password
}
store = &nodeCreds
}
systems, err := crawler.CrawlBMCForSystems(crawler.CrawlerConfig{ systems, err := crawler.CrawlBMCForSystems(crawler.CrawlerConfig{
URI: uri, URI: uri,
CredentialStore: store, CredentialStore: store,