-
Notifications
You must be signed in to change notification settings - Fork 35
Conversation
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.
Thanks for this one @cryptobioz! I do have a few comments we should look at first, but this will make a nice addition to the provider! 👍
for k, t := range templates { | ||
created, err := time.Parse("2006-01-02T15:04:05-0700", t.Created) | ||
if err != nil { | ||
panic(err) |
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.
Please do not panic here. You should never panic, but instead just return the error. So mostRecentTemplate
should then return (*cloudstack.Template, error)
...
Read: dataSourceCloudstackTemplateRead, | ||
Schema: map[string]*schema.Schema{ | ||
"filter": dataSourceFiltersSchema(), | ||
"templatefilter": { |
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.
In TF resources the schema attributes are usually written using snake case. So templatefilter
should be template_filter
instead.
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"displaytext": { |
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 should be display_text
|
||
func dataSourceCloudstackTemplateRead(d *schema.ResourceData, meta interface{}) error { | ||
cs := meta.(*cloudstack.CloudStackClient) | ||
ltp := cloudstack.ListTemplatesParams{} |
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.
nitting In other places within this provider we just call the param struct p
instead of in this case ltp
. And please insert a blank line between line 62 and 63 for readability 😉
ltp := cloudstack.ListTemplatesParams{} | ||
ltp.SetListall(true) | ||
ltp.SetTemplatefilter(d.Get("templatefilter").(string)) | ||
csTemplates, err := cs.Template.ListTemplates(<p) |
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.
nitting Please insert a blank line between line 64 and 65 for readability
func dataSourceFiltersSchema() *schema.Schema { | ||
return &schema.Schema{ | ||
Type: schema.TypeSet, | ||
Optional: 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.
Why make this optional? I assume this call is useless without a filter right? So I suggest making this required instead.
} | ||
|
||
func templateDescriptionAttributes(d *schema.ResourceData, template *cloudstack.Template) error { | ||
d.SetId(template.Id) |
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 this needed for a data source? To set the ID?
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.
You have to put an ID on a datasource. I chose to use the template ID like in the datasource aws_ami.
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.
Ah, check... I wasn't sure a datasource also needed an ID. All clear then...
|
||
for _, f := range filters.List() { | ||
m := f.(map[string]interface{}) | ||
r := regexp.MustCompile(m["value"].(string)) |
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.
regexp.MustCompile
generates a panic if the regex cannot compile. As this is user input we do not know upfront, we cannot be sure it will not panic. So instead please use regexp.Compile
and check (and return if needed) the error.
m := f.(map[string]interface{}) | ||
r := regexp.MustCompile(m["value"].(string)) | ||
templateField := templateJSON[m["name"].(string)].(string) | ||
if !r.Match([]byte(templateField)) { |
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.
Maybe r.MatchString
is a better fit here?
} | ||
|
||
return templates[mrt] | ||
} |
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.
Another suggestion...
func mostRecentTemplate(templates []*cloudstack.Template) (*cloudstack.Template, error) {
var latest *time.Time
var template *cloudstack.Template
for _, t := range templates {
created, err := time.Parse("2006-01-02T15:04:05-0700", t.Created)
if err != nil {
return nil, err
}
if latest == nil || created.After(latest) {
latest = created
template = t
}
}
return template, nil
}
Thanks for the review, I made the requested changes. |
There is still a small part that I would like to change/improve to make it a bit more idiomatic Go (using But overall it looks good now, so I'm going to merge this as is and then add a few small tweaks/fixes. Thanks again for the work! |
@cryptobioz see this commit for my additional changes: 1ca338f One more thing I totally forgot about is the documentation or this new data source! Would/could you please open a new PR with some docs (doesn't have to be much) to go with this data source? That would be awesome and is of course needed to make people aware of the fact that this data source now exists 😉 Thx! |
I'm sorry that you had to rewrite almost everything, however, it's very instructive. |
Don't be sorry! I only tweaked the style a bit, the logic is still all you 👍 |
This datasource allows you to retrieve a template according to filters you set.
There can be several versions for one template, the datasource will always returns the most recent one.
Parameters:
templatefilter
is needed according to the Cloudstack API (https://cloudstack.apache.org/api/apidocs-4.9/apis/listTemplates.html).filter
is used to sort templates.If you set a
filter
, the datasource will only returns templates where the fieldname
has the valuevalue
(the value can be a regex).To see the list of available options, check the Template struct of the Cloudstack client : https://godoc.org/github.com/xanzy/go-cloudstack/cloudstack#Template
Example:
Note:
At the moment, filters only work with string fields, you will not be able to set options like
size
,tags
orbootable
.