all: apply consistent imports of "json" packages

This runs:

        go run ./cmd/jsonimports -update -ignore=tempfork/

which applies the following rules:

  * Until the Go standard library formally accepts "encoding/json/v2"
    and "encoding/json/jsontext" into the standard library
    (i.e., they are no longer considered experimental),
    we forbid any code from directly importing those packages.
    Go code should instead import "github.com/go-json-experiment/json"
    and "github.com/go-json-experiment/json/jsontext".
    The latter packages contain aliases to the standard library
    if built on Go 1.25 with the goexperiment.jsonv2 tag specified.

  * Imports of "encoding/json" or "github.com/go-json-experiment/json/v1"
    must be explicitly imported under the package name "jsonv1".
    If both packages need to be imported, then
    the former should be imported under the package name "jsonv1std".

  * Imports of "github.com/go-json-experiment/json"
    must be explicitly imported under the package name "jsonv2".

The latter two rules exist to provide clarity when reading code.
Without them, it is unclear whether "json.Marshal" refers to v1 or v2.
With them, however, it is clear that "jsonv1.Marshal" is calling v1 and
that "jsonv2.Marshal" is calling v2.

Updates tailscale/corp#791

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
dsnet/jsonimports-ci
Joe Tsai 1 month ago
parent 77123a569b
commit c299a96624

@ -0,0 +1,37 @@
name: jsonimports
env:
HOME: ${{ github.workspace }}
on:
push:
branches:
- main
- "release-branch/*"
paths:
- "**.go"
pull_request:
paths:
- "**.go"
concurrency:
group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
check:
runs-on: [ self-hosted, linux ]
timeout-minutes: 5
steps:
- name: Check out code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
cache: true
go-version-file: go.mod
- name: Check that all Go files use the right "json" import
run: go run tailscale.com/cmd/jsonimports -ignore=tempfork/

@ -10,7 +10,7 @@ import (
"cmp" "cmp"
"context" "context"
"encoding/base64" "encoding/base64"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -216,7 +216,7 @@ func IsPreconditionsFailedError(err error) bool {
// object of type errorJSON, its non-empty error body. // object of type errorJSON, its non-empty error body.
func bestError(err error, body []byte) error { func bestError(err error, body []byte) error {
var j errorJSON var j errorJSON
if err := json.Unmarshal(body, &j); err == nil && j.Error != "" { if err := jsonv1.Unmarshal(body, &j); err == nil && j.Error != "" {
return errors.New(j.Error) return errors.New(j.Error)
} }
return err return err
@ -224,7 +224,7 @@ func bestError(err error, body []byte) error {
func errorMessageFromBody(body []byte) string { func errorMessageFromBody(body []byte) string {
var j errorJSON var j errorJSON
if err := json.Unmarshal(body, &j); err == nil && j.Error != "" { if err := jsonv1.Unmarshal(body, &j); err == nil && j.Error != "" {
return j.Error return j.Error
} }
return strings.TrimSpace(string(body)) return strings.TrimSpace(string(body))
@ -300,7 +300,7 @@ func WhoIs(ctx context.Context, remoteAddr string) (*apitype.WhoIsResponse, erro
} }
func decodeJSON[T any](b []byte) (ret T, err error) { func decodeJSON[T any](b []byte) (ret T, err error) {
if err := json.Unmarshal(b, &ret); err != nil { if err := jsonv1.Unmarshal(b, &ret); err != nil {
var zero T var zero T
return zero, fmt.Errorf("failed to unmarshal JSON into %T: %w", ret, err) return zero, fmt.Errorf("failed to unmarshal JSON into %T: %w", ret, err)
} }
@ -462,7 +462,7 @@ func (lc *Client) StreamBusEvents(ctx context.Context) iter.Seq2[eventbus.DebugE
return return
} }
defer res.Body.Close() defer res.Body.Close()
dec := json.NewDecoder(bufio.NewReader(res.Body)) dec := jsonv1.NewDecoder(bufio.NewReader(res.Body))
for { for {
var evt eventbus.DebugEvent var evt eventbus.DebugEvent
if err := dec.Decode(&evt); err == io.EOF { if err := dec.Decode(&evt); err == io.EOF {
@ -590,7 +590,7 @@ func (lc *Client) DebugResultJSON(ctx context.Context, action string) (any, erro
return nil, fmt.Errorf("error %w: %s", err, body) return nil, fmt.Errorf("error %w: %s", err, body)
} }
var x any var x any
if err := json.Unmarshal(body, &x); err != nil { if err := jsonv1.Unmarshal(body, &x); err != nil {
return nil, err return nil, err
} }
return x, nil return x, nil
@ -603,7 +603,7 @@ func (lc *Client) QueryOptionalFeatures(ctx context.Context) (*apitype.OptionalF
return nil, fmt.Errorf("error %w: %s", err, body) return nil, fmt.Errorf("error %w: %s", err, body)
} }
var x apitype.OptionalFeatures var x apitype.OptionalFeatures
if err := json.Unmarshal(body, &x); err != nil { if err := jsonv1.Unmarshal(body, &x); err != nil {
return nil, err return nil, err
} }
return &x, nil return &x, nil
@ -638,7 +638,7 @@ func (lc *Client) SetComponentDebugLogging(ctx context.Context, component string
var res struct { var res struct {
Error string Error string
} }
if err := json.Unmarshal(body, &res); err != nil { if err := jsonv1.Unmarshal(body, &res); err != nil {
return err return err
} }
if res.Error != "" { if res.Error != "" {
@ -778,7 +778,7 @@ func (lc *Client) CheckIPForwarding(ctx context.Context) error {
var jres struct { var jres struct {
Warning string Warning string
} }
if err := json.Unmarshal(body, &jres); err != nil { if err := jsonv1.Unmarshal(body, &jres); err != nil {
return fmt.Errorf("invalid JSON from check-ip-forwarding: %w", err) return fmt.Errorf("invalid JSON from check-ip-forwarding: %w", err)
} }
if jres.Warning != "" { if jres.Warning != "" {
@ -798,7 +798,7 @@ func (lc *Client) CheckUDPGROForwarding(ctx context.Context) error {
var jres struct { var jres struct {
Warning string Warning string
} }
if err := json.Unmarshal(body, &jres); err != nil { if err := jsonv1.Unmarshal(body, &jres); err != nil {
return fmt.Errorf("invalid JSON from check-udp-gro-forwarding: %w", err) return fmt.Errorf("invalid JSON from check-udp-gro-forwarding: %w", err)
} }
if jres.Warning != "" { if jres.Warning != "" {
@ -817,7 +817,7 @@ func (lc *Client) CheckReversePathFiltering(ctx context.Context) error {
var jres struct { var jres struct {
Warning string Warning string
} }
if err := json.Unmarshal(body, &jres); err != nil { if err := jsonv1.Unmarshal(body, &jres); err != nil {
return fmt.Errorf("invalid JSON from check-reverse-path-filtering: %w", err) return fmt.Errorf("invalid JSON from check-reverse-path-filtering: %w", err)
} }
if jres.Warning != "" { if jres.Warning != "" {
@ -838,7 +838,7 @@ func (lc *Client) SetUDPGROForwarding(ctx context.Context) error {
var jres struct { var jres struct {
Warning string Warning string
} }
if err := json.Unmarshal(body, &jres); err != nil { if err := jsonv1.Unmarshal(body, &jres); err != nil {
return fmt.Errorf("invalid JSON from set-udp-gro-forwarding: %w", err) return fmt.Errorf("invalid JSON from set-udp-gro-forwarding: %w", err)
} }
if jres.Warning != "" { if jres.Warning != "" {
@ -864,7 +864,7 @@ func (lc *Client) GetPrefs(ctx context.Context) (*ipn.Prefs, error) {
return nil, err return nil, err
} }
var p ipn.Prefs var p ipn.Prefs
if err := json.Unmarshal(body, &p); err != nil { if err := jsonv1.Unmarshal(body, &p); err != nil {
return nil, fmt.Errorf("invalid prefs JSON: %w", err) return nil, fmt.Errorf("invalid prefs JSON: %w", err)
} }
return &p, nil return &p, nil
@ -894,7 +894,7 @@ func (lc *Client) GetDNSOSConfig(ctx context.Context) (*apitype.DNSOSConfig, err
return nil, err return nil, err
} }
var osCfg apitype.DNSOSConfig var osCfg apitype.DNSOSConfig
if err := json.Unmarshal(body, &osCfg); err != nil { if err := jsonv1.Unmarshal(body, &osCfg); err != nil {
return nil, fmt.Errorf("invalid dns.OSConfig: %w", err) return nil, fmt.Errorf("invalid dns.OSConfig: %w", err)
} }
return &osCfg, nil return &osCfg, nil
@ -912,7 +912,7 @@ func (lc *Client) QueryDNS(ctx context.Context, name string, queryType string) (
return nil, nil, err return nil, nil, err
} }
var res apitype.DNSQueryResponse var res apitype.DNSQueryResponse
if err := json.Unmarshal(body, &res); err != nil { if err := jsonv1.Unmarshal(body, &res); err != nil {
return nil, nil, fmt.Errorf("invalid query response: %w", err) return nil, nil, fmt.Errorf("invalid query response: %w", err)
} }
return res.Bytes, res.Resolvers, nil return res.Bytes, res.Resolvers, nil
@ -1011,7 +1011,7 @@ func (lc *Client) CurrentDERPMap(ctx context.Context) (*tailcfg.DERPMap, error)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err = json.Unmarshal(res, &derpMap); err != nil { if err = jsonv1.Unmarshal(res, &derpMap); err != nil {
return nil, fmt.Errorf("invalid derp map json: %w", err) return nil, fmt.Errorf("invalid derp map json: %w", err)
} }
return &derpMap, nil return &derpMap, nil
@ -1098,7 +1098,7 @@ type jsonReader struct {
// jsonBody returns an io.Reader that marshals v as JSON and then reads it. // jsonBody returns an io.Reader that marshals v as JSON and then reads it.
func jsonBody(v any) jsonReader { func jsonBody(v any) jsonReader {
b, err := json.Marshal(v) b, err := jsonv1.Marshal(v)
if err != nil { if err != nil {
return jsonReader{err: err} return jsonReader{err: err}
} }
@ -1271,7 +1271,7 @@ func (lc *Client) WatchIPNBus(ctx context.Context, mask ipn.NotifyWatchOpt) (*IP
res.Body.Close() res.Body.Close()
return nil, errors.New(res.Status) return nil, errors.New(res.Status)
} }
dec := json.NewDecoder(res.Body) dec := jsonv1.NewDecoder(res.Body)
return &IPNBusWatcher{ return &IPNBusWatcher{
ctx: ctx, ctx: ctx,
httpRes: res, httpRes: res,
@ -1350,7 +1350,7 @@ func (lc *Client) DriveShareList(ctx context.Context) ([]*drive.Share, error) {
return nil, err return nil, err
} }
var shares []*drive.Share var shares []*drive.Share
err = json.Unmarshal(result, &shares) err = jsonv1.Unmarshal(result, &shares)
return shares, err return shares, err
} }
@ -1361,7 +1361,7 @@ func (lc *Client) DriveShareList(ctx context.Context) ([]*drive.Share, error) {
type IPNBusWatcher struct { type IPNBusWatcher struct {
ctx context.Context // from original WatchIPNBus call ctx context.Context // from original WatchIPNBus call
httpRes *http.Response httpRes *http.Response
dec *json.Decoder dec *jsonv1.Decoder
mu sync.Mutex mu sync.Mutex
closed bool closed bool

@ -7,7 +7,7 @@ package local
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
@ -34,7 +34,7 @@ func (lc *Client) GetServeConfig(ctx context.Context) (*ipn.ServeConfig, error)
} }
func getServeConfigFromJSON(body []byte) (sc *ipn.ServeConfig, err error) { func getServeConfigFromJSON(body []byte) (sc *ipn.ServeConfig, err error) {
if err := json.Unmarshal(body, &sc); err != nil { if err := jsonv1.Unmarshal(body, &sc); err != nil {
return nil, err return nil, err
} }
return sc, nil return sc, nil

@ -8,7 +8,7 @@ package local
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"net/url" "net/url"
@ -38,7 +38,7 @@ func (lc *Client) NetworkLockInit(ctx context.Context, keys []tka.Key, disableme
SupportDisablement []byte SupportDisablement []byte
} }
if err := json.NewEncoder(&b).Encode(initRequest{Keys: keys, DisablementValues: disablementValues, SupportDisablement: supportDisablement}); err != nil { if err := jsonv1.NewEncoder(&b).Encode(initRequest{Keys: keys, DisablementValues: disablementValues, SupportDisablement: supportDisablement}); err != nil {
return nil, err return nil, err
} }
@ -62,7 +62,7 @@ func (lc *Client) NetworkLockWrapPreauthKey(ctx context.Context, preauthKey stri
TSKey string TSKey string
TKAKey string // key.NLPrivate.MarshalText TKAKey string // key.NLPrivate.MarshalText
} }
if err := json.NewEncoder(&b).Encode(wrapRequest{TSKey: preauthKey, TKAKey: string(encodedPrivate)}); err != nil { if err := jsonv1.NewEncoder(&b).Encode(wrapRequest{TSKey: preauthKey, TKAKey: string(encodedPrivate)}); err != nil {
return "", err return "", err
} }
@ -81,7 +81,7 @@ func (lc *Client) NetworkLockModify(ctx context.Context, addKeys, removeKeys []t
RemoveKeys []tka.Key RemoveKeys []tka.Key
} }
if err := json.NewEncoder(&b).Encode(modifyRequest{AddKeys: addKeys, RemoveKeys: removeKeys}); err != nil { if err := jsonv1.NewEncoder(&b).Encode(modifyRequest{AddKeys: addKeys, RemoveKeys: removeKeys}); err != nil {
return err return err
} }
@ -100,7 +100,7 @@ func (lc *Client) NetworkLockSign(ctx context.Context, nodeKey key.NodePublic, r
RotationPublic []byte RotationPublic []byte
} }
if err := json.NewEncoder(&b).Encode(signRequest{NodeKey: nodeKey, RotationPublic: rotationPublic}); err != nil { if err := jsonv1.NewEncoder(&b).Encode(signRequest{NodeKey: nodeKey, RotationPublic: rotationPublic}); err != nil {
return err return err
} }
@ -134,7 +134,7 @@ func (lc *Client) NetworkLockLog(ctx context.Context, maxEntries int) ([]ipnstat
func (lc *Client) NetworkLockForceLocalDisable(ctx context.Context) error { func (lc *Client) NetworkLockForceLocalDisable(ctx context.Context) error {
// This endpoint expects an empty JSON stanza as the payload. // This endpoint expects an empty JSON stanza as the payload.
var b bytes.Buffer var b bytes.Buffer
if err := json.NewEncoder(&b).Encode(struct{}{}); err != nil { if err := jsonv1.NewEncoder(&b).Encode(struct{}{}); err != nil {
return err return err
} }

@ -8,7 +8,7 @@ package tailscale
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"net/netip" "net/netip"
@ -103,7 +103,7 @@ func (c *Client) ACL(ctx context.Context) (acl *ACL, err error) {
// Otherwise, try to decode the response. // Otherwise, try to decode the response.
var aclDetails ACLDetails var aclDetails ACLDetails
if err = json.Unmarshal(b, &aclDetails); err != nil { if err = jsonv1.Unmarshal(b, &aclDetails); err != nil {
return nil, err return nil, err
} }
acl = &ACL{ acl = &ACL{
@ -146,7 +146,7 @@ func (c *Client) ACLHuJSON(ctx context.Context) (acl *ACLHuJSON, err error) {
ACL []byte `json:"acl"` ACL []byte `json:"acl"`
Warnings []string `json:"warnings"` Warnings []string `json:"warnings"`
}{} }{}
if err := json.Unmarshal(b, &data); err != nil { if err := jsonv1.Unmarshal(b, &data); err != nil {
return nil, fmt.Errorf("json.Unmarshal %q: %w", b, err) return nil, fmt.Errorf("json.Unmarshal %q: %w", b, err)
} }
@ -206,7 +206,7 @@ func (c *Client) aclPOSTRequest(ctx context.Context, body []byte, avoidCollision
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
// check if test error // check if test error
var ate ACLTestError var ate ACLTestError
if err := json.Unmarshal(b, &ate); err != nil { if err := jsonv1.Unmarshal(b, &ate); err != nil {
return nil, "", err return nil, "", err
} }
ate.Status = resp.StatusCode ate.Status = resp.StatusCode
@ -230,7 +230,7 @@ func (c *Client) SetACL(ctx context.Context, acl ACL, avoidCollisions bool) (res
err = fmt.Errorf("tailscale.SetACL: %w", err) err = fmt.Errorf("tailscale.SetACL: %w", err)
} }
}() }()
postData, err := json.Marshal(acl.ACL) postData, err := jsonv1.Marshal(acl.ACL)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -241,7 +241,7 @@ func (c *Client) SetACL(ctx context.Context, acl ACL, avoidCollisions bool) (res
// Otherwise, try to decode the response. // Otherwise, try to decode the response.
var aclDetails ACLDetails var aclDetails ACLDetails
if err = json.Unmarshal(b, &aclDetails); err != nil { if err = jsonv1.Unmarshal(b, &aclDetails); err != nil {
return nil, err return nil, err
} }
res = &ACL{ res = &ACL{
@ -353,7 +353,7 @@ func (c *Client) previewACLPostRequest(ctx context.Context, body []byte, preview
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return nil, HandleErrorResponse(b, resp) return nil, HandleErrorResponse(b, resp)
} }
if err = json.Unmarshal(b, &res); err != nil { if err = jsonv1.Unmarshal(b, &res); err != nil {
return nil, err return nil, err
} }
@ -373,7 +373,7 @@ func (c *Client) PreviewACLForUser(ctx context.Context, acl ACL, user string) (r
err = fmt.Errorf("tailscale.PreviewACLForUser: %w", err) err = fmt.Errorf("tailscale.PreviewACLForUser: %w", err)
} }
}() }()
postData, err := json.Marshal(acl.ACL) postData, err := jsonv1.Marshal(acl.ACL)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -402,7 +402,7 @@ func (c *Client) PreviewACLForIPPort(ctx context.Context, acl ACL, ipport netip.
err = fmt.Errorf("tailscale.PreviewACLForIPPort: %w", err) err = fmt.Errorf("tailscale.PreviewACLForIPPort: %w", err)
} }
}() }()
postData, err := json.Marshal(acl.ACL) postData, err := jsonv1.Marshal(acl.ACL)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -484,7 +484,7 @@ func (c *Client) ValidateACLJSON(ctx context.Context, source, dest string) (test
}() }()
tests := []ACLTest{{User: source, Allow: []string{dest}}} tests := []ACLTest{{User: source, Allow: []string{dest}}}
postData, err := json.Marshal(tests) postData, err := jsonv1.Marshal(tests)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -514,7 +514,7 @@ func (c *Client) ValidateACLJSON(ctx context.Context, source, dest string) (test
var res ACLTestError var res ACLTestError
// The test returned errors. // The test returned errors.
if err = json.Unmarshal(b, &res); err != nil { if err = jsonv1.Unmarshal(b, &res); err != nil {
// failed to unmarshal // failed to unmarshal
return nil, err return nil, err
} }

@ -8,7 +8,7 @@ package tailscale
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
@ -160,7 +160,7 @@ func (c *Client) Devices(ctx context.Context, fields *DeviceFieldsOpts) (deviceL
} }
var devices GetDevicesResponse var devices GetDevicesResponse
err = json.Unmarshal(b, &devices) err = jsonv1.Unmarshal(b, &devices)
return devices.Devices, err return devices.Devices, err
} }
@ -198,7 +198,7 @@ func (c *Client) Device(ctx context.Context, deviceID string, fields *DeviceFiel
return nil, HandleErrorResponse(b, resp) return nil, HandleErrorResponse(b, resp)
} }
err = json.Unmarshal(b, &device) err = jsonv1.Unmarshal(b, &device)
return device, err return device, err
} }
@ -243,7 +243,7 @@ func (c *Client) SetAuthorized(ctx context.Context, deviceID string, authorized
params := &struct { params := &struct {
Authorized bool `json:"authorized"` Authorized bool `json:"authorized"`
}{Authorized: authorized} }{Authorized: authorized}
data, err := json.Marshal(params) data, err := jsonv1.Marshal(params)
if err != nil { if err != nil {
return err return err
} }
@ -271,7 +271,7 @@ func (c *Client) SetTags(ctx context.Context, deviceID string, tags []string) er
params := &struct { params := &struct {
Tags []string `json:"tags"` Tags []string `json:"tags"`
}{Tags: tags} }{Tags: tags}
data, err := json.Marshal(params) data, err := jsonv1.Marshal(params)
if err != nil { if err != nil {
return err return err
} }

@ -8,7 +8,7 @@ package tailscale
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
@ -65,7 +65,7 @@ func (c *Client) dnsGETRequest(ctx context.Context, endpoint string) ([]byte, er
func (c *Client) dnsPOSTRequest(ctx context.Context, endpoint string, postData any) ([]byte, error) { func (c *Client) dnsPOSTRequest(ctx context.Context, endpoint string, postData any) ([]byte, error) {
path := c.BuildTailnetURL("dns", endpoint) path := c.BuildTailnetURL("dns", endpoint)
data, err := json.Marshal(&postData) data, err := jsonv1.Marshal(&postData)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -103,7 +103,7 @@ func (c *Client) DNSConfig(ctx context.Context) (cfg *apitype.DNSConfig, err err
return nil, err return nil, err
} }
var dnsResp apitype.DNSConfig var dnsResp apitype.DNSConfig
err = json.Unmarshal(b, &dnsResp) err = jsonv1.Unmarshal(b, &dnsResp)
return &dnsResp, err return &dnsResp, err
} }
@ -119,7 +119,7 @@ func (c *Client) SetDNSConfig(ctx context.Context, cfg apitype.DNSConfig) (resp
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = json.Unmarshal(b, &dnsResp) err = jsonv1.Unmarshal(b, &dnsResp)
return &dnsResp, err return &dnsResp, err
} }
@ -136,7 +136,7 @@ func (c *Client) NameServers(ctx context.Context) (nameservers []string, err err
return nil, err return nil, err
} }
var dnsResp DNSNameServers var dnsResp DNSNameServers
err = json.Unmarshal(b, &dnsResp) err = jsonv1.Unmarshal(b, &dnsResp)
return dnsResp.DNS, err return dnsResp.DNS, err
} }
@ -157,7 +157,7 @@ func (c *Client) SetNameServers(ctx context.Context, nameservers []string) (dnsR
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = json.Unmarshal(b, &dnsResp) err = jsonv1.Unmarshal(b, &dnsResp)
return dnsResp, err return dnsResp, err
} }
@ -175,7 +175,7 @@ func (c *Client) DNSPreferences(ctx context.Context) (dnsResp *DNSPreferences, e
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = json.Unmarshal(b, &dnsResp) err = jsonv1.Unmarshal(b, &dnsResp)
return dnsResp, err return dnsResp, err
} }
@ -195,7 +195,7 @@ func (c *Client) SetDNSPreferences(ctx context.Context, magicDNS bool) (dnsResp
if err != nil { if err != nil {
return return
} }
err = json.Unmarshal(b, &dnsResp) err = jsonv1.Unmarshal(b, &dnsResp)
return dnsResp, err return dnsResp, err
} }
@ -211,7 +211,7 @@ func (c *Client) SearchPaths(ctx context.Context) (searchpaths []string, err err
return nil, err return nil, err
} }
var dnsResp *DNSSearchPaths var dnsResp *DNSSearchPaths
err = json.Unmarshal(b, &dnsResp) err = jsonv1.Unmarshal(b, &dnsResp)
return dnsResp.SearchPaths, err return dnsResp.SearchPaths, err
} }
@ -228,6 +228,6 @@ func (c *Client) SetSearchPaths(ctx context.Context, searchpaths []string) (newS
return nil, err return nil, err
} }
var dnsResp DNSSearchPaths var dnsResp DNSSearchPaths
err = json.Unmarshal(b, &dnsResp) err = jsonv1.Unmarshal(b, &dnsResp)
return dnsResp.SearchPaths, err return dnsResp.SearchPaths, err
} }

@ -6,7 +6,7 @@ package tailscale
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"time" "time"
@ -57,7 +57,7 @@ func (c *Client) Keys(ctx context.Context) ([]string, error) {
var keys struct { var keys struct {
Keys []*Key `json:"keys"` Keys []*Key `json:"keys"`
} }
if err := json.Unmarshal(b, &keys); err != nil { if err := jsonv1.Unmarshal(b, &keys); err != nil {
return nil, err return nil, err
} }
ret := make([]string, 0, len(keys.Keys)) ret := make([]string, 0, len(keys.Keys))
@ -94,7 +94,7 @@ func (c *Client) CreateKeyWithExpiry(ctx context.Context, caps KeyCapabilities,
Capabilities KeyCapabilities `json:"capabilities"` Capabilities KeyCapabilities `json:"capabilities"`
ExpirySeconds int64 `json:"expirySeconds,omitempty"` ExpirySeconds int64 `json:"expirySeconds,omitempty"`
}{caps, int64(expirySeconds)} }{caps, int64(expirySeconds)}
bs, err := json.Marshal(keyRequest) bs, err := jsonv1.Marshal(keyRequest)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
} }
@ -117,7 +117,7 @@ func (c *Client) CreateKeyWithExpiry(ctx context.Context, caps KeyCapabilities,
Key Key
Secret string `json:"key"` Secret string `json:"key"`
} }
if err := json.Unmarshal(b, &key); err != nil { if err := jsonv1.Unmarshal(b, &key); err != nil {
return "", nil, err return "", nil, err
} }
return key.Secret, &key.Key, nil return key.Secret, &key.Key, nil
@ -141,7 +141,7 @@ func (c *Client) Key(ctx context.Context, id string) (*Key, error) {
} }
var key Key var key Key
if err := json.Unmarshal(b, &key); err != nil { if err := jsonv1.Unmarshal(b, &key); err != nil {
return nil, err return nil, err
} }
return &key, nil return &key, nil

