tailscale / tailscale-client-go

A client implementation for the Tailscale HTTP API
MIT License
61 stars 27 forks source link

Issue with ACLs and omitted fields #31

Closed andy-careplanner closed 1 year ago

andy-careplanner commented 2 years ago

We are using the Tailscale Terraform provider and recently noticed an issue where a terraform plan would show planned removals for various null values/empty strings when updating an ACL:

# tailscale_acl.acl will be updated in-place
  ~ resource "tailscale_acl" "acl" {
      ~ acl = jsonencode(
          ~ {                                                                                                                            
                ~ acls      = [
                  ~ {
                      - ports  = null -> null
                      - proto  = "" -> null
                      ~ src    = [
                            # (1 unchanged element hidden)
                            "foo",
                          - "bar",
                            "foo2",
                            # (13 unchanged elements hidden)
                        ]
                      - users  = null -> null
                        # (2 unchanged elements hidden)                                                                                                   
              },

With the above example we are using the src and dst fields in the ACL, and the removal of 'bar' is expected. The fields ports, proto and users don't exist in the ACL associated with our tailnet, and they aren't present in our Terraform configuration either. If we apply a plan like the above we end up with those fields being added to our ACL (with null values in the case of users and ports, and an empty string in the case of proto). This doesn't seem to affect the functionality of the ACL, but it is confusing when reviewing it via the Tailscale console/as part of a Terraform plan.

I think the issue might be that the fields ports, proto and users are optional when getting or setting an ACL via the Tailscale API. When the Terraform provider retrieves the ACL using tailscale-client-go, if those fields are omitted in the API response they get set as null or empty values. I think the fix might be simply adding the omitempty option to the relevant fields in this struct:

https://github.com/tailscale/tailscale-client-go/blob/main/tailscale/client.go#L243-L250

But I'm not a Go developer, so I thought I'd raise an issue in the first instance instead of raising a PR :)