From 6fbf46c7db81713d905040e2b3168506dca664cc Mon Sep 17 00:00:00 2001 From: Anton Tolchanov Date: Wed, 14 Feb 2024 14:48:29 +0000 Subject: [PATCH] tailscale: support policies as HuJSON The `acl` argument of the `tailscale_acl` resource can now be a HuJSON string. Instead of unmarshalling `acl` into an `ACL` struct of the [API client](https://github.com/tailscale/tailscale-client-go) just to have the client serialize it into JSON again, policy content gets passed to the Tailscale API verbatim. This allows users to define their policy as HuJSON strings, with comments being preserved. Since JSON is a subset of HuJSON, this is backwards compatible, so I am not adding a separate field for this as has been previously suggested in #227. Validation is now performed by calling the [Validate and test policy file](https://github.com/tailscale/tailscale/blob/main/api.md#validate-and-test-policy-file) API, which will help catch any semantic errors in the policy at `terraform plan` stage (for example, when a syntactically correct policy contains configuration that is not supported by the Tailnet's current [pricing plan](https://tailscale.com/pricing)). Finally, this will also allow users to use new fields in the policy without requiring a new release of the Terraform provider. I've also added a new `hujson` field to the `tailscale_acl` data resource that shows current policy as a HuJSON string. Fixes #331 Fixes #227 Signed-off-by: Anton Tolchanov --- docs/data-sources/acl.md | 3 +- docs/resources/acl.md | 23 +++- examples/resources/tailscale_acl/resource.tf | 21 +++- go.mod | 16 ++- go.sum | 20 ++-- tailscale/data_source_acl.go | 25 ++-- tailscale/resource_acl.go | 116 +++++++------------ tailscale/resource_acl_test.go | 53 +++++---- tailscale/tailscale_test.go | 8 +- 9 files changed, 158 insertions(+), 127 deletions(-) diff --git a/docs/data-sources/acl.md b/docs/data-sources/acl.md index 2c4dcbd5..c6772f13 100644 --- a/docs/data-sources/acl.md +++ b/docs/data-sources/acl.md @@ -17,5 +17,6 @@ The acl data source gets the Tailscale ACL for a tailnet ### Read-Only +- `hujson` (String) The contents of Tailscale ACL as a HuJSON string - `id` (String) The ID of this resource. -- `json` (String) The contents of Tailscale ACL as JSON +- `json` (String) The contents of Tailscale ACL as a JSON string diff --git a/docs/resources/acl.md b/docs/resources/acl.md index 1d069c7d..79fd84f4 100644 --- a/docs/resources/acl.md +++ b/docs/resources/acl.md @@ -16,7 +16,7 @@ If tests are defined in the ACL (the top-level "tests" section), ACL validation ## Example Usage ```terraform -resource "tailscale_acl" "sample_acl" { +resource "tailscale_acl" "as_json" { acl = jsonencode({ acls : [ { @@ -24,9 +24,26 @@ resource "tailscale_acl" "sample_acl" { action = "accept", users = ["*"], ports = ["*:*"], - }], + }, + ], }) } + +resource "tailscale_acl" "as_hujson" { + acl = < @@ -34,7 +51,7 @@ resource "tailscale_acl" "sample_acl" { ### Required -- `acl` (String) The JSON-based policy that defines which devices and users are allowed to connect in your network +- `acl` (String) The policy that defines which devices and users are allowed to connect in your network. Can be either a JSON or a HuJSON string. ### Optional diff --git a/examples/resources/tailscale_acl/resource.tf b/examples/resources/tailscale_acl/resource.tf index 0dd35094..29933933 100644 --- a/examples/resources/tailscale_acl/resource.tf +++ b/examples/resources/tailscale_acl/resource.tf @@ -1,4 +1,4 @@ -resource "tailscale_acl" "sample_acl" { +resource "tailscale_acl" "as_json" { acl = jsonencode({ acls : [ { @@ -6,6 +6,23 @@ resource "tailscale_acl" "sample_acl" { action = "accept", users = ["*"], ports = ["*:*"], - }], + }, + ], }) } + +resource "tailscale_acl" "as_hujson" { + acl = <