mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-06-24 14:10:49 -04:00
cli: use custom byte-slice marshalling for state file (#2460)
* custom byte slice marshalling Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * byte slice compatibility Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * other byte slice compat test Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * add missing dep Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * export byte type alias Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * regenerate exported type Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> * test marshal and unmarshal together Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com> --------- Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>
This commit is contained in:
parent
c424ec8825
commit
a8605d7294
13 changed files with 144 additions and 16 deletions
|
@ -7401,8 +7401,8 @@ def go_dependencies():
|
||||||
build_file_generation = "on",
|
build_file_generation = "on",
|
||||||
build_file_proto_mode = "disable_global",
|
build_file_proto_mode = "disable_global",
|
||||||
importpath = "golang.org/x/net",
|
importpath = "golang.org/x/net",
|
||||||
sum = "h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=",
|
sum = "h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos=",
|
||||||
version = "v0.17.0",
|
version = "v0.16.0",
|
||||||
)
|
)
|
||||||
go_repository(
|
go_repository(
|
||||||
name = "org_golang_x_oauth2",
|
name = "org_golang_x_oauth2",
|
||||||
|
|
|
@ -26,5 +26,7 @@ go_test(
|
||||||
"@com_github_siderolabs_talos_pkg_machinery//config/encoder",
|
"@com_github_siderolabs_talos_pkg_machinery//config/encoder",
|
||||||
"@com_github_spf13_afero//:afero",
|
"@com_github_spf13_afero//:afero",
|
||||||
"@com_github_stretchr_testify//assert",
|
"@com_github_stretchr_testify//assert",
|
||||||
|
"@com_github_stretchr_testify//require",
|
||||||
|
"@in_gopkg_yaml_v3//:yaml_v3",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,6 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
package state
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"dario.cat/mergo"
|
"dario.cat/mergo"
|
||||||
|
@ -63,7 +64,7 @@ type ClusterValues struct {
|
||||||
OwnerID string `yaml:"ownerID"`
|
OwnerID string `yaml:"ownerID"`
|
||||||
// description: |
|
// description: |
|
||||||
// Salt used to generate the ClusterID on the bootstrapping node.
|
// Salt used to generate the ClusterID on the bootstrapping node.
|
||||||
MeasurementSalt []byte `yaml:"measurementSalt"`
|
MeasurementSalt HexBytes `yaml:"measurementSalt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Infrastructure describe the state related to the cloud resources of the cluster.
|
// Infrastructure describe the state related to the cloud resources of the cluster.
|
||||||
|
@ -76,7 +77,7 @@ type Infrastructure struct {
|
||||||
ClusterEndpoint string `yaml:"clusterEndpoint"`
|
ClusterEndpoint string `yaml:"clusterEndpoint"`
|
||||||
// description: |
|
// description: |
|
||||||
// Secret used to authenticate the bootstrapping node.
|
// Secret used to authenticate the bootstrapping node.
|
||||||
InitSecret []byte `yaml:"initSecret"`
|
InitSecret HexBytes `yaml:"initSecret"`
|
||||||
// description: |
|
// description: |
|
||||||
// List of Subject Alternative Names (SANs) to add to the Kubernetes API server certificate.
|
// List of Subject Alternative Names (SANs) to add to the Kubernetes API server certificate.
|
||||||
// If no SANs should be added, this field can be left empty.
|
// If no SANs should be added, this field can be left empty.
|
||||||
|
@ -164,3 +165,33 @@ func (s *State) Merge(other *State) (*State, error) {
|
||||||
}
|
}
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HexBytes is a byte slice that is marshalled to and from a hex string.
|
||||||
|
type HexBytes []byte
|
||||||
|
|
||||||
|
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
||||||
|
func (h *HexBytes) UnmarshalYAML(unmarshal func(any) error) error {
|
||||||
|
var hexString string
|
||||||
|
if err := unmarshal(&hexString); err != nil {
|
||||||
|
// TODO(msanft): Remove with v2.14.0
|
||||||
|
// fall back to unmarshalling as a byte slice for backwards compatibility
|
||||||
|
var oldHexBytes []byte
|
||||||
|
if err := unmarshal(&oldHexBytes); err != nil {
|
||||||
|
return fmt.Errorf("unmarshalling hex bytes: %w", err)
|
||||||
|
}
|
||||||
|
hexString = hex.EncodeToString(oldHexBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes, err := hex.DecodeString(hexString)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("decoding hex bytes: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*h = bytes
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalYAML implements the yaml.Marshaler interface.
|
||||||
|
func (h HexBytes) MarshalYAML() (any, error) {
|
||||||
|
return hex.EncodeToString(h), nil
|
||||||
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ func init() {
|
||||||
ClusterValuesDoc.Fields[1].Description = "Unique identifier of the owner of the cluster."
|
ClusterValuesDoc.Fields[1].Description = "Unique identifier of the owner of the cluster."
|
||||||
ClusterValuesDoc.Fields[1].Comments[encoder.LineComment] = "Unique identifier of the owner of the cluster."
|
ClusterValuesDoc.Fields[1].Comments[encoder.LineComment] = "Unique identifier of the owner of the cluster."
|
||||||
ClusterValuesDoc.Fields[2].Name = "measurementSalt"
|
ClusterValuesDoc.Fields[2].Name = "measurementSalt"
|
||||||
ClusterValuesDoc.Fields[2].Type = "[]byte"
|
ClusterValuesDoc.Fields[2].Type = "HexBytes"
|
||||||
ClusterValuesDoc.Fields[2].Note = ""
|
ClusterValuesDoc.Fields[2].Note = ""
|
||||||
ClusterValuesDoc.Fields[2].Description = "Salt used to generate the ClusterID on the bootstrapping node."
|
ClusterValuesDoc.Fields[2].Description = "Salt used to generate the ClusterID on the bootstrapping node."
|
||||||
ClusterValuesDoc.Fields[2].Comments[encoder.LineComment] = "Salt used to generate the ClusterID on the bootstrapping node."
|
ClusterValuesDoc.Fields[2].Comments[encoder.LineComment] = "Salt used to generate the ClusterID on the bootstrapping node."
|
||||||
|
@ -86,7 +86,7 @@ func init() {
|
||||||
InfrastructureDoc.Fields[1].Description = "Endpoint the cluster can be reached at."
|
InfrastructureDoc.Fields[1].Description = "Endpoint the cluster can be reached at."
|
||||||
InfrastructureDoc.Fields[1].Comments[encoder.LineComment] = "Endpoint the cluster can be reached at."
|
InfrastructureDoc.Fields[1].Comments[encoder.LineComment] = "Endpoint the cluster can be reached at."
|
||||||
InfrastructureDoc.Fields[2].Name = "initSecret"
|
InfrastructureDoc.Fields[2].Name = "initSecret"
|
||||||
InfrastructureDoc.Fields[2].Type = "[]byte"
|
InfrastructureDoc.Fields[2].Type = "HexBytes"
|
||||||
InfrastructureDoc.Fields[2].Note = ""
|
InfrastructureDoc.Fields[2].Note = ""
|
||||||
InfrastructureDoc.Fields[2].Description = "Secret used to authenticate the bootstrapping node."
|
InfrastructureDoc.Fields[2].Description = "Secret used to authenticate the bootstrapping node."
|
||||||
InfrastructureDoc.Fields[2].Comments[encoder.LineComment] = "Secret used to authenticate the bootstrapping node."
|
InfrastructureDoc.Fields[2].Comments[encoder.LineComment] = "Secret used to authenticate the bootstrapping node."
|
||||||
|
|
|
@ -14,6 +14,8 @@ import (
|
||||||
"github.com/siderolabs/talos/pkg/machinery/config/encoder"
|
"github.com/siderolabs/talos/pkg/machinery/config/encoder"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var defaultState = &State{
|
var defaultState = &State{
|
||||||
|
@ -326,3 +328,94 @@ func TestMerge(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMarshalHexBytes(t *testing.T) {
|
||||||
|
testCases := map[string]struct {
|
||||||
|
in HexBytes
|
||||||
|
expected string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
"success": {
|
||||||
|
in: []byte{0xab, 0xcd, 0xef},
|
||||||
|
expected: "abcdef\n",
|
||||||
|
},
|
||||||
|
"empty": {
|
||||||
|
in: []byte{},
|
||||||
|
expected: "\"\"\n",
|
||||||
|
},
|
||||||
|
"nil": {
|
||||||
|
in: nil,
|
||||||
|
expected: "\"\"\n",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, tc := range testCases {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
actual, err := yaml.Marshal(tc.in)
|
||||||
|
|
||||||
|
if tc.wantErr {
|
||||||
|
assert.Error(err)
|
||||||
|
} else {
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.Equal(tc.expected, string(actual))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalHexBytes(t *testing.T) {
|
||||||
|
testCases := map[string]struct {
|
||||||
|
in string
|
||||||
|
expected HexBytes
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
"success": {
|
||||||
|
in: "abcdef",
|
||||||
|
expected: []byte{0xab, 0xcd, 0xef},
|
||||||
|
},
|
||||||
|
"empty": {
|
||||||
|
in: "",
|
||||||
|
expected: nil,
|
||||||
|
},
|
||||||
|
"byte slice compat": {
|
||||||
|
in: "[0xab, 0xcd, 0xef]",
|
||||||
|
expected: []byte{0xab, 0xcd, 0xef},
|
||||||
|
},
|
||||||
|
"byte slice compat 2": {
|
||||||
|
in: "[00, 12, 34]",
|
||||||
|
expected: []byte{0x00, 0x0c, 0x22},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, tc := range testCases {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
var actual HexBytes
|
||||||
|
err := yaml.Unmarshal([]byte(tc.in), &actual)
|
||||||
|
|
||||||
|
if tc.wantErr {
|
||||||
|
assert.Error(err)
|
||||||
|
} else {
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.Equal(tc.expected, actual)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMarshalUnmarshalHexBytes(t *testing.T) {
|
||||||
|
in := HexBytes{0xab, 0xcd, 0xef}
|
||||||
|
expected := "abcdef\n"
|
||||||
|
|
||||||
|
actual, err := yaml.Marshal(in)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, expected, string(actual))
|
||||||
|
|
||||||
|
var actual2 HexBytes
|
||||||
|
err = yaml.Unmarshal(actual, &actual2)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, in, actual2)
|
||||||
|
}
|
||||||
|
|
|
@ -106,6 +106,7 @@ go_test(
|
||||||
],
|
],
|
||||||
embed = [":terraform"],
|
embed = [":terraform"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//cli/internal/state",
|
||||||
"//internal/cloud/cloudprovider",
|
"//internal/cloud/cloudprovider",
|
||||||
"//internal/constants",
|
"//internal/constants",
|
||||||
"//internal/file",
|
"//internal/file",
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/cli/internal/state"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||||
|
@ -477,7 +478,7 @@ func TestCreateCluster(t *testing.T) {
|
||||||
}
|
}
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.Equal("192.0.2.100", infraState.ClusterEndpoint)
|
assert.Equal("192.0.2.100", infraState.ClusterEndpoint)
|
||||||
assert.Equal([]byte("initSecret"), infraState.InitSecret)
|
assert.Equal(state.HexBytes("initSecret"), infraState.InitSecret)
|
||||||
assert.Equal("12345abc", infraState.UID)
|
assert.Equal("12345abc", infraState.UID)
|
||||||
if tc.provider == cloudprovider.Azure {
|
if tc.provider == cloudprovider.Azure {
|
||||||
assert.Equal(tc.expectedAttestationURL, infraState.Azure.AttestationURL)
|
assert.Equal(tc.expectedAttestationURL, infraState.Azure.AttestationURL)
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -322,7 +322,7 @@ require (
|
||||||
go.starlark.net v0.0.0-20220223235035-243c74974e97 // indirect
|
go.starlark.net v0.0.0-20220223235035-243c74974e97 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
|
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
|
||||||
golang.org/x/net v0.17.0 // indirect
|
golang.org/x/net v0.16.0 // indirect
|
||||||
golang.org/x/oauth2 v0.9.0 // indirect
|
golang.org/x/oauth2 v0.9.0 // indirect
|
||||||
golang.org/x/sync v0.4.0 // indirect
|
golang.org/x/sync v0.4.0 // indirect
|
||||||
golang.org/x/term v0.13.0 // indirect
|
golang.org/x/term v0.13.0 // indirect
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -1274,8 +1274,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos=
|
||||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
|
|
@ -274,7 +274,7 @@ require (
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
golang.org/x/crypto v0.14.0 // indirect
|
golang.org/x/crypto v0.14.0 // indirect
|
||||||
golang.org/x/mod v0.13.0 // indirect
|
golang.org/x/mod v0.13.0 // indirect
|
||||||
golang.org/x/net v0.17.0 // indirect
|
golang.org/x/net v0.16.0 // indirect
|
||||||
golang.org/x/oauth2 v0.9.0 // indirect
|
golang.org/x/oauth2 v0.9.0 // indirect
|
||||||
golang.org/x/sync v0.4.0 // indirect
|
golang.org/x/sync v0.4.0 // indirect
|
||||||
golang.org/x/sys v0.13.0 // indirect
|
golang.org/x/sys v0.13.0 // indirect
|
||||||
|
|
|
@ -1215,8 +1215,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos=
|
||||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
|
|
@ -106,7 +106,7 @@ require (
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
go.uber.org/zap v1.26.0 // indirect
|
go.uber.org/zap v1.26.0 // indirect
|
||||||
golang.org/x/crypto v0.14.0 // indirect
|
golang.org/x/crypto v0.14.0 // indirect
|
||||||
golang.org/x/net v0.17.0 // indirect
|
golang.org/x/net v0.16.0 // indirect
|
||||||
golang.org/x/oauth2 v0.9.0 // indirect
|
golang.org/x/oauth2 v0.9.0 // indirect
|
||||||
golang.org/x/sys v0.13.0 // indirect
|
golang.org/x/sys v0.13.0 // indirect
|
||||||
golang.org/x/term v0.13.0 // indirect
|
golang.org/x/term v0.13.0 // indirect
|
||||||
|
|
|
@ -435,8 +435,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos=
|
||||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue