Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 16 additions & 10 deletions internal/runner/lazy.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,13 @@ func GetLazyAuthFetchCallback(opts *AuthLazyFetchOptions) authx.LazyFetchSecret
var finalErr error
ctx.OnResult = func(e *output.InternalWrappedEvent) {
if e == nil {
finalErr = fmt.Errorf("no result found for template: %s", d.TemplatePath)
return
}

if !e.HasOperatorResult() {
finalErr = fmt.Errorf("no result found for template: %s", d.TemplatePath)
return
}

// dynamic values
for k, v := range e.OperatorsResult.DynamicValues {
// Iterate through all the values and choose the
Expand All @@ -123,31 +123,37 @@ func GetLazyAuthFetchCallback(opts *AuthLazyFetchOptions) authx.LazyFetchSecret
}
}
}

// named extractors
for k, v := range e.OperatorsResult.Extracts {
if len(v) > 0 {
data[k] = v[0]
}
}
if len(data) == 0 {
if e.OperatorsResult.Matched {
finalErr = fmt.Errorf("match found but no (dynamic/extracted) values found for template: %s", d.TemplatePath)
} else {
finalErr = fmt.Errorf("no match or (dynamic/extracted) values found for template: %s", d.TemplatePath)
// NOTE(dwisiswant0): Only set if we don't already have a
// value -- or -- if the new value is non-empty.
if _, exists := data[k]; !exists || data[k] == "" {
data[k] = v[0]
}
}
}

// log result of template in result file/screen
_ = writer.WriteResult(e, opts.ExecOpts.Output, opts.ExecOpts.Progress, opts.ExecOpts.IssuesClient)
}

_, err := tmpl.Executer.ExecuteWithResults(ctx)
if err != nil {
finalErr = err
}

if len(data) == 0 && finalErr == nil {
finalErr = fmt.Errorf("no extracted values found for template: %s", d.TemplatePath)
}

// store extracted result in auth context
d.Extracted = data
if finalErr != nil && opts.OnError != nil {
opts.OnError(finalErr)
}

return finalErr
}
}
65 changes: 53 additions & 12 deletions pkg/authprovider/authx/dynamic.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type Dynamic struct {
fetchCallback LazyFetchSecret `json:"-" yaml:"-"`
m *sync.Mutex `json:"-" yaml:"-"` // mutex for lazy fetch
fetched bool `json:"-" yaml:"-"` // flag to check if the secret has been fetched
fetching bool `json:"-" yaml:"-"` // flag to check if we're currently fetching (prevents recursion)
error error `json:"-" yaml:"-"` // error if any
}

Expand Down Expand Up @@ -184,34 +185,74 @@ func (d *Dynamic) applyValuesToSecret(secret *Secret) error {

// GetStrategy returns the auth strategies for the dynamic secret
func (d *Dynamic) GetStrategies() []AuthStrategy {
if !d.fetched {
_ = d.Fetch(true)
getStrategies := func() []AuthStrategy {
var strategies []AuthStrategy
if d.Secret != nil {
strategies = append(strategies, d.GetStrategy())
}

for _, secret := range d.Secrets {
strategies = append(strategies, secret.GetStrategy())
}

return strategies
}
if d.error != nil {
return nil

d.m.Lock()
isFetched := d.fetched
isFetching := d.fetching
d.m.Unlock()

if isFetched {
if d.error != nil {
return nil
}

return getStrategies()
}
var strategies []AuthStrategy
if d.Secret != nil {
strategies = append(strategies, d.GetStrategy())

if isFetching {
// NOTE(dwisiswant0): Bail out w/ empty here, or we will yeet into
// recursion hell. See line 242-245.
return nil
}
for _, secret := range d.Secrets {
strategies = append(strategies, secret.GetStrategy())

_ = d.Fetch(true)
if d.error != nil {
return nil
}
return strategies

return getStrategies()
}

// Fetch fetches the dynamic secret
// if isFatal is true, it will stop the execution if the secret could not be fetched
func (d *Dynamic) Fetch(isFatal bool) error {
d.m.Lock()
defer d.m.Unlock()

if d.fetched {
return d.error
}

if d.fetching {
return nil
}

d.fetching = true
defer func() {
d.fetching = false
}()

d.error = d.fetchCallback(d)
if d.error != nil && isFatal {
gologger.Fatal().Msgf("Could not fetch dynamic secret: %s\n", d.error)
if d.error != nil {
if isFatal {
gologger.Fatal().Msgf("Could not fetch dynamic secret: %s\n", d.error)
}
} else {
d.fetched = true
}

return d.error
}

Expand Down
Loading