Skip to content

Commit 3f13fb5

Browse files
committed
Add e2e tests
1 parent 9083648 commit 3f13fb5

File tree

16 files changed

+92
-96
lines changed

16 files changed

+92
-96
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ E2E_TIMEOUT ?= 3h
293293
run-e2e: e2e-essentials ## Run e2e testing. JOB is an optional REGEXP to select certainn test cases to run. e.g. JOB=PR-Blocking, JOB=Conformance
294294
$(KUBECTL) apply -f cloud-config.yaml && \
295295
cd test/e2e && \
296-
$(GINKGO) -v --trace --tags=e2e --focus=$(JOB) --timeout=$(E2E_TIMEOUT) --skip=Conformance --skip-package=kubeconfig_helper --nodes=1 --no-color=false ./... -- \
296+
$(GINKGO) -vv --trace --tags=e2e --focus=$(JOB) --timeout=$(E2E_TIMEOUT) --skip=Conformance --skip-package=kubeconfig_helper --nodes=1 --no-color=false ./... -- \
297297
-e2e.artifacts-folder=${REPO_ROOT}/_artifacts \
298298
-e2e.config=${E2E_CONFIG} \
299299
-e2e.skip-resource-cleanup=false -e2e.use-existing-cluster=true

api/v1beta2/cloudstackcluster_conversion.go

+9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package v1beta2
1818

1919
import (
20+
machineryconversion "k8s.io/apimachinery/pkg/conversion"
2021
"sigs.k8s.io/cluster-api-provider-cloudstack/api/v1beta3"
2122
"sigs.k8s.io/controller-runtime/pkg/conversion"
2223
)
@@ -30,3 +31,11 @@ func (dst *CloudStackCluster) ConvertFrom(srcRaw conversion.Hub) error { // noli
3031
src := srcRaw.(*v1beta3.CloudStackCluster)
3132
return Convert_v1beta3_CloudStackCluster_To_v1beta2_CloudStackCluster(src, dst, nil)
3233
}
34+
35+
func Convert_v1beta3_CloudStackClusterSpec_To_v1beta2_CloudStackClusterSpec(in *v1beta3.CloudStackClusterSpec, out *CloudStackClusterSpec, s machineryconversion.Scope) error { // nolint
36+
return autoConvert_v1beta3_CloudStackClusterSpec_To_v1beta2_CloudStackClusterSpec(in, out, s)
37+
}
38+
39+
func Convert_v1beta3_CloudStackClusterStatus_To_v1beta2_CloudStackClusterStatus(in *v1beta3.CloudStackClusterStatus, out *CloudStackClusterStatus, s machineryconversion.Scope) error { // nolint
40+
return autoConvert_v1beta3_CloudStackClusterStatus_To_v1beta2_CloudStackClusterStatus(in, out, s)
41+
}

api/v1beta2/zz_generated.conversion.go

+12-20
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1beta3/cloudstackcluster_types.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type CloudStackClusterSpec struct {
3737

3838
// SyncWithACS determines if an externalManaged CKS cluster should be created on ACS.
3939
// +optional
40-
SyncWithACS bool `json:"syncWithACS"`
40+
SyncWithACS bool `json:"syncWithACS,omitempty"`
4141
}
4242

4343
// The status of the CloudStackCluster object.

controllers/cloudstackcluster_controller.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ func (r *CloudStackClusterReconciliationRunner) Reconcile() (res ctrl.Result, re
9595
r.GetFailureDomains(r.FailureDomains),
9696
r.RemoveExtraneousFailureDomains(r.FailureDomains),
9797
r.VerifyFailureDomainCRDs,
98-
r.GetOrCreateUnmanagedCluster,
99-
r.SetReady)
98+
r.SetReady,
99+
r.GetOrCreateUnmanagedCluster)
100100
}
101101

102102
// GetOrCreateUnmanagedCluster checks if an unmanaged cluster is present in Cloudstack else creates one.

go.mod

+4-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module sigs.k8s.io/cluster-api-provider-cloudstack
33
go 1.19
44

55
require (
6-
github.com/apache/cloudstack-go/v2 v2.16.0-rc.2
6+
github.com/apache/cloudstack-go/v2 v2.16.1
77
github.com/go-logr/logr v1.2.4
88
github.com/golang/mock v1.6.0
99
github.com/hashicorp/go-multierror v1.1.1
@@ -70,11 +70,11 @@ require (
7070
github.com/rogpeppe/go-internal v1.9.0 // indirect
7171
github.com/spf13/cobra v1.6.1 // indirect
7272
go.uber.org/atomic v1.10.0 // indirect
73-
golang.org/x/net v0.17.0 // indirect
73+
golang.org/x/net v0.23.0 // indirect
7474
golang.org/x/oauth2 v0.6.0 // indirect
7575
golang.org/x/sync v0.2.0 // indirect
76-
golang.org/x/sys v0.13.0 // indirect
77-
golang.org/x/term v0.13.0 // indirect
76+
golang.org/x/sys v0.18.0 // indirect
77+
golang.org/x/term v0.18.0 // indirect
7878
golang.org/x/time v0.3.0 // indirect
7979
golang.org/x/tools v0.9.3 // indirect
8080
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
@@ -91,5 +91,3 @@ require (
9191
)
9292

9393
replace github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.0.0 // Indirect upgrade to address https://github.com/advisories/GHSA-w73w-5m7g-f7qc
94-
95-
replace github.com/apache/cloudstack-go/v2 => github.com/shapeblue/cloudstack-go/v2 v2.9.1-0.20230717062313-73e4efc8a510

go.sum

+9-9
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
2222
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
2323
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
2424
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves=
25+
github.com/apache/cloudstack-go/v2 v2.16.1 h1:2wOE4RKEjWPRZNO7ZNnZYmR3JJ+JJPQwhoc7W1fkiK4=
26+
github.com/apache/cloudstack-go/v2 v2.16.1/go.mod h1:cZsgFe+VmrgLBm7QjeHTJBXYe8E5+yGYkdfwGb+Pu9c=
2527
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
2628
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
2729
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
@@ -302,8 +304,6 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
302304
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
303305
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
304306
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
305-
github.com/shapeblue/cloudstack-go/v2 v2.9.1-0.20230717062313-73e4efc8a510 h1:FPRBv784robz6sZSqDGfZDZMse31lj96i+enH02Xzds=
306-
github.com/shapeblue/cloudstack-go/v2 v2.9.1-0.20230717062313-73e4efc8a510/go.mod h1:Mc+tXpujtslBuZFk5atoGT2LanVxOrXS2GGgidAoz1A=
307307
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
308308
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
309309
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
@@ -367,7 +367,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
367367
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
368368
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
369369
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
370-
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
370+
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
371371
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
372372
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
373373
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -409,8 +409,8 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
409409
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
410410
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
411411
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
412-
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
413-
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
412+
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
413+
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
414414
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
415415
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
416416
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -448,11 +448,11 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
448448
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
449449
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
450450
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
451-
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
452-
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
451+
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
452+
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
453453
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
454-
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
455-
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
454+
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
455+
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
456456
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
457457
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
458458
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=

pkg/cloud/cluster.go

+6-9
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func withExternalManaged() cloudstack.OptionFunc {
5151
func (c *client) GetOrCreateUnmanagedCluster(cluster *clusterv1.Cluster, csCluster *infrav1.CloudStackCluster, fd *infrav1.CloudStackFailureDomainSpec) error {
5252
// Get cluster
5353
if csCluster.Status.CloudStackClusterID != "" {
54-
externalManagedCluster, count, err := c.cs.Kubernetes.GetKubernetesClusterByID(csCluster.Status.CloudStackClusterID, withExternalManaged())
54+
externalManagedCluster, count, err := c.cs.Kubernetes.GetKubernetesClusterByID(csCluster.Status.CloudStackClusterID, withExternalManaged(), cloudstack.WithProject(c.user.Project.ID))
5555
if err != nil {
5656
return err
5757
} else if count > 0 {
@@ -62,20 +62,14 @@ func (c *client) GetOrCreateUnmanagedCluster(cluster *clusterv1.Cluster, csClust
6262

6363
// Check if a cluster exists with the same name
6464
clusterName := fmt.Sprintf("%s - %s - %s", cluster.GetName(), csCluster.GetName(), csCluster.GetUID())
65-
externalManagedCluster, count, err := c.cs.Kubernetes.GetKubernetesClusterByName(clusterName, withExternalManaged())
65+
externalManagedCluster, count, err := c.cs.Kubernetes.GetKubernetesClusterByName(clusterName, withExternalManaged(), cloudstack.WithProject(c.user.Project.ID))
6666
if err != nil && !strings.Contains(err.Error(), "No match found for ") {
6767
return err
6868
}
6969
if count > 0 {
7070
csCluster.Status.CloudStackClusterID = externalManagedCluster.Id
7171
} else if err == nil || (err != nil && strings.Contains(err.Error(), "No match found for ")) {
7272
// Create cluster
73-
domain := Domain{Path: rootDomain}
74-
if csCluster.Spec.FailureDomains[0].Domain != "" {
75-
domain.Path = fd.Domain
76-
}
77-
_ = c.ResolveDomain(&domain)
78-
7973
accountName := csCluster.Spec.FailureDomains[0].Account
8074
if accountName == "" {
8175
userParams := c.cs.User.NewGetUserParams(c.config.APIKey)
@@ -88,10 +82,13 @@ func (c *client) GetOrCreateUnmanagedCluster(cluster *clusterv1.Cluster, csClust
8882
// NewCreateKubernetesClusterParams(description string, kubernetesversionid string, name string, serviceofferingid string, size int64, zoneid string) *CreateKubernetesClusterParams
8983
params := c.cs.Kubernetes.NewCreateKubernetesClusterParams(fmt.Sprintf("%s managed by CAPC", clusterName), "", clusterName, "", 0, fd.Zone.ID)
9084

85+
setIfNotEmpty(c.user.Project.ID, params.SetProjectid)
9186
setIfNotEmpty(accountName, params.SetAccount)
92-
setIfNotEmpty(domain.ID, params.SetDomainid)
87+
setIfNotEmpty(c.user.Domain.ID, params.SetDomainid)
9388
setIfNotEmpty(fd.Zone.Network.ID, params.SetNetworkid)
9489
setIfNotEmpty(csCluster.Spec.ControlPlaneEndpoint.Host, params.SetExternalloadbalanceripaddress)
90+
params.ResetKubernetesversionid()
91+
params.ResetServiceofferingid()
9592
params.SetClustertype("ExternalManaged")
9693

9794
cloudStackCKSCluster, err := c.cs.Kubernetes.CreateKubernetesCluster(params)

test/e2e/config/cloudstack.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ providers:
9898
- sourcePath: "../data/infrastructure-cloudstack/v1beta3/cluster-template-invalid-ip.yaml"
9999
- sourcePath: "../data/infrastructure-cloudstack/v1beta3/cluster-template-kubernetes-version-upgrade-before.yaml"
100100
- sourcePath: "../data/infrastructure-cloudstack/v1beta3/cluster-template-kubernetes-version-upgrade-after.yaml"
101+
- sourcePath: "../data/infrastructure-cloudstack/v1beta3/cluster-template-k8s-unmanaged.yaml"
101102
- sourcePath: "../data/shared/v1beta1_provider/metadata.yaml"
102103
versions:
103104
- name: v1.0.0

test/e2e/data/infrastructure-cloudstack/v1beta3/bases/cluster-with-kcp.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ spec:
3535
name : ${CLOUDSTACK_ZONE_NAME}
3636
network:
3737
name: ${CLOUDSTACK_NETWORK_NAME}
38+
syncWithACS: false
3839
---
3940
kind: KubeadmControlPlane
4041
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
3+
kind: CloudStackCluster
4+
metadata:
5+
name: ${CLUSTER_NAME}
6+
spec:
7+
controlPlaneEndpoint:
8+
host: ""
9+
port: 6443
10+
failureDomains:
11+
- name: ${CLOUDSTACK_FD1_NAME}
12+
acsEndpoint:
13+
name: ${CLOUDSTACK_FD1_SECRET_NAME}
14+
namespace: default
15+
zone:
16+
name : ${CLOUDSTACK_ZONE_NAME}
17+
network:
18+
name: ${CLOUDSTACK_NETWORK_NAME}
19+
syncWithACS: true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
bases:
2+
- ../bases/cluster-with-kcp.yaml
3+
- ../bases/md.yaml
4+
5+
patchesStrategicMerge:
6+
- ./cloudstack-cluster.yaml

test/e2e/go.mod

+6-10
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ go 1.19
44

55
require (
66
github.com/Shopify/toxiproxy/v2 v2.5.0
7-
github.com/apache/cloudstack-go/v2 v2.16.0-rc.2
7+
github.com/apache/cloudstack-go/v2 v2.16.1
88
github.com/blang/semver v3.5.1+incompatible
9-
github.com/onsi/ginkgo v1.16.5
109
github.com/onsi/ginkgo/v2 v2.11.0
1110
github.com/onsi/gomega v1.27.8
1211
gopkg.in/yaml.v3 v3.0.1
@@ -19,8 +18,6 @@ require (
1918
sigs.k8s.io/controller-runtime v0.14.5
2019
)
2120

22-
require gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
23-
2421
require (
2522
github.com/BurntSushi/toml v1.0.0 // indirect
2623
github.com/MakeNowJust/heredoc v1.0.0 // indirect
@@ -81,7 +78,6 @@ require (
8178
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
8279
github.com/modern-go/reflect2 v1.0.2 // indirect
8380
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
84-
github.com/nxadm/tail v1.4.8 // indirect
8581
github.com/opencontainers/go-digest v1.0.0 // indirect
8682
github.com/opencontainers/image-spec v1.0.2 // indirect
8783
github.com/pelletier/go-toml v1.9.5 // indirect
@@ -101,12 +97,12 @@ require (
10197
github.com/stoewer/go-strcase v1.2.0 // indirect
10298
github.com/subosito/gotenv v1.4.2 // indirect
10399
github.com/valyala/fastjson v1.6.4 // indirect
104-
golang.org/x/crypto v0.14.0 // indirect
105-
golang.org/x/net v0.17.0 // indirect
100+
golang.org/x/crypto v0.21.0 // indirect
101+
golang.org/x/net v0.23.0 // indirect
106102
golang.org/x/oauth2 v0.6.0 // indirect
107-
golang.org/x/sys v0.13.0 // indirect
108-
golang.org/x/term v0.13.0 // indirect
109-
golang.org/x/text v0.13.0 // indirect
103+
golang.org/x/sys v0.18.0 // indirect
104+
golang.org/x/term v0.18.0 // indirect
105+
golang.org/x/text v0.14.0 // indirect
110106
golang.org/x/time v0.3.0 // indirect
111107
golang.org/x/tools v0.9.3 // indirect
112108
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect

0 commit comments

Comments
 (0)