-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
fix: incorrect templating not producing error #765
Changes from all commits
8f5dcbc
e818db1
454f4c9
d8ef177
93e68d0
1b10032
43eaa8b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -164,3 +164,36 @@ func ResourceFromType(r *PipelineResource) (PipelineResourceInterface, error) { | |
} | ||
return nil, fmt.Errorf("%s is an invalid or unimplemented PipelineResource", r.Spec.Type) | ||
} | ||
|
||
// AttributesFromType returns a list of available attributes that can be replaced | ||
// through templating. | ||
func AttributesFromType(prt PipelineResourceType) ([]string, error) { | ||
r := &PipelineResource{} | ||
r.Spec.Type = prt | ||
// Todo : The TaskResource struct lacks data to correctly infer the type of | ||
// a PipelineResourceTypeStorage. While all the currently implemented types | ||
// have the same attributes, this doesn't appear to be an explicit design | ||
// choice. Future types could not fit this constraint. So we cannot safely | ||
// make any assumptions about the attributes. | ||
if prt == PipelineResourceTypeStorage { | ||
r.Spec.Params = []Param{ | ||
{ | ||
Name: "type", | ||
Value: string(PipelineResourceTypeGCS), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct, I think this is the blocking issue at the moment. I left a comment above in the code which goes into more detail.
Still not exactly sure how to go about solving this problem, but I will think about it some more and update this PR with a better solution once I find the time. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems like there isn't enough information in a Options I can see right now are:
Have I misunderstood the implementation of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Your analysis seems correct to me and I was thinking about a few of those options as well. I agree that option 2 seems to counter the current design, though it's possible I have a misunderstanding. I think the rest of the options you mentioned are solid approaches. In my mind, option 3 sounds like an ideal approach and a convenient characteristic for all types of Option 4 seems like something that could be built now with not much effort and provide immediate benefit. There could be some cases in the future where different Option 5 seems reasonable and provides similar benefits as option 4. We will catch most kinds of templating errors earlier on but still have certain errors at After some thought, if we feel we could reach a consensus on option 3 then that seems like the most robust approach. If that's not something we think we can enforce, then option 4 or 5 sound great to me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Option 3 seems like a design that would be worth raising with the community - I doubt we could confidently come to a widely agreeable consensus in this github thread alone. So the process for that would be to create a github issue describing the problem along with a suggested resolution and design doc if the problem is gnarly enough (this one is, I think). It may also be that we can push this specific problem back until there is more movement on Pipeline Resource Extensibility, which may end up setting the "validatable surface area" simply as a byproduct of the interfaces that it defines for extensions. Having said all that it seems to me that we could move ahead with options 4 or 5 in this PR and work on option 3 out-of-band. If it were me I'd probably skip validating storage types completely, leave a comment explaining why, and create a github issue to describe the problem and possible solutions in detail. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually thinking about this some more, I reckon simply pushing the validation to the TaskRun (if at all possible, otherwise skipping for now) is totally fine. The whole point of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm now realizing that option 5, skipping storage params, is kind of tricky. It's not possible to easily express "ignore variables of this type" when doing the template validation atm. 🤔 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, if the task shouldn't have to worry about validating it deeply, then it's possible that we do not really want this kind of patch and may just want to revisit this in a more broad way with a github issue and a design doc at some point. Otherwise, it might be possible to go with a hybrid approach where we deeply validate all types of variables besides storage. Then for storage params, we just validate the top level variable (similar to how the validation works currently). But yeah, not sure if there is an easy way to express that as you said. Been busy so I haven't had time to take a look, but I can take a look this weekend to see if i can come up with a nice way to solve it. |
||
}, | ||
{ | ||
Name: "Location", | ||
Value: "/", | ||
}, | ||
} | ||
} | ||
resource, err := ResourceFromType(r) | ||
if err != nil { | ||
return nil, err | ||
} | ||
keys := []string{} | ||
for k := range resource.Replacements() { | ||
keys = append(keys, k) | ||
} | ||
return keys, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* | ||
Copyright 2018 The Knative Authors. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package v1alpha1 | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
) | ||
|
||
func TestAttributesFromType(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
resourceType PipelineResourceType | ||
expectedErr error | ||
}{ | ||
{ | ||
name: "git resource type", | ||
resourceType: PipelineResourceTypeGit, | ||
expectedErr: nil, | ||
}, | ||
{ | ||
name: "storage resource type", | ||
resourceType: PipelineResourceTypeStorage, | ||
expectedErr: nil, | ||
}, | ||
{ | ||
name: "image resource type", | ||
resourceType: PipelineResourceTypeImage, | ||
expectedErr: nil, | ||
}, | ||
{ | ||
name: "cluster resource type", | ||
resourceType: PipelineResourceTypeCluster, | ||
expectedErr: nil, | ||
}, | ||
} | ||
for _, tc := range tests { | ||
t.Run(tc.name, func(t *testing.T) { | ||
_, err := AttributesFromType(tc.resourceType) | ||
if d := cmp.Diff(err, tc.expectedErr); d != "" { | ||
t.Errorf("AttributesFromType error did not match expected error %s", d) | ||
} | ||
}) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,10 +47,7 @@ func extractVariablesFromString(s, prefix string) ([]string, bool) { | |
vars := make([]string, len(matches)) | ||
for i, match := range matches { | ||
groups := matchGroups(match, re) | ||
// foo -> foo | ||
// foo.bar -> foo | ||
// foo.bar.baz -> foo | ||
vars[i] = strings.SplitN(groups["var"], ".", 2)[0] | ||
vars[i] = groups["var"] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm having a hard time figuring out if the logic has remained the same here or has been changed to make an intentional difference to behaviour. Would you mind just quickly describing what this change is? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I intentionally made this change. I added a new test to the templating package which hopefully provides additional insight as to why this was needed. This new test would fail without this change.
Since the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK got it, thankyou, I understand the original issue and this fix more clearly now! |
||
} | ||
return vars, true | ||
} | ||
|
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 could have some unit tests for
AttributesFromType
too :DThere 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.
Glad you recommended this! Ended up running into an issue where this function was not working for one of the types (
PipelineResourceTypeStorage
). I included a fairly kludgy solution and a comment to help illustrate the problem.I do not have more time to look at this at the moment, but will find time soon to try to come up with a more elegant solution.