-
Notifications
You must be signed in to change notification settings - Fork 29
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
Add Interface Wireguard Support #153
Conversation
f191db9
to
f878e87
Compare
f878e87
to
70fdd97
Compare
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.
@DawoudMahmud nice work on this! This is a pretty large code change and involves some challenges that we haven't tackled in other parts of this provider yet (sensitive properties, etc), so don't be discouraged by the number of comments :)
@@ -5,8 +5,8 @@ go 1.18 | |||
require ( | |||
github.com/ddelnano/terraform-provider-mikrotik/client v0.0.0-00010101000000-000000000000 | |||
github.com/hashicorp/terraform-plugin-docs v0.13.0 | |||
github.com/hashicorp/terraform-plugin-framework v1.0.1 | |||
github.com/hashicorp/terraform-plugin-go v0.14.2 | |||
github.com/hashicorp/terraform-plugin-framework v1.2.0 |
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.
Upgrading these dependencies are not needed for adding the new resources as far as I can tell, so they should be done in another PR (if needed). Please let me know if you have trouble preventing the go toolchain from making these changes automatically and exclude the go.sum
and go.mod
changes from this PR.
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.
After reviewing this and running the tests locally, I realized this was necessary for the changes you made. Because our existing code has significant acceptance test coverage, upgrading this in place is fine. However, with most projects bumping the core sdk can be a large change that is usually best done prior to the dependent change (adding the resource functionality that needs it).
client/interface_wireguard.go
Outdated
ListenPort int `mikrotik:"listen-port"` | ||
Mtu int `mikrotik:"mtu"` | ||
PrivateKey string `mikrotik:"private-key"` | ||
PublicKey string `mikrotik:"public-key"` //read only property |
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.
It seems the readonly
mikrotik struct tag is missing here. When @jdelnano implemented this, it seems that was to avoid a situation where our client interface would try to change properties that are readonly. Any idea why this isn't causing an issue with the current test?
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 good catch, I'll add the readonly tag to public key as well. I believe the test was passing because PublicKey defaults to an empty string so it didn't show up when adding a new interface wireguard. However since Running defaults to false, the test was complaining that I was trying to create an interface wireguard with a parameter that shouldn't exist (below).
client/interface_wireguard_test.go
Outdated
err = c.Delete(found.(Resource)) | ||
if err != nil { | ||
t.Errorf("expected no error, got %v", err) | ||
} | ||
|
||
_, err = c.Find(findInterface) | ||
if err == nil { | ||
t.Errorf("expected error, got nothing") | ||
return | ||
} | ||
|
||
target := &NotFound{} | ||
if !errors.As(err, &target) { | ||
t.Errorf("expected error to be of type %T, got %T", &NotFound{}, 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.
Let's wrap this in a defer
right after the .Add()
call is deemed successful (on line 40). See this client test as an example.
We are a bit inconsistent with how to structure these client tests, but if this assertion fails we should still trigger the delete logic (which the defer
will take care of).
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, I updated the defer to mirror the style of the Bridge client test. Let me know if you have any issues with this approach.
"private_key": schema.StringAttribute{ | ||
Optional: true, | ||
Computed: true, | ||
Description: "A base64 private key. If not specified, it will be automatically generated upon interface creation.", | ||
}, |
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 private key is important to keep secret. Terraform has a concept of sensitive fields, and I think this needs to be one. Here is the godoc link showing what attributes are available for the StringAttribute struct.
Please update this property to be sensitive and ideally our acceptance test would validate this is in some way as well.
In addition to this all of the provider logging (such as this) will be print this value. We likely need to introduce a way to hide fields like this. One possibility could be adding a sensitive
struct tag similarly to how the readonly
tag works (added in #143).
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.
Added sensitive
attribute to PrivateKey but still need to create a sensitive
struct tag
// Schema defines the schema for the resource. | ||
func (i *interfaceWireguard) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { | ||
resp.Schema = schema.Schema{ | ||
Description: "Creates a Mikrotik interface wireguard.", |
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.
Add the explanation about Router OS v7+ here. This will be populated in the docs written by tfplugindocs
.
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 I just add "only supported by RouterOS v7+" at the end of the description or is there a different way to add it to let tfplugindocs
populate it in the docs? I'm not too familiar with tfplugindocs
.
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.
To circle back on this, I've generated the doc file with tfplugindocs
# mikrotik_interface_wireguard (Resource) | ||
Creates a Mikrotik interface_wireguard. | ||
|
||
!> This resource is supported for RouterOS v7+. |
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.
It looks like these docs were edited by hand. They must be generated with the tfplugindocs
tool. See my comment in the mikrotik/resource_interface_wireguard.go
file on how to add the RouterOS v7 information to the autogenerated file.
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 the default resource templating isn't appropriate, you can create resource specific templates as well (like the bgp_peer resource).
client/interface_wireguard_test.go
Outdated
defer func() { | ||
err = c.Delete(found.(Resource)) | ||
if err != nil { | ||
t.Errorf("expected no error, got %v", err) | ||
} | ||
|
||
_, err = c.Find(findInterface) | ||
if err == nil { | ||
t.Errorf("expected error, got nothing") | ||
return | ||
} | ||
_, err = c.Find(findInterface) | ||
if err == nil { | ||
t.Errorf("expected error, got nothing") | ||
return | ||
} | ||
|
||
target := &NotFound{} | ||
if !errors.As(err, &target) { | ||
t.Errorf("expected error to be of type %T, got %T", &NotFound{}, err) | ||
} | ||
target := &NotFound{} | ||
if !errors.As(err, &target) { | ||
t.Errorf("expected error to be of type %T, got %T", &NotFound{}, 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.
I'm pretty confident the placement of the defer
matters. For example, an error from line 43 will cause the defer
to get skipped completely.
We should place the defer
right after the creation happens to ensure it is registered after the creation completes.
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.
Here's an example that showcases this.
This PR was completed in #159. An earlier change was merged that introduced a conflict to the Thanks @DawoudMahmud for the contribution! WireGuard support is a great addition considering its growing popularity! |
Closes #137
This resource only exists for RouterOS v7+ so logic was included to exclude it for RouterOS v6 builds.