Closed paddycarver closed 5 years ago
Rather than copy your TODO list, I'm going to check off the things I believe have been covered, currently included in master.
Hi @displague,
Thanks for all your hard work on this provider so far, I wanted to get an idea of then this provider is going to be ready for official release. Do you have an eta on when all the issues Paddy raised will be addressed?
Looking forward to the release. Best, Chris
Hi @cgriggs01,
I've been trucking through the issues raised by @paddycarver above and incorporated linode_instance
resource changes discussed elsewhere with @paddycarver and @paultyng (both of which have been very helpful at every step).
These changes are being applied in #19 with a goal of supporting and documenting the schema described in the example in that PR description.
In terms of linode_instance
resource CRUD work, I have the CR_D done and now need to refactor Update behaviors to match. I believe I will have that work merged within a week.
I've also added support for Volumes, NodeBalancers, and DNS, so I'm hopeful that all of these can be considered for Review 2.
All of the changes I could act on based on this feedback have been merged into master.
Thanks, @paddycarver
So I have a few quick notes after reading through the provider. I think after this, you're all set. Feel free to ping me when you've addressed these concerns, and I'll come sign off. These should be all minor things.
_sec
fields on domain
and domain_record
, client_conn_throttle
on nodebalancer
, check_timeout
and check_attempts
on nodebalancer_config
, and so on. You can specify a ValidateFunc
on the schema.Schema
for these, which will allow Terraform to raise errors at plan time. The validation
package has some built-in: validation.IntBetween
can be used when you want to be sure an int is between two values, and validation.StringInSlice
can be used when you want to make sure that a string matches one of a few values. We don't have an IntInSlice yet, but it should be pretty straightforward to write one.user_defined_fields
in stackscript
, transfer
on nodebalancer
, and backups
on instance
. The parents should either be set to Optional
or Required
(depending on which applies), or the children should be set to Computed
with Optional
and Required
unset. ComputedWith
doesn't really work and shouldn't be used.ImportState
, but don't use ImportStateVerify
. To test import properly, you should use ImportStateVerify
there, too.nodebalancer_node
and nodebalancer_config
should have import tests on them, ideally.ConflictsWith
. When field A conflicts with field B, field A's ConflictsWith
needs to include B
, and field B's ConflictsWith
needs to include A
. They've got to be included in each other's ConflictsWith
, basically. In a few places, you only have them in one, not both.That's it! You're at the home stretch. Thank you for being so superhumanly patient.
Didn't intend to close the Issue, but #29 did cover the previous list of changes.
I've reviewed everything up to ae9e50a, and you went above and beyond in response to the last round of review. This looks good to me. I'm happy with the technical quality of it. 👍 Great work!
Closing -- See Issue #36
Hi! My name is Paddy, I'm part of the Terraform Ecosystem team at HashiCorp. I've been assigned to review your provider for possible acceptance into the terraform-providers org and inclusion on terraform.io. I've done a preliminary review of your data sources and the
linode_instance
resource, and found enough to give feedback on that I felt it was a representative review. I have not looked at the nodebalancers or other resources yet, but my intention is to point out areas that could be improved that are representative, and allow you to apply that feedback to other areas of the codebase, as well. When this part of the feedback has been addressed, I'll take another pass at all the resources.I do want to start by saying that your code looks great so far, and that you shouldn't be intimidated by the number of issues being raised here. Some are rather important and critical to get right, but you'll find a lot of them to be nitpicks that reflect lessons learned from maintaining a lot of providers for a long time, and how little things like error messages can be structured to make future maintenance easier. So just because I'm giving you a laundry list of things to address here doesn't mean your provider is bad or your code is sub-par, I'm just trying to pass on the things we've learned the hard way so you can take advantage of them.
Here's what I found:
context.TODO()
withcontext.Background()
d.Get("")
forreqPool
, which makes no sense. Should there be a required field on the resource?range
, butrange
will never be set, because it'sComputed
.return nil, fmt.Errorf("Failed to connect to the Linode API because %s", err)
We tend to favor error messages likeError connecting to Linode API: %s
, which is more flexible with a wider variety of error messages.WaitTimeout
is generically named for something that applies solely to instance status changes.init
function inresource_linode_instance.go
should be removed.kernelList
,regionList
, andtypeList
information in global mutable variables?InputDefault
so heavily? It's not wrong, it's just unusual, and I'm interested in the thought process there.linode_instance
'simage
is optional, and unset, does the API set a default value? If so, it should probably beComputed
.linode_instance
'sname
field,Optional
is required whenRemoved
is set because it needs to be a field that the user can set (orRemoved
is meaningless) but can't be required (or the user gets an error whether they set it or not).Removed
messages to be more along the lines ofPlease use $REPLACEMENT instead. See $URL for more information.
When usingRemoved
. The URL isn't required, but is a nice inclusion.linode_instance
tags 1) can't be repeated 2) don't have a specific order and 3) aren't guaranteed to come back in the same order, I'd recommend making them aTypeSet
.linode_instance
'splan_storage
can't have user input, there's not much point in marking it Removed, honestly.linode_instance
'sprivate_networking
isn't set, does the server set a default? If so,Computed
should be set.linode_instance
'sssh_key
field as fortags
.PromoteSingle
.root_password
should haveSensitive: true
.[WARN] removing %q from state because it no longer exists
.resourceLinodeInstanceExists
if there's an error retrieving the instance, it erroneously reports that there was an error parsing the ID.Exists
functions should not modify theschema.ResourceData
, including setting the Id.linode_instance
doesn't set, e.g.,tags
orssh_key
in state when reading; if either is returned from the API, it should be set in state. State can be accurately thought of as a local copy of what the API has, and should be updated and maintained as such.linode_instance
return if there isn't exactly one config? That has led to subtle bugs before, where things don't get set, because someone accidentally writes the code to set them after that. The code that uses the config should instead happen inside an if block, to avoid returning out of the function early and missing code that could have and should have run.boolToString
.linode_instance
store only the cumulative size of all the disks instead of storing each disk in a sub-block, even if it's read-only?linode_instance
, instead of having thelinodego.InstanceDiskCreateOptions
struct represented as a sub-block inlinode_instance
?storage
?linodego.InstanceConfigCreateOptions
—why is so much of that hardcoded instead of obtained from user input?Read
should be called at the end ofUpdate
.ForceNew
instead, so we can clearly indicate to users what will happen as part of an apply, especially when downtime may be a result?HasChange
can returntrue
even if it's going from unset to false, or false to unset, making theprivate_networking
update onlinode_instance
aggressive. Maybe useGetChange
and compare explicitly fromtrue => false
to only error when absolutely necessary? Also,CustomizeDiff
can be used to make changing this force a new resource, instead of throwing an error, which is a preferable UX, I think?acctest.RandomWithPrefix
can be used instead offmt.Sprintf
.Please let me know if any of this doesn't make sense or you'd like more information on anything.
Best, Paddy