Skip to content

Commit

Permalink
tailscale: read ACL validation errors from a 200 OK response
Browse files Browse the repository at this point in the history
Per [docs](https://github.com/tailscale/tailscale/blob/main/api.md):

> The HTTP status code will be '200' if the request was well formed and
> there were no server errors, even in the case of failing tests or an
> invalid ACL. Look at the response body to determine whether there was a
> problem within your ACL or tests:

Updates tailscale/terraform-provider-tailscale#227
  • Loading branch information
knyar committed Feb 12, 2024
1 parent 7263c64 commit 81318dd
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
9 changes: 8 additions & 1 deletion tailscale/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,14 @@ func (c *Client) ValidateACL(ctx context.Context, acl ACL) error {
return err
}

return c.performRequest(req, nil)
var response APIError
if err := c.performRequest(req, &response); err != nil {
return err
}
if response.Message != "" {
return fmt.Errorf("ACL validation failed: %s; %v", response.Message, response.Data)
}
return nil
}

type DNSPreferences struct {
Expand Down
29 changes: 29 additions & 0 deletions tailscale/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,36 @@ func TestClient_ValidateACL(t *testing.T) {
assert.NoError(t, err)
assert.EqualValues(t, server.ResponseBody, acl)
assert.EqualValues(t, http.MethodPost, server.Method)
assert.EqualValues(t, "application/json", server.Header.Get("Content-Type"))
assert.EqualValues(t, "/api/v2/tailnet/example.com/acl/validate", server.Path)

tests := []struct {
name string
responseCode int
responseBody any
wantErr string
}{
{
name: "403_response",
responseCode: 403,
responseBody: tailscale.APIError{Message: "access denied"},
wantErr: "access denied",
},
{
name: "200_response_with_error",
responseCode: 200,
responseBody: tailscale.APIError{Message: "validation failed"},
wantErr: "validation failed",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
server.ResponseCode = tt.responseCode
server.ResponseBody = tt.responseBody
err := client.ValidateACL(context.Background(), acl)
assert.ErrorContains(t, err, tt.wantErr)
})
}
}

func TestClient_UserAgent(t *testing.T) {
Expand Down

0 comments on commit 81318dd

Please sign in to comment.