-
Notifications
You must be signed in to change notification settings - Fork 206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial attempt to wire-up parameters #66
Conversation
This uses mitchellh's reflectwalk to walk the step's Data map. It currently handles replacing things of the form source: bundle.parameter.name in a map or an Array. We can implement additional callbacks later on if needed to handle other datatypes that might be in the YAML.
pkg/porter/resolver.go
Outdated
return nil | ||
} | ||
|
||
func (p *Porter) Slice(val reflect.Value) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and the map function are empty just to implement the interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have to implement this interface because we are passing in an instance of porter to reflectwalk.Walk
, yeah?
You're closer to this than me, do you think it's a small enough change to have this pass in just the manifest instead?
pkg/porter/resolver.go
Outdated
} | ||
|
||
func (p *Porter) resolveValue(key string) (interface{}, error) { | ||
source := strings.Split(key, ".") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the handling of this probably needs to change as we get more complicated "sourcing" like when dependencies are introduced.
pkg/porter/resolver.go
Outdated
v = v.Elem() | ||
} | ||
if kind := v.Kind(); kind == reflect.Map { | ||
if len(v.MapKeys()) == 1 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if something has more than one key, it seems like not something to replace so this is short circuiting that logic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, probably a good idea to put what you just said in a comment so that we don't forget what's going on here. 😀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really good to have because in another part of the manifest I want to use source again, and this lets me get away with it. e.g.
dependencies:
- name: mysql
connections:
- source: bundle.parameters.foo
destination: bundle.dependencies.mysql.parameters.foo
Right now, if I encounter a "source: <...>" thing that isn't resolvable, that's an error condition. After thinking about it a bit, it seems like we should maybe just log that that status occured but not error to cover situations where someone wanted to use that as a map key or it's in a string that happens to match that regex? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is good to merge as-is if you want. Everything I have in here is just fine as follow-ups.
@@ -290,6 +290,14 @@ | |||
pruneopts = "NUT" | |||
revision = "95e2e42e3ece7421c14512f79f796fe3f5d7e5dc" | |||
|
|||
[[projects]] | |||
digest = "1:44e35ced240c6d8316dc8d604a73774ab052d40ebe636fd8f2ba5934f6329034" | |||
name = "github.com/mitchellh/reflectwalk" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love this package, so useful. 💕
pkg/porter/resolver.go
Outdated
v = v.Elem() | ||
} | ||
if kind := v.Kind(); kind == reflect.Map { | ||
if len(v.MapKeys()) == 1 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, probably a good idea to put what you just said in a comment so that we don't forget what's going on here. 😀
pkg/porter/resolver.go
Outdated
value := kv.String() | ||
replacement, err := p.resolveValue(value) | ||
if err != nil { | ||
return errors.Wrap(err, "unable to source value") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have enough context here that the message could say which value it couldn't find? Or is that baked in the error that we are wrapping?
pkg/porter/resolver.go
Outdated
return nil | ||
} | ||
|
||
func (p *Porter) Slice(val reflect.Value) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have to implement this interface because we are passing in an instance of porter to reflectwalk.Walk
, yeah?
You're closer to this than me, do you think it's a small enough change to have this pass in just the manifest instead?
pkg/porter/resolver.go
Outdated
v = v.Elem() | ||
} | ||
if kind := v.Kind(); kind == reflect.Map { | ||
if len(v.MapKeys()) == 1 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really good to have because in another part of the manifest I want to use source again, and this lets me get away with it. e.g.
dependencies:
- name: mysql
connections:
- source: bundle.parameters.foo
destination: bundle.dependencies.mysql.parameters.foo
pkg/porter/resolver.go
Outdated
source := matches[1] | ||
r, err := p.resolveValue(source) | ||
if err != nil { | ||
return errors.Wrap(err, "unable to source value") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above, can we make this error message provide a bit more context into exactly which source node isn't resolving?
pkg/porter/resolver.go
Outdated
} else if param.Destination == nil && param.Destination.Path != "" { | ||
replacement = param.Destination.Path | ||
} else { | ||
return nil, errors.New("unknown parameter definition") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the problem here that the parameter that it's trying to source from isn't declared? Maybe this error should be reference to declared parameter bundle.parameters.foo in <insert some context so we know which ones is borked
.
pkg/porter/resolver.go
Outdated
} else if cred.EnvironmentVariable != "" { | ||
replacement = os.Getenv(cred.EnvironmentVariable) | ||
} else { | ||
return nil, errors.New("unknown credential definition") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above, if we can, let's provide more context
pkg/porter/resolver.go
Outdated
} | ||
} | ||
} else { | ||
return nil, errors.New(fmt.Sprintf("unknown parameter source: %s", source[1])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this error case? I can't quite tell from the error message. Is it that the key used is invalid, e.g. not path or environment variable?
pkg/porter/resolver_test.go
Outdated
}, | ||
} | ||
|
||
os.Setenv("PERSON", "Ralpha") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:excellent:
Do you have an example of when we could get a false positive? I would hate to make it super easy for a typo in the source path to go unnoticed. Like I fat finger If we do have cases where it doesn't resolve, and that's expected, maybe let people add a flag for strict resolution vs. loose? So that we fail immediately, then let them know that if we are being too aggressive in our matching, use a flag when building to ignore the problem? |
No, I was mostly thinking proactively, but I agree with that case beacuse I can't spell. |
This uses mitchellh's reflectwalk to walk the step's Data map. It currently
handles replacing things of the form source: bundle.parameter.name in a map
or an Array. We can implement additional callbacks later on if needed to handle
other datatypes that might be in the YAML.
For example:
Both the
thing
entry inparameters
and the first entry of thearguments
array will be updated to the value of the "hello" parameter.