@ -8,7 +8,7 @@ package tailscale
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"net/netip" "net/netip"
@ -48,7 +48,7 @@ func (c *Client) Routes(ctx context.Context, deviceID string) (routes *Routes, e
} }
var sr Routes var sr Routes
err = json.Unmarshal(b, &sr) err = jsonv1.Unmarshal(b, &sr)
return &sr, err return &sr, err
} }
@ -67,7 +67,7 @@ func (c *Client) SetRoutes(ctx context.Context, deviceID string, subnets []netip
} }
}() }()
params := &postRoutesParams{Routes: subnets} params := &postRoutesParams{Routes: subnets}
data, err := json.Marshal(params) data, err := jsonv1.Marshal(params)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -88,7 +88,7 @@ func (c *Client) SetRoutes(ctx context.Context, deviceID string, subnets []netip
} }
var srr *Routes var srr *Routes
if err := json.Unmarshal(b, &srr); err != nil { if err := jsonv1.Unmarshal(b, &srr); err != nil {
return nil, err return nil, err
} }
return srr, err return srr, err

@ -12,7 +12,7 @@
package tailscale package tailscale
import ( import (
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -198,7 +198,7 @@ func (e ErrResponse) Error() string {
// Deprecated: use [tailscale.com/client/tailscale/v2] instead. // Deprecated: use [tailscale.com/client/tailscale/v2] instead.
func HandleErrorResponse(b []byte, resp *http.Response) error { func HandleErrorResponse(b []byte, resp *http.Response) error {
var errResp ErrResponse var errResp ErrResponse
if err := json.Unmarshal(b, &errResp); err != nil { if err := jsonv1.Unmarshal(b, &errResp); err != nil {
return fmt.Errorf("json.Unmarshal %q: %w", b, err) return fmt.Errorf("json.Unmarshal %q: %w", b, err)
} }
errResp.Status = resp.StatusCode errResp.Status = resp.StatusCode

@ -7,7 +7,7 @@ package web
import ( import (
"cmp" "cmp"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -604,7 +604,7 @@ func (a *apiHandler[data]) handle(h http.HandlerFunc) {
func (a *apiHandler[data]) handleJSON(h func(ctx context.Context, data data) error) { func (a *apiHandler[data]) handleJSON(h func(ctx context.Context, data data) error) {
defer a.r.Body.Close() defer a.r.Body.Close()
var body data var body data
if err := json.NewDecoder(a.r.Body).Decode(&body); err != nil { if err := jsonv1.NewDecoder(a.r.Body).Decode(&body); err != nil {
http.Error(a.w, err.Error(), http.StatusInternalServerError) http.Error(a.w, err.Error(), http.StatusInternalServerError)
return return
} }
@ -1275,9 +1275,9 @@ func (s *Server) serveTailscaleUp(w http.ResponseWriter, r *http.Request) {
var opt tailscaleUpOptions var opt tailscaleUpOptions
type mi map[string]any type mi map[string]any
if err := json.NewDecoder(r.Body).Decode(&opt); err != nil { if err := jsonv1.NewDecoder(r.Body).Decode(&opt); err != nil {
w.WriteHeader(400) w.WriteHeader(400)
json.NewEncoder(w).Encode(mi{"error": err.Error()}) jsonv1.NewEncoder(w).Encode(mi{"error": err.Error()})
return return
} }
@ -1287,11 +1287,11 @@ func (s *Server) serveTailscaleUp(w http.ResponseWriter, r *http.Request) {
s.logf("tailscaleUp = (URL %v, %v)", url != "", err) s.logf("tailscaleUp = (URL %v, %v)", url != "", err)
if err != nil { if err != nil {
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
json.NewEncoder(w).Encode(mi{"error": err.Error()}) jsonv1.NewEncoder(w).Encode(mi{"error": err.Error()})
return return
} }
if url != "" { if url != "" {
json.NewEncoder(w).Encode(mi{"url": url}) jsonv1.NewEncoder(w).Encode(mi{"url": url})
} else { } else {
io.WriteString(w, "{}") io.WriteString(w, "{}")
} }
@ -1376,7 +1376,7 @@ func enforcePrefix(prefix string, h http.HandlerFunc) http.HandlerFunc {
func writeJSON(w http.ResponseWriter, data any) { func writeJSON(w http.ResponseWriter, data any) {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(data); err != nil { if err := jsonv1.NewEncoder(w).Encode(data); err != nil {
w.Header().Set("Content-Type", "text/plain") w.Header().Set("Content-Type", "text/plain")
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return

@ -6,7 +6,7 @@ package web
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -796,7 +796,7 @@ func TestServeAuth(t *testing.T) {
} }
var wantResp string var wantResp string
if tt.wantResp != nil { if tt.wantResp != nil {
b, _ := json.Marshal(tt.wantResp) b, _ := jsonv1.Marshal(tt.wantResp)
wantResp = string(b) wantResp = string(b)
} }
if diff := cmp.Diff(gotResp, string(wantResp)); diff != "" { if diff := cmp.Diff(gotResp, string(wantResp)); diff != "" {
@ -1458,7 +1458,7 @@ func mockLocalAPI(t *testing.T, whoIs map[string]*apitype.WhoIsResponse, self fu
} }
var metricNames []metricName var metricNames []metricName
if err := json.NewDecoder(r.Body).Decode(&metricNames); err != nil { if err := jsonv1.NewDecoder(r.Body).Decode(&metricNames); err != nil {
http.Error(w, "invalid JSON body", http.StatusBadRequest) http.Error(w, "invalid JSON body", http.StatusBadRequest)
return return
} }

@ -12,7 +12,7 @@ import (
"bytes" "bytes"
"compress/gzip" "compress/gzip"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -1207,7 +1207,7 @@ func latestPackages(track string) (*trackPackages, error) {
} }
defer res.Body.Close() defer res.Body.Close()
var latest trackPackages var latest trackPackages
if err := json.NewDecoder(res.Body).Decode(&latest); err != nil { if err := jsonv1.NewDecoder(res.Body).Decode(&latest); err != nil {
return nil, fmt.Errorf("decoding JSON: %v: %w", res.Status, err) return nil, fmt.Errorf("decoding JSON: %v: %w", res.Status, err)
} }
return &latest, nil return &latest, nil

@ -4,7 +4,7 @@
package main package main
import ( import (
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
@ -40,7 +40,7 @@ func aws() {
defer r.Body.Close() defer r.Body.Close()
var aws AWSMeta var aws AWSMeta
if err := json.NewDecoder(r.Body).Decode(&aws); err != nil { if err := jsonv1.NewDecoder(r.Body).Decode(&aws); err != nil {
log.Fatal(err) log.Fatal(err)
} }

@ -4,7 +4,7 @@
package main package main
import ( import (
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
@ -51,7 +51,7 @@ func github() {
var ghm GithubMeta var ghm GithubMeta
if err := json.NewDecoder(r.Body).Decode(&ghm); err != nil { if err := jsonv1.NewDecoder(r.Body).Decode(&ghm); err != nil {
log.Fatal(err) log.Fatal(err)
} }
r.Body.Close() r.Body.Close()

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"log" "log"
@ -393,7 +393,7 @@ func (ep *egressProxy) getConfigs() (*egressservices.Configs, error) {
return nil, nil return nil, nil
} }
cfg := &egressservices.Configs{} cfg := &egressservices.Configs{}
if err := json.Unmarshal(j, &cfg); err != nil { if err := jsonv1.Unmarshal(j, &cfg); err != nil {
return nil, err return nil, err
} }
return cfg, nil return cfg, nil
@ -413,7 +413,7 @@ func (ep *egressProxy) getStatus(ctx context.Context) (*egressservices.Status, e
if !ok { if !ok {
return nil, nil return nil, nil
} }
if err := json.Unmarshal([]byte(raw), status); err != nil { if err := jsonv1.Unmarshal([]byte(raw), status); err != nil {
return nil, fmt.Errorf("error unmarshalling previous config: %w", err) return nil, fmt.Errorf("error unmarshalling previous config: %w", err)
} }
if reflect.DeepEqual(status.PodIPv4, ep.podIPv4) { if reflect.DeepEqual(status.PodIPv4, ep.podIPv4) {
@ -434,7 +434,7 @@ func (ep *egressProxy) setStatus(ctx context.Context, status *egressservices.Sta
if err != nil { if err != nil {
return fmt.Errorf("error retrieving state Secret: %w", err) return fmt.Errorf("error retrieving state Secret: %w", err)
} }
bs, err := json.Marshal(status) bs, err := jsonv1.Marshal(status)
if err != nil { if err != nil {
return fmt.Errorf("error marshalling service config: %w", err) return fmt.Errorf("error marshalling service config: %w", err)
} }

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"log" "log"
"net/netip" "net/netip"
@ -131,7 +131,7 @@ func (p *ingressProxy) getConfigs() (*ingressservices.Configs, error) {
return nil, nil return nil, nil
} }
cfg := &ingressservices.Configs{} cfg := &ingressservices.Configs{}
if err := json.Unmarshal(j, &cfg); err != nil { if err := jsonv1.Unmarshal(j, &cfg); err != nil {
return nil, err return nil, err
} }
return cfg, nil return cfg, nil
@ -152,7 +152,7 @@ func (p *ingressProxy) getStatus(ctx context.Context) (*ingressservices.Status,
if !ok { if !ok {
return nil, nil return nil, nil
} }
if err := json.Unmarshal([]byte(raw), status); err != nil { if err := jsonv1.Unmarshal([]byte(raw), status); err != nil {
return nil, fmt.Errorf("error unmarshalling previous config: %w", err) return nil, fmt.Errorf("error unmarshalling previous config: %w", err)
} }
return status, nil return status, nil
@ -189,7 +189,7 @@ func (p *ingressProxy) recordStatus(ctx context.Context, newCfg *ingressservices
if err != nil { if err != nil {
return fmt.Errorf("error retrieving state Secret: %w", err) return fmt.Errorf("error retrieving state Secret: %w", err)
} }
bs, err := json.Marshal(status) bs, err := jsonv1.Marshal(status)
if err != nil { if err != nil {
return fmt.Errorf("error marshalling status: %w", err) return fmt.Errorf("error marshalling status: %w", err)
} }

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"log" "log"
@ -73,7 +73,7 @@ func (kc *kubeClient) storeDeviceEndpoints(ctx context.Context, fqdn string, add
for _, addr := range addresses { for _, addr := range addresses {
ips = append(ips, addr.Addr().String()) ips = append(ips, addr.Addr().String())
} }
deviceIPs, err := json.Marshal(ips) deviceIPs, err := jsonv1.Marshal(ips)
if err != nil { if err != nil {
return err return err
} }

@ -9,7 +9,7 @@ import (
"bytes" "bytes"
_ "embed" _ "embed"
"encoding/base64" "encoding/base64"
"encoding/json" jsonv1 "encoding/json"
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt" "fmt"
@ -1347,7 +1347,7 @@ func (l *localAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if f, ok := w.(http.Flusher); ok { if f, ok := w.(http.Flusher); ok {
f.Flush() f.Flush()
} }
enc := json.NewEncoder(w) enc := jsonv1.NewEncoder(w)
l.Lock() l.Lock()
defer l.Unlock() defer l.Unlock()
for { for {
@ -1456,7 +1456,7 @@ func (k *kubeServer) serveSSAR(w http.ResponseWriter, r *http.Request) {
} `json:"resourceAttributes"` } `json:"resourceAttributes"`
} `json:"spec"` } `json:"spec"`
} }
if err := json.NewDecoder(r.Body).Decode(&req); err != nil { if err := jsonv1.NewDecoder(r.Body).Decode(&req); err != nil {
panic(fmt.Sprintf("decoding SSAR request: %v", err)) panic(fmt.Sprintf("decoding SSAR request: %v", err))
} }
ok := true ok := true
@ -1490,7 +1490,7 @@ func (k *kubeServer) serveSecret(w http.ResponseWriter, r *http.Request) {
v := base64.StdEncoding.EncodeToString([]byte(v)) v := base64.StdEncoding.EncodeToString([]byte(v))
ret["data"][k] = v ret["data"][k] = v
} }
if err := json.NewEncoder(w).Encode(ret); err != nil { if err := jsonv1.NewEncoder(w).Encode(ret); err != nil {
panic("encode failed") panic("encode failed")
} }
case "PATCH": case "PATCH":
@ -1502,7 +1502,7 @@ func (k *kubeServer) serveSecret(w http.ResponseWriter, r *http.Request) {
switch r.Header.Get("Content-Type") { switch r.Header.Get("Content-Type") {
case "application/json-patch+json": case "application/json-patch+json":
req := []kubeclient.JSONPatch{} req := []kubeclient.JSONPatch{}
if err := json.Unmarshal(bs, &req); err != nil { if err := jsonv1.Unmarshal(bs, &req); err != nil {
panic(fmt.Sprintf("json decode failed: %v. Body:\n\n%s", err, string(bs))) panic(fmt.Sprintf("json decode failed: %v. Body:\n\n%s", err, string(bs)))
} }
for _, op := range req { for _, op := range req {
@ -1534,7 +1534,7 @@ func (k *kubeServer) serveSecret(w http.ResponseWriter, r *http.Request) {
req := struct { req := struct {
Data map[string][]byte `json:"data"` Data map[string][]byte `json:"data"`
}{} }{}
if err := json.Unmarshal(bs, &req); err != nil { if err := jsonv1.Unmarshal(bs, &req); err != nil {
panic(fmt.Sprintf("json decode failed: %v. Body:\n\n%s", err, string(bs))) panic(fmt.Sprintf("json decode failed: %v. Body:\n\n%s", err, string(bs)))
} }
for key, val := range req.Data { for key, val := range req.Data {
@ -1555,7 +1555,7 @@ func mustBase64(t *testing.T, v any) string {
} }
func mustJSON(t *testing.T, v any) []byte { func mustJSON(t *testing.T, v any) []byte {
b, err := json.Marshal(v) b, err := jsonv1.Marshal(v)
if err != nil { if err != nil {
t.Fatalf("error converting %v to json: %v", v, err) t.Fatalf("error converting %v to json: %v", v, err)
} }

@ -8,7 +8,7 @@ package main
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
@ -164,7 +164,7 @@ func readServeConfig(path, certDomain string) (*ipn.ServeConfig, error) {
} }
j = bytes.ReplaceAll(j, []byte("${TS_CERT_DOMAIN}"), []byte(certDomain)) j = bytes.ReplaceAll(j, []byte("${TS_CERT_DOMAIN}"), []byte(certDomain))
var sc ipn.ServeConfig var sc ipn.ServeConfig
if err := json.Unmarshal(j, &sc); err != nil { if err := jsonv1.Unmarshal(j, &sc); err != nil {
return nil, err return nil, err
} }
return &sc, nil return &sc, nil

@ -6,7 +6,7 @@ package main
import ( import (
"context" "context"
"encoding/binary" "encoding/binary"
"encoding/json" jsonv1 "encoding/json"
"expvar" "expvar"
"log" "log"
"math/rand/v2" "math/rand/v2"
@ -75,7 +75,7 @@ func refreshBootstrapDNS() {
for _, vv := range dnsEntries.IPs { for _, vv := range dnsEntries.IPs {
slicesx.Shuffle(vv) slicesx.Shuffle(vv)
} }
j, err := json.MarshalIndent(dnsEntries.IPs, "", "\t") j, err := jsonv1.MarshalIndent(dnsEntries.IPs, "", "\t")
if err != nil { if err != nil {
// leave the old values in place // leave the old values in place
return return
@ -156,7 +156,7 @@ func handleBootstrapDNS(w http.ResponseWriter, r *http.Request) {
if remoteAddrMatchesPercent(r.RemoteAddr, percent) { if remoteAddrMatchesPercent(r.RemoteAddr, percent) {
// Only return the specific query, not everything. // Only return the specific query, not everything.
m := map[string][]net.IP{q: m.IPs[q]} m := map[string][]net.IP{q: m.IPs[q]}
j, err := json.MarshalIndent(m, "", "\t") j, err := jsonv1.MarshalIndent(m, "", "\t")
if err == nil { if err == nil {
w.Write(j) w.Write(j)
return return

@ -5,7 +5,7 @@ package main
import ( import (
"bytes" "bytes"
"encoding/json" jsonv1 "encoding/json"
"io" "io"
"net" "net"
"net/http" "net/http"
@ -53,7 +53,7 @@ func getBootstrapDNS(t *testing.T, q string) map[string][]net.IP {
} }
var m map[string][]net.IP var m map[string][]net.IP
var buf bytes.Buffer var buf bytes.Buffer
if err := json.NewDecoder(io.TeeReader(res.Body, &buf)).Decode(&m); err != nil { if err := jsonv1.NewDecoder(io.TeeReader(res.Body, &buf)).Decode(&m); err != nil {
t.Fatalf("error decoding response body %q: %v", buf.Bytes(), err) t.Fatalf("error decoding response body %q: %v", buf.Bytes(), err)
} }
return m return m

@ -11,7 +11,7 @@ import (
"crypto/tls" "crypto/tls"
"crypto/x509" "crypto/x509"
"crypto/x509/pkix" "crypto/x509/pkix"
"encoding/json" jsonv1 "encoding/json"
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt" "fmt"
@ -107,7 +107,7 @@ func NewManualCertManager(certdir, hostname string) (certProvider, error) {
HostName: hostname, HostName: hostname,
CertName: fmt.Sprintf("sha256-raw:%-02x", sha256.Sum256(x509Cert.Raw)), CertName: fmt.Sprintf("sha256-raw:%-02x", sha256.Sum256(x509Cert.Raw)),
} }
dnJSON, _ := json.Marshal(dn) dnJSON, _ := jsonv1.Marshal(dn)
log.Printf("Using self-signed certificate for IP address %q. Configure it in DERPMap using: (https://tailscale.com/s/custom-derp)\n %s", hostname, dnJSON) log.Printf("Using self-signed certificate for IP address %q. Configure it in DERPMap using: (https://tailscale.com/s/custom-derp)\n %s", hostname, dnJSON)
} }
return &manualCertManager{ return &manualCertManager{

@ -14,7 +14,7 @@ import (
"cmp" "cmp"
"context" "context"
"crypto/tls" "crypto/tls"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"expvar" "expvar"
"flag" "flag"
@ -133,7 +133,7 @@ func loadConfig() config {
panic("unreachable") panic("unreachable")
default: default:
var cfg config var cfg config
if err := json.Unmarshal(b, &cfg); err != nil { if err := jsonv1.Unmarshal(b, &cfg); err != nil {
log.Fatalf("derper: config: %v", err) log.Fatalf("derper: config: %v", err)
} }
return cfg return cfg
@ -148,7 +148,7 @@ func writeNewConfig() config {
cfg := config{ cfg := config{
PrivateKey: k, PrivateKey: k,
} }
b, err := json.MarshalIndent(cfg, "", "\t") b, err := jsonv1.MarshalIndent(cfg, "", "\t")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }

@ -4,7 +4,7 @@
package main package main
import ( import (
"encoding/json" jsonv1 "encoding/json"
"os" "os"
) )
@ -38,7 +38,7 @@ func (c *Cache) Save(fname string) error {
} }
defer fout.Close() defer fout.Close()
return json.NewEncoder(fout).Encode(c) return jsonv1.NewEncoder(fout).Encode(c)
} }
// LoadCache loads the cache from a given file. // LoadCache loads the cache from a given file.
@ -51,7 +51,7 @@ func LoadCache(fname string) (*Cache, error) {
} }
defer fin.Close() defer fin.Close()
err = json.NewDecoder(fin).Decode(&result) err = jsonv1.NewDecoder(fin).Decode(&result)
if err != nil { if err != nil {
return nil, err return nil, err
} }

@ -10,7 +10,7 @@ import (
"bytes" "bytes"
"context" "context"
"crypto/sha256" "crypto/sha256"
"encoding/json" jsonv1 "encoding/json"
"flag" "flag"
"fmt" "fmt"
"io" "io"
@ -288,7 +288,7 @@ func applyNewACL(ctx context.Context, client *http.Client, tailnet, apiKey, poli
want := http.StatusOK want := http.StatusOK
if got != want { if got != want {
var ate ACLGitopsTestError var ate ACLGitopsTestError
err := json.NewDecoder(resp.Body).Decode(&ate) err := jsonv1.NewDecoder(resp.Body).Decode(&ate)
if err != nil { if err != nil {
return err return err
} }
@ -324,7 +324,7 @@ func testNewACLs(ctx context.Context, client *http.Client, tailnet, apiKey, poli
defer resp.Body.Close() defer resp.Body.Close()
var ate ACLGitopsTestError var ate ACLGitopsTestError
err = json.NewDecoder(resp.Body).Decode(&ate) err = jsonv1.NewDecoder(resp.Body).Decode(&ate)
if err != nil { if err != nil {
return err return err
} }

@ -4,7 +4,7 @@
package main package main
import ( import (
"encoding/json" jsonv1 "encoding/json"
"strings" "strings"
"testing" "testing"
@ -31,9 +31,9 @@ func TestEmbeddedTypeUnmarshal(t *testing.T) {
} }
t.Run("unmarshal gitops type from acl type", func(t *testing.T) { t.Run("unmarshal gitops type from acl type", func(t *testing.T) {
b, _ := json.Marshal(aclTestErr) b, _ := jsonv1.Marshal(aclTestErr)
var e ACLGitopsTestError var e ACLGitopsTestError
err := json.Unmarshal(b, &e) err := jsonv1.Unmarshal(b, &e)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -42,9 +42,9 @@ func TestEmbeddedTypeUnmarshal(t *testing.T) {
} }
}) })
t.Run("unmarshal acl type from gitops type", func(t *testing.T) { t.Run("unmarshal acl type from gitops type", func(t *testing.T) {
b, _ := json.Marshal(gitopsErr) b, _ := jsonv1.Marshal(gitopsErr)
var e tailscale.ACLTestError var e tailscale.ACLTestError
err := json.Unmarshal(b, &e) err := jsonv1.Unmarshal(b, &e)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

@ -8,7 +8,7 @@ import (
"context" "context"
"crypto/tls" "crypto/tls"
_ "embed" _ "embed"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"flag" "flag"
"html/template" "html/template"
@ -41,7 +41,7 @@ func main() {
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
e := json.NewEncoder(os.Stdout) e := jsonv1.NewEncoder(os.Stdout)
e.SetIndent("", "\t") e.SetIndent("", "\t")
e.Encode(res) e.Encode(res)
return return

@ -43,9 +43,11 @@ func mustFormatFile(in []byte) (out []byte) {
"github.com/go-json-experiment/json", "github.com/go-json-experiment/json",
"github.com/go-json-experiment/json/v1", "github.com/go-json-experiment/json/v1",
"github.com/go-json-experiment/json/jsontext": "github.com/go-json-experiment/json/jsontext":
if imp.Name.String() != "_" {
jsonImports[pkgPath] = append(jsonImports[pkgPath], imp) jsonImports[pkgPath] = append(jsonImports[pkgPath], imp)
} }
} }
}
if len(jsonImports) == 0 { if len(jsonImports) == 0 {
return in return in
} }

@ -60,8 +60,23 @@ import (
"tailscale.com/util/safediff" "tailscale.com/util/safediff"
) )
type ignoreList []string
func (s *ignoreList) String() string {
return strings.Join(*s, ",")
}
func (s *ignoreList) Set(value string) error {
for v := range strings.SplitSeq(value, ",") {
*s = append(*s, strings.TrimSpace(v))
}
return nil
}
func main() { func main() {
var ignore ignoreList
update := flag.Bool("update", false, "update all Go source files") update := flag.Bool("update", false, "update all Go source files")
flag.Var(&ignore, "ignore", "files and directories to ignore (may be repeated)")
flag.Parse() flag.Parse()
// Change working directory to Git repository root. // Change working directory to Git repository root.
@ -87,6 +102,13 @@ func main() {
return return
} }
// Ignore files that match the ignore prefixes.
for _, prefix := range ignore {
if strings.HasPrefix(file, prefix) {
return
}
}
// Format all "json" imports in the Go source file. // Format all "json" imports in the Go source file.
srcIn := must.Get(os.ReadFile(file)) srcIn := must.Get(os.ReadFile(file))
srcOut := mustFormatFile(srcIn) srcOut := mustFormatFile(srcIn)
@ -118,7 +140,11 @@ func main() {
if numDiffs > 0 && !*update { if numDiffs > 0 && !*update {
fmt.Printf(`%d files with "json" imports that need formatting`+"\n", numDiffs) fmt.Printf(`%d files with "json" imports that need formatting`+"\n", numDiffs)
fmt.Println("Please run:") fmt.Println("Please run:")
fmt.Println("\t./tool/go run tailscale.com/cmd/jsonimports -update") var ignoreFlags string
for _, path := range ignore {
ignoreFlags += " -ignore=" + path
}
fmt.Println("\t./tool/go run tailscale.com/cmd/jsonimports -update" + ignoreFlags)
os.Exit(1) os.Exit(1)
} }
} }

@ -10,7 +10,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"log" "log"
"net" "net"
@ -240,7 +240,7 @@ func (n *nameserver) resetRecords() error {
return nil return nil
} }
dnsCfg := &operatorutils.Records{} dnsCfg := &operatorutils.Records{}
err = json.Unmarshal(dnsCfgBytes, dnsCfg) err = jsonv1.Unmarshal(dnsCfgBytes, dnsCfg)
if err != nil { if err != nil {
return fmt.Errorf("error unmarshalling nameserver configuration: %v\n", err) return fmt.Errorf("error unmarshalling nameserver configuration: %v\n", err)
} }

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"maps" "maps"
@ -392,7 +392,7 @@ func (r *KubeAPIServerTSServiceReconciler) maybeAdvertiseServices(ctx context.Co
} }
// Update the config Secret. // Update the config Secret.
cfgB, err := json.Marshal(conf.VersionedConfig{ cfgB, err := jsonv1.Marshal(conf.VersionedConfig{
Version: "v1alpha1", Version: "v1alpha1",
ConfigV1Alpha1: &cfg.Parsed, ConfigV1Alpha1: &cfg.Parsed,
}) })
@ -437,7 +437,7 @@ func exclusiveOwnerAnnotations(pg *tsapi.ProxyGroup, operatorID string, svc *tai
} }
if svc == nil { if svc == nil {
c := ownerAnnotationValue{OwnerRefs: []OwnerRef{ref}} c := ownerAnnotationValue{OwnerRefs: []OwnerRef{ref}}
json, err := json.Marshal(c) json, err := jsonv1.Marshal(c)
if err != nil { if err != nil {
return nil, fmt.Errorf("[unexpected] unable to marshal Tailscale Service's owner annotation contents: %w, please report this", err) return nil, fmt.Errorf("[unexpected] unable to marshal Tailscale Service's owner annotation contents: %w, please report this", err)
} }
@ -466,7 +466,7 @@ func exclusiveOwnerAnnotations(pg *tsapi.ProxyGroup, operatorID string, svc *tai
o.OwnerRefs[0].Resource.Name = pg.Name o.OwnerRefs[0].Resource.Name = pg.Name
} }
oBytes, err := json.Marshal(o) oBytes, err := jsonv1.Marshal(o)
if err != nil { if err != nil {
return nil, err return nil, err
} }

@ -4,7 +4,7 @@
package main package main
import ( import (
"encoding/json" jsonv1 "encoding/json"
"reflect" "reflect"
"strings" "strings"
"testing" "testing"
@ -64,7 +64,7 @@ func TestAPIServerProxyReconciler(t *testing.T) {
}, },
} }
expectedCfg := *initialCfg expectedCfg := *initialCfg
initialCfgB, err := json.Marshal(initialCfg) initialCfgB, err := jsonv1.Marshal(initialCfg)
if err != nil { if err != nil {
t.Fatalf("marshaling initial config: %v", err) t.Fatalf("marshaling initial config: %v", err)
} }
@ -86,7 +86,7 @@ func TestAPIServerProxyReconciler(t *testing.T) {
Build() Build()
expectCfg := func(c *conf.VersionedConfig) { expectCfg := func(c *conf.VersionedConfig) {
t.Helper() t.Helper()
cBytes, err := json.Marshal(c) cBytes, err := jsonv1.Marshal(c)
if err != nil { if err != nil {
t.Fatalf("marshaling expected config: %v", err) t.Fatalf("marshaling expected config: %v", err)
} }

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"slices" "slices"
"strings" "strings"
@ -314,12 +314,12 @@ func (dnsRR *dnsRecordsReconciler) updateDNSConfig(ctx context.Context, update f
} }
dnsRecords := operatorutils.Records{Version: operatorutils.Alpha1Version, IP4: map[string][]string{}} dnsRecords := operatorutils.Records{Version: operatorutils.Alpha1Version, IP4: map[string][]string{}}
if cm.Data != nil && cm.Data[operatorutils.DNSRecordsCMKey] != "" { if cm.Data != nil && cm.Data[operatorutils.DNSRecordsCMKey] != "" {
if err := json.Unmarshal([]byte(cm.Data[operatorutils.DNSRecordsCMKey]), &dnsRecords); err != nil { if err := jsonv1.Unmarshal([]byte(cm.Data[operatorutils.DNSRecordsCMKey]), &dnsRecords); err != nil {
return err return err
} }
} }
update(&dnsRecords) update(&dnsRecords)
dnsRecordsBs, err := json.Marshal(dnsRecords) dnsRecordsBs, err := jsonv1.Marshal(dnsRecords)
if err != nil { if err != nil {
return fmt.Errorf("error marshalling DNS records: %w", err) return fmt.Errorf("error marshalling DNS records: %w", err)
} }

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"testing" "testing"
@ -469,7 +469,7 @@ func expectHostsRecords(t *testing.T, cl client.Client, wantsHosts map[string][]
t.Fatal("dnsconfig ConfigMap does not contain dnsconfig") t.Fatal("dnsconfig ConfigMap does not contain dnsconfig")
} }
dnsConfig := &operatorutils.Records{} dnsConfig := &operatorutils.Records{}
if err := json.Unmarshal([]byte(dnsConfigString), dnsConfig); err != nil { if err := jsonv1.Unmarshal([]byte(dnsConfigString), dnsConfig); err != nil {
t.Fatalf("unmarshaling dnsconfig: %v", err) t.Fatalf("unmarshaling dnsconfig: %v", err)
} }
if diff := cmp.Diff(dnsConfig.IP4, wantsHosts); diff != "" { if diff := cmp.Diff(dnsConfig.IP4, wantsHosts); diff != "" {
@ -491,7 +491,7 @@ func expectHostsRecordsWithIPv6(t *testing.T, cl client.Client, wantsHostsIPv4,
t.Fatal("dnsconfig ConfigMap does not contain dnsconfig") t.Fatal("dnsconfig ConfigMap does not contain dnsconfig")
} }
dnsConfig := &operatorutils.Records{} dnsConfig := &operatorutils.Records{}
if err := json.Unmarshal([]byte(dnsConfigString), dnsConfig); err != nil { if err := jsonv1.Unmarshal([]byte(dnsConfigString), dnsConfig); err != nil {
t.Fatalf("unmarshaling dnsconfig: %v", err) t.Fatalf("unmarshaling dnsconfig: %v", err)
} }
if diff := cmp.Diff(dnsConfig.IP4, wantsHostsIPv4); diff != "" { if diff := cmp.Diff(dnsConfig.IP4, wantsHostsIPv4); diff != "" {

@ -4,7 +4,7 @@
package e2e package e2e
import ( import (
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"testing" "testing"
"time" "time"
@ -99,7 +99,7 @@ func hostNameFromOperatorSecret(t *testing.T, s corev1.Secret) string {
} }
prefs := ipn.Prefs{} prefs := ipn.Prefs{}
if err := json.Unmarshal(prefsBytes, &prefs); err != nil { if err := jsonv1.Unmarshal(prefsBytes, &prefs); err != nil {
t.Fatal(err) t.Fatal(err)
} }

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"net/netip" "net/netip"
"reflect" "reflect"
@ -189,7 +189,7 @@ func (er *egressEpsReconciler) podIsReadyToRouteTraffic(ctx context.Context, pod
return false, nil return false, nil
} }
svcStatus := &egressservices.Status{} svcStatus := &egressservices.Status{}
if err := json.Unmarshal(svcStatusBS, svcStatus); err != nil { if err := jsonv1.Unmarshal(svcStatusBS, svcStatus); err != nil {
return false, fmt.Errorf("error unmarshalling egress service status: %w", err) return false, fmt.Errorf("error unmarshalling egress service status: %w", err)
} }
if !strings.EqualFold(podIP, svcStatus.PodIPv4) { if !strings.EqualFold(podIP, svcStatus.PodIPv4) {

@ -6,7 +6,7 @@
package main package main
import ( import (
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"math/rand/v2" "math/rand/v2"
"testing" "testing"
@ -144,7 +144,7 @@ func configMapForSvc(t *testing.T, svc *corev1.Service, p uint16) *corev1.Config
} }
name := tailnetSvcName(svc) name := tailnetSvcName(svc)
cfgs := egressservices.Configs{name: cfg} cfgs := egressservices.Configs{name: cfg}
bs, err := json.Marshal(&cfgs) bs, err := jsonv1.Marshal(&cfgs)
if err != nil { if err != nil {
t.Fatalf("error marshalling config: %v", err) t.Fatalf("error marshalling config: %v", err)
} }
@ -176,7 +176,7 @@ func serviceStatusForPodIP(t *testing.T, svc *corev1.Service, ip string, p uint1
PodIPv4: ip, PodIPv4: ip,
Services: map[string]*egressservices.ServiceStatus{svcName: &svcSt}, Services: map[string]*egressservices.ServiceStatus{svcName: &svcSt},
} }
bs, err := json.Marshal(st) bs, err := jsonv1.Marshal(st)
if err != nil { if err != nil {
t.Fatalf("error marshalling service status: %v", err) t.Fatalf("error marshalling service status: %v", err)
} }

@ -8,7 +8,7 @@ package main
import ( import (
"context" "context"
"crypto/sha256" "crypto/sha256"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"math/rand/v2" "math/rand/v2"
@ -352,7 +352,7 @@ func (esr *egressSvcsReconciler) provision(ctx context.Context, proxyGroupName s
if !reflect.DeepEqual(gotCfg, wantsCfg) { if !reflect.DeepEqual(gotCfg, wantsCfg) {
l.Debugf("updating egress services ConfigMap %s", cm.Name) l.Debugf("updating egress services ConfigMap %s", cm.Name)
mak.Set(cfgs, tailnetSvc, wantsCfg) mak.Set(cfgs, tailnetSvc, wantsCfg)
bs, err := json.Marshal(cfgs) bs, err := jsonv1.Marshal(cfgs)
if err != nil { if err != nil {
return nil, false, fmt.Errorf("error marshalling egress services configs: %w", err) return nil, false, fmt.Errorf("error marshalling egress services configs: %w", err)
} }
@ -485,7 +485,7 @@ func (esr *egressSvcsReconciler) ensureEgressSvcCfgDeleted(ctx context.Context,
return nil return nil
} }
cfgs := &egressservices.Configs{} cfgs := &egressservices.Configs{}
if err := json.Unmarshal(bs, cfgs); err != nil { if err := jsonv1.Unmarshal(bs, cfgs); err != nil {
return fmt.Errorf("error unmarshalling egress services configs") return fmt.Errorf("error unmarshalling egress services configs")
} }
tailnetSvc := tailnetSvcName(svc) tailnetSvc := tailnetSvcName(svc)
@ -497,7 +497,7 @@ func (esr *egressSvcsReconciler) ensureEgressSvcCfgDeleted(ctx context.Context,
l.Infof("before deleting config %+#v", *cfgs) l.Infof("before deleting config %+#v", *cfgs)
delete(*cfgs, tailnetSvc) delete(*cfgs, tailnetSvc)
l.Infof("after deleting config %+#v", *cfgs) l.Infof("after deleting config %+#v", *cfgs)
bs, err := json.Marshal(cfgs) bs, err := jsonv1.Marshal(cfgs)
if err != nil { if err != nil {
return fmt.Errorf("error marshalling egress services configs: %w", err) return fmt.Errorf("error marshalling egress services configs: %w", err)
} }
@ -665,7 +665,7 @@ func egressSvcsConfigs(ctx context.Context, cl client.Client, proxyGroupName, ts
} }
cfgs = &egressservices.Configs{} cfgs = &egressservices.Configs{}
if len(cm.BinaryData[egressservices.KeyEgressServices]) != 0 { if len(cm.BinaryData[egressservices.KeyEgressServices]) != 0 {
if err := json.Unmarshal(cm.BinaryData[egressservices.KeyEgressServices], cfgs); err != nil { if err := jsonv1.Unmarshal(cm.BinaryData[egressservices.KeyEgressServices], cfgs); err != nil {
return nil, nil, fmt.Errorf("error unmarshaling egress services config %v: %w", cm.BinaryData[egressservices.KeyEgressServices], err) return nil, nil, fmt.Errorf("error unmarshaling egress services config %v: %w", cm.BinaryData[egressservices.KeyEgressServices], err)
} }
} }
@ -715,7 +715,7 @@ func svcConfigurationUpToDate(svc *corev1.Service, l *zap.SugaredLogger) bool {
} }
func cfgHash(c cfg, l *zap.SugaredLogger) string { func cfgHash(c cfg, l *zap.SugaredLogger) string {
bs, err := json.Marshal(c) bs, err := jsonv1.Marshal(c)
if err != nil { if err != nil {
// Don't use l.Error as that messes up component logs with, in this case, unnecessary stack trace. // Don't use l.Error as that messes up component logs with, in this case, unnecessary stack trace.
l.Infof("error marhsalling Config: %v", err) l.Infof("error marhsalling Config: %v", err)

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"testing" "testing"
@ -284,7 +284,7 @@ func configFromCM(t *testing.T, cm *corev1.ConfigMap, svcName string) *egressser
return nil return nil
} }
cfgs := &egressservices.Configs{} cfgs := &egressservices.Configs{}
if err := json.Unmarshal(cfgBs, cfgs); err != nil { if err := jsonv1.Unmarshal(cfgBs, cfgs); err != nil {
t.Fatalf("error unmarshalling config: %v", err) t.Fatalf("error unmarshalling config: %v", err)
} }
cfg, ok := (*cfgs)[svcName] cfg, ok := (*cfgs)[svcName]

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"math/rand/v2" "math/rand/v2"
@ -303,7 +303,7 @@ func (r *HAIngressReconciler) maybeProvision(ctx context.Context, hostname strin
if !reflect.DeepEqual(gotCfg, ingCfg) { if !reflect.DeepEqual(gotCfg, ingCfg) {
logger.Infof("Updating serve config") logger.Infof("Updating serve config")
mak.Set(&cfg.Services, serviceName, ingCfg) mak.Set(&cfg.Services, serviceName, ingCfg)
cfgBytes, err := json.Marshal(cfg) cfgBytes, err := jsonv1.Marshal(cfg)
if err != nil { if err != nil {
return false, fmt.Errorf("error marshaling serve config: %w", err) return false, fmt.Errorf("error marshaling serve config: %w", err)
} }
@ -488,7 +488,7 @@ func (r *HAIngressReconciler) maybeCleanupProxyGroup(ctx context.Context, proxyG
} }
if serveConfigChanged { if serveConfigChanged {
cfgBytes, err := json.Marshal(cfg) cfgBytes, err := jsonv1.Marshal(cfg)
if err != nil { if err != nil {
return false, fmt.Errorf("marshaling serve config: %w", err) return false, fmt.Errorf("marshaling serve config: %w", err)
} }
@ -573,7 +573,7 @@ func (r *HAIngressReconciler) maybeCleanup(ctx context.Context, hostname string,
// 5. Remove the Tailscale Service from the serve config for the ProxyGroup. // 5. Remove the Tailscale Service from the serve config for the ProxyGroup.
logger.Infof("Removing TailscaleService %q from serve config for ProxyGroup %q", hostname, pg) logger.Infof("Removing TailscaleService %q from serve config for ProxyGroup %q", hostname, pg)
delete(cfg.Services, serviceName) delete(cfg.Services, serviceName)
cfgBytes, err := json.Marshal(cfg) cfgBytes, err := jsonv1.Marshal(cfg)
if err != nil { if err != nil {
return false, fmt.Errorf("error marshaling serve config: %w", err) return false, fmt.Errorf("error marshaling serve config: %w", err)
} }
@ -622,7 +622,7 @@ func (r *HAIngressReconciler) proxyGroupServeConfig(ctx context.Context, pg stri
} }
cfg = &ipn.ServeConfig{} cfg = &ipn.ServeConfig{}
if len(cm.BinaryData[serveConfigKey]) != 0 { if len(cm.BinaryData[serveConfigKey]) != 0 {
if err := json.Unmarshal(cm.BinaryData[serveConfigKey], cfg); err != nil { if err := jsonv1.Unmarshal(cm.BinaryData[serveConfigKey], cfg); err != nil {
return nil, nil, fmt.Errorf("error unmarshaling ingress serve config %v: %w", cm.BinaryData[serveConfigKey], err) return nil, nil, fmt.Errorf("error unmarshaling ingress serve config %v: %w", cm.BinaryData[serveConfigKey], err)
} }
} }
@ -733,7 +733,7 @@ func (r *HAIngressReconciler) cleanupTailscaleService(ctx context.Context, svc *
} }
o.OwnerRefs = slices.Delete(o.OwnerRefs, ix, ix+1) o.OwnerRefs = slices.Delete(o.OwnerRefs, ix, ix+1)
logger.Infof("Deleting Tailscale Service %q", svc.Name) logger.Infof("Deleting Tailscale Service %q", svc.Name)
json, err := json.Marshal(o) json, err := jsonv1.Marshal(o)
if err != nil { if err != nil {
return false, fmt.Errorf("error marshalling updated Tailscale Service owner reference: %w", err) return false, fmt.Errorf("error marshalling updated Tailscale Service owner reference: %w", err)
} }
@ -784,7 +784,7 @@ func (a *HAIngressReconciler) maybeUpdateAdvertiseServicesConfig(ctx context.Con
var updated bool var updated bool
for fileName, confB := range secret.Data { for fileName, confB := range secret.Data {
var conf ipn.ConfigVAlpha var conf ipn.ConfigVAlpha
if err := json.Unmarshal(confB, &conf); err != nil { if err := jsonv1.Unmarshal(confB, &conf); err != nil {
return fmt.Errorf("error unmarshalling ProxyGroup config: %w", err) return fmt.Errorf("error unmarshalling ProxyGroup config: %w", err)
} }
@ -804,7 +804,7 @@ func (a *HAIngressReconciler) maybeUpdateAdvertiseServicesConfig(ctx context.Con
} }
// Update the Secret. // Update the Secret.
confB, err := json.Marshal(conf) confB, err := jsonv1.Marshal(conf)
if err != nil { if err != nil {
return fmt.Errorf("error marshalling ProxyGroup config: %w", err) return fmt.Errorf("error marshalling ProxyGroup config: %w", err)
} }
@ -880,7 +880,7 @@ func ownerAnnotations(operatorID string, svc *tailscale.VIPService) (map[string]
} }
if svc == nil { if svc == nil {
c := ownerAnnotationValue{OwnerRefs: []OwnerRef{ref}} c := ownerAnnotationValue{OwnerRefs: []OwnerRef{ref}}
json, err := json.Marshal(c) json, err := jsonv1.Marshal(c)
if err != nil { if err != nil {
return nil, fmt.Errorf("[unexpected] unable to marshal Tailscale Service's owner annotation contents: %w, please report this", err) return nil, fmt.Errorf("[unexpected] unable to marshal Tailscale Service's owner annotation contents: %w, please report this", err)
} }
@ -902,7 +902,7 @@ func ownerAnnotations(operatorID string, svc *tailscale.VIPService) (map[string]
return nil, fmt.Errorf("Tailscale Service %s is owned by another resource: %#v; cannot be reused for an Ingress", svc.Name, o.OwnerRefs[0].Resource) return nil, fmt.Errorf("Tailscale Service %s is owned by another resource: %#v; cannot be reused for an Ingress", svc.Name, o.OwnerRefs[0].Resource)
} }
o.OwnerRefs = append(o.OwnerRefs, ref) o.OwnerRefs = append(o.OwnerRefs, ref)
json, err := json.Marshal(o) json, err := jsonv1.Marshal(o)
if err != nil { if err != nil {
return nil, fmt.Errorf("error marshalling updated owner references: %w", err) return nil, fmt.Errorf("error marshalling updated owner references: %w", err)
} }
@ -921,7 +921,7 @@ func parseOwnerAnnotation(tsSvc *tailscale.VIPService) (*ownerAnnotationValue, e
return nil, nil return nil, nil
} }
o := &ownerAnnotationValue{} o := &ownerAnnotationValue{}
if err := json.Unmarshal([]byte(tsSvc.Annotations[ownerAnnotation]), o); err != nil { if err := jsonv1.Unmarshal([]byte(tsSvc.Annotations[ownerAnnotation]), o); err != nil {
return nil, fmt.Errorf("error parsing Tailscale Service's %s annotation %q: %w", ownerAnnotation, tsSvc.Annotations[ownerAnnotation], err) return nil, fmt.Errorf("error parsing Tailscale Service's %s annotation %q: %w", ownerAnnotation, tsSvc.Annotations[ownerAnnotation], err)
} }
return o, nil return o, nil

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"maps" "maps"
"reflect" "reflect"
@ -166,7 +166,7 @@ func TestIngressPGReconciler(t *testing.T) {
} }
cfg := &ipn.ServeConfig{} cfg := &ipn.ServeConfig{}
if err := json.Unmarshal(cm.BinaryData[serveConfigKey], cfg); err != nil { if err := jsonv1.Unmarshal(cm.BinaryData[serveConfigKey], cfg); err != nil {
t.Fatalf("unmarshaling serve config: %v", err) t.Fatalf("unmarshaling serve config: %v", err)
} }
@ -215,7 +215,7 @@ func TestIngressPGReconciler(t *testing.T) {
} }
cfg = &ipn.ServeConfig{} cfg = &ipn.ServeConfig{}
if err := json.Unmarshal(cm.BinaryData[serveConfigKey], cfg); err != nil { if err := jsonv1.Unmarshal(cm.BinaryData[serveConfigKey], cfg); err != nil {
t.Fatalf("unmarshaling serve config: %v", err) t.Fatalf("unmarshaling serve config: %v", err)
} }
@ -771,7 +771,7 @@ func verifyServeConfig(t *testing.T, fc client.Client, serviceName string, wantH
} }
cfg := &ipn.ServeConfig{} cfg := &ipn.ServeConfig{}
if err := json.Unmarshal(cm.BinaryData["serve-config.json"], cfg); err != nil { if err := jsonv1.Unmarshal(cm.BinaryData["serve-config.json"], cfg); err != nil {
t.Fatalf("unmarshaling serve config: %v", err) t.Fatalf("unmarshaling serve config: %v", err)
} }
@ -814,7 +814,7 @@ func verifyTailscaledConfig(t *testing.T, fc client.Client, pgName string, expec
t.Helper() t.Helper()
var expected string var expected string
if expectedServices != nil && len(expectedServices) > 0 { if expectedServices != nil && len(expectedServices) > 0 {
expectedServicesJSON, err := json.Marshal(expectedServices) expectedServicesJSON, err := jsonv1.Marshal(expectedServices)
if err != nil { if err != nil {
t.Fatalf("marshaling expected services: %v", err) t.Fatalf("marshaling expected services: %v", err)
} }

@ -9,7 +9,7 @@
package main package main
import ( import (
"encoding/json" jsonv1 "encoding/json"
"testing" "testing"
"time" "time"
@ -150,7 +150,7 @@ func TestNameserverReconciler(t *testing.T) {
// Verify that when another actor sets ConfigMap data, it does not get // Verify that when another actor sets ConfigMap data, it does not get
// overwritten by nameserver reconciler. // overwritten by nameserver reconciler.
dnsRecords := &operatorutils.Records{Version: "v1alpha1", IP4: map[string][]string{"foo.ts.net": {"1.2.3.4"}}} dnsRecords := &operatorutils.Records{Version: "v1alpha1", IP4: map[string][]string{"foo.ts.net": {"1.2.3.4"}}}
bs, err := json.Marshal(dnsRecords) bs, err := jsonv1.Marshal(dnsRecords)
if err != nil { if err != nil {
t.Fatalf("error marshalling ConfigMap contents: %v", err) t.Fatalf("error marshalling ConfigMap contents: %v", err)
} }

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"testing" "testing"
"time" "time"
@ -1282,7 +1282,7 @@ func TestServiceProxyClassAnnotation(t *testing.T) {
slist := &corev1.SecretList{} slist := &corev1.SecretList{}
fc.List(context.Background(), slist, client.InNamespace("operator-ns")) fc.List(context.Background(), slist, client.InNamespace("operator-ns"))
for _, i := range slist.Items { for _, i := range slist.Items {
l, _ := json.Marshal(i.Labels) l, _ := jsonv1.Marshal(i.Labels)
t.Logf("found secret %q with labels %q ", i.Name, string(l)) t.Logf("found secret %q with labels %q ", i.Name, string(l))
} }

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
@ -796,7 +796,7 @@ func (r *ProxyGroupReconciler) ensureConfigSecretsCreated(ctx context.Context, p
} }
if !deviceAuthed { if !deviceAuthed {
existingCfg := conf.ConfigV1Alpha1{} existingCfg := conf.ConfigV1Alpha1{}
if err := json.Unmarshal(existingCfgSecret.Data[kubetypes.KubeAPIServerConfigFile], &existingCfg); err != nil { if err := jsonv1.Unmarshal(existingCfgSecret.Data[kubetypes.KubeAPIServerConfigFile], &existingCfg); err != nil {
return nil, fmt.Errorf("error unmarshalling existing config: %w", err) return nil, fmt.Errorf("error unmarshalling existing config: %w", err)
} }
if existingCfg.AuthKey != nil { if existingCfg.AuthKey != nil {
@ -835,7 +835,7 @@ func (r *ProxyGroupReconciler) ensureConfigSecretsCreated(ctx context.Context, p
if existingCfgSecret != nil { if existingCfgSecret != nil {
if k8sProxyCfg, ok := cfgSecret.Data[kubetypes.KubeAPIServerConfigFile]; ok { if k8sProxyCfg, ok := cfgSecret.Data[kubetypes.KubeAPIServerConfigFile]; ok {
k8sCfg := &conf.ConfigV1Alpha1{} k8sCfg := &conf.ConfigV1Alpha1{}
if err := json.Unmarshal(k8sProxyCfg, k8sCfg); err != nil { if err := jsonv1.Unmarshal(k8sProxyCfg, k8sCfg); err != nil {
return nil, fmt.Errorf("failed to unmarshal kube-apiserver config: %w", err) return nil, fmt.Errorf("failed to unmarshal kube-apiserver config: %w", err)
} }
@ -862,7 +862,7 @@ func (r *ProxyGroupReconciler) ensureConfigSecretsCreated(ctx context.Context, p
cfg.StaticEndpoints = endpoints[nodePortSvcName] cfg.StaticEndpoints = endpoints[nodePortSvcName]
} }
cfgB, err := json.Marshal(cfg) cfgB, err := jsonv1.Marshal(cfg)
if err != nil { if err != nil {
return nil, fmt.Errorf("error marshalling k8s-proxy config: %w", err) return nil, fmt.Errorf("error marshalling k8s-proxy config: %w", err)
} }
@ -881,7 +881,7 @@ func (r *ProxyGroupReconciler) ensureConfigSecretsCreated(ctx context.Context, p
} }
for cap, cfg := range configs { for cap, cfg := range configs {
cfgJSON, err := json.Marshal(cfg) cfgJSON, err := jsonv1.Marshal(cfg)
if err != nil { if err != nil {
return nil, fmt.Errorf("error marshalling tailscaled config: %w", err) return nil, fmt.Errorf("error marshalling tailscaled config: %w", err)
} }
@ -923,7 +923,7 @@ func (r *ProxyGroupReconciler) findStaticEndpoints(ctx context.Context, existing
oldConfB := existingCfgSecret.Data[tsoperator.TailscaledConfigFileName(106)] oldConfB := existingCfgSecret.Data[tsoperator.TailscaledConfigFileName(106)]
if len(oldConfB) > 0 { if len(oldConfB) > 0 {
var oldConf ipn.ConfigVAlpha var oldConf ipn.ConfigVAlpha
if err := json.Unmarshal(oldConfB, &oldConf); err == nil { if err := jsonv1.Unmarshal(oldConfB, &oldConf); err == nil {
currAddrs = oldConf.StaticEndpoints currAddrs = oldConf.StaticEndpoints
} else { } else {
logger.Debugf("failed to unmarshal tailscaled config from secret %q: %v", existingCfgSecret.Name, err) logger.Debugf("failed to unmarshal tailscaled config from secret %q: %v", existingCfgSecret.Name, err)
@ -1150,7 +1150,7 @@ func (r *ProxyGroupReconciler) getRunningProxies(ctx context.Context, pg *tsapi.
if ipsB := m.stateSecret.Data[kubetypes.KeyDeviceIPs]; len(ipsB) > 0 { if ipsB := m.stateSecret.Data[kubetypes.KeyDeviceIPs]; len(ipsB) > 0 {
ips := []string{} ips := []string{}
if err := json.Unmarshal(ipsB, &ips); err != nil { if err := jsonv1.Unmarshal(ipsB, &ips); err != nil {
return nil, fmt.Errorf("failed to extract device IPs from state Secret %q: %w", m.stateSecret.Name, err) return nil, fmt.Errorf("failed to extract device IPs from state Secret %q: %w", m.stateSecret.Name, err)
} }
device.TailnetIPs = ips device.TailnetIPs = ips

@ -6,7 +6,7 @@
package main package main
import ( import (
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"net/netip" "net/netip"
"slices" "slices"
@ -705,7 +705,7 @@ func TestProxyGroupWithStaticEndpoints(t *testing.T) {
config := &ipn.ConfigVAlpha{} config := &ipn.ConfigVAlpha{}
foundConfig := false foundConfig := false
for _, d := range sec.Data { for _, d := range sec.Data {
if err := json.Unmarshal(d, config); err == nil { if err := jsonv1.Unmarshal(d, config); err == nil {
foundConfig = true foundConfig = true
break break
} }
@ -1383,7 +1383,7 @@ func TestKubeAPIServerType_DoesNotOverwriteServicesConfig(t *testing.T) {
HealthCheckEnabled: opt.NewBool(true), HealthCheckEnabled: opt.NewBool(true),
}, },
} }
cfgB, err := json.Marshal(cfg) cfgB, err := jsonv1.Marshal(cfg)
if err != nil { if err != nil {
t.Fatalf("failed to marshal config: %v", err) t.Fatalf("failed to marshal config: %v", err)
} }
@ -1405,7 +1405,7 @@ func TestKubeAPIServerType_DoesNotOverwriteServicesConfig(t *testing.T) {
// then check the proxygroup reconciler doesn't overwrite it. // then check the proxygroup reconciler doesn't overwrite it.
cfg.APIServerProxy.ServiceName = ptr.To(tailcfg.ServiceName("svc:some-svc-name")) cfg.APIServerProxy.ServiceName = ptr.To(tailcfg.ServiceName("svc:some-svc-name"))
cfg.AdvertiseServices = []string{"svc:should-not-be-overwritten"} cfg.AdvertiseServices = []string{"svc:should-not-be-overwritten"}
cfgB, err = json.Marshal(cfg) cfgB, err = jsonv1.Marshal(cfg)
if err != nil { if err != nil {
t.Fatalf("failed to marshal config: %v", err) t.Fatalf("failed to marshal config: %v", err)
} }
@ -1433,7 +1433,7 @@ func TestIngressAdvertiseServicesConfigPreserved(t *testing.T) {
} }
existingServices := []string{"svc1", "svc2"} existingServices := []string{"svc1", "svc2"}
existingConfigBytes, err := json.Marshal(ipn.ConfigVAlpha{ existingConfigBytes, err := jsonv1.Marshal(ipn.ConfigVAlpha{
AdvertiseServices: existingServices, AdvertiseServices: existingServices,
Version: "should-get-overwritten", Version: "should-get-overwritten",
}) })
@ -1464,7 +1464,7 @@ func TestIngressAdvertiseServicesConfigPreserved(t *testing.T) {
}) })
expectReconciled(t, reconciler, "", pgName) expectReconciled(t, reconciler, "", pgName)
expectedConfigBytes, err := json.Marshal(ipn.ConfigVAlpha{ expectedConfigBytes, err := jsonv1.Marshal(ipn.ConfigVAlpha{
// Preserved. // Preserved.
AdvertiseServices: existingServices, AdvertiseServices: existingServices,
@ -1802,7 +1802,7 @@ func addNodeIDToStateSecrets(t *testing.T, fc client.WithWatch, pg *tsapi.ProxyG
t.Helper() t.Helper()
const key = "profile-abc" const key = "profile-abc"
for i := range pgReplicas(pg) { for i := range pgReplicas(pg) {
bytes, err := json.Marshal(map[string]any{ bytes, err := jsonv1.Marshal(map[string]any{
"Config": map[string]any{ "Config": map[string]any{
"NodeID": fmt.Sprintf("nodeid-%d", i), "NodeID": fmt.Sprintf("nodeid-%d", i),
}, },

@ -8,7 +8,7 @@ package main
import ( import (
"context" "context"
_ "embed" _ "embed"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
@ -417,7 +417,7 @@ func (a *tailscaleSTSReconciler) provisionSecrets(ctx context.Context, logger *z
var latestConfig ipn.ConfigVAlpha var latestConfig ipn.ConfigVAlpha
for key, val := range configs { for key, val := range configs {
fn := tsoperator.TailscaledConfigFileName(key) fn := tsoperator.TailscaledConfigFileName(key)
b, err := json.Marshal(val) b, err := jsonv1.Marshal(val)
if err != nil { if err != nil {
return nil, fmt.Errorf("error marshalling tailscaled config: %w", err) return nil, fmt.Errorf("error marshalling tailscaled config: %w", err)
} }
@ -430,7 +430,7 @@ func (a *tailscaleSTSReconciler) provisionSecrets(ctx context.Context, logger *z
} }
if stsC.ServeConfig != nil { if stsC.ServeConfig != nil {
j, err := json.Marshal(stsC.ServeConfig) j, err := jsonv1.Marshal(stsC.ServeConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -585,7 +585,7 @@ func deviceInfo(sec *corev1.Secret, podUID string, log *zap.SugaredLogger) (dev
} }
if rawDeviceIPs, ok := sec.Data[kubetypes.KeyDeviceIPs]; ok { if rawDeviceIPs, ok := sec.Data[kubetypes.KeyDeviceIPs]; ok {
ips := make([]string, 0) ips := make([]string, 0)
if err := json.Unmarshal(rawDeviceIPs, &ips); err != nil { if err := jsonv1.Unmarshal(rawDeviceIPs, &ips); err != nil {
return nil, err return nil, err
} }
dev.ips = ips dev.ips = ips
@ -1091,7 +1091,7 @@ func latestConfigFromSecret(s *corev1.Secret) (*ipn.ConfigVAlpha, error) {
var conf *ipn.ConfigVAlpha var conf *ipn.ConfigVAlpha
if latestStr != "" { if latestStr != "" {
conf = &ipn.ConfigVAlpha{} conf = &ipn.ConfigVAlpha{}
if err := json.Unmarshal([]byte(s.Data[latestStr]), conf); err != nil { if err := jsonv1.Unmarshal([]byte(s.Data[latestStr]), conf); err != nil {
return nil, fmt.Errorf("error unmarshaling tailscaled config from Secret %q in field %q: %w", s.Name, latestStr, err) return nil, fmt.Errorf("error unmarshaling tailscaled config from Secret %q in field %q: %w", s.Name, latestStr, err)
} }
} }

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
@ -317,7 +317,7 @@ func (r *HAServiceReconciler) maybeProvision(ctx context.Context, hostname strin
existingCfg := cfgs[serviceName.String()] existingCfg := cfgs[serviceName.String()]
if !reflect.DeepEqual(existingCfg, cfg) { if !reflect.DeepEqual(existingCfg, cfg) {
mak.Set(&cfgs, serviceName.String(), cfg) mak.Set(&cfgs, serviceName.String(), cfg)
cfgBytes, err := json.Marshal(cfgs) cfgBytes, err := jsonv1.Marshal(cfgs)
if err != nil { if err != nil {
return false, fmt.Errorf("error marshaling ingress config: %w", err) return false, fmt.Errorf("error marshaling ingress config: %w", err)
} }
@ -417,7 +417,7 @@ func (r *HAServiceReconciler) maybeCleanup(ctx context.Context, hostname string,
} }
logger.Infof("Removing Tailscale Service %q from ingress config for ProxyGroup %q", hostname, pgName) logger.Infof("Removing Tailscale Service %q from ingress config for ProxyGroup %q", hostname, pgName)
delete(cfgs, serviceName.String()) delete(cfgs, serviceName.String())
cfgBytes, err := json.Marshal(cfgs) cfgBytes, err := jsonv1.Marshal(cfgs)
if err != nil { if err != nil {
return false, fmt.Errorf("error marshaling ingress config: %w", err) return false, fmt.Errorf("error marshaling ingress config: %w", err)
} }
@ -470,7 +470,7 @@ func (r *HAServiceReconciler) maybeCleanupProxyGroup(ctx context.Context, proxyG
} }
if ingressConfigChanged { if ingressConfigChanged {
configBytes, err := json.Marshal(config) configBytes, err := jsonv1.Marshal(config)
if err != nil { if err != nil {
return false, fmt.Errorf("marshaling serve config: %w", err) return false, fmt.Errorf("marshaling serve config: %w", err)
} }
@ -573,7 +573,7 @@ func cleanupTailscaleService(ctx context.Context, tsClient tsClient, name tailcf
} }
o.OwnerRefs = slices.Delete(o.OwnerRefs, ix, ix+1) o.OwnerRefs = slices.Delete(o.OwnerRefs, ix, ix+1)
logger.Infof("Updating Tailscale Service %q", name) logger.Infof("Updating Tailscale Service %q", name)
json, err := json.Marshal(o) json, err := jsonv1.Marshal(o)
if err != nil { if err != nil {
return false, fmt.Errorf("error marshalling updated Tailscale Service owner reference: %w", err) return false, fmt.Errorf("error marshalling updated Tailscale Service owner reference: %w", err)
} }
@ -606,7 +606,7 @@ func (a *HAServiceReconciler) backendRoutesSetup(ctx context.Context, serviceNam
} }
gotCfgB := secret.Data[ingressservices.IngressConfigKey] gotCfgB := secret.Data[ingressservices.IngressConfigKey]
var gotCfgs ingressservices.Status var gotCfgs ingressservices.Status
if err := json.Unmarshal(gotCfgB, &gotCfgs); err != nil { if err := jsonv1.Unmarshal(gotCfgB, &gotCfgs); err != nil {
return false, fmt.Errorf("error unmarshalling ingress config: %w", err) return false, fmt.Errorf("error unmarshalling ingress config: %w", err)
} }
statusUpToDate, err := isCurrentStatus(gotCfgs, pod, logger) statusUpToDate, err := isCurrentStatus(gotCfgs, pod, logger)
@ -668,7 +668,7 @@ func (a *HAServiceReconciler) maybeUpdateAdvertiseServicesConfig(ctx context.Con
var updated bool var updated bool
for fileName, confB := range secret.Data { for fileName, confB := range secret.Data {
var conf ipn.ConfigVAlpha var conf ipn.ConfigVAlpha
if err := json.Unmarshal(confB, &conf); err != nil { if err := jsonv1.Unmarshal(confB, &conf); err != nil {
return fmt.Errorf("error unmarshalling ProxyGroup config: %w", err) return fmt.Errorf("error unmarshalling ProxyGroup config: %w", err)
} }
@ -701,7 +701,7 @@ func (a *HAServiceReconciler) maybeUpdateAdvertiseServicesConfig(ctx context.Con
conf.AdvertiseServices = append(conf.AdvertiseServices, serviceName.String()) conf.AdvertiseServices = append(conf.AdvertiseServices, serviceName.String())
} }
confB, err := json.Marshal(conf) confB, err := jsonv1.Marshal(conf)
if err != nil { if err != nil {
return fmt.Errorf("error marshalling ProxyGroup config: %w", err) return fmt.Errorf("error marshalling ProxyGroup config: %w", err)
} }
@ -770,7 +770,7 @@ func ingressSvcsConfigs(ctx context.Context, cl client.Client, proxyGroupName, t
} }
cfgs = ingressservices.Configs{} cfgs = ingressservices.Configs{}
if len(cm.BinaryData[ingressservices.IngressConfigKey]) != 0 { if len(cm.BinaryData[ingressservices.IngressConfigKey]) != 0 {
if err := json.Unmarshal(cm.BinaryData[ingressservices.IngressConfigKey], &cfgs); err != nil { if err := jsonv1.Unmarshal(cm.BinaryData[ingressservices.IngressConfigKey], &cfgs); err != nil {
return nil, nil, fmt.Errorf("error unmarshaling ingress services config %v: %w", cm.BinaryData[ingressservices.IngressConfigKey], err) return nil, nil, fmt.Errorf("error unmarshaling ingress services config %v: %w", cm.BinaryData[ingressservices.IngressConfigKey], err)
} }
} }

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"math/rand/v2" "math/rand/v2"
"net/netip" "net/netip"
@ -67,7 +67,7 @@ func TestServicePGReconciler(t *testing.T) {
} }
cfgs := ingressservices.Configs{} cfgs := ingressservices.Configs{}
if err := json.Unmarshal(cm.BinaryData[ingressservices.IngressConfigKey], &cfgs); err != nil { if err := jsonv1.Unmarshal(cm.BinaryData[ingressservices.IngressConfigKey], &cfgs); err != nil {
t.Fatalf("unmarshaling serve config: %v", err) t.Fatalf("unmarshaling serve config: %v", err)
} }
@ -368,7 +368,7 @@ func updateIngressConfigSecret(t *testing.T, fc client.Client, stateSecret *core
PodIPv4: "4.3.2.1", PodIPv4: "4.3.2.1",
} }
icJson, err := json.Marshal(ingressStatus) icJson, err := jsonv1.Marshal(ingressStatus)
if err != nil { if err != nil {
t.Fatalf("failed to json marshal ingress config: %s", err.Error()) t.Fatalf("failed to json marshal ingress config: %s", err.Error())
} }

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"net/netip" "net/netip"
@ -501,7 +501,7 @@ func expectedSecret(t *testing.T, cl client.Client, opts configOpts) *corev1.Sec
}, },
} }
if opts.serveConfig != nil { if opts.serveConfig != nil {
serveConfigBs, err := json.Marshal(opts.serveConfig) serveConfigBs, err := jsonv1.Marshal(opts.serveConfig)
if err != nil { if err != nil {
t.Fatalf("error marshalling serve config: %v", err) t.Fatalf("error marshalling serve config: %v", err)
} }
@ -548,12 +548,12 @@ func expectedSecret(t *testing.T, cl client.Client, opts configOpts) *corev1.Sec
} }
} }
conf.AdvertiseRoutes = routes conf.AdvertiseRoutes = routes
bnn, err := json.Marshal(conf) bnn, err := jsonv1.Marshal(conf)
if err != nil { if err != nil {
t.Fatalf("error marshalling tailscaled config") t.Fatalf("error marshalling tailscaled config")
} }
conf.AppConnector = nil conf.AppConnector = nil
bn, err := json.Marshal(conf) bn, err := jsonv1.Marshal(conf)
if err != nil { if err != nil {
t.Fatalf("error marshalling tailscaled config") t.Fatalf("error marshalling tailscaled config")
} }
@ -897,11 +897,11 @@ func removeAuthKeyIfExistsModifier(t *testing.T) func(s *corev1.Secret) {
t.Helper() t.Helper()
if len(secret.StringData["cap-95.hujson"]) != 0 { if len(secret.StringData["cap-95.hujson"]) != 0 {
conf := &ipn.ConfigVAlpha{} conf := &ipn.ConfigVAlpha{}
if err := json.Unmarshal([]byte(secret.StringData["cap-95.hujson"]), conf); err != nil { if err := jsonv1.Unmarshal([]byte(secret.StringData["cap-95.hujson"]), conf); err != nil {
t.Fatalf("error umarshalling 'cap-95.hujson' contents: %v", err) t.Fatalf("error umarshalling 'cap-95.hujson' contents: %v", err)
} }
conf.AuthKey = nil conf.AuthKey = nil
b, err := json.Marshal(conf) b, err := jsonv1.Marshal(conf)
if err != nil { if err != nil {
t.Fatalf("error marshalling 'cap-95.huson' contents: %v", err) t.Fatalf("error marshalling 'cap-95.huson' contents: %v", err)
} }
@ -909,11 +909,11 @@ func removeAuthKeyIfExistsModifier(t *testing.T) func(s *corev1.Secret) {
} }
if len(secret.StringData["cap-107.hujson"]) != 0 { if len(secret.StringData["cap-107.hujson"]) != 0 {
conf := &ipn.ConfigVAlpha{} conf := &ipn.ConfigVAlpha{}
if err := json.Unmarshal([]byte(secret.StringData["cap-107.hujson"]), conf); err != nil { if err := jsonv1.Unmarshal([]byte(secret.StringData["cap-107.hujson"]), conf); err != nil {
t.Fatalf("error umarshalling 'cap-107.hujson' contents: %v", err) t.Fatalf("error umarshalling 'cap-107.hujson' contents: %v", err)
} }
conf.AuthKey = nil conf.AuthKey = nil
b, err := json.Marshal(conf) b, err := jsonv1.Marshal(conf)
if err != nil { if err != nil {
t.Fatalf("error marshalling 'cap-107.huson' contents: %v", err) t.Fatalf("error marshalling 'cap-107.huson' contents: %v", err)
} }

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
@ -433,7 +433,7 @@ func getDevicePrefs(secret *corev1.Secret) (prefs prefs, ok bool, err error) {
if !ok { if !ok {
return prefs, false, nil return prefs, false, nil
} }
if err := json.Unmarshal(profileBytes, &prefs); err != nil { if err := jsonv1.Unmarshal(profileBytes, &prefs); err != nil {
return prefs, false, fmt.Errorf("failed to extract node profile info from state Secret %s: %w", secret.Name, err) return prefs, false, fmt.Errorf("failed to extract node profile info from state Secret %s: %w", secret.Name, err)
} }

@ -7,7 +7,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"strings" "strings"
"testing" "testing"
@ -180,7 +180,7 @@ func TestRecorder(t *testing.T) {
}) })
t.Run("populate_node_info_in_state_secret_and_see_it_appear_in_status", func(t *testing.T) { t.Run("populate_node_info_in_state_secret_and_see_it_appear_in_status", func(t *testing.T) {
bytes, err := json.Marshal(map[string]any{ bytes, err := jsonv1.Marshal(map[string]any{
"Config": map[string]any{ "Config": map[string]any{
"NodeID": "nodeid-123", "NodeID": "nodeid-123",
"UserProfile": map[string]any{ "UserProfile": map[string]any{

@ -5,7 +5,7 @@ package ippool
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"log" "log"
@ -68,7 +68,7 @@ func (ipp *ConsensusIPPool) IPForDomain(nid tailcfg.NodeID, domain string) (neti
ReuseDeadline: now.Add(-1 * ipp.unusedAddressLifetime), ReuseDeadline: now.Add(-1 * ipp.unusedAddressLifetime),
UpdatedAt: now, UpdatedAt: now,
} }
bs, err := json.Marshal(args) bs, err := jsonv1.Marshal(args)
if err != nil { if err != nil {
return netip.Addr{}, err return netip.Addr{}, err
} }
@ -86,7 +86,7 @@ func (ipp *ConsensusIPPool) IPForDomain(nid tailcfg.NodeID, domain string) (neti
return netip.Addr{}, result.Err return netip.Addr{}, result.Err
} }
var addr netip.Addr var addr netip.Addr
err = json.Unmarshal(result.Result, &addr) err = jsonv1.Unmarshal(result.Result, &addr)
return addr, err return addr, err
} }
@ -230,7 +230,7 @@ type readDomainForIPArgs struct {
// executeReadDomainForIP parses a readDomainForIP log entry and applies it. // executeReadDomainForIP parses a readDomainForIP log entry and applies it.
func (ipp *ConsensusIPPool) executeReadDomainForIP(bs []byte) tsconsensus.CommandResult { func (ipp *ConsensusIPPool) executeReadDomainForIP(bs []byte) tsconsensus.CommandResult {
var args readDomainForIPArgs var args readDomainForIPArgs
err := json.Unmarshal(bs, &args) err := jsonv1.Unmarshal(bs, &args)
if err != nil { if err != nil {
return tsconsensus.CommandResult{Err: err} return tsconsensus.CommandResult{Err: err}
} }
@ -249,7 +249,7 @@ func (ipp *ConsensusIPPool) applyReadDomainForIP(from tailcfg.NodeID, addr netip
} }
return ww.Domain return ww.Domain
}() }()
resultBs, err := json.Marshal(domain) resultBs, err := jsonv1.Marshal(domain)
return tsconsensus.CommandResult{Result: resultBs, Err: err} return tsconsensus.CommandResult{Result: resultBs, Err: err}
} }
@ -259,7 +259,7 @@ func (ipp *ConsensusIPPool) readDomainForIP(nid tailcfg.NodeID, addr netip.Addr)
NodeID: nid, NodeID: nid,
Addr: addr, Addr: addr,
} }
bs, err := json.Marshal(args) bs, err := jsonv1.Marshal(args)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -277,7 +277,7 @@ func (ipp *ConsensusIPPool) readDomainForIP(nid tailcfg.NodeID, addr netip.Addr)
return "", result.Err return "", result.Err
} }
var domain string var domain string
err = json.Unmarshal(result.Result, &domain) err = jsonv1.Unmarshal(result.Result, &domain)
return domain, err return domain, err
} }
@ -291,7 +291,7 @@ type markLastUsedArgs struct {
// executeMarkLastUsed parses a markLastUsed log entry and applies it. // executeMarkLastUsed parses a markLastUsed log entry and applies it.
func (ipp *ConsensusIPPool) executeMarkLastUsed(bs []byte) tsconsensus.CommandResult { func (ipp *ConsensusIPPool) executeMarkLastUsed(bs []byte) tsconsensus.CommandResult {
var args markLastUsedArgs var args markLastUsedArgs
err := json.Unmarshal(bs, &args) err := jsonv1.Unmarshal(bs, &args)
if err != nil { if err != nil {
return tsconsensus.CommandResult{Err: err} return tsconsensus.CommandResult{Err: err}
} }
@ -339,7 +339,7 @@ func (ipp *ConsensusIPPool) markLastUsed(nid tailcfg.NodeID, addr netip.Addr, do
Domain: domain, Domain: domain,
UpdatedAt: lastUsed, UpdatedAt: lastUsed,
} }
bs, err := json.Marshal(args) bs, err := jsonv1.Marshal(args)
if err != nil { if err != nil {
return err return err
} }
@ -369,7 +369,7 @@ type checkoutAddrArgs struct {
// executeCheckoutAddr parses a checkoutAddr raft log entry and applies it. // executeCheckoutAddr parses a checkoutAddr raft log entry and applies it.
func (ipp *ConsensusIPPool) executeCheckoutAddr(bs []byte) tsconsensus.CommandResult { func (ipp *ConsensusIPPool) executeCheckoutAddr(bs []byte) tsconsensus.CommandResult {
var args checkoutAddrArgs var args checkoutAddrArgs
err := json.Unmarshal(bs, &args) err := jsonv1.Unmarshal(bs, &args)
if err != nil { if err != nil {
return tsconsensus.CommandResult{Err: err} return tsconsensus.CommandResult{Err: err}
} }
@ -377,7 +377,7 @@ func (ipp *ConsensusIPPool) executeCheckoutAddr(bs []byte) tsconsensus.CommandRe
if err != nil { if err != nil {
return tsconsensus.CommandResult{Err: err} return tsconsensus.CommandResult{Err: err}
} }
resultBs, err := json.Marshal(addr) resultBs, err := jsonv1.Marshal(addr)
if err != nil { if err != nil {
return tsconsensus.CommandResult{Err: err} return tsconsensus.CommandResult{Err: err}
} }
@ -424,7 +424,7 @@ func (ipp *ConsensusIPPool) applyCheckoutAddr(nid tailcfg.NodeID, domain string,
// Apply is part of the raft.FSM interface. It takes an incoming log entry and applies it to the state. // Apply is part of the raft.FSM interface. It takes an incoming log entry and applies it to the state.
func (ipp *ConsensusIPPool) Apply(l *raft.Log) any { func (ipp *ConsensusIPPool) Apply(l *raft.Log) any {
var c tsconsensus.Command var c tsconsensus.Command
if err := json.Unmarshal(l.Data, &c); err != nil { if err := jsonv1.Unmarshal(l.Data, &c); err != nil {
panic(fmt.Sprintf("failed to unmarshal command: %s", err.Error())) panic(fmt.Sprintf("failed to unmarshal command: %s", err.Error()))
} }
switch c.Name { switch c.Name {

@ -5,7 +5,7 @@ package ippool
import ( import (
"bytes" "bytes"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"io" "io"
"net/netip" "net/netip"
@ -30,7 +30,7 @@ type FakeConsensus struct {
} }
func (c *FakeConsensus) ExecuteCommand(cmd tsconsensus.Command) (tsconsensus.CommandResult, error) { func (c *FakeConsensus) ExecuteCommand(cmd tsconsensus.Command) (tsconsensus.CommandResult, error) {
b, err := json.Marshal(cmd) b, err := jsonv1.Marshal(cmd)
if err != nil { if err != nil {
return tsconsensus.CommandResult{}, err return tsconsensus.CommandResult{}, err
} }
@ -345,7 +345,7 @@ func TestConsensusRestore(t *testing.T) {
} }
// restore the snapshot // restore the snapshot
bs, err := json.Marshal(snap) bs, err := jsonv1.Marshal(snap)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

@ -4,7 +4,7 @@
package ippool package ippool
import ( import (
"encoding/json" jsonv1 "encoding/json"
"io" "io"
"log" "log"
"maps" "maps"
@ -73,7 +73,7 @@ func (mipr *persistableIPRange) toIPRange() netipx.IPRange {
// - the FSM must discard all previous state before restoring // - the FSM must discard all previous state before restoring
func (ipp *ConsensusIPPool) Restore(rc io.ReadCloser) error { func (ipp *ConsensusIPPool) Restore(rc io.ReadCloser) error {
var snap fsmSnapshot var snap fsmSnapshot
if err := json.NewDecoder(rc).Decode(&snap); err != nil { if err := jsonv1.NewDecoder(rc).Decode(&snap); err != nil {
return err return err
} }
ipset, ppm, err := snap.getData() ipset, ppm, err := snap.getData()
@ -93,7 +93,7 @@ type fsmSnapshot struct {
// Persist is part of the raft.FSMSnapshot interface // Persist is part of the raft.FSMSnapshot interface
// According to the docs Persist may be called concurrently with Apply // According to the docs Persist may be called concurrently with Apply
func (f fsmSnapshot) Persist(sink raft.SnapshotSink) error { func (f fsmSnapshot) Persist(sink raft.SnapshotSink) error {
if err := json.NewEncoder(sink).Encode(f); err != nil { if err := jsonv1.NewEncoder(sink).Encode(f); err != nil {
log.Printf("Error encoding snapshot as JSON: %v", err) log.Printf("Error encoding snapshot as JSON: %v", err)
return sink.Cancel() return sink.Cancel()
} }

@ -8,7 +8,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"expvar" "expvar"
"flag" "flag"
@ -652,7 +652,7 @@ func httpClusterAdmin(ipp *ippool.ConsensusIPPool) http.Handler {
http.Error(w, "", http.StatusInternalServerError) http.Error(w, "", http.StatusInternalServerError)
return return
} }
if err := json.NewEncoder(w).Encode(c); err != nil { if err := jsonv1.NewEncoder(w).Encode(c); err != nil {
log.Printf("cluster admin http: error encoding raft configuration: %v", err) log.Printf("cluster admin http: error encoding raft configuration: %v", err)
} }
}) })
@ -664,7 +664,7 @@ func httpClusterAdmin(ipp *ippool.ConsensusIPPool) http.Handler {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
if err := json.NewEncoder(w).Encode(idx); err != nil { if err := jsonv1.NewEncoder(w).Encode(idx); err != nil {
log.Printf("cluster admin http: error encoding delete index: %v", err) log.Printf("cluster admin http: error encoding delete index: %v", err)
return return
} }

@ -27,7 +27,7 @@ package main
import ( import (
"cmp" "cmp"
"encoding/base64" "encoding/base64"
"encoding/json" jsonv1 "encoding/json"
"flag" "flag"
"fmt" "fmt"
"io" "io"
@ -305,7 +305,7 @@ func mustMakeNamesByAddr() map[netip.Addr]string {
Addrs []netip.Addr `json:"addresses"` Addrs []netip.Addr `json:"addresses"`
} `json:"devices"` } `json:"devices"`
} }
must.Do(json.Unmarshal(b, &m)) must.Do(jsonv1.Unmarshal(b, &m))
// Construct a unique mapping of Tailscale IP addresses to hostnames. // Construct a unique mapping of Tailscale IP addresses to hostnames.
// For brevity, we start with the first segment of the name and // For brevity, we start with the first segment of the name and

@ -5,7 +5,7 @@ package main
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"flag" "flag"
"fmt" "fmt"
"log" "log"
@ -144,7 +144,7 @@ func TestSNIProxyWithNetmapConfig(t *testing.T) {
}, },
}, },
} }
b, err := json.Marshal(config) b, err := jsonv1.Marshal(config)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

@ -9,7 +9,7 @@ import (
"cmp" "cmp"
"context" "context"
"crypto/tls" "crypto/tls"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
@ -80,7 +80,7 @@ func getDERPMap(ctx context.Context, url string) (*tailcfg.DERPMap, error) {
return nil, fmt.Errorf("non-200 derp map resp: %d", resp.StatusCode) return nil, fmt.Errorf("non-200 derp map resp: %d", resp.StatusCode)
} }
dm := tailcfg.DERPMap{} dm := tailcfg.DERPMap{}
err = json.NewDecoder(resp.Body).Decode(&dm) err = jsonv1.NewDecoder(resp.Body).Decode(&dm)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to decode derp map resp: %v", err) return nil, fmt.Errorf("failed to decode derp map resp: %v", err)
} }

@ -5,7 +5,7 @@ package cli
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"flag" "flag"
"fmt" "fmt"
"slices" "slices"
@ -52,11 +52,11 @@ https://tailscale.com/kb/1281/app-connectors
} }
func getAllOutput(ri *appctype.RouteInfo) (string, error) { func getAllOutput(ri *appctype.RouteInfo) (string, error) {
domains, err := json.MarshalIndent(ri.Domains, " ", " ") domains, err := jsonv1.MarshalIndent(ri.Domains, " ", " ")
if err != nil { if err != nil {
return "", err return "", err
} }
control, err := json.MarshalIndent(ri.Control, " ", " ") control, err := jsonv1.MarshalIndent(ri.Control, " ", " ")
if err != nil { if err != nil {
return "", err return "", err
} }
@ -131,7 +131,7 @@ func runAppcRoutesInfo(ctx context.Context, args []string) error {
} }
if appcRoutesArgs.domainMap { if appcRoutesArgs.domainMap {
domains, err := json.Marshal(routeInfo.Domains) domains, err := jsonv1.Marshal(routeInfo.Domains)
if err != nil { if err != nil {
return err return err
} }

@ -7,7 +7,7 @@ package cli
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
@ -505,7 +505,7 @@ type flagDoc struct {
func printJSONDocs(root *ffcli.Command) error { func printJSONDocs(root *ffcli.Command) error {
docs := jsonDocsWalk(root) docs := jsonDocsWalk(root)
return json.NewEncoder(os.Stdout).Encode(docs) return jsonv1.NewEncoder(os.Stdout).Encode(docs)
} }
func jsonDocsWalk(cmd *ffcli.Command) *commandDoc { func jsonDocsWalk(cmd *ffcli.Command) *commandDoc {

@ -6,7 +6,7 @@ package cli
import ( import (
"bytes" "bytes"
stdcmp "cmp" stdcmp "cmp"
"encoding/json" jsonv1 "encoding/json"
"flag" "flag"
"fmt" "fmt"
"io" "io"
@ -905,8 +905,8 @@ func TestPrefsFromUpArgs(t *testing.T) {
t.Fatal("tt.want is nil") t.Fatal("tt.want is nil")
} }
if !got.Equals(tt.want) { if !got.Equals(tt.want) {
jgot, _ := json.MarshalIndent(got, "", "\t") jgot, _ := jsonv1.MarshalIndent(got, "", "\t")
jwant, _ := json.MarshalIndent(tt.want, "", "\t") jwant, _ := jsonv1.MarshalIndent(tt.want, "", "\t")
if bytes.Equal(jgot, jwant) { if bytes.Equal(jgot, jwant) {
t.Logf("prefs differ only in non-JSON-visible ways (nil/non-nil zero-length arrays)") t.Logf("prefs differ only in non-JSON-visible ways (nil/non-nil zero-length arrays)")
} }

@ -7,7 +7,7 @@ package cli
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
@ -153,7 +153,7 @@ func listCerts(ctx context.Context, c synoAPICaller) ([]certificateInfo, error)
var payload struct { var payload struct {
Certificates []certificateInfo `json:"certificates"` Certificates []certificateInfo `json:"certificates"`
} }
if err := json.Unmarshal(rawData, &payload); err != nil { if err := jsonv1.Unmarshal(rawData, &payload); err != nil {
return nil, fmt.Errorf("decoding certificate list response payload: %w", err) return nil, fmt.Errorf("decoding certificate list response payload: %w", err)
} }
@ -179,7 +179,7 @@ func uploadCert(ctx context.Context, c synoAPICaller, certFile, keyFile string,
var payload struct { var payload struct {
NewID string `json:"id"` NewID string `json:"id"`
} }
if err := json.Unmarshal(rawData, &payload); err != nil { if err := jsonv1.Unmarshal(rawData, &payload); err != nil {
return fmt.Errorf("decoding certificate upload response payload: %w", err) return fmt.Errorf("decoding certificate upload response payload: %w", err)
} }
log.Printf("Tailnet Certificate uploaded with ID %q.", payload.NewID) log.Printf("Tailnet Certificate uploaded with ID %q.", payload.NewID)
@ -189,13 +189,13 @@ func uploadCert(ctx context.Context, c synoAPICaller, certFile, keyFile string,
} }
type synoAPICaller interface { type synoAPICaller interface {
Call(context.Context, string, string, map[string]string) (json.RawMessage, error) Call(context.Context, string, string, map[string]string) (jsonv1.RawMessage, error)
} }
type apiResponse struct { type apiResponse struct {
Success bool `json:"success"` Success bool `json:"success"`
Error *apiError `json:"error,omitempty"` Error *apiError `json:"error,omitempty"`
Data json.RawMessage `json:"data"` Data jsonv1.RawMessage `json:"data"`
} }
type apiError struct { type apiError struct {
@ -206,7 +206,7 @@ type apiError struct {
// synowebapiCommand implements synoAPICaller using the /usr/syno/bin/synowebapi binary. Must be run as root. // synowebapiCommand implements synoAPICaller using the /usr/syno/bin/synowebapi binary. Must be run as root.
type synowebapiCommand struct{} type synowebapiCommand struct{}
func (s synowebapiCommand) Call(ctx context.Context, api, method string, params map[string]string) (json.RawMessage, error) { func (s synowebapiCommand) Call(ctx context.Context, api, method string, params map[string]string) (jsonv1.RawMessage, error) {
args := []string{"--exec", fmt.Sprintf("api=%s", api), fmt.Sprintf("method=%s", method)} args := []string{"--exec", fmt.Sprintf("api=%s", api), fmt.Sprintf("method=%s", method)}
for k, v := range params { for k, v := range params {
@ -219,7 +219,7 @@ func (s synowebapiCommand) Call(ctx context.Context, api, method string, params
} }
var payload apiResponse var payload apiResponse
if err := json.Unmarshal(out, &payload); err != nil { if err := jsonv1.Unmarshal(out, &payload); err != nil {
return nil, fmt.Errorf("decoding response json from %q method of %q API: %w", method, api, err) return nil, fmt.Errorf("decoding response json from %q method of %q API: %w", method, api, err)
} }

@ -7,18 +7,18 @@ package cli
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"reflect" "reflect"
"testing" "testing"
) )
type fakeAPICaller struct { type fakeAPICaller struct {
Data json.RawMessage Data jsonv1.RawMessage
Error error Error error
} }
func (c fakeAPICaller) Call(_ context.Context, _, _ string, _ map[string]string) (json.RawMessage, error) { func (c fakeAPICaller) Call(_ context.Context, _, _ string, _ map[string]string) (jsonv1.RawMessage, error) {
return c.Data, c.Error return c.Data, c.Error
} }
@ -32,7 +32,7 @@ func Test_listCerts(t *testing.T) {
{ {
name: "normal response", name: "normal response",
caller: fakeAPICaller{ caller: fakeAPICaller{
Data: json.RawMessage(`{ Data: jsonv1.RawMessage(`{
"certificates" : [ "certificates" : [
{ {
"desc" : "Tailnet Certificate", "desc" : "Tailnet Certificate",
@ -123,7 +123,7 @@ func Test_listCerts(t *testing.T) {
}, },
{ {
name: "payload decode error", name: "payload decode error",
caller: fakeAPICaller{json.RawMessage("This isn't JSON!"), nil}, caller: fakeAPICaller{jsonv1.RawMessage("This isn't JSON!"), nil},
wantErr: true, wantErr: true,
}, },
} }

@ -9,7 +9,7 @@ import (
"cmp" "cmp"
"context" "context"
"encoding/binary" "encoding/binary"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
@ -387,7 +387,7 @@ func runGoBuildInfo(ctx context.Context, args []string) error {
if !ok { if !ok {
return errors.New("no Go build info") return errors.New("no Go build info")
} }
e := json.NewEncoder(os.Stdout) e := jsonv1.NewEncoder(os.Stdout)
e.SetIndent("", "\t") e.SetIndent("", "\t")
return e.Encode(bi) return e.Encode(bi)
} }
@ -453,7 +453,7 @@ func runDebug(ctx context.Context, args []string) error {
if err != nil { if err != nil {
fatalf("%v\n", err) fatalf("%v\n", err)
} }
e := json.NewEncoder(Stdout) e := jsonv1.NewEncoder(Stdout)
e.SetIndent("", "\t") e.SetIndent("", "\t")
e.Encode(wfs) e.Encode(wfs)
return nil return nil
@ -607,7 +607,7 @@ func runPrefs(ctx context.Context, args []string) error {
if prefsArgs.pretty { if prefsArgs.pretty {
outln(prefs.Pretty()) outln(prefs.Pretty())
} else { } else {
j, _ := json.MarshalIndent(prefs, "", "\t") j, _ := jsonv1.MarshalIndent(prefs, "", "\t")
outln(string(j)) outln(string(j))
} }
return nil return nil
@ -646,7 +646,7 @@ func runWatchIPN(ctx context.Context, args []string) error {
if !watchIPNArgs.netmap { if !watchIPNArgs.netmap {
n.NetMap = nil n.NetMap = nil
} }
j, _ := json.MarshalIndent(n, "", "\t") j, _ := jsonv1.MarshalIndent(n, "", "\t")
fmt.Printf("%s\n", j) fmt.Printf("%s\n", j)
} }
return nil return nil
@ -674,7 +674,7 @@ func runNetmap(ctx context.Context, args []string) error {
if err != nil { if err != nil {
return err return err
} }
j, _ := json.MarshalIndent(n.NetMap, "", "\t") j, _ := jsonv1.MarshalIndent(n.NetMap, "", "\t")
fmt.Printf("%s\n", j) fmt.Printf("%s\n", j)
return nil return nil
} }
@ -686,7 +686,7 @@ func runDERPMap(ctx context.Context, args []string) error {
"failed to get local derp map, instead `curl %s/derpmap/default`: %w", ipn.DefaultControlURL, err, "failed to get local derp map, instead `curl %s/derpmap/default`: %w", ipn.DefaultControlURL, err,
) )
} }
enc := json.NewEncoder(Stdout) enc := jsonv1.NewEncoder(Stdout)
enc.SetIndent("", "\t") enc.SetIndent("", "\t")
enc.Encode(dm) enc.Encode(dm)
return nil return nil
@ -701,7 +701,7 @@ func forcePreferDERP(ctx context.Context, args []string) error {
if err != nil { if err != nil {
return fmt.Errorf("expected exactly one integer argument: %w", err) return fmt.Errorf("expected exactly one integer argument: %w", err)
} }
b, err := json.Marshal(n) b, err := jsonv1.Marshal(n)
if err != nil { if err != nil {
return fmt.Errorf("failed to marshal DERP region: %w", err) return fmt.Errorf("failed to marshal DERP region: %w", err)
} }
@ -765,7 +765,7 @@ func runStat(ctx context.Context, args []string) error {
func runHostinfo(ctx context.Context, args []string) error { func runHostinfo(ctx context.Context, args []string) error {
hi := hostinfo.New() hi := hostinfo.New()
j, _ := json.MarshalIndent(hi, "", " ") j, _ := jsonv1.MarshalIndent(hi, "", " ")
Stdout.Write(j) Stdout.Write(j)
return nil return nil
} }
@ -789,7 +789,7 @@ func runDaemonLogs(ctx context.Context, args []string) error {
if err != nil { if err != nil {
return err return err
} }
d := json.NewDecoder(logs) d := jsonv1.NewDecoder(logs)
for { for {
var line struct { var line struct {
Text string `json:"text"` Text string `json:"text"`
@ -837,7 +837,7 @@ func runDaemonBusGraph(ctx context.Context, args []string) error {
} }
if daemonBusGraphArgs.format == "dot" { if daemonBusGraphArgs.format == "dot" {
var topics eventbus.DebugTopics var topics eventbus.DebugTopics
if err := json.Unmarshal(graph, &topics); err != nil { if err := jsonv1.Unmarshal(graph, &topics); err != nil {
return fmt.Errorf("unable to parse json: %w", err) return fmt.Errorf("unable to parse json: %w", err)
} }
fmt.Print(generateDOTGraph(topics.Topics)) fmt.Print(generateDOTGraph(topics.Topics))
@ -1019,7 +1019,7 @@ func runTS2021(ctx context.Context, args []string) error {
log.Printf("Status: %v", res.Status) log.Printf("Status: %v", res.Status)
return errors.New(res.Status) return errors.New(res.Status)
} }
if err := json.NewDecoder(res.Body).Decode(&keys); err != nil { if err := jsonv1.NewDecoder(res.Body).Decode(&keys); err != nil {
log.Printf("JSON: %v", err) log.Printf("JSON: %v", err)
return fmt.Errorf("decoding /keys JSON: %w", err) return fmt.Errorf("decoding /keys JSON: %w", err)
} }
@ -1061,7 +1061,7 @@ func runTS2021(ctx context.Context, args []string) error {
return fmt.Errorf("reading dial plan JSON file: %w", err) return fmt.Errorf("reading dial plan JSON file: %w", err)
} }
dialPlan = new(tailcfg.ControlDialPlan) dialPlan = new(tailcfg.ControlDialPlan)
if err := json.Unmarshal(b, dialPlan); err != nil { if err := jsonv1.Unmarshal(b, dialPlan); err != nil {
return fmt.Errorf("unmarshaling dial plan JSON file: %w", err) return fmt.Errorf("unmarshaling dial plan JSON file: %w", err)
} }
} else if ts2021Args.aceHost != "" { } else if ts2021Args.aceHost != "" {
@ -1203,7 +1203,7 @@ func runDebugDERP(ctx context.Context, args []string) error {
if err != nil { if err != nil {
return err return err
} }
fmt.Printf("%s\n", must.Get(json.MarshalIndent(st, "", " "))) fmt.Printf("%s\n", must.Get(jsonv1.MarshalIndent(st, "", " ")))
return nil return nil
} }
@ -1265,7 +1265,7 @@ func runPeerEndpointChanges(ctx context.Context, args []string) error {
} }
var dst bytes.Buffer var dst bytes.Buffer
if err := json.Indent(&dst, body, "", " "); err != nil { if err := jsonv1.Indent(&dst, body, "", " "); err != nil {
return fmt.Errorf("indenting returned JSON: %w", err) return fmt.Errorf("indenting returned JSON: %w", err)
} }
@ -1284,7 +1284,7 @@ func debugControlKnobs(ctx context.Context, args []string) error {
if err != nil { if err != nil {
return err return err
} }
e := json.NewEncoder(os.Stdout) e := jsonv1.NewEncoder(os.Stdout)
e.SetIndent("", " ") e.SetIndent("", " ")
e.Encode(v) e.Encode(v)
return nil return nil
@ -1379,7 +1379,7 @@ func runPeerRelayServers(ctx context.Context, args []string) error {
if err != nil { if err != nil {
return err return err
} }
e := json.NewEncoder(os.Stdout) e := jsonv1.NewEncoder(os.Stdout)
e.SetIndent("", " ") e.SetIndent("", " ")
e.Encode(v) e.Encode(v)
return nil return nil

@ -5,7 +5,7 @@ package cli
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"flag" "flag"
"fmt" "fmt"
"io" "io"
@ -135,9 +135,9 @@ func printReport(dm *tailcfg.DERPMap, report *netcheck.Report) error {
switch netcheckArgs.format { switch netcheckArgs.format {
case "": case "":
case "json": case "json":
j, err = json.MarshalIndent(report, "", "\t") j, err = jsonv1.MarshalIndent(report, "", "\t")
case "json-line": case "json-line":
j, err = json.Marshal(report) j, err = jsonv1.Marshal(report)
default: default:
return fmt.Errorf("unknown output format %q", netcheckArgs.format) return fmt.Errorf("unknown output format %q", netcheckArgs.format)
} }
@ -256,7 +256,7 @@ func prodDERPMap(ctx context.Context, httpc *http.Client) (*tailcfg.DERPMap, err
return nil, fmt.Errorf("fetch prodDERPMap: %v: %s", res.Status, b) return nil, fmt.Errorf("fetch prodDERPMap: %v: %s", res.Status, b)
} }
var derpMap tailcfg.DERPMap var derpMap tailcfg.DERPMap
if err = json.Unmarshal(b, &derpMap); err != nil { if err = jsonv1.Unmarshal(b, &derpMap); err != nil {
return nil, fmt.Errorf("fetch prodDERPMap: %w", err) return nil, fmt.Errorf("fetch prodDERPMap: %w", err)
} }
return &derpMap, nil return &derpMap, nil

@ -10,7 +10,7 @@ import (
"context" "context"
"crypto/rand" "crypto/rand"
"encoding/hex" "encoding/hex"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
@ -219,7 +219,7 @@ func runNetworkLockStatus(ctx context.Context, args []string) error {
} }
if nlStatusArgs.json { if nlStatusArgs.json {
enc := json.NewEncoder(os.Stdout) enc := jsonv1.NewEncoder(os.Stdout)
enc.SetIndent("", " ") enc.SetIndent("", " ")
return enc.Encode(st) return enc.Encode(st)
} }
@ -678,7 +678,7 @@ func nlDescribeUpdate(update ipnstate.NetworkLockUpdate, color bool) (string, er
default: default:
// Print a JSON encoding of the AUM as a fallback. // Print a JSON encoding of the AUM as a fallback.
e := json.NewEncoder(&stanza) e := jsonv1.NewEncoder(&stanza)
e.SetIndent("", "\t") e.SetIndent("", "\t")
if err := e.Encode(aum); err != nil { if err := e.Encode(aum); err != nil {
return "", err return "", err
@ -703,7 +703,7 @@ func runNetworkLockLog(ctx context.Context, args []string) error {
return fixTailscaledConnectError(err) return fixTailscaledConnectError(err)
} }
if nlLogArgs.json { if nlLogArgs.json {
enc := json.NewEncoder(Stdout) enc := jsonv1.NewEncoder(Stdout)
enc.SetIndent("", " ") enc.SetIndent("", " ")
return enc.Encode(updates) return enc.Encode(updates)
} }

@ -7,7 +7,7 @@ package cli
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
@ -238,7 +238,7 @@ func (e *serveEnv) runServe(ctx context.Context, args []string) error {
return err return err
} }
sc := new(ipn.ServeConfig) sc := new(ipn.ServeConfig)
if err := json.Unmarshal(valb, sc); err != nil { if err := jsonv1.Unmarshal(valb, sc); err != nil {
return fmt.Errorf("invalid JSON: %w", err) return fmt.Errorf("invalid JSON: %w", err)
} }
return e.lc.SetServeConfig(ctx, sc) return e.lc.SetServeConfig(ctx, sc)
@ -617,7 +617,7 @@ func (e *serveEnv) runServeStatus(ctx context.Context, args []string) error {
return err return err
} }
if e.json { if e.json {
j, err := json.MarshalIndent(sc, "", " ") j, err := jsonv1.MarshalIndent(sc, "", " ")
if err != nil { if err != nil {
return err return err
} }

@ -7,7 +7,7 @@ package cli
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
@ -368,7 +368,7 @@ func (e *serveEnv) runServeCombined(subcmd serveMode) execFunc {
return err return err
} }
sc := new(ipn.ServeConfig) sc := new(ipn.ServeConfig)
if err := json.Unmarshal(valb, sc); err != nil { if err := jsonv1.Unmarshal(valb, sc); err != nil {
return fmt.Errorf("invalid JSON: %w", err) return fmt.Errorf("invalid JSON: %w", err)
} }
return e.lc.SetServeConfig(ctx, sc) return e.lc.SetServeConfig(ctx, sc)
@ -755,7 +755,7 @@ func (e *serveEnv) runServeGetConfig(ctx context.Context, args []string) (err er
} }
mak.Set(&scf.Services, svcName, sdf) mak.Set(&scf.Services, svcName, sdf)
} }
j, err = json.MarshalIndent(scf, "", " ") j, err = jsonv1.MarshalIndent(scf, "", " ")
if err != nil { if err != nil {
return err return err
} }
@ -769,7 +769,7 @@ func (e *serveEnv) runServeGetConfig(ctx context.Context, args []string) (err er
return err return err
} }
sdf.Version = "0.0.1" sdf.Version = "0.0.1"
j, err = json.MarshalIndent(sdf, "", " ") j, err = jsonv1.MarshalIndent(sdf, "", " ")
if err != nil { if err != nil {
return err return err
} }

@ -6,7 +6,7 @@ package cli
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"net/netip" "net/netip"
"os" "os"
@ -966,8 +966,8 @@ func TestServeDevConfigMutations(t *testing.T) {
got = lc.config got = lc.config
} }
if !reflect.DeepEqual(got, st.want) { if !reflect.DeepEqual(got, st.want) {
gotbts, _ := json.MarshalIndent(got, "", "\t") gotbts, _ := jsonv1.MarshalIndent(got, "", "\t")
wantbts, _ := json.MarshalIndent(st.want, "", "\t") wantbts, _ := jsonv1.MarshalIndent(st.want, "", "\t")
t.Fatalf("step: %d, cmd: %v, diff:\n%s", i, st.command, cmp.Diff(string(gotbts), string(wantbts))) t.Fatalf("step: %d, cmd: %v, diff:\n%s", i, st.command, cmp.Diff(string(gotbts), string(wantbts)))
} }
@ -1484,7 +1484,7 @@ func TestMessageForPort(t *testing.T) {
netip.MustParseAddr("fd7a:115c:a1e0:ab12:4843:cd96:6565:6565"), netip.MustParseAddr("fd7a:115c:a1e0:ab12:4843:cd96:6565:6565"),
}, },
} }
svcIPMapJSON, _ := json.Marshal(svcIPMap) svcIPMapJSON, _ := jsonv1.Marshal(svcIPMap)
svcIPMapJSONRawMSG := tailcfg.RawMessage(svcIPMapJSON) svcIPMapJSONRawMSG := tailcfg.RawMessage(svcIPMapJSON)
tests := []struct { tests := []struct {

@ -6,7 +6,7 @@ package cli
import ( import (
"cmp" "cmp"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
@ -94,7 +94,7 @@ func runStatus(ctx context.Context, args []string) error {
} }
} }
} }
j, err := json.MarshalIndent(st, "", " ") j, err := jsonv1.MarshalIndent(st, "", " ")
if err != nil { if err != nil {
return err return err
} }

@ -7,7 +7,7 @@ package cli
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"flag" "flag"
"fmt" "fmt"
"os" "os"
@ -80,7 +80,7 @@ func runSysPolicyReload(ctx context.Context, args []string) error {
func printPolicySettings(policy *setting.Snapshot) { func printPolicySettings(policy *setting.Snapshot) {
if syspolicyArgs.json { if syspolicyArgs.json {
json, err := json.MarshalIndent(policy, "", "\t") json, err := jsonv1.MarshalIndent(policy, "", "\t")
if err != nil { if err != nil {
errf("syspolicy marshalling error: %v", err) errf("syspolicy marshalling error: %v", err)
} else { } else {

@ -6,7 +6,7 @@ package cli
import ( import (
"context" "context"
"encoding/base64" "encoding/base64"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
@ -729,7 +729,7 @@ func runUp(ctx context.Context, cmd string, args []string, upArgs upArgsT) (retE
} }
} }
data, err := json.MarshalIndent(js, "", "\t") data, err := jsonv1.MarshalIndent(js, "", "\t")
if err != nil { if err != nil {
printf("upOutputJSON marshalling error: %v", err) printf("upOutputJSON marshalling error: %v", err)
} else { } else {
@ -848,7 +848,7 @@ func checkUpWarnings(ctx context.Context) {
func printUpDoneJSON(state ipn.State, errorString string) { func printUpDoneJSON(state ipn.State, errorString string) {
js := &upOutputJSON{BackendState: state.String(), Error: errorString} js := &upOutputJSON{BackendState: state.String(), Error: errorString}
data, err := json.MarshalIndent(js, "", " ") data, err := jsonv1.MarshalIndent(js, "", " ")
if err != nil { if err != nil {
log.Printf("printUpDoneJSON marshalling error: %v", err) log.Printf("printUpDoneJSON marshalling error: %v", err)
} else { } else {

@ -5,7 +5,7 @@ package cli
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"flag" "flag"
"fmt" "fmt"
@ -69,7 +69,7 @@ func runVersion(ctx context.Context, args []string) error {
Meta: m, Meta: m,
Upstream: upstreamVer, Upstream: upstreamVer,
} }
e := json.NewEncoder(Stdout) e := jsonv1.NewEncoder(Stdout)
e.SetIndent("", "\t") e.SetIndent("", "\t")
return e.Encode(out) return e.Encode(out)
} }

@ -5,7 +5,7 @@ package cli
import ( import (
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
@ -47,7 +47,7 @@ func runWhoIs(ctx context.Context, args []string) error {
return err return err
} }
if whoIsArgs.json { if whoIsArgs.json {
ec := json.NewEncoder(Stdout) ec := jsonv1.NewEncoder(Stdout)
ec.SetIndent("", " ") ec.SetIndent("", " ")
ec.Encode(who) ec.Encode(who)
return nil return nil
@ -77,7 +77,7 @@ func runWhoIs(ctx context.Context, args []string) error {
// To make the output more readable, we have to reindent the JSON // To make the output more readable, we have to reindent the JSON
// values so they line up with the cap name. // values so they line up with the cap name.
if len(vals) > 0 { if len(vals) > 0 {
v, _ := json.MarshalIndent(vals, " ", " ") v, _ := jsonv1.MarshalIndent(vals, " ", " ")
printf(" - %s:\n", cap) printf(" - %s:\n", cap)
printf(" %s\n", v) printf(" %s\n", v)

@ -8,7 +8,7 @@ package main
import ( import (
"context" "context"
"crypto/tls" "crypto/tls"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
@ -103,7 +103,7 @@ func runMonitor(ctx context.Context, loop bool) error {
defer b.Close() defer b.Close()
dump := func(st *netmon.State) { dump := func(st *netmon.State) {
j, _ := json.MarshalIndent(st, "", " ") j, _ := jsonv1.MarshalIndent(st, "", " ")
os.Stderr.Write(j) os.Stderr.Write(j)
} }
mon, err := netmon.New(b, log.Printf) mon, err := netmon.New(b, log.Printf)
@ -232,7 +232,7 @@ func checkDerp(ctx context.Context, derpRegion string) (err error) {
return fmt.Errorf("fetch derp map: %v: %s", res.Status, b) return fmt.Errorf("fetch derp map: %v: %s", res.Status, b)
} }
var dmap tailcfg.DERPMap var dmap tailcfg.DERPMap
if err = json.Unmarshal(b, &dmap); err != nil { if err = jsonv1.Unmarshal(b, &dmap); err != nil {
return fmt.Errorf("fetch DERP map: %w", err) return fmt.Errorf("fetch DERP map: %w", err)
} }
getRegion := func() *tailcfg.DERPRegion { getRegion := func() *tailcfg.DERPRegion {

@ -21,7 +21,7 @@ package main // import "tailscale.com/cmd/tailscaled"
import ( import (
"bufio" "bufio"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -380,7 +380,7 @@ func beFirewallKillswitch() bool {
// Note(maisem): when local lan access toggled, tailscaled needs to // Note(maisem): when local lan access toggled, tailscaled needs to
// inform the firewall to let local routes through. The set of routes // inform the firewall to let local routes through. The set of routes
// is passed in via stdin encoded in json. // is passed in via stdin encoded in json.
dcd := json.NewDecoder(os.Stdin) dcd := jsonv1.NewDecoder(os.Stdin)
for { for {
var routes []netip.Prefix var routes []netip.Prefix
if err := dcd.Decode(&routes); err != nil { if err := dcd.Decode(&routes); err != nil {

@ -12,7 +12,7 @@ import (
"bytes" "bytes"
"cmp" "cmp"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -112,7 +112,7 @@ func runTests(ctx context.Context, attempt int, pt *packageTests, goTestArgs, te
resultMap := make(map[string]map[string]*testAttempt) // pkg -> test -> testAttempt resultMap := make(map[string]map[string]*testAttempt) // pkg -> test -> testAttempt
for s.Scan() { for s.Scan() {
var goOutput goTestOutput var goOutput goTestOutput
if err := json.Unmarshal(s.Bytes(), &goOutput); err != nil { if err := jsonv1.Unmarshal(s.Bytes(), &goOutput); err != nil {
return fmt.Errorf("failed to parse go test output %q: %w", s.Bytes(), err) return fmt.Errorf("failed to parse go test output %q: %w", s.Bytes(), err)
} }
pkg := cmp.Or( pkg := cmp.Or(
@ -265,7 +265,7 @@ func main() {
os.Exit(1) os.Exit(1)
} }
if thisRun.attempt > 1 { if thisRun.attempt > 1 {
j, _ := json.Marshal(thisRun.tests) j, _ := jsonv1.Marshal(thisRun.tests)
fmt.Printf("\n\nAttempt #%d: Retrying flaky tests:\n\nflakytest failures JSON: %s\n\n", thisRun.attempt, j) fmt.Printf("\n\nAttempt #%d: Retrying flaky tests:\n\nflakytest failures JSON: %s\n\n", thisRun.attempt, j)
} }
@ -326,7 +326,7 @@ func main() {
if len(fatalFailures) > 0 { if len(fatalFailures) > 0 {
tests := slicesx.MapKeys(fatalFailures) tests := slicesx.MapKeys(fatalFailures)
sort.Strings(tests) sort.Strings(tests)
j, _ := json.Marshal(tests) j, _ := jsonv1.Marshal(tests)
fmt.Printf("non-flakytest failures: %s\n", j) fmt.Printf("non-flakytest failures: %s\n", j)
} }
fmt.Println() fmt.Println()

@ -6,7 +6,7 @@
package main package main
import ( import (
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"log" "log"
"os" "os"
@ -77,12 +77,12 @@ func updateVersion() error {
if err != nil { if err != nil {
return fmt.Errorf("Could not standardize template package.json: %w", err) return fmt.Errorf("Could not standardize template package.json: %w", err)
} }
if err := json.Unmarshal(packageJSONBytes, &packageJSON); err != nil { if err := jsonv1.Unmarshal(packageJSONBytes, &packageJSON); err != nil {
return fmt.Errorf("Could not unmarshal package.json: %w", err) return fmt.Errorf("Could not unmarshal package.json: %w", err)
} }
packageJSON["version"] = version.Long() packageJSON["version"] = version.Long()
packageJSONBytes, err = json.MarshalIndent(packageJSON, "", " ") packageJSONBytes, err = jsonv1.MarshalIndent(packageJSON, "", " ")
if err != nil { if err != nil {
return fmt.Errorf("Could not marshal package.json: %w", err) return fmt.Errorf("Could not marshal package.json: %w", err)
} }

@ -6,7 +6,7 @@
package main package main
import ( import (
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"log" "log"
"os" "os"
@ -61,7 +61,7 @@ func runBuild() {
// which are awkward if we're running with a different cwd at serving time). // which are awkward if we're running with a different cwd at serving time).
func fixEsbuildMetadataPaths(metadataStr string) ([]byte, error) { func fixEsbuildMetadataPaths(metadataStr string) ([]byte, error) {
var metadata EsbuildMetadata var metadata EsbuildMetadata
if err := json.Unmarshal([]byte(metadataStr), &metadata); err != nil { if err := jsonv1.Unmarshal([]byte(metadataStr), &metadata); err != nil {
return nil, fmt.Errorf("Cannot parse metadata: %w", err) return nil, fmt.Errorf("Cannot parse metadata: %w", err)
} }
distAbsPath, err := filepath.Abs(*distDir) distAbsPath, err := filepath.Abs(*distDir)
@ -80,7 +80,7 @@ func fixEsbuildMetadataPaths(metadataStr string) ([]byte, error) {
delete(metadata.Outputs, outputPath) delete(metadata.Outputs, outputPath)
metadata.Outputs[outputRelPath] = output metadata.Outputs[outputRelPath] = output
} }
return json.Marshal(metadata) return jsonv1.Marshal(metadata)
} }
func precompressDist(fastCompression bool) error { func precompressDist(fastCompression bool) error {

@ -8,7 +8,7 @@ package main
import ( import (
"bytes" "bytes"
"embed" "embed"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"io" "io"
"io/fs" "io/fs"
@ -80,7 +80,7 @@ func generateServeIndex(distFS fs.FS) ([]byte, error) {
return nil, fmt.Errorf("Could not read esbuild-metadata.json: %w", err) return nil, fmt.Errorf("Could not read esbuild-metadata.json: %w", err)
} }
var esbuildMetadata EsbuildMetadata var esbuildMetadata EsbuildMetadata
if err := json.Unmarshal(esbuildMetadataBytes, &esbuildMetadata); err != nil { if err := jsonv1.Unmarshal(esbuildMetadataBytes, &esbuildMetadata); err != nil {
return nil, fmt.Errorf("Could not parse esbuild-metadata.json: %w", err) return nil, fmt.Errorf("Could not parse esbuild-metadata.json: %w", err)
} }
entryPointsToHashedDistPaths := make(map[string]string) entryPointsToHashedDistPaths := make(map[string]string)

@ -13,7 +13,7 @@ import (
"bytes" "bytes"
"context" "context"
"encoding/hex" "encoding/hex"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"log" "log"
"math/rand/v2" "math/rand/v2"
@ -291,7 +291,7 @@ func (i *jsIPN) run(jsCallbacks js.Value) {
}), }),
LockedOut: nm.TKAEnabled && nm.SelfNode.KeySignature().Len() == 0, LockedOut: nm.TKAEnabled && nm.SelfNode.KeySignature().Len() == 0,
} }
if jsonNetMap, err := json.Marshal(jsNetMap); err == nil { if jsonNetMap, err := jsonv1.Marshal(jsNetMap); err == nil {
jsCallbacks.Call("notifyNetMap", string(jsonNetMap)) jsCallbacks.Call("notifyNetMap", string(jsonNetMap))
} else { } else {
log.Printf("Could not generate JSON netmap: %v", err) log.Printf("Could not generate JSON netmap: %v", err)

@ -16,7 +16,7 @@ import (
"crypto/x509" "crypto/x509"
"encoding/base64" "encoding/base64"
"encoding/binary" "encoding/binary"
"encoding/json" jsonv1 "encoding/json"
"encoding/pem" "encoding/pem"
"errors" "errors"
"flag" "flag"
@ -223,7 +223,7 @@ func main() {
f, err := os.Open(clientsFilePath) f, err := os.Open(clientsFilePath)
if err == nil { if err == nil {
if err := json.NewDecoder(f).Decode(&srv.funnelClients); err != nil { if err := jsonv1.NewDecoder(f).Decode(&srv.funnelClients); err != nil {
log.Fatalf("could not parse %s: %v", clientsFilePath, err) log.Fatalf("could not parse %s: %v", clientsFilePath, err)
} }
f.Close() f.Close()
@ -694,7 +694,7 @@ func (s *idpServer) serveUserInfo(w http.ResponseWriter, r *http.Request) {
// Write the final result // Write the final result
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(userInfo); err != nil { if err := jsonv1.NewEncoder(w).Encode(userInfo); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
} }
} }
@ -810,14 +810,14 @@ func addClaimValue(sets map[string]map[string]struct{}, claim string, val any) {
// Returns the merged claims map or an error if any protected claim is violated or JSON (un)marshaling fails. // Returns the merged claims map or an error if any protected claim is violated or JSON (un)marshaling fails.
func withExtraClaims(v any, rules []capRule) (map[string]any, error) { func withExtraClaims(v any, rules []capRule) (map[string]any, error) {
// Marshal the static struct // Marshal the static struct
data, err := json.Marshal(v) data, err := jsonv1.Marshal(v)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Unmarshal into a generic map // Unmarshal into a generic map
var claimMap map[string]any var claimMap map[string]any
if err := json.Unmarshal(data, &claimMap); err != nil { if err := jsonv1.Unmarshal(data, &claimMap); err != nil {
return nil, err return nil, err
} }
@ -993,7 +993,7 @@ func (s *idpServer) serveToken(w http.ResponseWriter, r *http.Request) {
s.mu.Unlock() s.mu.Unlock()
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(oidcTokenResponse{ if err := jsonv1.NewEncoder(w).Encode(oidcTokenResponse{
AccessToken: at, AccessToken: at,
TokenType: "Bearer", TokenType: "Bearer",
ExpiresIn: 5 * 60, ExpiresIn: 5 * 60,
@ -1074,7 +1074,7 @@ func (s *idpServer) serveJWKS(w http.ResponseWriter, r *http.Request) {
} }
// TODO(maisem): maybe only marshal this once and reuse? // TODO(maisem): maybe only marshal this once and reuse?
// TODO(maisem): implement key rotation. // TODO(maisem): implement key rotation.
je := json.NewEncoder(w) je := jsonv1.NewEncoder(w)
je.SetIndent("", " ") je.SetIndent("", " ")
if err := je.Encode(jose.JSONWebKeySet{ if err := je.Encode(jose.JSONWebKeySet{
Keys: []jose.JSONWebKey{ Keys: []jose.JSONWebKey{
@ -1202,7 +1202,7 @@ func (s *idpServer) serveOpenIDConfig(w http.ResponseWriter, r *http.Request) {
} }
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
je := json.NewEncoder(w) je := jsonv1.NewEncoder(w)
je.SetIndent("", " ") je.SetIndent("", " ")
if err := je.Encode(openIDProviderMetadata{ if err := je.Encode(openIDProviderMetadata{
AuthorizationEndpoint: authorizeEndpoint, AuthorizationEndpoint: authorizeEndpoint,
@ -1261,7 +1261,7 @@ func (s *idpServer) serveClients(w http.ResponseWriter, r *http.Request) {
case "DELETE": case "DELETE":
s.serveDeleteClient(w, r, path) s.serveDeleteClient(w, r, path)
case "GET": case "GET":
json.NewEncoder(w).Encode(&funnelClient{ jsonv1.NewEncoder(w).Encode(&funnelClient{
ID: c.ID, ID: c.ID,
Name: c.Name, Name: c.Name,
Secret: "", Secret: "",
@ -1301,7 +1301,7 @@ func (s *idpServer) serveNewClient(w http.ResponseWriter, r *http.Request) {
delete(s.funnelClients, clientID) delete(s.funnelClients, clientID)
return return
} }
json.NewEncoder(w).Encode(newClient) jsonv1.NewEncoder(w).Encode(newClient)
} }
func (s *idpServer) serveGetClientsList(w http.ResponseWriter, r *http.Request) { func (s *idpServer) serveGetClientsList(w http.ResponseWriter, r *http.Request) {
@ -1320,7 +1320,7 @@ func (s *idpServer) serveGetClientsList(w http.ResponseWriter, r *http.Request)
}) })
} }
s.mu.Unlock() s.mu.Unlock()
json.NewEncoder(w).Encode(redactedClients) jsonv1.NewEncoder(w).Encode(redactedClients)
} }
func (s *idpServer) serveDeleteClient(w http.ResponseWriter, r *http.Request, clientID string) { func (s *idpServer) serveDeleteClient(w http.ResponseWriter, r *http.Request, clientID string) {
@ -1356,7 +1356,7 @@ func (s *idpServer) serveDeleteClient(w http.ResponseWriter, r *http.Request, cl
// otherwise uses oidc-funnel-clients.json. s.mu must be held while calling this. // otherwise uses oidc-funnel-clients.json. s.mu must be held while calling this.
func (s *idpServer) storeFunnelClientsLocked() error { func (s *idpServer) storeFunnelClientsLocked() error {
var buf bytes.Buffer var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(s.funnelClients); err != nil { if err := jsonv1.NewEncoder(&buf).Encode(s.funnelClients); err != nil {
return err return err
} }
@ -1421,7 +1421,7 @@ func (sk *signingKey) MarshalJSON() ([]byte, error) {
Bytes: x509.MarshalPKCS1PrivateKey(sk.k), Bytes: x509.MarshalPKCS1PrivateKey(sk.k),
} }
bts := pem.EncodeToMemory(&b) bts := pem.EncodeToMemory(&b)
return json.Marshal(rsaPrivateKeyJSONWrapper{ return jsonv1.Marshal(rsaPrivateKeyJSONWrapper{
Key: base64.URLEncoding.EncodeToString(bts), Key: base64.URLEncoding.EncodeToString(bts),
ID: sk.kid, ID: sk.kid,
}) })
@ -1429,7 +1429,7 @@ func (sk *signingKey) MarshalJSON() ([]byte, error) {
func (sk *signingKey) UnmarshalJSON(b []byte) error { func (sk *signingKey) UnmarshalJSON(b []byte) error {
var wrapper rsaPrivateKeyJSONWrapper var wrapper rsaPrivateKeyJSONWrapper
if err := json.Unmarshal(b, &wrapper); err != nil { if err := jsonv1.Unmarshal(b, &wrapper); err != nil {
return err return err
} }
if len(wrapper.Key) == 0 { if len(wrapper.Key) == 0 {

@ -19,7 +19,7 @@ package main
import ( import (
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -79,7 +79,7 @@ func normalizeMap(t *testing.T, m map[string]any) map[string]any {
func mustMarshalJSON(t *testing.T, v any) tailcfg.RawMessage { func mustMarshalJSON(t *testing.T, v any) tailcfg.RawMessage {
t.Helper() t.Helper()
b, err := json.Marshal(v) b, err := jsonv1.Marshal(v)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -461,13 +461,13 @@ func TestExtraClaims(t *testing.T) {
} }
// Marshal to JSON then unmarshal back to map[string]any // Marshal to JSON then unmarshal back to map[string]any
gotClaims, err := json.Marshal(claims) gotClaims, err := jsonv1.Marshal(claims)
if err != nil { if err != nil {
t.Errorf("json.Marshal(claims) error = %v", err) t.Errorf("json.Marshal(claims) error = %v", err)
} }
var gotClaimsMap map[string]any var gotClaimsMap map[string]any
if err := json.Unmarshal(gotClaims, &gotClaimsMap); err != nil { if err := jsonv1.Unmarshal(gotClaims, &gotClaimsMap); err != nil {
t.Fatalf("json.Unmarshal(gotClaims) error = %v", err) t.Fatalf("json.Unmarshal(gotClaims) error = %v", err)
} }
@ -671,7 +671,7 @@ func TestServeToken(t *testing.T) {
var resp struct { var resp struct {
IDToken string `json:"id_token"` IDToken string `json:"id_token"`
} }
if err := json.Unmarshal(rr.Body.Bytes(), &resp); err != nil { if err := jsonv1.Unmarshal(rr.Body.Bytes(), &resp); err != nil {
t.Fatalf("failed to unmarshal response: %v", err) t.Fatalf("failed to unmarshal response: %v", err)
} }
@ -861,7 +861,7 @@ func TestExtraUserInfo(t *testing.T) {
} }
var resp map[string]any var resp map[string]any
if err := json.Unmarshal(rr.Body.Bytes(), &resp); err != nil { if err := jsonv1.Unmarshal(rr.Body.Bytes(), &resp); err != nil {
t.Fatalf("failed to parse JSON response: %v", err) t.Fatalf("failed to parse JSON response: %v", err)
} }
@ -898,7 +898,7 @@ func TestFunnelClientsPersistence(t *testing.T) {
}, },
} }
testData, err := json.Marshal(testClients) testData, err := jsonv1.Marshal(testClients)
if err != nil { if err != nil {
t.Fatalf("failed to marshal test data: %v", err) t.Fatalf("failed to marshal test data: %v", err)
} }
@ -915,7 +915,7 @@ func TestFunnelClientsPersistence(t *testing.T) {
srv.funnelClients = make(map[string]*funnelClient) srv.funnelClients = make(map[string]*funnelClient)
f, err := os.Open(tmpFile) f, err := os.Open(tmpFile)
if err == nil { if err == nil {
if err := json.NewDecoder(f).Decode(&srv.funnelClients); err != nil { if err := jsonv1.NewDecoder(f).Decode(&srv.funnelClients); err != nil {
t.Fatalf("could not parse %s: %v", tmpFile, err) t.Fatalf("could not parse %s: %v", tmpFile, err)
} }
f.Close() f.Close()
@ -950,7 +950,7 @@ func TestFunnelClientsPersistence(t *testing.T) {
srv.funnelClients = make(map[string]*funnelClient) srv.funnelClients = make(map[string]*funnelClient)
f, err := os.Open(nonExistentFile) f, err := os.Open(nonExistentFile)
if err == nil { if err == nil {
if err := json.NewDecoder(f).Decode(&srv.funnelClients); err != nil { if err := jsonv1.NewDecoder(f).Decode(&srv.funnelClients); err != nil {
t.Fatalf("could not parse %s: %v", nonExistentFile, err) t.Fatalf("could not parse %s: %v", nonExistentFile, err)
} }
f.Close() f.Close()
@ -982,7 +982,7 @@ func TestFunnelClientsPersistence(t *testing.T) {
} }
// Save clients to file (simulating saveFunnelClients) // Save clients to file (simulating saveFunnelClients)
data, err := json.Marshal(srv1.funnelClients) data, err := jsonv1.Marshal(srv1.funnelClients)
if err != nil { if err != nil {
t.Fatalf("failed to marshal clients: %v", err) t.Fatalf("failed to marshal clients: %v", err)
} }
@ -995,7 +995,7 @@ func TestFunnelClientsPersistence(t *testing.T) {
srv2.funnelClients = make(map[string]*funnelClient) srv2.funnelClients = make(map[string]*funnelClient)
f, err := os.Open(tmpFile2) f, err := os.Open(tmpFile2)
if err == nil { if err == nil {
if err := json.NewDecoder(f).Decode(&srv2.funnelClients); err != nil { if err := jsonv1.NewDecoder(f).Decode(&srv2.funnelClients); err != nil {
t.Fatalf("could not parse %s: %v", tmpFile2, err) t.Fatalf("could not parse %s: %v", tmpFile2, err)
} }
f.Close() f.Close()
@ -1255,7 +1255,7 @@ func TestMigrateOAuthClients(t *testing.T) {
// Setup old file if needed // Setup old file if needed
if tt.setupOldFile { if tt.setupOldFile {
oldData, err := json.Marshal(tt.oldFileContent) oldData, err := jsonv1.Marshal(tt.oldFileContent)
if err != nil { if err != nil {
t.Fatalf("failed to marshal old file content: %v", err) t.Fatalf("failed to marshal old file content: %v", err)
} }
@ -1267,7 +1267,7 @@ func TestMigrateOAuthClients(t *testing.T) {
// Setup new file if needed // Setup new file if needed
if tt.setupNewFile { if tt.setupNewFile {
newData, err := json.Marshal(tt.newFileContent) newData, err := jsonv1.Marshal(tt.newFileContent)
if err != nil { if err != nil {
t.Fatalf("failed to marshal new file content: %v", err) t.Fatalf("failed to marshal new file content: %v", err)
} }
@ -1309,7 +1309,7 @@ func TestMigrateOAuthClients(t *testing.T) {
} }
var clients map[string]*funnelClient var clients map[string]*funnelClient
if err := json.Unmarshal(data, &clients); err != nil { if err := jsonv1.Unmarshal(data, &clients); err != nil {
t.Fatalf("failed to unmarshal new file: %v", err) t.Fatalf("failed to unmarshal new file: %v", err)
} }
@ -1854,7 +1854,7 @@ func TestServeTokenWithClientValidation(t *testing.T) {
ExpiresIn int `json:"expires_in"` ExpiresIn int `json:"expires_in"`
} }
if err := json.Unmarshal(rr.Body.Bytes(), &resp); err != nil { if err := jsonv1.Unmarshal(rr.Body.Bytes(), &resp); err != nil {
t.Fatalf("failed to unmarshal response: %v", err) t.Fatalf("failed to unmarshal response: %v", err)
} }
@ -2035,7 +2035,7 @@ func TestServeUserInfoWithClientValidation(t *testing.T) {
} }
var resp map[string]any var resp map[string]any
if err := json.Unmarshal(rr.Body.Bytes(), &resp); err != nil { if err := jsonv1.Unmarshal(rr.Body.Bytes(), &resp); err != nil {
t.Fatalf("failed to parse JSON response: %v", err) t.Fatalf("failed to parse JSON response: %v", err)
} }

@ -10,7 +10,7 @@ import (
"crypto" "crypto"
"crypto/sha256" "crypto/sha256"
"encoding/binary" "encoding/binary"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -379,7 +379,7 @@ func (c *Direct) SetHostinfo(hi *tailcfg.Hostinfo) bool {
return false return false
} }
c.hostinfo = hi.Clone() c.hostinfo = hi.Clone()
j, _ := json.Marshal(c.hostinfo) j, _ := jsonv1.Marshal(c.hostinfo)
c.logf("[v1] HostInfo: %s", j) c.logf("[v1] HostInfo: %s", j)
return true return true
} }
@ -681,7 +681,7 @@ func (c *Direct) doLogin(ctx context.Context, opt loginOpt) (mustRegen bool, new
} }
} }
if DevKnob.DumpRegister() { if DevKnob.DumpRegister() {
j, _ := json.MarshalIndent(request, "", "\t") j, _ := jsonv1.MarshalIndent(request, "", "\t")
c.logf("RegisterRequest: %s", j) c.logf("RegisterRequest: %s", j)
} }
@ -722,7 +722,7 @@ func (c *Direct) doLogin(ctx context.Context, opt loginOpt) (mustRegen bool, new
return regen, opt.URL, nil, fmt.Errorf("register request: %v", err) return regen, opt.URL, nil, fmt.Errorf("register request: %v", err)
} }
if DevKnob.DumpRegister() { if DevKnob.DumpRegister() {
j, _ := json.MarshalIndent(resp, "", "\t") j, _ := jsonv1.MarshalIndent(resp, "", "\t")
c.logf("RegisterResponse: %s", j) c.logf("RegisterResponse: %s", j)
} }
@ -1257,7 +1257,7 @@ func decode(res *http.Response, v any) error {
if res.StatusCode != 200 { if res.StatusCode != 200 {
return fmt.Errorf("%d: %v", res.StatusCode, string(msg)) return fmt.Errorf("%d: %v", res.StatusCode, string(msg))
} }
return json.Unmarshal(msg, v) return jsonv1.Unmarshal(msg, v)
} }
var jsonEscapedZero = []byte(`\u0000`) var jsonEscapedZero = []byte(`\u0000`)
@ -1281,14 +1281,14 @@ func (sess *mapSession) decodeMsg(compressedMsg []byte, v *tailcfg.MapResponse)
if DevKnob.DumpNetMaps() { if DevKnob.DumpNetMaps() {
var buf bytes.Buffer var buf bytes.Buffer
json.Indent(&buf, b, "", " ") jsonv1.Indent(&buf, b, "", " ")
log.Printf("MapResponse: %s", buf.Bytes()) log.Printf("MapResponse: %s", buf.Bytes())
} }
if bytes.Contains(b, jsonEscapedZero) { if bytes.Contains(b, jsonEscapedZero) {
log.Printf("[unexpected] zero byte in controlclient.Direct.decodeMsg into %T: %q", v, b) log.Printf("[unexpected] zero byte in controlclient.Direct.decodeMsg into %T: %q", v, b)
} }
if err := json.Unmarshal(b, v); err != nil { if err := jsonv1.Unmarshal(b, v); err != nil {
return fmt.Errorf("response: %v", err) return fmt.Errorf("response: %v", err)
} }
if v.KeepAlive && string(b) == justKeepAliveStr { if v.KeepAlive && string(b) == justKeepAliveStr {
@ -1300,7 +1300,7 @@ func (sess *mapSession) decodeMsg(compressedMsg []byte, v *tailcfg.MapResponse)
// encode JSON encodes v as JSON, logging tailcfg.MapRequest values if // encode JSON encodes v as JSON, logging tailcfg.MapRequest values if
// debugMap is set. // debugMap is set.
func encode(v any) ([]byte, error) { func encode(v any) ([]byte, error) {
b, err := json.Marshal(v) b, err := jsonv1.Marshal(v)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1331,7 +1331,7 @@ func loadServerPubKeys(ctx context.Context, httpc *http.Client, serverURL string
return nil, fmt.Errorf("fetch control key: %v", res.Status) return nil, fmt.Errorf("fetch control key: %v", res.Status)
} }
var out tailcfg.OverTLSPublicKeyResponse var out tailcfg.OverTLSPublicKeyResponse
jsonErr := json.Unmarshal(b, &out) jsonErr := jsonv1.Unmarshal(b, &out)
if jsonErr == nil { if jsonErr == nil {
return &out, nil return &out, nil
} }
@ -1568,7 +1568,7 @@ func (c *Direct) setDNSNoise(ctx context.Context, req *tailcfg.SetDNSRequest) er
return fmt.Errorf("set-dns response: %v, %.200s", res.Status, strings.TrimSpace(string(msg))) return fmt.Errorf("set-dns response: %v, %.200s", res.Status, strings.TrimSpace(string(msg)))
} }
var setDNSRes tailcfg.SetDNSResponse var setDNSRes tailcfg.SetDNSResponse
if err := json.NewDecoder(res.Body).Decode(&setDNSRes); err != nil { if err := jsonv1.NewDecoder(res.Body).Decode(&setDNSRes); err != nil {
c.logf("error decoding SetDNSResponse: %v", err) c.logf("error decoding SetDNSResponse: %v", err)
return fmt.Errorf("set-dns-response: %w", err) return fmt.Errorf("set-dns-response: %w", err)
} }
@ -1635,7 +1635,7 @@ func postPingResult(start time.Time, logf logger.Logf, c *http.Client, pr *tailc
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel() defer cancel()
jsonPingRes, err := json.Marshal(res) jsonPingRes, err := jsonv1.Marshal(res)
if err != nil { if err != nil {
return err return err
} }

@ -4,7 +4,7 @@
package controlclient package controlclient
import ( import (
"encoding/json" jsonv1 "encoding/json"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"net/netip" "net/netip"
@ -134,7 +134,7 @@ func TestTsmpPing(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close() defer r.Body.Close()
body := new(ipnstate.PingResult) body := new(ipnstate.PingResult)
if err := json.NewDecoder(r.Body).Decode(body); err != nil { if err := jsonv1.NewDecoder(r.Body).Decode(body); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if pingRes.IP != body.IP { if pingRes.IP != body.IP {

@ -8,7 +8,7 @@ import (
"context" "context"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"encoding/json" jsonv1 "encoding/json"
"io" "io"
"maps" "maps"
"net" "net"
@ -598,7 +598,7 @@ func (ms *mapSession) patchifyPeersChanged(resp *tailcfg.MapResponse) {
if p, ok := ms.patchifyPeer(n); ok { if p, ok := ms.patchifyPeer(n); ok {
patchifiedPeer.Add(1) patchifiedPeer.Add(1)
if debugPatchifyPeer() { if debugPatchifyPeer() {
patchj, _ := json.Marshal(p) patchj, _ := jsonv1.Marshal(p)
ms.logf("debug: patchifyPeer[ID=%v]: %s", n.ID, patchj) ms.logf("debug: patchifyPeer[ID=%v]: %s", n.ID, patchj)
} }
if p != nil { if p != nil {

@ -6,7 +6,7 @@ package controlclient
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"maps" "maps"
"net/netip" "net/netip"
@ -524,7 +524,7 @@ func TestNetmapForResponse(t *testing.T) {
t.Fatal("nil Node in 1st netmap") t.Fatal("nil Node in 1st netmap")
} }
if !reflect.DeepEqual(nm1.SelfNode, wantNode) { if !reflect.DeepEqual(nm1.SelfNode, wantNode) {
j, _ := json.Marshal(nm1.SelfNode) j, _ := jsonv1.Marshal(nm1.SelfNode)
t.Errorf("Node mismatch in 1st netmap; got: %s", j) t.Errorf("Node mismatch in 1st netmap; got: %s", j)
} }
@ -534,7 +534,7 @@ func TestNetmapForResponse(t *testing.T) {
t.Fatal("nil Node in 1st netmap") t.Fatal("nil Node in 1st netmap")
} }
if !reflect.DeepEqual(nm2.SelfNode, wantNode) { if !reflect.DeepEqual(nm2.SelfNode, wantNode) {
j, _ := json.Marshal(nm2.SelfNode) j, _ := jsonv1.Marshal(nm2.SelfNode)
t.Errorf("Node mismatch in 2nd netmap; got: %s", j) t.Errorf("Node mismatch in 2nd netmap; got: %s", j)
} }
}) })
@ -1002,7 +1002,7 @@ func TestPatchifyPeersChanged(t *testing.T) {
ms := newTestMapSession(t, nu) ms := newTestMapSession(t, nu)
ms.updateStateFromResponse(tt.mr0) ms.updateStateFromResponse(tt.mr0)
mr1 := new(tailcfg.MapResponse) mr1 := new(tailcfg.MapResponse)
must.Do(json.Unmarshal(must.Get(json.Marshal(tt.mr1)), mr1)) must.Do(jsonv1.Unmarshal(must.Get(jsonv1.Marshal(tt.mr1)), mr1))
ms.patchifyPeersChanged(mr1) ms.patchifyPeersChanged(mr1)
opts := []cmp.Option{ opts := []cmp.Option{
cmp.Comparer(func(a, b netip.AddrPort) bool { return a == b }), cmp.Comparer(func(a, b netip.AddrPort) bool { return a == b }),
@ -1450,7 +1450,7 @@ func TestNetmapForMapResponseForDebug(t *testing.T) {
func TestLearnZstdOfKeepAlive(t *testing.T) { func TestLearnZstdOfKeepAlive(t *testing.T) {
keepAliveMsgZstd := (func() []byte { keepAliveMsgZstd := (func() []byte {
msg := must.Get(json.Marshal(tailcfg.MapResponse{ msg := must.Get(jsonv1.Marshal(tailcfg.MapResponse{
KeepAlive: true, KeepAlive: true,
})) }))
return zstdframe.AppendEncode(nil, msg, zstdframe.FastestCompression) return zstdframe.AppendEncode(nil, msg, zstdframe.FastestCompression)

@ -4,7 +4,7 @@
package controlclient package controlclient
import ( import (
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
"reflect" "reflect"
@ -117,7 +117,7 @@ func (s *Status) Equal(s2 *Status) bool {
} }
func (s Status) String() string { func (s Status) String() string {
b, err := json.MarshalIndent(s, "", "\t") b, err := jsonv1.MarshalIndent(s, "", "\t")
if err != nil { if err != nil {
panic(err) panic(err)
} }

@ -7,7 +7,7 @@ import (
"bytes" "bytes"
"cmp" "cmp"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"log" "log"
@ -291,7 +291,7 @@ func (nc *Client) Post(ctx context.Context, path string, nodeKey key.NodePublic,
} }
func (nc *Client) DoWithBody(ctx context.Context, method, path string, nodeKey key.NodePublic, body any) (*http.Response, error) { func (nc *Client) DoWithBody(ctx context.Context, method, path string, nodeKey key.NodePublic, body any) (*http.Response, error) {
jbody, err := json.Marshal(body) jbody, err := jsonv1.Marshal(body)
if err != nil { if err != nil {
return nil, err return nil, err
} }

@ -6,7 +6,7 @@ package ts2021
import ( import (
"context" "context"
"encoding/binary" "encoding/binary"
"encoding/json" jsonv1 "encoding/json"
"io" "io"
"math" "math"
"net/http" "net/http"
@ -323,7 +323,7 @@ func (up *Upgrader) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if !up.sendEarlyPayload { if !up.sendEarlyPayload {
return nil return nil
} }
earlyJSON, err := json.Marshal(&tailcfg.EarlyNoise{ earlyJSON, err := jsonv1.Marshal(&tailcfg.EarlyNoise{
NodeKeyChallenge: up.challenge.Public(), NodeKeyChallenge: up.challenge.Public(),
}) })
if err != nil { if err != nil {

@ -10,7 +10,7 @@ import (
"bytes" "bytes"
"context" "context"
"encoding/binary" "encoding/binary"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"io" "io"
"sync" "sync"
@ -150,7 +150,7 @@ func (c *Conn) readHeader() {
setErr(err) setErr(err)
return return
} }
if err := json.Unmarshal(payBuf, &c.earlyPayload); err != nil { if err := jsonv1.Unmarshal(payBuf, &c.earlyPayload); err != nil {
setErr(err) setErr(err)
return return
} }

@ -6,7 +6,7 @@ package derp
import ( import (
"bufio" "bufio"
"encoding/binary" "encoding/binary"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -154,7 +154,7 @@ func (c *Client) parseServerInfo(b []byte) (*ServerInfo, error) {
return nil, fmt.Errorf("failed to open naclbox from server key %s", c.serverKey) return nil, fmt.Errorf("failed to open naclbox from server key %s", c.serverKey)
} }
info := new(ServerInfo) info := new(ServerInfo)
if err := json.Unmarshal(msg, info); err != nil { if err := jsonv1.Unmarshal(msg, info); err != nil {
return nil, fmt.Errorf("invalid JSON: %v", err) return nil, fmt.Errorf("invalid JSON: %v", err)
} }
return info, nil return info, nil
@ -193,7 +193,7 @@ func (c *ClientInfo) Equal(other *ClientInfo) bool {
} }
func (c *Client) sendClientKey() error { func (c *Client) sendClientKey() error {
msg, err := json.Marshal(ClientInfo{ msg, err := jsonv1.Marshal(ClientInfo{
Version: ProtocolVersion, Version: ProtocolVersion,
MeshKey: c.meshKey, MeshKey: c.meshKey,
CanAckPings: c.canAckPings, CanAckPings: c.canAckPings,

@ -7,7 +7,7 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"context" "context"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"expvar" "expvar"
"fmt" "fmt"
@ -64,7 +64,7 @@ func TestClientInfoUnmarshal(t *testing.T) {
t.Run(i, func(t *testing.T) { t.Run(i, func(t *testing.T) {
t.Parallel() t.Parallel()
var got ClientInfo var got ClientInfo
err := json.Unmarshal([]byte(in.json), &got) err := jsonv1.Unmarshal([]byte(in.json), &got)
if in.wantErr != "" { if in.wantErr != "" {
if err == nil || !strings.Contains(err.Error(), in.wantErr) { if err == nil || !strings.Contains(err.Error(), in.wantErr) {
t.Errorf("Unmarshal(%q) = %v, want error containing %q", in.json, err, in.wantErr) t.Errorf("Unmarshal(%q) = %v, want error containing %q", in.json, err, in.wantErr)

@ -7,7 +7,7 @@ import (
"bytes" "bytes"
"context" "context"
"crypto/tls" "crypto/tls"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
@ -574,7 +574,7 @@ func TestManualDial(t *testing.T) {
t.Fatalf("fetching DERPMap: %v", err) t.Fatalf("fetching DERPMap: %v", err)
} }
defer res.Body.Close() defer res.Body.Close()
if err := json.NewDecoder(res.Body).Decode(dm); err != nil { if err := jsonv1.NewDecoder(res.Body).Decode(dm); err != nil {
t.Fatalf("decoding DERPMap: %v", err) t.Fatalf("decoding DERPMap: %v", err)
} }
@ -601,7 +601,7 @@ func TestURLDial(t *testing.T) {
t.Fatalf("fetching DERPMap: %v", err) t.Fatalf("fetching DERPMap: %v", err)
} }
defer res.Body.Close() defer res.Body.Close()
if err := json.NewDecoder(res.Body).Decode(dm); err != nil { if err := jsonv1.NewDecoder(res.Body).Decode(dm); err != nil {
t.Fatalf("decoding DERPMap: %v", err) t.Fatalf("decoding DERPMap: %v", err)
} }

@ -16,7 +16,7 @@ import (
"crypto/x509" "crypto/x509"
"crypto/x509/pkix" "crypto/x509/pkix"
"encoding/binary" "encoding/binary"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"expvar" "expvar"
"fmt" "fmt"
@ -1396,7 +1396,7 @@ func (s *Server) verifyClient(ctx context.Context, clientKey key.NodePublic, inf
ctx, cancel := context.WithTimeout(ctx, 5*time.Second) ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel() defer cancel()
jreq, err := json.Marshal(&tailcfg.DERPAdmitClientRequest{ jreq, err := jsonv1.Marshal(&tailcfg.DERPAdmitClientRequest{
NodePublic: clientKey, NodePublic: clientKey,
Source: clientIP, Source: clientIP,
}) })
@ -1420,7 +1420,7 @@ func (s *Server) verifyClient(ctx context.Context, clientKey key.NodePublic, inf
return fmt.Errorf("admission controller: %v", res.Status) return fmt.Errorf("admission controller: %v", res.Status)
} }
var jres tailcfg.DERPAdmitClientResponse var jres tailcfg.DERPAdmitClientResponse
if err := json.NewDecoder(io.LimitReader(res.Body, 4<<10)).Decode(&jres); err != nil { if err := jsonv1.NewDecoder(io.LimitReader(res.Body, 4<<10)).Decode(&jres); err != nil {
return err return err
} }
if !jres.Allow { if !jres.Allow {
@ -1503,7 +1503,7 @@ func (s *Server) noteClientActivity(c *sclient) {
type ServerInfo = derp.ServerInfo type ServerInfo = derp.ServerInfo
func (s *Server) sendServerInfo(bw *lazyBufioWriter, clientKey key.NodePublic) error { func (s *Server) sendServerInfo(bw *lazyBufioWriter, clientKey key.NodePublic) error {
msg, err := json.Marshal(ServerInfo{Version: derp.ProtocolVersion}) msg, err := jsonv1.Marshal(ServerInfo{Version: derp.ProtocolVersion})
if err != nil { if err != nil {
return err return err
} }
@ -1548,7 +1548,7 @@ func (s *Server) recvClientKey(br *bufio.Reader) (clientKey key.NodePublic, info
return zpub, nil, fmt.Errorf("msgbox: cannot open len=%d with client key %s", msgLen, clientKey) return zpub, nil, fmt.Errorf("msgbox: cannot open len=%d with client key %s", msgLen, clientKey)
} }
info = new(derp.ClientInfo) info = new(derp.ClientInfo)
if err := json.Unmarshal(msg, info); err != nil { if err := jsonv1.Unmarshal(msg, info); err != nil {
return zpub, nil, fmt.Errorf("msg: %v", err) return zpub, nil, fmt.Errorf("msg: %v", err)
} }
return clientKey, info, nil return clientKey, info, nil
@ -2335,7 +2335,7 @@ func parseSSOutput(raw string) map[netip.AddrPort]BytesSentRecv {
func (s *Server) ServeDebugTraffic(w http.ResponseWriter, r *http.Request) { func (s *Server) ServeDebugTraffic(w http.ResponseWriter, r *http.Request) {
prevState := map[netip.AddrPort]BytesSentRecv{} prevState := map[netip.AddrPort]BytesSentRecv{}
enc := json.NewEncoder(w) enc := jsonv1.NewEncoder(w)
for r.Context().Err() == nil { for r.Context().Err() == nil {
output, err := exec.Command("ss", "-i", "-H", "-t").Output() output, err := exec.Command("ss", "-i", "-H", "-t").Output()
if err != nil { if err != nil {

@ -10,7 +10,7 @@ import (
"crypto/sha256" "crypto/sha256"
"crypto/subtle" "crypto/subtle"
"encoding/hex" "encoding/hex"
"encoding/json" jsonv1 "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -105,7 +105,7 @@ func verifyWebhookSignature(req *http.Request, secret string) (events []event, e
} }
// If verified, return the events. // If verified, return the events.
if err := json.Unmarshal(b, &events); err != nil { if err := jsonv1.Unmarshal(b, &events); err != nil {
return nil, err return nil, err
} }
return events, nil return events, nil

@ -4,7 +4,7 @@
package drive package drive
import ( import (
"encoding/json" jsonv1 "encoding/json"
"fmt" "fmt"
) )
@ -37,7 +37,7 @@ func ParsePermissions(rawGrants [][]byte) (Permissions, error) {
permissions := make(Permissions) permissions := make(Permissions)
for _, rawGrant := range rawGrants { for _, rawGrant := range rawGrants {
var g grant var g grant
err := json.Unmarshal(rawGrant, &g) err := jsonv1.Unmarshal(rawGrant, &g)
if err != nil { if err != nil {
return nil, fmt.Errorf("unmarshal raw grants %s: %v", rawGrant, err) return nil, fmt.Errorf("unmarshal raw grants %s: %v", rawGrant, err)
} }

@ -4,7 +4,7 @@
package drive package drive
import ( import (
"encoding/json" jsonv1 "encoding/json"
"testing" "testing"
) )
@ -40,7 +40,7 @@ func TestPermissions(t *testing.T) {
t.Run(tt.share, func(t *testing.T) { t.Run(tt.share, func(t *testing.T) {
var rawPerms [][]byte var rawPerms [][]byte
for _, perm := range tt.perms { for _, perm := range tt.perms {
b, err := json.Marshal(perm) b, err := jsonv1.Marshal(perm)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

@ -5,7 +5,7 @@
package appconnectors package appconnectors
import ( import (
"encoding/json" jsonv1 "encoding/json"
"net/http" "net/http"
"tailscale.com/ipn/ipnlocal" "tailscale.com/ipn/ipnlocal"
@ -28,12 +28,12 @@ func handleC2NAppConnectorDomainRoutesGet(b *ipnlocal.LocalBackend, w http.Respo
appConnector := b.AppConnector() appConnector := b.AppConnector()
if appConnector == nil { if appConnector == nil {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(res) jsonv1.NewEncoder(w).Encode(res)
return return
} }
res.Domains = appConnector.DomainRoutes() res.Domains = appConnector.DomainRoutes()
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(res) jsonv1.NewEncoder(w).Encode(res)
} }

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save