diff --git a/.github/linters/.codespellrc b/.github/linters/.codespellrc index b5e61bb96..a3059a0e3 100644 --- a/.github/linters/.codespellrc +++ b/.github/linters/.codespellrc @@ -1,2 +1,3 @@ [codespell] skip = *.pdf,*.png,*.jpg,*.gif,*.ico,*.sum,*.mod,*.pb.go,*go.sum,*/go.sum,vendor,.git +ignore-words-list = dne diff --git a/.mk/kind.mk b/.mk/kind.mk index 9d3c9a017..8afd3f9c5 100644 --- a/.mk/kind.mk +++ b/.mk/kind.mk @@ -3,7 +3,7 @@ KIND_CLUSTER_NAME := "kne" .PHONY: kind-install kind-install: - go get sigs.k8s.io/kind@v0.11.1 + go install sigs.k8s.io/kind@v0.32.0 .PHONY: kind-stop kind-stop: diff --git a/api/metallb/clientset/v1beta1/client.go b/api/metallb/clientset/v1beta1/client.go index 0c88fbb6c..2091033a4 100644 --- a/api/metallb/clientset/v1beta1/client.go +++ b/api/metallb/clientset/v1beta1/client.go @@ -87,13 +87,11 @@ func L2AdvertisementGVR() schema.GroupVersionResource { } var ( - groupVersion = metallbv1.GroupVersion + groupVersion = schema.GroupVersion{Group: "metallb.io", Version: "v1beta1"} Scheme = runtime.NewScheme() ) func init() { - metallbv1.AddToScheme(Scheme) - metav1.AddToGroupVersion(Scheme, groupVersion) metav1.AddMetaToScheme(Scheme) } diff --git a/api/metallb/clientset/v1beta1/ipaddresspool.go b/api/metallb/clientset/v1beta1/ipaddresspool.go index 7c50a4052..51bbc0fa8 100644 --- a/api/metallb/clientset/v1beta1/ipaddresspool.go +++ b/api/metallb/clientset/v1beta1/ipaddresspool.go @@ -23,7 +23,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/dynamic" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" ) type addressPoolClient struct { @@ -56,13 +55,9 @@ func (a *addressPoolClient) Get(ctx context.Context, name string, opts metav1.Ge } func (a *addressPoolClient) Create(ctx context.Context, pool *metallbv1.IPAddressPool, opts metav1.CreateOptions) (*metallbv1.IPAddressPool, error) { - gvk, err := apiutil.GVKForObject(pool, Scheme) - if err != nil { - return nil, fmt.Errorf("failed to get gvk for AddressPool: %w", err) - } pool.TypeMeta = metav1.TypeMeta{ - Kind: gvk.Kind, - APIVersion: gvk.GroupVersion().String(), + Kind: "IPAddressPool", + APIVersion: metallbv1.GroupVersion.String(), } obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(pool) if err != nil { diff --git a/api/metallb/clientset/v1beta1/l2advertisement.go b/api/metallb/clientset/v1beta1/l2advertisement.go index f513e43be..b5fb206a2 100644 --- a/api/metallb/clientset/v1beta1/l2advertisement.go +++ b/api/metallb/clientset/v1beta1/l2advertisement.go @@ -23,7 +23,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/dynamic" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" ) type l2AdvertisementClient struct { @@ -56,13 +55,9 @@ func (l *l2AdvertisementClient) Get(ctx context.Context, name string, opts metav } func (l *l2AdvertisementClient) Create(ctx context.Context, pool *metallbv1.L2Advertisement, opts metav1.CreateOptions) (*metallbv1.L2Advertisement, error) { - gvk, err := apiutil.GVKForObject(pool, Scheme) - if err != nil { - return nil, fmt.Errorf("failed to get gvk for AddressPool: %w", err) - } pool.TypeMeta = metav1.TypeMeta{ - Kind: gvk.Kind, - APIVersion: gvk.GroupVersion().String(), + Kind: "L2Advertisement", + APIVersion: metallbv1.GroupVersion.String(), } obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(pool) if err != nil { diff --git a/cloudbuild/external.pkr.hcl b/cloudbuild/external.pkr.hcl index 417c93fdd..5e40edae6 100644 --- a/cloudbuild/external.pkr.hcl +++ b/cloudbuild/external.pkr.hcl @@ -94,8 +94,8 @@ build { provisioner "shell" { inline = [ "echo Installing kubectl...", - "curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.35/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg", - "echo \"deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.35/deb/ /\" | sudo tee /etc/apt/sources.list.d/kubernetes.list", + "curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.36/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg", + "echo \"deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.36/deb/ /\" | sudo tee /etc/apt/sources.list.d/kubernetes.list", "sudo apt-get update", // kube-proxy requires conntrack to route traffic, and kubeadm v1.31+ enforces it in preflight checks "sudo apt-get install conntrack -y", @@ -154,7 +154,7 @@ build { provisioner "shell" { inline = [ "echo Installing kind...", - "/usr/local/go/bin/go install sigs.k8s.io/kind@v0.24.0", + "/usr/local/go/bin/go install sigs.k8s.io/kind@v0.32.0", "curl --create-dirs -o third_party/licenses/kind/LICENSE https://raw.githubusercontent.com/kubernetes-sigs/kind/main/LICENSE", "sudo cp /home/$USER/go/bin/kind /usr/local/bin/", "/home/$USER/go/bin/kind version", diff --git a/cloudbuild/internal.pkr.hcl b/cloudbuild/internal.pkr.hcl index 5f9a3be47..f8b43813c 100644 --- a/cloudbuild/internal.pkr.hcl +++ b/cloudbuild/internal.pkr.hcl @@ -97,6 +97,7 @@ build { "sudo docker pull us-west1-docker.pkg.dev/gep-kne/cisco/8000e:ga & pids=\"$pids $!\"", "sudo docker pull us-west1-docker.pkg.dev/gep-kne/juniper/ncptx:ga & pids=\"$pids $!\"", "sudo docker pull us-west1-docker.pkg.dev/gep-kne/nokia/srlinux:ga & pids=\"$pids $!\"", + "sudo docker pull us-west1-docker.pkg.dev/kne-external/kne/meshnet:ga & pids=\"$pids $!\"", "echo 'Waiting for all docker pulls to complete...'", "for pid in $pids; do wait \"$pid\" || exit 1; done", "echo 'All docker images pulled successfully.'", @@ -106,8 +107,8 @@ build { provisioner "shell" { inline = [ "echo Installing kubectl...", - "curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.35/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg", - "echo \"deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.35/deb/ /\" | sudo tee /etc/apt/sources.list.d/kubernetes.list", + "curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.36/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg", + "echo \"deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.36/deb/ /\" | sudo tee /etc/apt/sources.list.d/kubernetes.list", "sudo apt-get update", // kube-proxy requires conntrack to route traffic, and kubeadm v1.31+ enforces it in preflight checks "sudo apt-get install conntrack -y", @@ -156,7 +157,7 @@ build { provisioner "shell" { inline = [ "echo Installing kind...", - "/usr/local/go/bin/go install sigs.k8s.io/kind@v0.24.0", + "/usr/local/go/bin/go install sigs.k8s.io/kind@v0.32.0", "sudo cp /home/$USER/go/bin/kind /usr/local/bin/", "/home/$USER/go/bin/kind version", ] diff --git a/cloudbuild/kne_test.sh b/cloudbuild/kne_test.sh index 7e65f3b51..4455a411c 100755 --- a/cloudbuild/kne_test.sh +++ b/cloudbuild/kne_test.sh @@ -29,6 +29,31 @@ go build -o kne cli="$HOME/kne/kne_cli/kne" popd +# Sync host dependencies with external.pkr.hcl if needed +target_kind_pkg=$(grep -o 'sigs.k8s.io/kind@v[0-9.]*' "$HOME/kne/cloudbuild/external.pkr.hcl" | head -n 1) +if [ -n "$target_kind_pkg" ]; then + target_kind_ver=$(echo "$target_kind_pkg" | grep -o 'v[0-9.]*') + current_kind_ver=$(kind version 2>/dev/null | awk '{print $2}' || true) + if [[ "$current_kind_ver" != "$target_kind_ver" && "$current_kind_ver" != "${target_kind_ver#v}" ]]; then + echo "Syncing host kind from ${current_kind_ver:-none} to $target_kind_ver..." + go install "$target_kind_pkg" + sudo cp -f "$(go env GOPATH)/bin/kind" /usr/local/bin/ + fi +fi + +target_repo=$(grep -o 'https://pkgs.k8s.io/core:/stable:/v[0-9.]*/deb/' "$HOME/kne/cloudbuild/external.pkr.hcl" | head -n 1) +if [ -n "$target_repo" ]; then + target_ver=$(echo "$target_repo" | grep -o 'v[0-9.]*') + current_kubeadm=$(kubeadm version -o short 2>/dev/null || true) + if [[ "$current_kubeadm" != ${target_ver}* ]]; then + echo "Syncing host kubeadm/kubelet from ${current_kubeadm:-none} to $target_ver..." + curl -fsSL "https://pkgs.k8s.io/core:/stable:/${target_ver}/deb/Release.key" | sudo gpg --dearmor --yes -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg + echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] ${target_repo} /" | sudo tee /etc/apt/sources.list.d/kubernetes.list + sudo apt-get update -y + sudo apt-get install -y --allow-change-held-packages --allow-downgrades kubeadm kubelet + fi +fi + # Deploy a kind cluster pushd "$HOME" $cli deploy kne/deploy/kne/kind-bridge.yaml --report_usage=false @@ -50,8 +75,6 @@ cluster: spec: name: kne recycle: True - version: v0.17.0 - image: 'kindest/node:v1.26.0' googleArtifactRegistries: - us-west1-docker.pkg.dev containerImages: diff --git a/cloudbuild/vendors/deployment.yaml b/cloudbuild/vendors/deployment.yaml index fdd38c018..7e79edcb0 100644 --- a/cloudbuild/vendors/deployment.yaml +++ b/cloudbuild/vendors/deployment.yaml @@ -6,8 +6,8 @@ cluster: spec: name: kne recycle: True - version: v0.24.0 - image: kindest/node:v1.31.0 + version: v0.32.0 + image: kindest/node:v1.36.1 googleArtifactRegistries: - us-west1-docker.pkg.dev config: ../../manifests/kind/config.yaml diff --git a/cloudbuild/vendors_test.sh b/cloudbuild/vendors_test.sh index cc8de4fc0..700be8cc2 100755 --- a/cloudbuild/vendors_test.sh +++ b/cloudbuild/vendors_test.sh @@ -29,6 +29,18 @@ go build -o kne cli="$HOME/kne/kne_cli/kne" popd +# Sync host dependencies with external.pkr.hcl if needed +target_kind_pkg=$(grep -o 'sigs.k8s.io/kind@v[0-9.]*' "$HOME/kne/cloudbuild/external.pkr.hcl" | head -n 1) +if [ -n "$target_kind_pkg" ]; then + target_kind_ver=$(echo "$target_kind_pkg" | grep -o 'v[0-9.]*') + current_kind_ver=$(kind version 2>/dev/null | awk '{print $2}' || true) + if [[ "$current_kind_ver" != "$target_kind_ver" && "$current_kind_ver" != "${target_kind_ver#v}" ]]; then + echo "Syncing host kind from ${current_kind_ver:-none} to $target_kind_ver..." + go install "$target_kind_pkg" + sudo cp -f "$(go env GOPATH)/bin/kind" /usr/local/bin/ + fi +fi + # Deploy a cluster + topo pushd "$HOME" $cli deploy kne/cloudbuild/vendors/deployment.yaml --report_usage=false diff --git a/cluster/kubeadm/kubeadm.go b/cluster/kubeadm/kubeadm.go index fbbf29141..1e8e93c21 100644 --- a/cluster/kubeadm/kubeadm.go +++ b/cluster/kubeadm/kubeadm.go @@ -22,6 +22,7 @@ type InitConfigOptions struct { TokenTTL string ImageRepository string ServiceNodePortRange string + KubernetesVersion string } type initConfiguration struct { @@ -40,11 +41,12 @@ type bootstrapToken struct { } type clusterConfiguration struct { - APIVersion string `json:"apiVersion" yaml:"apiVersion"` - Kind string `json:"kind" yaml:"kind"` - ImageRepository string `json:"imageRepository,omitempty" yaml:"imageRepository,omitempty"` - Networking *networking `json:"networking,omitempty" yaml:"networking,omitempty"` - APIServer *apiServer `json:"apiServer,omitempty" yaml:"apiServer,omitempty"` + APIVersion string `json:"apiVersion" yaml:"apiVersion"` + Kind string `json:"kind" yaml:"kind"` + KubernetesVersion string `json:"kubernetesVersion,omitempty" yaml:"kubernetesVersion,omitempty"` + ImageRepository string `json:"imageRepository,omitempty" yaml:"imageRepository,omitempty"` + Networking *networking `json:"networking,omitempty" yaml:"networking,omitempty"` + APIServer *apiServer `json:"apiServer,omitempty" yaml:"apiServer,omitempty"` } type networking struct { @@ -78,9 +80,10 @@ func CreateInitConfigFile(opts InitConfigOptions) (string, func(), error) { } clusterCfg := clusterConfiguration{ - APIVersion: "kubeadm.k8s.io/v1beta3", - Kind: "ClusterConfiguration", - ImageRepository: opts.ImageRepository, + APIVersion: "kubeadm.k8s.io/v1beta3", + Kind: "ClusterConfiguration", + KubernetesVersion: opts.KubernetesVersion, + ImageRepository: opts.ImageRepository, } if opts.PodNetworkCIDR != "" { clusterCfg.Networking = &networking{PodSubnet: opts.PodNetworkCIDR} diff --git a/cluster/kubeadm/kubeadm_test.go b/cluster/kubeadm/kubeadm_test.go index 6f8316383..519303cd3 100644 --- a/cluster/kubeadm/kubeadm_test.go +++ b/cluster/kubeadm/kubeadm_test.go @@ -134,6 +134,21 @@ func TestCreateInitConfigFile(t *testing.T) { "podSubnet: 10.244.0.0/16", "service-node-port-range: 20000-30000", }, + }, { + desc: "with kubernetes version", + opts: InitConfigOptions{ + KubernetesVersion: "v1.35.8", + ImageRepository: "us-west1-docker.pkg.dev/kne-external/kne", + ServiceNodePortRange: "10000-32767", + }, + wantInitCfg: false, + wantYAMLContains: []string{ + "apiVersion: kubeadm.k8s.io/v1beta3", + "kind: ClusterConfiguration", + "kubernetesVersion: v1.35.8", + "imageRepository: us-west1-docker.pkg.dev/kne-external/kne", + "service-node-port-range: 10000-32767", + }, }} for _, tt := range tests { diff --git a/cmd/topology/topology_test.go b/cmd/topology/topology_test.go index 044807334..0c1639939 100644 --- a/cmd/topology/topology_test.go +++ b/cmd/topology/topology_test.go @@ -11,16 +11,17 @@ import ( "testing" "github.com/google/go-cmp/cmp" - tfake "github.com/openconfig/kne/third_party/meshnet/api/clientset/v1beta1/fake" "github.com/openconfig/gnmi/errdiff" cpb "github.com/openconfig/kne/proto/controller" tpb "github.com/openconfig/kne/proto/topo" + topologyv1 "github.com/openconfig/kne/third_party/meshnet/api/types/v1beta1" "github.com/openconfig/kne/topo" "github.com/openconfig/kne/topo/node" "github.com/spf13/cobra" "github.com/spf13/viper" "google.golang.org/protobuf/encoding/prototext" "google.golang.org/protobuf/testing/protocmp" + dfake "k8s.io/client-go/dynamic/fake" kfake "k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/rest" ) @@ -220,14 +221,11 @@ func TestReset(t *testing.T) { rCmd := New() origOpts := opts - tf, err := tfake.NewSimpleClientset() - if err != nil { - t.Fatalf("cannot create fake topology clientset") - } + tf := dfake.NewSimpleDynamicClient(topologyv1.Scheme) opts = []topo.Option{ topo.WithClusterConfig(&rest.Config{}), topo.WithKubeClient(kfake.NewSimpleClientset()), - topo.WithTopoClient(tf), + topo.WithDynamicClient(tf), } defer func() { opts = origOpts @@ -614,14 +612,11 @@ func TestPush(t *testing.T) { rCmd := New() origOpts := opts - tf, err := tfake.NewSimpleClientset() - if err != nil { - t.Fatalf("cannot create fake topology clientset") - } + tf := dfake.NewSimpleDynamicClient(topologyv1.Scheme) opts = []topo.Option{ topo.WithClusterConfig(&rest.Config{}), topo.WithKubeClient(kfake.NewSimpleClientset()), - topo.WithTopoClient(tf), + topo.WithDynamicClient(tf), } defer func() { opts = origOpts diff --git a/controller/server/main.go b/controller/server/main.go index 82cdd8000..5411f8cd4 100644 --- a/controller/server/main.go +++ b/controller/server/main.go @@ -133,6 +133,7 @@ func newDeployment(req *cpb.CreateClusterRequest) (*deploy.Deployment, error) { AllowControlPlaneScheduling: req.GetKubeadm().AllowControlPlaneScheduling, CredentialProviderConfig: req.GetKubeadm().CredentialProviderConfig, ImageRepository: req.GetKubeadm().ImageRepository, + KubernetesVersion: req.GetKubeadm().KubernetesVersion, } switch t := req.GetKubeadm().GetPodNetworkAddOnManifest().GetManifestData().(type) { case *cpb.Manifest_Data: diff --git a/controller/server/main_test.go b/controller/server/main_test.go index b193dc4fb..9510ec1d0 100644 --- a/controller/server/main_test.go +++ b/controller/server/main_test.go @@ -90,6 +90,7 @@ func TestNewDeployment(t *testing.T) { AllowControlPlaneScheduling: true, Network: "my-network", ImageRepository: "us-west1-docker.pkg.dev/kne-external/kne", + KubernetesVersion: "v1.35.8", }, }, IngressSpec: &cpb.CreateClusterRequest_Metallb{ @@ -121,6 +122,7 @@ func TestNewDeployment(t *testing.T) { AllowControlPlaneScheduling: true, Network: "my-network", ImageRepository: "us-west1-docker.pkg.dev/kne-external/kne", + KubernetesVersion: "v1.35.8", }, Ingress: &deploy.MetalLBSpec{ Manifest: testFile.Name(), diff --git a/deploy/deploy.go b/deploy/deploy.go index 635cbe3f3..540741583 100644 --- a/deploy/deploy.go +++ b/deploy/deploy.go @@ -41,7 +41,11 @@ import ( "sigs.k8s.io/yaml" ) -const defaultKubeadmImageRepository = "us-west1-docker.pkg.dev/kne-external/kne" +const ( + defaultKubeadmImageRepository = "us-west1-docker.pkg.dev/kne-external/kne" + defaultKubernetesVersion = "v1.36.1" + defaultKindNodeImage = "kindest/node:v1.36.1" +) var ( setPIDMaxScript = filepath.Join(homedir.HomeDir(), "kne-internal", "set_pid_max.sh") @@ -223,6 +227,11 @@ func (d *Deployment) Deploy(ctx context.Context, kubecfg string) (rerr error) { return fmt.Errorf("kubectl version outside of supported range: %v", err) } + log.Infof("Validating cluster server version") + if err := d.validateClusterVersion(kClient); err != nil { + return fmt.Errorf("cluster server version validation failed: %w", err) + } + ctx, cancel := context.WithCancel(ctx) // Watch the container status of the pods so we can fail if a container fails to start running. @@ -336,6 +345,65 @@ func parseVersion(s string) (semver.Version, error) { return v, nil } +func (d *Deployment) validateClusterVersion(kClient kubernetes.Interface) error { + info, err := kClient.Discovery().ServerVersion() + if err != nil { + return fmt.Errorf("failed to discover cluster server version: %w", err) + } + // Allow unconfigured fake discovery clients in unit tests. + if strings.Contains(info.GitVersion, "Format:%H") { + log.V(1).Infof("Skipping version validation on fake discovery client: %s", info.GitVersion) + return nil + } + serverVer, err := parseVersion(info.GitVersion) + if err != nil { + return fmt.Errorf("failed to parse server version %q: %w", info.GitVersion, err) + } + + wantVerStr := "" + switch c := d.Cluster.(type) { + case *KubeadmSpec: + wantVerStr = c.KubernetesVersion + if wantVerStr == "" { + wantVerStr = defaultKubernetesVersion + } + case *KindSpec: + img := c.Image + if img == "" { + img = defaultKindNodeImage + } + wantVerStr = extractVersionFromImage(img) + } + + if wantVerStr != "" { + wantVer, err := parseVersion(wantVerStr) + if err != nil { + return fmt.Errorf("failed to parse expected version %q: %w", wantVerStr, err) + } + if serverVer.Major != wantVer.Major || serverVer.Minor != wantVer.Minor { + return fmt.Errorf("cluster server version mismatch: got %s, want %s", info.GitVersion, wantVerStr) + } + log.Infof("Validated cluster server version: %s matches expected %s", info.GitVersion, wantVerStr) + } + return nil +} + +func extractVersionFromImage(img string) string { + if idx := strings.Index(img, "@"); idx != -1 { + img = img[:idx] + } + if idx := strings.LastIndex(img, ":"); idx != -1 { + tag := img[idx+1:] + if !strings.HasPrefix(tag, "v") && len(tag) > 0 && tag[0] >= '0' && tag[0] <= '9' { + tag = "v" + tag + } + if _, err := parseVersion(tag); err == nil { + return tag + } + } + return "" +} + func (d *Deployment) Delete() error { log.Infof("Deleting cluster...") if err := d.Cluster.Delete(); err != nil { @@ -435,6 +503,7 @@ type KubeadmSpec struct { AllowControlPlaneScheduling bool `yaml:"allowControlPlaneScheduling"` ImageRepository string `yaml:"imageRepository"` ServiceNodePortRange string `yaml:"serviceNodePortRange"` + KubernetesVersion string `yaml:"kubernetesVersion"` } func (k *KubeadmSpec) checkDependencies() error { @@ -460,12 +529,17 @@ func (k *KubeadmSpec) Deploy(ctx context.Context) error { if k.ServiceNodePortRange != "" { portRange = k.ServiceNodePortRange } + k8sVersion := defaultKubernetesVersion + if k.KubernetesVersion != "" { + k8sVersion = k.KubernetesVersion + } cfgPath, cleanup, err := kubeadm.CreateInitConfigFile(kubeadm.InitConfigOptions{ CRISocket: k.CRISocket, PodNetworkCIDR: k.PodNetworkCIDR, TokenTTL: k.TokenTTL, ImageRepository: imageRepository, ServiceNodePortRange: portRange, + KubernetesVersion: k8sVersion, }) if err != nil { return fmt.Errorf("failed to create kubeadm init config file: %w", err) @@ -647,9 +721,10 @@ func (k *KindSpec) create() error { if k.Name != "" { args = append(args, "--name", k.Name) } - if k.Image != "" { - args = append(args, "--image", k.Image) + if k.Image == "" { + k.Image = defaultKindNodeImage } + args = append(args, "--image", k.Image) if k.Retain { args = append(args, "--retain") } @@ -1061,9 +1136,12 @@ func (m *MeshnetSpec) Healthy(ctx context.Context) error { return err } for { + if ctx.Err() != nil { + return fmt.Errorf("context canceled before meshnet healthy: %w", ctx.Err()) + } select { case <-ctx.Done(): - return fmt.Errorf("context canceled before meshnet healthy") + return fmt.Errorf("context canceled before meshnet healthy: %w", ctx.Err()) case e, ok := <-w.ResultChan(): if !ok { return fmt.Errorf("watch channel closed before meshnet healthy") @@ -1365,9 +1443,12 @@ func deploymentHealthy(ctx context.Context, c kubernetes.Interface, name string) } ch := w.ResultChan() for { + if ctx.Err() != nil { + return fmt.Errorf("context canceled before %q healthy: %w", name, ctx.Err()) + } select { case <-ctx.Done(): - return fmt.Errorf("context canceled before %q healthy", name) + return fmt.Errorf("context canceled before %q healthy: %w", name, ctx.Err()) case e, ok := <-ch: if !ok { return fmt.Errorf("watch channel closed before %q healthy", name) diff --git a/deploy/deploy_test.go b/deploy/deploy_test.go index 258f887ba..0fa3ac073 100644 --- a/deploy/deploy_test.go +++ b/deploy/deploy_test.go @@ -7,10 +7,10 @@ import ( "testing" "time" - "github.com/moby/moby/api/types/network" - dclient "github.com/moby/moby/client" "github.com/golang/mock/gomock" "github.com/google/go-cmp/cmp" + "github.com/moby/moby/api/types/network" + dclient "github.com/moby/moby/client" "github.com/openconfig/gnmi/errdiff" mfake "github.com/openconfig/kne/api/metallb/clientset/v1beta1/fake" "github.com/openconfig/kne/deploy/mocks" @@ -24,7 +24,9 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + kversion "k8s.io/apimachinery/pkg/version" "k8s.io/apimachinery/pkg/watch" + fakediscovery "k8s.io/client-go/discovery/fake" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/fake" fakecorev1 "k8s.io/client-go/kubernetes/typed/core/v1/fake" @@ -130,6 +132,16 @@ func TestKubeadmSpec(t *testing.T) { {Cmd: "sudo", Args: []string{"cat", "/etc/kubernetes/admin.conf"}}, {Cmd: "docker", Args: []string{"network", "create", "kne-kubeadm-.*"}}, }, + }, { + desc: "custom kubernetes version", + k: &KubeadmSpec{ + KubernetesVersion: "v1.36.1", + }, + resp: []fexec.Response{ + {Cmd: "sudo", Args: []string{"kubeadm", "init", "--config", ".*"}}, + {Cmd: "sudo", Args: []string{"cat", "/etc/kubernetes/admin.conf"}}, + {Cmd: "docker", Args: []string{"network", "create", "kne-kubeadm-.*"}}, + }, }} for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { @@ -224,7 +236,7 @@ func TestKindSpec(t *testing.T) { Name: "test", }, resp: []fexec.Response{ - {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test"}}, + {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test", "--image", defaultKindNodeImage}}, }, }, { desc: "create cluster with recycle", @@ -234,7 +246,7 @@ func TestKindSpec(t *testing.T) { }, resp: []fexec.Response{ {Cmd: "kubectl", Args: []string{"cluster-info", "--context", "kind-test"}, Err: "already exists"}, - {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test"}}, + {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test", "--image", defaultKindNodeImage}}, }, }, { desc: "exists cluster with recycle", @@ -258,7 +270,7 @@ func TestKindSpec(t *testing.T) { Name: "test", }, resp: []fexec.Response{ - {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test"}, Err: "failed to create cluster"}, + {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test", "--image", defaultKindNodeImage}, Err: "failed to create cluster"}, }, wantErr: "failed to create cluster", }, { @@ -268,7 +280,7 @@ func TestKindSpec(t *testing.T) { GoogleArtifactRegistries: []string{"us-west1-docker.pkg.dev", "us-central1-docker.pkg.dev"}, }, resp: []fexec.Response{ - {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test"}}, + {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test", "--image", defaultKindNodeImage}}, }, }, { desc: "create cluster with GAR - failure", @@ -277,7 +289,7 @@ func TestKindSpec(t *testing.T) { GoogleArtifactRegistries: []string{"us-west1-docker.pkg.dev", "us-central1-docker.pkg.dev"}, }, resp: []fexec.Response{ - {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test"}}, + {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test", "--image", defaultKindNodeImage}}, }, setupGARErr: true, wantErr: "failed to setup GAR access", @@ -369,7 +381,7 @@ func TestKindSpec(t *testing.T) { }, }, resp: []fexec.Response{ - {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test"}}, + {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test", "--image", defaultKindNodeImage}}, {Cmd: "docker", Args: []string{"pull", "docker"}, Err: "failed to pull"}, {Cmd: "docker", Args: []string{"pull", "docker"}, Err: "failed to pull"}, {Cmd: "docker", Args: []string{"pull", "docker"}, Err: "failed to pull"}, @@ -385,7 +397,7 @@ func TestKindSpec(t *testing.T) { }, }, resp: []fexec.Response{ - {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test"}}, + {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test", "--image", defaultKindNodeImage}}, {Cmd: "docker", Args: []string{"pull", "docker"}, Err: "failed to pull"}, {Cmd: "docker", Args: []string{"pull", "docker"}}, {Cmd: "docker", Args: []string{"tag", "docker", "local"}}, @@ -400,7 +412,7 @@ func TestKindSpec(t *testing.T) { }, }, resp: []fexec.Response{ - {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test"}}, + {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test", "--image", defaultKindNodeImage}}, {Cmd: "docker", Args: []string{"pull", "docker"}, Err: "failed to pull", Stdout: "not found"}, }, wantErr: "not found", @@ -413,7 +425,7 @@ func TestKindSpec(t *testing.T) { }, }, resp: []fexec.Response{ - {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test"}}, + {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test", "--image", defaultKindNodeImage}}, {Cmd: "docker", Args: []string{"pull", "docker"}}, {Cmd: "docker", Args: []string{"tag", "docker", "local"}, Err: "failed to tag"}, }, @@ -427,7 +439,7 @@ func TestKindSpec(t *testing.T) { }, }, resp: []fexec.Response{ - {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test"}}, + {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test", "--image", defaultKindNodeImage}}, {Cmd: "docker", Args: []string{"pull", "docker"}}, {Cmd: "docker", Args: []string{"tag", "docker", "local"}}, {Cmd: "kind", Args: []string{"load", "docker-image", "local", "--name", "test"}, Err: "failed to load"}, @@ -442,7 +454,7 @@ func TestKindSpec(t *testing.T) { }, }, resp: []fexec.Response{ - {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test"}}, + {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test", "--image", defaultKindNodeImage}}, }, wantErr: "source container must not be empty", }, { @@ -454,7 +466,7 @@ func TestKindSpec(t *testing.T) { }, }, resp: []fexec.Response{ - {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test"}}, + {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test", "--image", defaultKindNodeImage}}, {Cmd: "docker", Args: []string{"pull", "docker"}}, {Cmd: "kind", Args: []string{"load", "docker-image", "docker", "--name", "test"}}, }, @@ -541,7 +553,7 @@ func TestKindSpec(t *testing.T) { }, resp: []fexec.Response{ {Cmd: "kind", Args: []string{"version"}, Stdout: "kind v0.15.0 go1.18.2 linux/amd64"}, - {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test"}}, + {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test", "--image", defaultKindNodeImage}}, }, }, { desc: "kind prerelease version pass", @@ -551,7 +563,7 @@ func TestKindSpec(t *testing.T) { }, resp: []fexec.Response{ {Cmd: "kind", Args: []string{"version"}, Stdout: "kind v0.15.0-prelease go1.18.2 linux/amd64"}, - {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test"}}, + {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test", "--image", defaultKindNodeImage}}, }, }, { desc: "kind version pass - major", @@ -561,7 +573,7 @@ func TestKindSpec(t *testing.T) { }, resp: []fexec.Response{ {Cmd: "kind", Args: []string{"version"}, Stdout: "kind v1.15.0 go1.18.2 linux/amd64"}, - {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test"}}, + {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test", "--image", defaultKindNodeImage}}, }, }, { desc: "kind version pass - patch", @@ -571,7 +583,7 @@ func TestKindSpec(t *testing.T) { }, resp: []fexec.Response{ {Cmd: "kind", Args: []string{"version"}, Stdout: "kind v0.15.1 go1.18.2 linux/amd64"}, - {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test"}}, + {Cmd: "kind", Args: []string{"create", "cluster", "--name", "test", "--image", defaultKindNodeImage}}, }, }} for _, tt := range tests { @@ -2322,3 +2334,102 @@ func TestCheckDependencies(t *testing.T) { }) } } + +func TestValidateClusterVersion(t *testing.T) { + tests := []struct { + desc string + cluster Cluster + serverVersion string + wantErr string + }{{ + desc: "kubeadm default matching version", + cluster: &KubeadmSpec{}, + serverVersion: defaultKubernetesVersion, + }, { + desc: "kubeadm custom matching version", + cluster: &KubeadmSpec{ + KubernetesVersion: "v1.35.8", + }, + serverVersion: "v1.35.8", + }, { + desc: "kubeadm version mismatch", + cluster: &KubeadmSpec{ + KubernetesVersion: "v1.36.1", + }, + serverVersion: "v1.26.0", + wantErr: "cluster server version mismatch: got v1.26.0, want v1.36.1", + }, { + desc: "kind default matching version", + cluster: &KindSpec{}, + serverVersion: extractVersionFromImage(defaultKindNodeImage), + }, { + desc: "kind image matching version", + cluster: &KindSpec{ + Image: "kindest/node:v1.36.1@sha256:3489c7674813ba5d8b1a9977baea8a6e553784dab7b84759d1014dbd78f7ebd5", + }, + serverVersion: "v1.36.1", + }, { + desc: "kind image version mismatch", + cluster: &KindSpec{ + Image: "kindest/node:v1.36.1", + }, + serverVersion: "v1.26.0", + wantErr: "cluster server version mismatch: got v1.26.0, want v1.36.1", + }, { + desc: "external cluster skipped", + cluster: &ExternalSpec{}, + serverVersion: "v1.26.0", + }} + + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + kClient := fake.NewSimpleClientset() + if fakeDisc, ok := kClient.Discovery().(*fakediscovery.FakeDiscovery); ok { + fakeDisc.FakedServerVersion = &kversion.Info{ + GitVersion: tt.serverVersion, + } + } + d := &Deployment{ + Cluster: tt.cluster, + } + err := d.validateClusterVersion(kClient) + if s := errdiff.Substring(err, tt.wantErr); s != "" { + t.Fatalf("unexpected error: %s", s) + } + }) + } +} + +func TestExtractVersionFromImage(t *testing.T) { + tests := []struct { + input string + want string + }{{ + input: "kindest/node:v1.36.1", + want: "v1.36.1", + }, { + input: "kindest/node:v1.36.1@sha256:3489c7674813ba5d8b1a9977baea8a6e553784dab7b84759d1014dbd78f7ebd5", + want: "v1.36.1", + }, { + input: "us-west1-docker.pkg.dev/kne-external/kne/kindest/node:v1.36.1", + want: "v1.36.1", + }, { + input: "kindest/node:1.36.1", + want: "v1.36.1", + }, { + input: "kindest/node:latest", + want: "", + }, { + input: "", + want: "", + }} + + for _, tt := range tests { + t.Run(tt.input, func(t *testing.T) { + got := extractVersionFromImage(tt.input) + if got != tt.want { + t.Errorf("extractVersionFromImage(%q) = %q, want %q", tt.input, got, tt.want) + } + }) + } +} diff --git a/deploy/kne/kind-bridge-cdnos.yaml b/deploy/kne/kind-bridge-cdnos.yaml index c07f19e32..b92767bc9 100644 --- a/deploy/kne/kind-bridge-cdnos.yaml +++ b/deploy/kne/kind-bridge-cdnos.yaml @@ -6,8 +6,8 @@ cluster: spec: name: kne recycle: True - version: v0.24.0 - image: kindest/node:v1.31.0 + version: v0.32.0 + image: kindest/node:v1.36.1 config: ../../manifests/kind/config.yaml additionalManifests: - ../../manifests/kind/bridge.yaml @@ -36,4 +36,4 @@ controllers: operator: ../../manifests/controllers/lemming/manifest.yaml - kind: Cdnos spec: - operator: ../../manifests/controllers/cdnos/manifest.yaml \ No newline at end of file + operator: ../../manifests/controllers/cdnos/manifest.yaml diff --git a/deploy/kne/kind-bridge.yaml b/deploy/kne/kind-bridge.yaml index afe6d381b..18f191f81 100644 --- a/deploy/kne/kind-bridge.yaml +++ b/deploy/kne/kind-bridge.yaml @@ -6,8 +6,8 @@ cluster: spec: name: kne recycle: True - version: v0.24.0 - image: kindest/node:v1.31.0 + version: v0.32.0 + image: kindest/node:v1.36.1 config: ../../manifests/kind/config.yaml additionalManifests: - ../../manifests/kind/bridge.yaml diff --git a/deploy/kne/kubeadm.yaml b/deploy/kne/kubeadm.yaml index a2bd07a0d..bf25c5255 100644 --- a/deploy/kne/kubeadm.yaml +++ b/deploy/kne/kubeadm.yaml @@ -9,6 +9,7 @@ cluster: tokenTTL: 0 # no timeout podNetworkAddOnManifest: ../../manifests/flannel/manifest.yaml allowControlPlaneScheduling: true + kubernetesVersion: v1.36.1 ingress: kind: MetalLB spec: diff --git a/docs/setup.md b/docs/setup.md index ccbe9bc6f..e3e553411 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -59,12 +59,10 @@ sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl ## Install Kind -> NOTE: This will install version `0.27.0` which was known to work with KNE at -> some point in time. You can instead install a newer version if you need new -> features or are having problems. +Install the latest version of kind: ```bash -go install sigs.k8s.io/kind@v0.27.0 +go install sigs.k8s.io/kind@latest ``` ## Clone openconfig/kne GitHub repo diff --git a/go.mod b/go.mod index 6f6a75aa3..8d8202c58 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/openconfig/kne go 1.26.3 require ( - cloud.google.com/go/cloudbuild v1.32.0 + cloud.google.com/go/cloudbuild v1.33.0 cloud.google.com/go/pubsub/v2 v2.6.2 github.com/aristanetworks/arista-ceoslab-operator/v2 v2.1.2 github.com/blang/semver v3.5.1+incompatible @@ -17,8 +17,8 @@ require ( github.com/open-traffic-generator/keng-operator v0.4.2 github.com/open-traffic-generator/snappi/gosnappi v1.61.0 github.com/openconfig/gnmi v0.14.1 - github.com/openconfig/kne/third_party/meshnet v0.5.0 - github.com/openconfig/lemming/operator v0.2.7 + github.com/openconfig/kne/third_party/meshnet v0.5.1 + github.com/openconfig/lemming/operator v0.2.8 github.com/openconfig/ondatra v0.14.6 github.com/pborman/uuid v1.2.1 github.com/pkg/errors v0.9.1 @@ -34,18 +34,19 @@ require ( golang.org/x/oauth2 v0.36.0 golang.org/x/sync v0.22.0 google.golang.org/api v0.293.0 - google.golang.org/grpc v1.83.1 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.12 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.36.3 - k8s.io/apimachinery v0.36.3 - k8s.io/client-go v0.36.3 + k8s.io/api v0.36.4 + k8s.io/apimachinery v0.36.4 + k8s.io/client-go v0.36.4 k8s.io/klog/v2 v2.140.0 k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 - sigs.k8s.io/controller-runtime v0.24.1 sigs.k8s.io/yaml v1.6.0 ) +require sigs.k8s.io/controller-runtime v0.24.1 // indirect + require ( bitbucket.org/creachadair/stringset v0.0.14 // indirect cloud.google.com/go v0.123.0 // indirect @@ -67,7 +68,6 @@ require ( github.com/docker/go-connections v0.8.1 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/emicklei/go-restful/v3 v3.13.0 // indirect - github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/felixge/httpsnoop v1.1.0 // indirect github.com/fsnotify/fsnotify v1.10.1 // indirect github.com/fxamacker/cbor/v2 v2.9.1 // indirect @@ -148,12 +148,12 @@ require ( go.opentelemetry.io/proto/otlp v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.5 // indirect - golang.org/x/crypto v0.54.0 // indirect + golang.org/x/crypto v0.55.0 // indirect golang.org/x/exp v0.0.0-20260709172345-9ea1abe57597 // indirect - golang.org/x/net v0.57.0 // indirect + golang.org/x/net v0.58.0 // indirect golang.org/x/sys v0.47.0 // indirect golang.org/x/term v0.45.0 // indirect - golang.org/x/text v0.40.0 // indirect + golang.org/x/text v0.41.0 // indirect golang.org/x/time v0.15.0 // indirect google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d // indirect @@ -163,7 +163,7 @@ require ( gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/kube-openapi v0.0.0-20260330154417-16be699c7b31 // indirect - k8s.io/streaming v0.36.3 // indirect + k8s.io/streaming v0.36.4 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.3 // indirect diff --git a/go.sum b/go.sum index 813c33e48..e948dfdd2 100644 --- a/go.sum +++ b/go.sum @@ -7,8 +7,8 @@ cloud.google.com/go/auth v0.23.0 h1:6Gg1CMgpgubRG7DGz5Vf1pcoNo8RfiRiRAPS4crTp54= cloud.google.com/go/auth v0.23.0/go.mod h1:4DhBRcqvtljQN3dJ57qtqbib5ZGCYE5f2crfiiC2EM0= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= -cloud.google.com/go/cloudbuild v1.32.0 h1:tlF+KSIJJ0kaKkxACpk9htZ1euDpyOqPuO1aHR4j3oI= -cloud.google.com/go/cloudbuild v1.32.0/go.mod h1:mYgcM8CMaPmAnO7GxSQ9ADAxVRwS+1b7s6WVkt29OXY= +cloud.google.com/go/cloudbuild v1.33.0 h1:DI9EeUcrHMNqipbzs8TzxGKqTutQ3sUygDv7Ofu3Ha4= +cloud.google.com/go/cloudbuild v1.33.0/go.mod h1:0CpB3eBpWT4JCIUqV7C9mqszd/q/D8Jvs5HGkDQJO1k= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= cloud.google.com/go/iam v1.11.0 h1:KieQ9Pb+LLPak1O3Rv3GgCxhnmkYf7Xyh0P5HfF1jFM= @@ -26,8 +26,6 @@ github.com/aristanetworks/arista-ceoslab-operator/v2 v2.1.2 h1:1aAxwwu4xyfiU1/FX github.com/aristanetworks/arista-ceoslab-operator/v2 v2.1.2/go.mod h1:/mvSt2fEmlVEU7dppip3UNz/MUt380f50dFsZRGn83o= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/carlmontanari/difflibgo v0.0.0-20210718194309-31b9e131c298 h1:Y8rTum6LZ8oP/2aC+OaaP76OCjHbunKMkim81mzNCH0= @@ -75,8 +73,6 @@ github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMDjpqGAGacLe2T0ds= github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0= -github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= -github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/felixge/httpsnoop v1.1.0 h1:3YtUj32ZZkqZtt3sZZsClsymw/QDuVfpNhoA31zeORc= github.com/felixge/httpsnoop v1.1.0/go.mod h1:Zqxgdd+1Rkcz8euOqdr7lqgCRJztwr5hp9vDSi5UZCE= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -92,8 +88,6 @@ github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= -github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.23.1 h1:1HBACs7XIwR2RcmItfdSFlALhGbe6S92p0ry4d1GWg4= github.com/go-openapi/jsonpointer v0.23.1/go.mod h1:iWRmZTrGn7XwYhtPt/fvdSFj1OfNBngqRT2UG3BxSqY= github.com/go-openapi/jsonreference v0.21.6 h1:NZ5nGfnaM1n4I43Xjm1e5/M2GjOwQwndQz22uhxwD+Y= @@ -136,8 +130,8 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/glog v1.2.5 h1:DrW6hGnjIhtvhOIiAKT6Psh/Kd/ldepEa81DKeiRJ5I= github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= @@ -185,8 +179,6 @@ github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5T github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 h1:5VipnvEpbqr2gA2VbM+nYVbkIF28c5ZQfqCBQ5g2xfk= github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0/go.mod h1:Hyl3n6Twe1hvtd9XUXDec4pTvgMSEixRuQKPTMH2bNs= -github.com/h-fam/errdiff v1.0.2 h1:rPsW4ob2fMOIulwTEoZXaaUIuud7XUudw5SLKTZj3Ss= -github.com/h-fam/errdiff v1.0.2/go.mod h1:FOzgnHXSEE3rRvmGXgmiqWl+H3lwLywYm9CSXqXrSTg= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -250,8 +242,8 @@ github.com/openconfig/gribi v1.9.1 h1:lN5KMEKu+X5L24XVHnwMJe52De5CSNZb1rR0F/ym13 github.com/openconfig/gribi v1.9.1/go.mod h1:P1ZjH4Nj5u+D+jgZ89YpAR8RFyGixQ3U5tR+LHUNTbc= github.com/openconfig/grpctunnel v0.1.0 h1:EN99qtlExZczgQgp5ANnHRC/Rs62cAG+Tz2BQ5m/maM= github.com/openconfig/grpctunnel v0.1.0/go.mod h1:G04Pdu0pml98tdvXrvLaU+EBo3PxYfI9MYqpvdaEHLo= -github.com/openconfig/lemming/operator v0.2.7 h1:ZSzu4v5WGT/HYJg2z1AA8480e8VKNSWzknObe/sVycY= -github.com/openconfig/lemming/operator v0.2.7/go.mod h1:guu/+tddTcE9L+vPjGev5WCnxitlZO6C8Kucm9/GmfA= +github.com/openconfig/lemming/operator v0.2.8 h1:LETV6PE8tgwMvSoKTWpVfWx+f+MNr0cOdxgdHv+uGME= +github.com/openconfig/lemming/operator v0.2.8/go.mod h1:pUjAPw3FU9BUI/3xwkPooURsJ1oIYQHppWlNyzW0AGw= github.com/openconfig/ondatra v0.14.6 h1:Ci4W4MA4CqmK6khTPms2ZX5rkvDKUqRQX9BUE6WjH0g= github.com/openconfig/ondatra v0.14.6/go.mod h1:qsX19FqgyioshI2vlGjbZx5o+yK86UztMWuAKp1KhPY= github.com/openconfig/testt v0.0.0-20220311054427-efbb1a32ec07 h1:X631iD/B0ximGFb5P9LY5wHju4SiedxUhc5UZEo7VSw= @@ -280,15 +272,7 @@ github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= -github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= -github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= -github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= -github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= -github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -376,10 +360,6 @@ go.opentelemetry.io/proto/otlp v1.11.0 h1:5rrYs0Ykyj50sdU/JU0x8etU+LubXWb+gED6Tb go.opentelemetry.io/proto/otlp v1.11.0/go.mod h1:SmVizdCOAm3XBtG1g1NnOdhW6jtddT72hLMhv8VwA8E= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= -go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.universe.tf/metallb v0.16.1 h1:iVtjCslcUFMOEvuNeAyW2ygZxyW+6YjnNcEuCTOZezc= go.universe.tf/metallb v0.16.1/go.mod h1:bcFtsBPqKJChcT7gf4bhRtR6HAu8TeY7OGLYanK2tOQ= go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= @@ -393,8 +373,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= -golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= +golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= +golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20260709172345-9ea1abe57597 h1:qLvzZeaANDgyVOA8pyHCOStGlXn0rseXma+GQjeuv2g= golang.org/x/exp v0.0.0-20260709172345-9ea1abe57597/go.mod h1:EdfpwwqSu+0Li0mzskwHU6FWDV3t9Q+RZDo3QMUtL3Q= @@ -419,8 +399,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b 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.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= -golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= +golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= +golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= @@ -455,8 +435,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= -golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= +golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= +golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -494,8 +474,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.83.1 h1:HIO0+BEtBP6soyqvqC8sNUjZ7bTs+0hFQuFF+RAy++Y= -google.golang.org/grpc v1.83.1/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -528,20 +508,18 @@ gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.36.3 h1:NxB+05W2UGqXWFXcLO0RB5cnqnUPP5v5sVlaOH0Iz4w= -k8s.io/api v0.36.3/go.mod h1:JzLQKqRHC5+I8RVj/lS3lCg0mg6nWI9Fo/Sk3ElxHzg= -k8s.io/apiextensions-apiserver v0.36.0 h1:Wt7E8J+VBCbj4FjiBfDTK/neXDDjyJVJc7xfuOHImZ0= -k8s.io/apiextensions-apiserver v0.36.0/go.mod h1:kGDjH0msuiIB3tgsYRV0kS9GqpMYMUsQ3GHv7TApyug= -k8s.io/apimachinery v0.36.3 h1:PkzMRBRG8joFD8EhCuQAtNPvJlxb82FwplP26HIzvAM= -k8s.io/apimachinery v0.36.3/go.mod h1:cTSjBWgPe/6CQyBKzY/hDIRWCQQQeK0mfLbml0UYFHE= -k8s.io/client-go v0.36.3 h1:M4JdVzXxYcZk4fGpfDdYnxSwhLKWCFoQsHW6t+z8Hfg= -k8s.io/client-go v0.36.3/go.mod h1:gcPwr0c87vjjG6HB6pWEqOeuYVoXSsREjzux2j6GF30= +k8s.io/api v0.36.4 h1:RxrvqCL6vgH5/+UnTeu1IIFqYmGfy0hnyrod1rn35Oo= +k8s.io/api v0.36.4/go.mod h1:S2B3orCFBDhrgyWbLeuKcT2QdHIpQesBkCYSlWtwUOw= +k8s.io/apimachinery v0.36.4 h1:PT2UzkupGuAx/+xT5XjiMJ1WGpY3fn9/hdAvjweRet4= +k8s.io/apimachinery v0.36.4/go.mod h1:p2I2dipt7JHG+quVwQ1d02d28O4GdDi77RByQ13MTpk= +k8s.io/client-go v0.36.4 h1:MDvfDNvMSt0Br94SK8neviVlwL9qifw9B26hJCpD1K0= +k8s.io/client-go v0.36.4/go.mod h1:pNK4WKELbwlEDvtbE8l22lEZL5THYF61H5EealokZmA= k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= k8s.io/kube-openapi v0.0.0-20260330154417-16be699c7b31 h1:V+sn9a/1fEYDGwnllCmqXBk8x7obZ+hl869Q3Abumkg= k8s.io/kube-openapi v0.0.0-20260330154417-16be699c7b31/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0= -k8s.io/streaming v0.36.3 h1:9rAaqBk0C0Pc7+/fqGekj07NV+/Xrew58p647A0JT8w= -k8s.io/streaming v0.36.3/go.mod h1:z6fV3D+NVkoeqRMtWwlUZK6U17SY/LqNzOxWL6GyR/s= +k8s.io/streaming v0.36.4 h1:RS5YlhrdBN2pKGVjgygGntdu6SNdsduyjGWGe3cX0vo= +k8s.io/streaming v0.36.4/go.mod h1:tJ6S2bZa2HxIBauguBbCWSCYyd93Grfz1+z3tcOvlDE= k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 h1:jVkFFVfXdXP74B/zbO3hM3hpSFD0xvhQ5U686DPurkE= k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3/go.mod h1:M2s5JB1lIYP3jzZdorPLHXIPJzt9vv2muW5a6L9DtNM= pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= diff --git a/load/testdata/manifests/controllers/lemming/manifest.yaml b/load/testdata/manifests/controllers/lemming/manifest.yaml index 049ccc373..f12af151b 100644 --- a/load/testdata/manifests/controllers/lemming/manifest.yaml +++ b/load/testdata/manifests/controllers/lemming/manifest.yaml @@ -537,7 +537,7 @@ spec: - --leader-elect command: - /manager - image: us-west1-docker.pkg.dev/openconfig-lemming/release/operator:v0.2.8 + image: us-west1-docker.pkg.dev/openconfig-lemming/release/operator:v0.2.9 livenessProbe: httpGet: path: /healthz diff --git a/manifests/controllers/ceoslab/manifest.yaml b/manifests/controllers/ceoslab/manifest.yaml index f9d2be424..4a7da60ed 100644 --- a/manifests/controllers/ceoslab/manifest.yaml +++ b/manifests/controllers/ceoslab/manifest.yaml @@ -21,193 +21,193 @@ spec: singular: ceoslabdevice scope: Namespaced versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: CEosLabDevice is the Schema for the ceoslabdevices API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: CEosLabDeviceSpec defines the desired state of CEosLabDevice - properties: - args: - description: Additional arguments to pass to /sbin/init. Those necessary to boot properly are already present. - items: - type: string - type: array - certconfig: - description: X.509 certificate configuration. - properties: - selfsignedcerts: - description: Configuration for self-signed certificates. - items: - properties: - certname: - description: Certificate name on the node. - type: string - commonname: - description: Common name to set in the cert. - type: string - keyname: - description: Key name on the node. - type: string - keysize: - description: RSA keysize to use for key generation. - format: int32 - type: integer - type: object - type: array - type: object - envvars: - additionalProperties: - type: string - description: Additional environment variables. Those necessary to boot properly are already present. - type: object - image: - description: 'Image name. Default: ceos:latest' - type: string - initcontainerimage: - description: 'Init container image name. Default: networkop/init-wait:latest' - type: string - intfmapping: - additionalProperties: - type: string - description: Explicit interface mapping between kernel devices and interface names. If this is defined, any unmapped devices are ignored. - type: object - numinterfaces: - description: 'Number of data interfaces to create. An additional interface (eth0) is created for pod connectivity. Default: 0 interfaces' - format: int32 - type: integer - resourcerequirements: - additionalProperties: - type: string - description: 'Resource requests to configure on the pod. Default: none' - type: object - services: - additionalProperties: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: CEosLabDevice is the Schema for the ceoslabdevices API + properties: + apiVersion: + description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" + type: string + kind: + description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + type: string + metadata: + type: object + spec: + description: CEosLabDeviceSpec defines the desired state of CEosLabDevice + properties: + args: + description: Additional arguments to pass to /sbin/init. Those necessary to boot properly are already present. + items: + type: string + type: array + certconfig: + description: X.509 certificate configuration. properties: - tcpports: - description: TCP ports to forward to the pod. + selfsignedcerts: + description: Configuration for self-signed certificates. items: properties: - in: - description: Port inside the container. - format: int32 - type: integer - out: - description: Port outside the container. Defaults to the same as in. + certname: + description: Certificate name on the node. + type: string + commonname: + description: Common name to set in the cert. + type: string + keyname: + description: Key name on the node. + type: string + keysize: + description: RSA keysize to use for key generation. format: int32 type: integer type: object type: array type: object - description: 'Port mappings for container services. Default: none' - type: object - sleep: - description: 'Time (in seconds) to wait before starting the device. Default: 0 seconds' - format: int32 - type: integer - toggleoverrides: - additionalProperties: - type: boolean - description: EOS feature toggle overrides - type: object - waitforagents: - description: EOS agents to for the startup probe to block on - items: + envvars: + additionalProperties: + type: string + description: Additional environment variables. Those necessary to boot properly are already present. + type: object + image: + description: "Image name. Default: ceos:latest" type: string - type: array - type: object - status: - description: CEosLabDeviceStatus defines the observed state of CEosLabDevice - properties: - configmapconfig: - description: ConfigMap state as configured in configmaps - properties: - intfmappingstatus: - additionalProperties: - type: string + initcontainerimage: + description: "Init container image name. Default: networkop/init-wait:latest" + type: string + intfmapping: + additionalProperties: + type: string + description: Explicit interface mapping between kernel devices and interface names. If this is defined, any unmapped devices are ignored. + type: object + numinterfaces: + description: "Number of data interfaces to create. An additional interface (eth0) is created for pod connectivity. Default: 0 interfaces" + format: int32 + type: integer + resourcerequirements: + additionalProperties: + type: string + description: "Resource requests to configure on the pod. Default: none" + type: object + services: + additionalProperties: + properties: + tcpports: + description: TCP ports to forward to the pod. + items: + properties: + in: + description: Port inside the container. + format: int32 + type: integer + out: + description: Port outside the container. Defaults to the same as in. + format: int32 + type: integer + type: object + type: array type: object - rceosstale: + description: "Port mappings for container services. Default: none" + type: object + sleep: + description: "Time (in seconds) to wait before starting the device. Default: 0 seconds" + format: int32 + type: integer + toggleoverrides: + additionalProperties: type: boolean - selfsignedcertstatus: - additionalProperties: - properties: - certname: - description: Certificate name on the node. - type: string - commonname: - description: Common name to set in the cert. - type: string - keyname: - description: Key name on the node. - type: string - keysize: - description: RSA keysize to use for key generation. - format: int32 - type: integer - type: object - type: object - startupconfigresourceversion: + description: EOS feature toggle overrides + type: object + waitforagents: + description: EOS agents to for the startup probe to block on + items: type: string - toggleoverridesstatus: - additionalProperties: + type: array + type: object + status: + description: CEosLabDeviceStatus defines the observed state of CEosLabDevice + properties: + configmapconfig: + description: ConfigMap state as configured in configmaps + properties: + intfmappingstatus: + additionalProperties: + type: string + type: object + rceosstale: type: boolean - type: object - type: object - podconfigmapconfig: - description: ConfigMap state as present in the pod. If these diverge, we need to restart the pod to update. Even if an in-place update is possible these are needed at boot time. - properties: - intfmappingstatus: - additionalProperties: + selfsignedcertstatus: + additionalProperties: + properties: + certname: + description: Certificate name on the node. + type: string + commonname: + description: Common name to set in the cert. + type: string + keyname: + description: Key name on the node. + type: string + keysize: + description: RSA keysize to use for key generation. + format: int32 + type: integer + type: object + type: object + startupconfigresourceversion: type: string - type: object - rceosstale: - type: boolean - selfsignedcertstatus: - additionalProperties: - properties: - certname: - description: Certificate name on the node. - type: string - commonname: - description: Common name to set in the cert. - type: string - keyname: - description: Key name on the node. - type: string - keysize: - description: RSA keysize to use for key generation. - format: int32 - type: integer + toggleoverridesstatus: + additionalProperties: + type: boolean type: object - type: object - startupconfigresourceversion: - type: string - toggleoverridesstatus: - additionalProperties: + type: object + podconfigmapconfig: + description: ConfigMap state as present in the pod. If these diverge, we need to restart the pod to update. Even if an in-place update is possible these are needed at boot time. + properties: + intfmappingstatus: + additionalProperties: + type: string + type: object + rceosstale: type: boolean - type: object - type: object - reason: - description: Reason for potential failure - type: string - status: - description: Device status - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} + selfsignedcertstatus: + additionalProperties: + properties: + certname: + description: Certificate name on the node. + type: string + commonname: + description: Common name to set in the cert. + type: string + keyname: + description: Key name on the node. + type: string + keysize: + description: RSA keysize to use for key generation. + format: int32 + type: integer + type: object + type: object + startupconfigresourceversion: + type: string + toggleoverridesstatus: + additionalProperties: + type: boolean + type: object + type: object + reason: + description: Reason for potential failure + type: string + status: + description: Device status + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} status: acceptedNames: kind: "" @@ -227,37 +227,37 @@ metadata: name: arista-ceoslab-operator-leader-election-role namespace: arista-ceoslab-operator-system rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -265,108 +265,108 @@ metadata: creationTimestamp: null name: arista-ceoslab-operator-manager-role rules: -- apiGroups: - - ceoslab.arista.com - resources: - - ceoslabdevices - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - ceoslab.arista.com - resources: - - ceoslabdevices/finalizers - verbs: - - update -- apiGroups: - - ceoslab.arista.com - resources: - - ceoslabdevices/status - verbs: - - get - - patch - - update -- apiGroups: - - "" - resources: - - configmaps - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - pods - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - secrets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - services - verbs: - - create - - delete - - get - - list - - patch - - update - - watch + - apiGroups: + - ceoslab.arista.com + resources: + - ceoslabdevices + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - ceoslab.arista.com + resources: + - ceoslabdevices/finalizers + verbs: + - update + - apiGroups: + - ceoslab.arista.com + resources: + - ceoslabdevices/status + verbs: + - get + - patch + - update + - apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - pods + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: arista-ceoslab-operator-metrics-reader rules: -- nonResourceURLs: - - /metrics - verbs: - - get + - nonResourceURLs: + - /metrics + verbs: + - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: arista-ceoslab-operator-proxy-role rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding @@ -378,9 +378,9 @@ roleRef: kind: Role name: arista-ceoslab-operator-leader-election-role subjects: -- kind: ServiceAccount - name: arista-ceoslab-operator-controller-manager - namespace: arista-ceoslab-operator-system + - kind: ServiceAccount + name: arista-ceoslab-operator-controller-manager + namespace: arista-ceoslab-operator-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -391,9 +391,9 @@ roleRef: kind: ClusterRole name: arista-ceoslab-operator-manager-role subjects: -- kind: ServiceAccount - name: arista-ceoslab-operator-controller-manager - namespace: arista-ceoslab-operator-system + - kind: ServiceAccount + name: arista-ceoslab-operator-controller-manager + namespace: arista-ceoslab-operator-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -404,9 +404,9 @@ roleRef: kind: ClusterRole name: arista-ceoslab-operator-proxy-role subjects: -- kind: ServiceAccount - name: arista-ceoslab-operator-controller-manager - namespace: arista-ceoslab-operator-system + - kind: ServiceAccount + name: arista-ceoslab-operator-controller-manager + namespace: arista-ceoslab-operator-system --- apiVersion: v1 data: @@ -436,10 +436,10 @@ metadata: namespace: arista-ceoslab-operator-system spec: ports: - - name: https - port: 8443 - protocol: TCP - targetPort: https + - name: https + port: 8443 + protocol: TCP + targetPort: https selector: control-plane: controller-manager --- @@ -463,53 +463,35 @@ spec: control-plane: controller-manager spec: containers: - - args: - - --secure-listen-address=0.0.0.0:8443 - - --upstream=http://127.0.0.1:8080/ - - --logtostderr=true - - --v=0 - image: registry.k8s.io/kubebuilder/kube-rbac-proxy:v0.11.0 - name: kube-rbac-proxy - ports: - - containerPort: 8443 - name: https - protocol: TCP - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi - - args: - - --health-probe-bind-address=:8081 - - --metrics-bind-address=127.0.0.1:8080 - - --leader-elect - command: - - /manager - image: ghcr.io/aristanetworks/arista-ceoslab-operator:v2.1.2 - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - name: manager - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 10m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=127.0.0.1:8080 + - --leader-elect + command: + - /manager + image: ghcr.io/aristanetworks/arista-ceoslab-operator:v2.1.2 + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false securityContext: runAsNonRoot: true serviceAccountName: arista-ceoslab-operator-controller-manager diff --git a/manifests/controllers/lemming/manifest.yaml b/manifests/controllers/lemming/manifest.yaml index 2628fcf34..788cb5c59 100644 --- a/manifests/controllers/lemming/manifest.yaml +++ b/manifests/controllers/lemming/manifest.yaml @@ -559,7 +559,7 @@ spec: - --leader-elect command: - /manager - image: us-west1-docker.pkg.dev/openconfig-lemming/release/operator:v0.2.8 + image: us-west1-docker.pkg.dev/openconfig-lemming/release/operator:v0.2.9 livenessProbe: httpGet: path: /healthz diff --git a/manifests/controllers/srlinux/manifest.yaml b/manifests/controllers/srlinux/manifest.yaml index ba211a4b2..3ce8e2ea4 100644 --- a/manifests/controllers/srlinux/manifest.yaml +++ b/manifests/controllers/srlinux/manifest.yaml @@ -26,159 +26,166 @@ spec: singular: srlinux scope: Namespaced versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.image - name: Image - type: string - - jsonPath: .status.status - name: Status - type: string - - jsonPath: .status.ready - name: Ready - type: boolean - - jsonPath: .status.startup-config.phase - name: Config - type: string - name: v1 - schema: - openAPIV3Schema: - description: Srlinux is the Schema for the srlinuxes API. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - license_key: - description: license key from license secret that contains a license file - for this Srlinux - type: string - metadata: - type: object - spec: - description: SrlinuxSpec defines the desired state of Srlinux. - properties: - config: - description: NodeConfig represents srlinux node configuration parameters. - properties: - args: - description: Command args to pass into the pod. - items: - type: string - type: array - cert: - description: CertificateCfg represents srlinux certificate configuration - parameters. - properties: - cert_name: - description: Certificate name on the node. + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.image + name: Image + type: string + - jsonPath: .status.status + name: Status + type: string + - jsonPath: .status.ready + name: Ready + type: boolean + - jsonPath: .status.startup-config.phase + name: Config + type: string + name: v1 + schema: + openAPIV3Schema: + description: Srlinux is the Schema for the srlinuxes API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + license_key: + description: + license key from license secret that contains a license file + for this Srlinux + type: string + metadata: + type: object + spec: + description: SrlinuxSpec defines the desired state of Srlinux. + properties: + config: + description: NodeConfig represents srlinux node configuration parameters. + properties: + args: + description: Command args to pass into the pod. + items: type: string - common_name: - description: Common name to set in the cert. + type: array + cert: + description: + CertificateCfg represents srlinux certificate configuration + parameters. + properties: + cert_name: + description: Certificate name on the node. + type: string + common_name: + description: Common name to set in the cert. + type: string + key_name: + description: Key name on the node. + type: string + key_size: + description: RSA keysize to use for key generation. + format: int32 + type: integer + type: object + command: + description: Command to pass into pod. + items: type: string - key_name: - description: Key name on the node. + type: array + config_data_present: + description: + When set to true by kne, srlinux controller will + attempt to mount the file with startup config to the pod + type: boolean + config_file: + description: + Startup configuration file name for the pod. Set + in the kne topo and created by kne as a config map + type: string + config_path: + description: + Mount point for configuration inside the pod. Should + point to a dir that contains ConfigFile + type: string + entry_command: + description: Specific entry point command for accessing the pod. + type: string + env: + additionalProperties: type: string - key_size: - description: RSA keysize to use for key generation. - format: int32 - type: integer - type: object - command: - description: Command to pass into pod. - items: + description: Map of environment variables to pass into the pod. + type: object + image: + description: Container image to use with for the SR Linux container. type: string - type: array - config_data_present: - description: When set to true by kne, srlinux controller will - attempt to mount the file with startup config to the pod - type: boolean - config_file: - description: Startup configuration file name for the pod. Set - in the kne topo and created by kne as a config map - type: string - config_path: - description: Mount point for configuration inside the pod. Should - point to a dir that contains ConfigFile - type: string - entry_command: - description: Specific entry point command for accessing the pod. - type: string - env: - additionalProperties: + init-image: + description: + Init container image to use with for the SR Linux + container. type: string - description: Map of environment variables to pass into the pod. - type: object - image: - description: Container image to use with for the SR Linux container. - type: string - init-image: - description: Init container image to use with for the SR Linux - container. + sleep: + description: Sleep time before starting the pod. + format: int32 + type: integer + type: object + constraints: + additionalProperties: type: string - sleep: - description: Sleep time before starting the pod. - format: int32 - type: integer - type: object - constraints: - additionalProperties: + type: object + model: + description: Model encodes SR Linux variant (ixr-d3, ixr-6e, etc) type: string - type: object - model: - description: Model encodes SR Linux variant (ixr-d3, ixr-6e, etc) - type: string - num-interfaces: - type: integer - version: - description: |- - Version may be set in kne topology as a mean to explicitly provide version information - in case it is not encoded in the image tag - type: string - type: object - status: - description: SrlinuxStatus defines the observed state of Srlinux. - properties: - image: - description: Image used to run srlinux pod - type: string - ready: - description: |- - Ready is true if the srlinux NOS is ready to receive config. - This is when management server is running and initial commit is processed. - type: boolean - startup-config: - description: StartupConfig contains the status of the startup-config. - properties: - phase: - description: 'Phase is the phase startup-config is in. Can be - one of: "pending", "loaded", "not-provided", "failed".' - type: string - type: object - status: - description: |- - Status is the status of the srlinux custom resource. - Can be one of: "created", "running", "error". - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} + num-interfaces: + type: integer + version: + description: |- + Version may be set in kne topology as a mean to explicitly provide version information + in case it is not encoded in the image tag + type: string + type: object + status: + description: SrlinuxStatus defines the observed state of Srlinux. + properties: + image: + description: Image used to run srlinux pod + type: string + ready: + description: |- + Ready is true if the srlinux NOS is ready to receive config. + This is when management server is running and initial commit is processed. + type: boolean + startup-config: + description: StartupConfig contains the status of the startup-config. + properties: + phase: + description: + 'Phase is the phase startup-config is in. Can be + one of: "pending", "loaded", "not-provided", "failed".' + type: string + type: object + status: + description: |- + Status is the status of the srlinux custom resource. + Can be one of: "created", "running", "error". + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} --- apiVersion: v1 kind: ServiceAccount @@ -206,89 +213,88 @@ metadata: name: srlinux-controller-leader-election-role namespace: srlinux-controller rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: srlinux-controller-manager-role rules: -- apiGroups: - - "" - resources: - - configmaps - - pods - - secrets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - kne.srlinux.dev - resources: - - srlinuxes - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - kne.srlinux.dev - resources: - - srlinuxes/finalizers - verbs: - - update -- apiGroups: - - kne.srlinux.dev - resources: - - srlinuxes/status - verbs: - - get - - patch - - update + - apiGroups: + - "" + resources: + - configmaps + - pods + - secrets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - kne.srlinux.dev + resources: + - srlinuxes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - kne.srlinux.dev + resources: + - srlinuxes/finalizers + verbs: + - update + - apiGroups: + - kne.srlinux.dev + resources: + - srlinuxes/status + verbs: + - get + - patch + - update --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: - app.kubernetes.io/component: kube-rbac-proxy app.kubernetes.io/created-by: srlinux-controller app.kubernetes.io/instance: metrics-reader app.kubernetes.io/managed-by: kustomize @@ -296,16 +302,15 @@ metadata: app.kubernetes.io/part-of: srlinux-controller name: srlinux-controller-metrics-reader rules: -- nonResourceURLs: - - /metrics - verbs: - - get + - nonResourceURLs: + - /metrics + verbs: + - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: - app.kubernetes.io/component: kube-rbac-proxy app.kubernetes.io/created-by: srlinux-controller app.kubernetes.io/instance: proxy-role app.kubernetes.io/managed-by: kustomize @@ -313,18 +318,18 @@ metadata: app.kubernetes.io/part-of: srlinux-controller name: srlinux-controller-proxy-role rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding @@ -343,9 +348,9 @@ roleRef: kind: Role name: srlinux-controller-leader-election-role subjects: -- kind: ServiceAccount - name: srlinux-controller-controller-manager - namespace: srlinux-controller + - kind: ServiceAccount + name: srlinux-controller-controller-manager + namespace: srlinux-controller --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -363,15 +368,14 @@ roleRef: kind: ClusterRole name: srlinux-controller-manager-role subjects: -- kind: ServiceAccount - name: srlinux-controller-controller-manager - namespace: srlinux-controller + - kind: ServiceAccount + name: srlinux-controller-controller-manager + namespace: srlinux-controller --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: - app.kubernetes.io/component: kube-rbac-proxy app.kubernetes.io/created-by: srlinux-controller app.kubernetes.io/instance: proxy-rolebinding app.kubernetes.io/managed-by: kustomize @@ -383,15 +387,14 @@ roleRef: kind: ClusterRole name: srlinux-controller-proxy-role subjects: -- kind: ServiceAccount - name: srlinux-controller-controller-manager - namespace: srlinux-controller + - kind: ServiceAccount + name: srlinux-controller-controller-manager + namespace: srlinux-controller --- apiVersion: v1 kind: Service metadata: labels: - app.kubernetes.io/component: kube-rbac-proxy app.kubernetes.io/created-by: srlinux-controller app.kubernetes.io/instance: controller-manager-metrics-service app.kubernetes.io/managed-by: kustomize @@ -402,10 +405,10 @@ metadata: namespace: srlinux-controller spec: ports: - - name: https - port: 8443 - protocol: TCP - targetPort: https + - name: https + port: 8443 + protocol: TCP + targetPort: https selector: control-plane: controller-manager --- @@ -438,74 +441,51 @@ spec: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/arch - operator: In - values: - - amd64 - - arm64 - - ppc64le - - s390x - - key: kubernetes.io/os - operator: In - values: - - linux + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - arm64 + - ppc64le + - s390x + - key: kubernetes.io/os + operator: In + values: + - linux containers: - - args: - - --secure-listen-address=0.0.0.0:8443 - - --upstream=http://127.0.0.1:8080/ - - --logtostderr=true - - --v=0 - image: registry.k8s.io/kubebuilder/kube-rbac-proxy:v0.13.1 - name: kube-rbac-proxy - ports: - - containerPort: 8443 - name: https - protocol: TCP - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - - args: - - --health-probe-bind-address=:8081 - - --metrics-bind-address=127.0.0.1:8080 - - --leader-elect - command: - - /manager - image: ghcr.io/srl-labs/srl-controller:v0.7.1 - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - name: manager - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 10m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=127.0.0.1:8080 + - --leader-elect + command: + - /manager + image: ghcr.io/srl-labs/srl-controller:v0.7.1 + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL securityContext: runAsNonRoot: true serviceAccountName: srlinux-controller-controller-manager diff --git a/manifests/keysight/ixiatg-configmap.yaml b/manifests/keysight/ixiatg-configmap.yaml index 2028969b0..17368e02c 100644 --- a/manifests/keysight/ixiatg-configmap.yaml +++ b/manifests/keysight/ixiatg-configmap.yaml @@ -11,26 +11,26 @@ data: { "name": "controller", "path": "ghcr.io/open-traffic-generator/keng-controller", - "tag": "1.32.0-1" + "tag": "1.61.0-1" }, { "name": "gnmi-server", "path": "ghcr.io/open-traffic-generator/otg-gnmi-server", - "tag": "1.32.0" + "tag": "1.61.0" }, { "name": "traffic-engine", "path": "ghcr.io/open-traffic-generator/ixia-c-traffic-engine", - "tag": "1.8.0.245" + "tag": "1.8.0.544" }, { "name": "protocol-engine", "path": "ghcr.io/open-traffic-generator/ixia-c-protocol-engine", - "tag": "1.00.0.457" + "tag": "1.00.0.534" }, { "name": "ixhw-server", "path": "ghcr.io/open-traffic-generator/keng-layer23-hw-server", - "tag": "1.32.0-1" + "tag": "1.61.0-2" }] } diff --git a/manifests/keysight/ixiatg-operator.yaml b/manifests/keysight/ixiatg-operator.yaml index 7905959fe..60d6df777 100644 --- a/manifests/keysight/ixiatg-operator.yaml +++ b/manifests/keysight/ixiatg-operator.yaml @@ -9,8 +9,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.4.1 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.16.3 name: ixiatgs.network.keysight.com spec: group: network.keysight.com @@ -21,110 +20,119 @@ spec: singular: ixiatg scope: Namespaced versions: - - name: v1beta1 - schema: - openAPIV3Schema: - description: IxiaTG is the Schema for the ixiatg API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: IxiaTGSpec defines the desired state of IxiaTG - properties: - api_endpoint_map: - additionalProperties: - description: IxiaTGSvcPort defines the endpoint services for configuration and stats for the OTG node - properties: - in: - format: int32 - type: integer - out: - format: int32 - type: integer - required: - - in + - name: v1beta1 + schema: + openAPIV3Schema: + description: IxiaTG is the Schema for the ixiatg API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: IxiaTGSpec defines the desired state of IxiaTG + properties: + api_endpoint_map: + additionalProperties: + description: + IxiaTGSvcPort defines the endpoint services for configuration + and stats for the OTG node + properties: + in: + format: int32 + type: integer + out: + format: int32 + type: integer + required: + - in + type: object + description: ApiEndPoint as define in OTG config type: object - description: ApiEndPoint as define in OTG config - type: object - desired_state: - description: Desired state by network emulation (KNE) - type: string - init_container: - description: Init container image of the node - properties: - image: - type: string - sleep: - format: int32 - type: integer - type: object - interfaces: - description: Interfaces with DUT - items: - description: IxiaTGSvcPort defines the endpoint ports for network traffic for the OTG node + desired_state: + description: Desired state by network emulation (KNE) + type: string + init_container: + description: Init container image of the node properties: - group: + image: type: string - name: - type: string - required: - - name + sleep: + format: int32 + type: integer type: object - type: array - release: - description: Version of the node - type: string - type: object - status: - description: IxiaTGStatus defines the observed state of IxiaTG - properties: - api_endpoint: - description: List of OTG service names - properties: - pod_name: - type: string - service_names: - items: - type: string - type: array - type: object - interfaces: - description: List of OTG port and pod mapping - items: - description: IxiaTGIntfStatus defines the mapping between endpoint ports and encasing pods + interfaces: + description: Interfaces with DUT + items: + description: + IxiaTGSvcPort defines the endpoint ports for network + traffic for the OTG node + properties: + group: + type: string + name: + type: string + required: + - name + type: object + type: array + release: + description: Version of the node + type: string + type: object + status: + description: IxiaTGStatus defines the observed state of IxiaTG + properties: + api_endpoint: + description: List of OTG service names properties: - interface: - type: string - name: - type: string pod_name: type: string + service_names: + items: + type: string + type: array type: object - type: array - reason: - description: Reason in case of failure - type: string - state: - description: Observed state - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] + interfaces: + description: List of OTG port and pod mapping + items: + description: + IxiaTGIntfStatus defines the mapping between endpoint + ports and encasing pods + properties: + interface: + type: string + name: + type: string + pod_name: + type: string + type: object + type: array + reason: + description: Reason in case of failure + type: string + state: + description: Observed state + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} --- apiVersion: v1 kind: ServiceAccount @@ -138,146 +146,120 @@ metadata: name: ixiatg-op-leader-election-role namespace: ixiatg-op-system rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - creationTimestamp: null name: ixiatg-op-manager-role rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - pods - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - secrets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - "" - resources: - - services - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - network.keysight.com - resources: - - ixiatgs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - network.keysight.com - resources: - - ixiatgs/finalizers - verbs: - - update -- apiGroups: - - network.keysight.com - resources: - - ixiatgs/status - verbs: - - get - - patch - - update + - apiGroups: + - "" + resources: + - configmaps + - pods + - services + verbs: + - create + - delete + - get + - list + - watch + - apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - get + - list + - update + - watch + - apiGroups: + - network.keysight.com + resources: + - ixiatgs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - network.keysight.com + resources: + - ixiatgs/finalizers + verbs: + - update + - apiGroups: + - network.keysight.com + resources: + - ixiatgs/status + verbs: + - get + - patch + - update --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: ixiatg-op-metrics-reader rules: -- nonResourceURLs: - - /metrics - verbs: - - get + - nonResourceURLs: + - /metrics + verbs: + - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: ixiatg-op-proxy-role rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding @@ -289,9 +271,9 @@ roleRef: kind: Role name: ixiatg-op-leader-election-role subjects: -- kind: ServiceAccount - name: ixiatg-op-controller-manager - namespace: ixiatg-op-system + - kind: ServiceAccount + name: ixiatg-op-controller-manager + namespace: ixiatg-op-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -302,9 +284,9 @@ roleRef: kind: ClusterRole name: ixiatg-op-manager-role subjects: -- kind: ServiceAccount - name: ixiatg-op-controller-manager - namespace: ixiatg-op-system + - kind: ServiceAccount + name: ixiatg-op-controller-manager + namespace: ixiatg-op-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -315,9 +297,9 @@ roleRef: kind: ClusterRole name: ixiatg-op-proxy-role subjects: -- kind: ServiceAccount - name: ixiatg-op-controller-manager - namespace: ixiatg-op-system + - kind: ServiceAccount + name: ixiatg-op-controller-manager + namespace: ixiatg-op-system --- apiVersion: v1 data: @@ -327,7 +309,7 @@ data: health: healthProbeBindAddress: :8081 metrics: - bindAddress: 127.0.0.1:8080 + bindAddress: :8443 webhook: port: 9443 leaderElection: @@ -347,9 +329,10 @@ metadata: namespace: ixiatg-op-system spec: ports: - - name: https - port: 8443 - targetPort: https + - name: https + port: 8443 + protocol: TCP + targetPort: 8443 selector: control-plane: controller-manager --- @@ -371,47 +354,43 @@ spec: control-plane: controller-manager spec: containers: - - args: - - --secure-listen-address=0.0.0.0:8443 - - --upstream=http://127.0.0.1:8080/ - - --logtostderr=true - - --v=10 - image: registry.k8s.io/kubebuilder/kube-rbac-proxy:v0.8.0 - name: kube-rbac-proxy - ports: - - containerPort: 8443 - name: https - - args: - - --health-probe-bind-address=:8081 - - --metrics-bind-address=127.0.0.1:8080 - - --leader-elect - command: - - /manager - image: ghcr.io/open-traffic-generator/keng-operator:0.3.34 - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - name: manager - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - resources: - limits: - cpu: 100m - memory: 200Mi - requests: - cpu: 100m - memory: 20Mi - securityContext: - allowPrivilegeEscalation: false - imagePullSecrets: - - name: ixia-pull-secret + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=:8443 + - --leader-elect + command: + - /manager + image: ghcr.io/open-traffic-generator/keng-operator:0.4.2 + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 100m + memory: 200Mi + requests: + cpu: 100m + memory: 20Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - all + readOnlyRootFilesystem: true + runAsGroup: 1000 + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault securityContext: runAsNonRoot: true serviceAccountName: ixiatg-op-controller-manager diff --git a/manifests/meshnet/grpc/manifest.yaml b/manifests/meshnet/grpc/manifest.yaml index f6fd7d447..4f86e634d 100644 --- a/manifests/meshnet/grpc/manifest.yaml +++ b/manifests/meshnet/grpc/manifest.yaml @@ -326,7 +326,7 @@ spec: hostNetwork: true hostPID: true nodeSelector: - beta.kubernetes.io/arch: amd64 + kubernetes.io/arch: amd64 serviceAccountName: meshnet terminationGracePeriodSeconds: 30 tolerations: diff --git a/manifests/meshnet/vxlan/manifest.yaml b/manifests/meshnet/vxlan/manifest.yaml index f37073e02..d9140120b 100644 --- a/manifests/meshnet/vxlan/manifest.yaml +++ b/manifests/meshnet/vxlan/manifest.yaml @@ -326,7 +326,7 @@ spec: hostNetwork: true hostPID: true nodeSelector: - beta.kubernetes.io/arch: amd64 + kubernetes.io/arch: amd64 serviceAccountName: meshnet terminationGracePeriodSeconds: 30 tolerations: diff --git a/proto/ciena/ciena.pb.go b/proto/ciena/ciena.pb.go index f680b861a..b52fb8e8f 100644 --- a/proto/ciena/ciena.pb.go +++ b/proto/ciena/ciena.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 -// protoc v6.31.1 +// protoc-gen-go v1.34.2 +// protoc v3.21.12 // source: ciena.proto package ciena @@ -157,7 +157,7 @@ func file_ciena_proto_rawDescGZIP() []byte { } var file_ciena_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_ciena_proto_goTypes = []interface{}{ +var file_ciena_proto_goTypes = []any{ (*SystemEquipment)(nil), // 0: ciena.SystemEquipment (*CienaConfig)(nil), // 1: ciena.CienaConfig } @@ -176,7 +176,7 @@ func file_ciena_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_ciena_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_ciena_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*SystemEquipment); i { case 0: return &v.state @@ -188,7 +188,7 @@ func file_ciena_proto_init() { return nil } } - file_ciena_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_ciena_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*CienaConfig); i { case 0: return &v.state diff --git a/proto/controller.proto b/proto/controller.proto index 4add57a59..87f1287fb 100644 --- a/proto/controller.proto +++ b/proto/controller.proto @@ -74,6 +74,7 @@ message KubeadmSpec { bool allow_control_plane_scheduling = 6; string credential_provider_config = 7; string image_repository = 8; + string kubernetes_version = 9; } // External cluster specifications diff --git a/proto/controller/controller.pb.go b/proto/controller/controller.pb.go index 6c0ce84c6..d9a73e427 100644 --- a/proto/controller/controller.pb.go +++ b/proto/controller/controller.pb.go @@ -282,6 +282,7 @@ type KubeadmSpec struct { AllowControlPlaneScheduling bool `protobuf:"varint,6,opt,name=allow_control_plane_scheduling,json=allowControlPlaneScheduling,proto3" json:"allow_control_plane_scheduling,omitempty"` CredentialProviderConfig string `protobuf:"bytes,7,opt,name=credential_provider_config,json=credentialProviderConfig,proto3" json:"credential_provider_config,omitempty"` ImageRepository string `protobuf:"bytes,8,opt,name=image_repository,json=imageRepository,proto3" json:"image_repository,omitempty"` + KubernetesVersion string `protobuf:"bytes,9,opt,name=kubernetes_version,json=kubernetesVersion,proto3" json:"kubernetes_version,omitempty"` } func (x *KubeadmSpec) Reset() { @@ -372,6 +373,13 @@ func (x *KubeadmSpec) GetImageRepository() string { return "" } +func (x *KubeadmSpec) GetKubernetesVersion() string { + if x != nil { + return x.KubernetesVersion + } + return "" +} + // External cluster specifications type ExternalSpec struct { state protoimpl.MessageState @@ -2368,7 +2376,7 @@ var file_controller_proto_rawDesc = []byte{ 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x8f, 0x03, 0x0a, 0x0b, 0x4b, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xbe, 0x03, 0x0a, 0x0b, 0x4b, 0x75, 0x62, 0x65, 0x61, 0x64, 0x6d, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x69, 0x5f, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x69, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x70, 0x6f, 0x64, @@ -2393,294 +2401,297 @@ var file_controller_proto_rawDesc = []byte{ 0x69, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x69, 0x6d, 0x61, - 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x28, 0x0a, 0x0c, - 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x70, 0x65, 0x63, 0x12, 0x18, 0x0a, 0x07, - 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, - 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x22, 0x81, 0x01, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x61, 0x6c, - 0x6c, 0x62, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0c, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, - 0x73, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, - 0x52, 0x0b, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x44, 0x69, 0x72, 0x12, 0x19, 0x0a, - 0x08, 0x69, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x07, 0x69, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x30, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, - 0x66, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, - 0x52, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x22, 0x66, 0x0a, 0x0b, 0x4d, 0x65, - 0x73, 0x68, 0x6e, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0c, 0x6d, 0x61, 0x6e, + 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x2d, 0x0a, 0x12, + 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x65, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x28, 0x0a, 0x0c, 0x45, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x70, 0x65, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x6e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x22, 0x81, 0x01, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x6c, + 0x62, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0c, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, + 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, + 0x0b, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x44, 0x69, 0x72, 0x12, 0x19, 0x0a, 0x08, + 0x69, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, + 0x69, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x30, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, + 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, + 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x22, 0x66, 0x0a, 0x0b, 0x4d, 0x65, 0x73, + 0x68, 0x6e, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0c, 0x6d, 0x61, 0x6e, 0x69, + 0x66, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, + 0x18, 0x01, 0x52, 0x0b, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x44, 0x69, 0x72, 0x12, + 0x30, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x4d, + 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, + 0x74, 0x22, 0x98, 0x02, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, + 0x53, 0x70, 0x65, 0x63, 0x12, 0x30, 0x0a, 0x06, 0x69, 0x78, 0x69, 0x61, 0x74, 0x67, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x2e, 0x49, 0x78, 0x69, 0x61, 0x54, 0x47, 0x53, 0x70, 0x65, 0x63, 0x48, 0x00, 0x52, 0x06, + 0x69, 0x78, 0x69, 0x61, 0x74, 0x67, 0x12, 0x33, 0x0a, 0x07, 0x73, 0x72, 0x6c, 0x69, 0x6e, 0x75, + 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x52, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x53, 0x70, 0x65, 0x63, + 0x48, 0x00, 0x52, 0x07, 0x73, 0x72, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x12, 0x33, 0x0a, 0x07, 0x63, + 0x65, 0x6f, 0x73, 0x6c, 0x61, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x45, 0x4f, 0x53, 0x4c, 0x61, + 0x62, 0x53, 0x70, 0x65, 0x63, 0x48, 0x00, 0x52, 0x07, 0x63, 0x65, 0x6f, 0x73, 0x6c, 0x61, 0x62, + 0x12, 0x33, 0x0a, 0x07, 0x6c, 0x65, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x4c, + 0x65, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x70, 0x65, 0x63, 0x48, 0x00, 0x52, 0x07, 0x6c, 0x65, + 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x2d, 0x0a, 0x05, 0x63, 0x64, 0x6e, 0x6f, 0x73, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x2e, 0x43, 0x64, 0x6e, 0x6f, 0x73, 0x53, 0x70, 0x65, 0x63, 0x48, 0x00, 0x52, 0x05, 0x63, + 0x64, 0x6e, 0x6f, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0xd4, 0x01, 0x0a, + 0x0a, 0x49, 0x78, 0x69, 0x61, 0x54, 0x47, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0c, 0x6d, + 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x44, + 0x69, 0x72, 0x12, 0x3e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6d, 0x61, 0x70, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x6c, 0x65, 0x72, 0x2e, 0x49, 0x78, 0x69, 0x61, 0x54, 0x47, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x4d, 0x61, 0x70, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, + 0x61, 0x70, 0x12, 0x30, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x12, 0x2d, 0x0a, 0x07, 0x63, 0x66, 0x67, 0x5f, 0x6d, 0x61, 0x70, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, + 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x06, 0x63, 0x66, 0x67, + 0x4d, 0x61, 0x70, 0x22, 0x5c, 0x0a, 0x0f, 0x49, 0x78, 0x69, 0x61, 0x54, 0x47, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, + 0x12, 0x2f, 0x0a, 0x06, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x49, 0x78, + 0x69, 0x61, 0x54, 0x47, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x06, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x73, 0x22, 0x47, 0x0a, 0x0b, 0x49, 0x78, 0x69, 0x61, 0x54, 0x47, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, 0x66, 0x0a, 0x0b, 0x53, 0x52, + 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0c, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x44, 0x69, 0x72, - 0x12, 0x30, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, - 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, - 0x73, 0x74, 0x22, 0x98, 0x02, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, - 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x30, 0x0a, 0x06, 0x69, 0x78, 0x69, 0x61, 0x74, 0x67, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x65, 0x72, 0x2e, 0x49, 0x78, 0x69, 0x61, 0x54, 0x47, 0x53, 0x70, 0x65, 0x63, 0x48, 0x00, 0x52, - 0x06, 0x69, 0x78, 0x69, 0x61, 0x74, 0x67, 0x12, 0x33, 0x0a, 0x07, 0x73, 0x72, 0x6c, 0x69, 0x6e, - 0x75, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x52, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x53, 0x70, 0x65, - 0x63, 0x48, 0x00, 0x52, 0x07, 0x73, 0x72, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x12, 0x33, 0x0a, 0x07, - 0x63, 0x65, 0x6f, 0x73, 0x6c, 0x61, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x45, 0x4f, 0x53, 0x4c, - 0x61, 0x62, 0x53, 0x70, 0x65, 0x63, 0x48, 0x00, 0x52, 0x07, 0x63, 0x65, 0x6f, 0x73, 0x6c, 0x61, - 0x62, 0x12, 0x33, 0x0a, 0x07, 0x6c, 0x65, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, - 0x4c, 0x65, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x70, 0x65, 0x63, 0x48, 0x00, 0x52, 0x07, 0x6c, - 0x65, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x2d, 0x0a, 0x05, 0x63, 0x64, 0x6e, 0x6f, 0x73, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x65, 0x72, 0x2e, 0x43, 0x64, 0x6e, 0x6f, 0x73, 0x53, 0x70, 0x65, 0x63, 0x48, 0x00, 0x52, 0x05, - 0x63, 0x64, 0x6e, 0x6f, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0xd4, 0x01, - 0x0a, 0x0a, 0x49, 0x78, 0x69, 0x61, 0x54, 0x47, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0c, - 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, - 0x44, 0x69, 0x72, 0x12, 0x3e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6d, 0x61, - 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x49, 0x78, 0x69, 0x61, 0x54, 0x47, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x4d, 0x61, 0x70, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x4d, 0x61, 0x70, 0x12, 0x30, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x08, 0x6f, 0x70, 0x65, - 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x2d, 0x0a, 0x07, 0x63, 0x66, 0x67, 0x5f, 0x6d, 0x61, 0x70, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x06, 0x63, 0x66, - 0x67, 0x4d, 0x61, 0x70, 0x22, 0x5c, 0x0a, 0x0f, 0x49, 0x78, 0x69, 0x61, 0x54, 0x47, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, - 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, - 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x49, - 0x78, 0x69, 0x61, 0x54, 0x47, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x06, 0x69, 0x6d, 0x61, 0x67, - 0x65, 0x73, 0x22, 0x47, 0x0a, 0x0b, 0x49, 0x78, 0x69, 0x61, 0x54, 0x47, 0x49, 0x6d, 0x61, 0x67, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, 0x66, 0x0a, 0x0b, 0x53, - 0x52, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0c, 0x6d, 0x61, - 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x44, 0x69, - 0x72, 0x12, 0x30, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, - 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x22, 0x66, 0x0a, 0x0b, 0x43, 0x45, 0x4f, 0x53, 0x4c, 0x61, 0x62, 0x53, 0x70, - 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0c, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x5f, 0x64, - 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x6d, 0x61, - 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x44, 0x69, 0x72, 0x12, 0x30, 0x0a, 0x08, 0x6f, 0x70, 0x65, - 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, - 0x74, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x66, 0x0a, 0x0b, 0x4c, - 0x65, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0c, 0x6d, 0x61, - 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x44, 0x69, - 0x72, 0x12, 0x30, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, - 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x22, 0x3d, 0x0a, 0x09, 0x43, 0x64, 0x6e, 0x6f, 0x73, 0x53, 0x70, 0x65, 0x63, - 0x12, 0x30, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x12, 0x30, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, - 0x6f, 0x72, 0x22, 0x47, 0x0a, 0x08, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x14, - 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x04, - 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x66, 0x20, 0x01, - 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x42, 0x0f, 0x0a, 0x0d, 0x6d, 0x61, - 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x22, 0x8c, 0x03, 0x0a, 0x14, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x6f, 0x72, 0x22, 0x66, 0x0a, 0x0b, 0x43, 0x45, 0x4f, 0x53, 0x4c, 0x61, 0x62, 0x53, 0x70, 0x65, + 0x63, 0x12, 0x25, 0x0a, 0x0c, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x69, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x6d, 0x61, 0x6e, + 0x69, 0x66, 0x65, 0x73, 0x74, 0x44, 0x69, 0x72, 0x12, 0x30, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, + 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x66, 0x0a, 0x0b, 0x4c, 0x65, + 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0c, 0x6d, 0x61, 0x6e, + 0x69, 0x66, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x02, 0x18, 0x01, 0x52, 0x0b, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x44, 0x69, 0x72, + 0x12, 0x30, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, - 0x4b, 0x69, 0x6e, 0x64, 0x53, 0x70, 0x65, 0x63, 0x48, 0x00, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, - 0x12, 0x36, 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, - 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x70, 0x65, 0x63, 0x48, 0x00, 0x52, 0x08, - 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x33, 0x0a, 0x07, 0x6b, 0x75, 0x62, 0x65, - 0x61, 0x64, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x61, 0x64, 0x6d, 0x53, 0x70, - 0x65, 0x63, 0x48, 0x00, 0x52, 0x07, 0x6b, 0x75, 0x62, 0x65, 0x61, 0x64, 0x6d, 0x12, 0x33, 0x0a, - 0x07, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x6c, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x61, - 0x6c, 0x6c, 0x62, 0x53, 0x70, 0x65, 0x63, 0x48, 0x01, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x61, 0x6c, - 0x6c, 0x62, 0x12, 0x33, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x68, 0x6e, 0x65, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, - 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x6e, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x48, 0x02, 0x52, 0x07, - 0x6d, 0x65, 0x73, 0x68, 0x6e, 0x65, 0x74, 0x12, 0x45, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x43, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0f, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x73, 0x42, 0x0e, - 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x42, 0x0e, - 0x0a, 0x0c, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x42, 0x0a, - 0x0a, 0x08, 0x63, 0x6e, 0x69, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x22, 0x5b, 0x0a, 0x15, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x2a, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x0a, 0x12, - 0x53, 0x68, 0x6f, 0x77, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x91, 0x02, 0x0a, 0x13, 0x53, 0x68, 0x6f, 0x77, 0x43, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, - 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x25, - 0x0a, 0x0e, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x70, 0x69, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x11, 0x61, 0x70, 0x69, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x64, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x3e, 0x0a, 0x1c, 0x64, - 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x63, - 0x61, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x18, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x43, 0x61, 0x43, 0x65, 0x72, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x63, - 0x72, 0x69, 0x5f, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x63, 0x72, 0x69, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x22, 0x5d, 0x0a, 0x15, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x2e, 0x54, 0x6f, 0x70, - 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, - 0x18, 0x0a, 0x07, 0x6b, 0x75, 0x62, 0x65, 0x63, 0x66, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x6b, 0x75, 0x62, 0x65, 0x63, 0x66, 0x67, 0x22, 0x9e, 0x01, 0x0a, 0x16, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0d, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, - 0x0c, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, - 0x67, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2a, - 0x0a, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0e, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, - 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x22, 0x3c, 0x0a, 0x15, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x6f, 0x70, 0x6f, - 0x6c, 0x6f, 0x67, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x3a, 0x0a, 0x13, 0x53, 0x68, 0x6f, 0x77, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, - 0x67, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x70, - 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x73, - 0x0a, 0x14, 0x53, 0x68, 0x6f, 0x77, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x65, 0x72, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x0a, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x6c, - 0x6f, 0x67, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x6f, 0x70, 0x6f, - 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x6c, - 0x6f, 0x67, 0x79, 0x22, 0x71, 0x0a, 0x11, 0x50, 0x75, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x70, 0x6f, - 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, - 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, - 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x14, 0x0a, 0x12, 0x50, 0x75, 0x73, 0x68, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5a, 0x0a, 0x12, - 0x52, 0x65, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x22, 0x3d, 0x0a, 0x09, 0x43, 0x64, 0x6e, 0x6f, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, + 0x30, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x4d, + 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x22, 0x47, 0x0a, 0x08, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x66, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x42, 0x0f, 0x0a, 0x0d, 0x6d, 0x61, 0x6e, + 0x69, 0x66, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x22, 0x8c, 0x03, 0x0a, 0x14, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x4b, + 0x69, 0x6e, 0x64, 0x53, 0x70, 0x65, 0x63, 0x48, 0x00, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, + 0x36, 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x45, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x70, 0x65, 0x63, 0x48, 0x00, 0x52, 0x08, 0x65, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x33, 0x0a, 0x07, 0x6b, 0x75, 0x62, 0x65, 0x61, + 0x64, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x61, 0x64, 0x6d, 0x53, 0x70, 0x65, + 0x63, 0x48, 0x00, 0x52, 0x07, 0x6b, 0x75, 0x62, 0x65, 0x61, 0x64, 0x6d, 0x12, 0x33, 0x0a, 0x07, + 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x6c, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x6c, + 0x6c, 0x62, 0x53, 0x70, 0x65, 0x63, 0x48, 0x01, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x6c, + 0x62, 0x12, 0x33, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x68, 0x6e, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, + 0x4d, 0x65, 0x73, 0x68, 0x6e, 0x65, 0x74, 0x53, 0x70, 0x65, 0x63, 0x48, 0x02, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x68, 0x6e, 0x65, 0x74, 0x12, 0x45, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0f, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x73, 0x42, 0x0e, 0x0a, + 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x42, 0x0e, 0x0a, + 0x0c, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x42, 0x0a, 0x0a, + 0x08, 0x63, 0x6e, 0x69, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x22, 0x5b, 0x0a, 0x15, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, + 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x2a, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x0a, 0x12, 0x53, + 0x68, 0x6f, 0x77, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x91, 0x02, 0x0a, 0x13, 0x53, 0x68, 0x6f, 0x77, 0x43, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x25, 0x0a, + 0x0e, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x70, 0x69, 0x5f, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x11, 0x61, 0x70, 0x69, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x3e, 0x0a, 0x1c, 0x64, 0x69, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x63, 0x61, + 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x18, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x43, 0x61, 0x43, 0x65, 0x72, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, + 0x69, 0x5f, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x63, 0x72, 0x69, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x22, 0x5d, 0x0a, 0x15, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x2e, 0x54, 0x6f, 0x70, 0x6f, + 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x18, + 0x0a, 0x07, 0x6b, 0x75, 0x62, 0x65, 0x63, 0x66, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x6b, 0x75, 0x62, 0x65, 0x63, 0x66, 0x67, 0x22, 0x9e, 0x01, 0x0a, 0x16, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0d, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0c, + 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, + 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x0a, + 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0e, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, + 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x22, 0x3c, 0x0a, 0x15, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x6f, 0x70, 0x6f, 0x6c, - 0x6f, 0x67, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x65, - 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x41, 0x0a, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x22, 0x16, 0x0a, 0x14, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf7, 0x01, 0x0a, 0x12, 0x4a, - 0x6f, 0x69, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x70, 0x69, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, - 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, - 0x61, 0x70, 0x69, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, - 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x3e, 0x0a, 0x1c, 0x64, 0x69, 0x73, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x79, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x63, 0x61, 0x5f, 0x63, 0x65, - 0x72, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x64, - 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x61, 0x43, - 0x65, 0x72, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x69, 0x5f, 0x73, - 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x69, - 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x3c, 0x0a, 0x1a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x63, 0x72, 0x65, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x22, 0x15, 0x0a, 0x13, 0x4a, 0x6f, 0x69, 0x6e, 0x43, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x7d, 0x0a, 0x0c, 0x43, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x43, - 0x4c, 0x55, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4c, - 0x55, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x52, 0x45, 0x41, - 0x54, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4c, 0x55, 0x53, 0x54, 0x45, - 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, - 0x02, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4c, 0x55, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x2a, 0x82, 0x01, 0x0a, 0x0d, 0x54, - 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x1a, - 0x54, 0x4f, 0x50, 0x4f, 0x4c, 0x4f, 0x47, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, - 0x54, 0x4f, 0x50, 0x4f, 0x4c, 0x4f, 0x47, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, - 0x52, 0x45, 0x41, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x4f, 0x50, - 0x4f, 0x4c, 0x4f, 0x47, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4e, 0x4e, - 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x4f, 0x50, 0x4f, 0x4c, 0x4f, 0x47, - 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x32, - 0xe6, 0x06, 0x0a, 0x0f, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x4d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x72, 0x12, 0x59, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x70, - 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x21, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, - 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, - 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x59, - 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, - 0x12, 0x21, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0c, 0x53, 0x68, 0x6f, - 0x77, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x6f, 0x67, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x3a, 0x0a, 0x13, 0x53, 0x68, 0x6f, 0x77, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x70, 0x6f, + 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x73, 0x0a, + 0x14, 0x53, 0x68, 0x6f, 0x77, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x0a, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, + 0x67, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x2e, + 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, + 0x67, 0x79, 0x22, 0x71, 0x0a, 0x11, 0x50, 0x75, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x70, 0x6f, 0x6c, + 0x6f, 0x67, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x14, 0x0a, 0x12, 0x50, 0x75, 0x73, 0x68, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5a, 0x0a, 0x12, 0x52, + 0x65, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, + 0x67, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x65, 0x74, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x41, + 0x0a, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x22, 0x16, 0x0a, 0x14, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf7, 0x01, 0x0a, 0x12, 0x4a, 0x6f, + 0x69, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x70, 0x69, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x65, + 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x61, + 0x70, 0x69, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x3e, 0x0a, 0x1c, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, + 0x65, 0x72, 0x79, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x63, 0x61, 0x5f, 0x63, 0x65, 0x72, + 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x64, 0x69, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x61, 0x43, 0x65, + 0x72, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x69, 0x5f, 0x73, 0x6f, + 0x63, 0x6b, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x69, 0x53, + 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x3c, 0x0a, 0x1a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x63, 0x72, 0x65, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x22, 0x15, 0x0a, 0x13, 0x4a, 0x6f, 0x69, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x7d, 0x0a, 0x0c, 0x43, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4c, + 0x55, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4c, 0x55, + 0x53, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, + 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4c, 0x55, 0x53, 0x54, 0x45, 0x52, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x02, + 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4c, 0x55, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x2a, 0x82, 0x01, 0x0a, 0x0d, 0x54, 0x6f, + 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x1a, 0x54, + 0x4f, 0x50, 0x4f, 0x4c, 0x4f, 0x47, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x54, + 0x4f, 0x50, 0x4f, 0x4c, 0x4f, 0x47, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x52, + 0x45, 0x41, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x4f, 0x50, 0x4f, + 0x4c, 0x4f, 0x47, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4e, 0x4e, 0x49, + 0x4e, 0x47, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x4f, 0x50, 0x4f, 0x4c, 0x4f, 0x47, 0x59, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x32, 0xe6, + 0x06, 0x0a, 0x0f, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x4d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x72, 0x12, 0x59, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, + 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x21, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, + 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a, + 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, + 0x21, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0c, 0x53, 0x68, 0x6f, 0x77, + 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x68, 0x6f, 0x77, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, + 0x67, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x68, 0x6f, 0x77, 0x54, 0x6f, 0x70, 0x6f, 0x6c, - 0x6f, 0x67, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x68, 0x6f, 0x77, 0x54, 0x6f, 0x70, 0x6f, - 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, - 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, - 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x21, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, - 0x0a, 0x0b, 0x53, 0x68, 0x6f, 0x77, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x68, 0x6f, 0x77, 0x43, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x68, 0x6f, 0x77, 0x43, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x4d, 0x0a, 0x0a, 0x50, 0x75, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x75, 0x73, 0x68, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, + 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, + 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x20, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x21, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x6c, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, + 0x0b, 0x53, 0x68, 0x6f, 0x77, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x68, 0x6f, 0x77, 0x43, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x68, 0x6f, 0x77, 0x43, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x4d, 0x0a, 0x0a, 0x50, 0x75, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x50, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1e, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x65, - 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x65, - 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x53, 0x0a, 0x0c, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x41, - 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, - 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0b, 0x4a, 0x6f, 0x69, 0x6e, 0x43, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x65, 0x72, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x65, 0x72, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2f, 0x6b, 0x6e, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, + 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1e, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x53, 0x0a, 0x0c, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x41, 0x70, + 0x70, 0x6c, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x41, + 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0b, 0x4a, 0x6f, 0x69, 0x6e, 0x43, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2f, 0x6b, 0x6e, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/third_party/meshnet/.mk/kind.mk b/third_party/meshnet/.mk/kind.mk index b9fb2290f..608113b77 100644 --- a/third_party/meshnet/.mk/kind.mk +++ b/third_party/meshnet/.mk/kind.mk @@ -3,7 +3,7 @@ KIND_CLUSTER_NAME := "meshnet" .PHONY: kind-install kind-install: - go install sigs.k8s.io/kind@v0.17.0 + go install sigs.k8s.io/kind@v0.32.0 .PHONY: kind-stop kind-stop: diff --git a/third_party/meshnet/api/clientset/v1beta1/topology.go b/third_party/meshnet/api/clientset/v1beta1/topology.go index 65ae49716..7031eeb3e 100644 --- a/third_party/meshnet/api/clientset/v1beta1/topology.go +++ b/third_party/meshnet/api/clientset/v1beta1/topology.go @@ -27,7 +27,6 @@ import ( "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" topologyv1 "github.com/openconfig/kne/third_party/meshnet/api/types/v1beta1" ) @@ -134,13 +133,9 @@ func (t *topologyClient) Get(ctx context.Context, name string, opts metav1.GetOp } func (t *topologyClient) Create(ctx context.Context, topology *topologyv1.Topology, opts metav1.CreateOptions) (*topologyv1.Topology, error) { - gvk, err := apiutil.GVKForObject(topology, topologyv1.Scheme) - if err != nil { - return nil, fmt.Errorf("failed to get gvk for Topology: %w", err) - } topology.TypeMeta = metav1.TypeMeta{ - Kind: gvk.Kind, - APIVersion: gvk.GroupVersion().String(), + Kind: "Topology", + APIVersion: topologyv1.SchemeGroupVersion.String(), } obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(topology) if err != nil { diff --git a/third_party/meshnet/go.mod b/third_party/meshnet/go.mod index dd559c931..c14ed48f8 100644 --- a/third_party/meshnet/go.mod +++ b/third_party/meshnet/go.mod @@ -7,19 +7,18 @@ require ( github.com/containernetworking/plugins v1.9.1 github.com/google/go-cmp v0.7.0 github.com/google/gopacket v1.1.19 - github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 + github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/h-fam/errdiff v1.0.2 github.com/openconfig/gnmi v0.14.1 github.com/redhat-nfvpe/koko v0.0.0-20241203052104-ec78eb8730bf github.com/safchain/ethtool v0.7.0 - github.com/sirupsen/logrus v1.10.1 + github.com/sirupsen/logrus v1.10.2 github.com/vishvananda/netlink v1.3.1 golang.org/x/sys v0.47.0 - google.golang.org/grpc v1.83.1 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.12 - k8s.io/apimachinery v0.36.3 - k8s.io/client-go v0.36.3 - sigs.k8s.io/controller-runtime v0.24.1 + k8s.io/apimachinery v0.36.4 + k8s.io/client-go v0.36.4 ) require ( @@ -43,7 +42,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect @@ -52,6 +51,8 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/onsi/ginkgo/v2 v2.27.4 // indirect + github.com/onsi/gomega v1.39.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -62,23 +63,22 @@ require ( go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 // indirect go.opentelemetry.io/otel v1.44.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 // indirect go.opentelemetry.io/otel/metric v1.44.0 // indirect go.opentelemetry.io/otel/trace v1.44.0 // indirect + go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect - go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/mod v0.35.0 // indirect - golang.org/x/net v0.55.0 // indirect + go.yaml.in/yaml/v3 v3.0.5 // indirect + golang.org/x/net v0.58.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect - golang.org/x/sync v0.20.0 // indirect - golang.org/x/term v0.43.0 // indirect - golang.org/x/text v0.37.0 // indirect + golang.org/x/term v0.45.0 // indirect + golang.org/x/text v0.41.0 // indirect golang.org/x/time v0.14.0 // indirect - golang.org/x/tools v0.44.0 // indirect google.golang.org/genproto v0.0.0-20220714211235-042d03aeabc9 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.36.3 // indirect + k8s.io/api v0.36.4 // indirect k8s.io/cri-api v0.31.3 // indirect k8s.io/cri-client v0.31.3 // indirect k8s.io/klog/v2 v2.140.0 // indirect diff --git a/third_party/meshnet/go.sum b/third_party/meshnet/go.sum index c6d1abf29..d8f70424f 100644 --- a/third_party/meshnet/go.sum +++ b/third_party/meshnet/go.sum @@ -4,16 +4,9 @@ github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg6 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= -github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= -github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= -github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -23,20 +16,11 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v1.3.0 h1:v6EpN8RznAZj9765HhXQrtXgX+ECGebEYEmnuFjskwo= github.com/containernetworking/cni v1.3.0/go.mod h1:Bs8glZjjFfGPHMw6hQu82RUgEPNGEaBb9KS5KtNMnJ4= -github.com/containernetworking/plugins v0.9.1 h1:FD1tADPls2EEi3flPc2OegIY1M9pUa9r2Quag7HMLV8= -github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= github.com/containernetworking/plugins v1.9.1 h1:8oU6WsIsU3bpnNZuvHp74a6cE1MJwbj2P7s4/yTUNlA= github.com/containernetworking/plugins v1.9.1/go.mod h1:fj7kS55qg3o/RgS+WGsF3+ZxwIImMPusQZKzBpcSr4c= -github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= -github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= -github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= -github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -55,13 +39,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= -github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= -github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= @@ -71,8 +50,6 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= -github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= @@ -84,7 +61,6 @@ github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -93,38 +69,26 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= -github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= +github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 h1:EEHtgt9IwisQ2AZ4pIsMjahcegHh6rmhqxzIRQIyepY= +github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3/go.mod h1:NbCUVmiS4foBGBHOYlCT25+YmGpJ32dZPi75pGEUpj4= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 h1:X+2YciYSxvMQK0UZ7sg45ZVabVZBeBuvMkmuI2V3Fak= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7/go.mod h1:lW34nIZuQ8UDPdkon5fmfp2l3+ZkQ2me/+oecHYLOII= github.com/h-fam/errdiff v1.0.2 h1:rPsW4ob2fMOIulwTEoZXaaUIuud7XUudw5SLKTZj3Ss= github.com/h-fam/errdiff v1.0.2/go.mod h1:FOzgnHXSEE3rRvmGXgmiqWl+H3lwLywYm9CSXqXrSTg= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -142,7 +106,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/moby v27.3.1+incompatible h1:KQbXBjo7PavKpzIl7UkHT31y9lw/e71Uvrqhr4X+zMA= @@ -159,15 +122,8 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo/v2 v2.27.4 h1:fcEcQW/A++6aZAZQNUmNjvA9PSOzefMJBerHJ4t8v8Y= github.com/onsi/ginkgo/v2 v2.27.4/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q= github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4= github.com/openconfig/gnmi v0.14.1 h1:qKMuFvhIRR2/xxCOsStPQ25aKpbMDdWr3kI+nP9bhMs= @@ -183,26 +139,16 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= -github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= -github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= -github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= -github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= -github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/redhat-nfvpe/koko v0.0.0-20241203052104-ec78eb8730bf h1:a6VTUhyo84BNgbPfGcOImbHtLJfNQsf4hkXsL17mdlU= github.com/redhat-nfvpe/koko v0.0.0-20241203052104-ec78eb8730bf/go.mod h1:UE3j+If4lh+G/2B/op5HPA70ocHKlTiL46A4Pco/eSc= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= -github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= github.com/safchain/ethtool v0.7.0 h1:rlJzfDetsVvT61uz8x1YIcFn12akMfuPulHtZjtb7Is= github.com/safchain/ethtool v0.7.0/go.mod h1:MenQKEjXdfkjD3mp2QdCk8B/hwvkrlOTm/FD4gTpFxQ= -github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.10.1 h1:xi4336Zh11WpU14fXR6I67V3yaTPQYwRx2WEtHbRg4Q= -github.com/sirupsen/logrus v1.10.1/go.mod h1:vsQHnG7xzNsxk3NrwboUiWPnIC3dmbjcGPykD7+tiHk= +github.com/sirupsen/logrus v1.10.2 h1:G2SED73/qrAu6YwbdxOD6peLkCBI3z7L+ykJFTXJBBo= +github.com/sirupsen/logrus v1.10.2/go.mod h1:SLEg8TqYulVKKfIGHldVp2K2aYz2DKSVBq4g/H5bR7Q= github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -218,12 +164,10 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.12.0 h1:K6Mr6jO9JICuend/5xzTM03ydSV3vdNRYAdPSukj8uI= -github.com/stretchr/testify v1.12.0/go.mod h1:bOYBZb5qJ00vPzWfIqBUZPaxK8jWiXc6d3ErP4Ca9Gw= -github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= +github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= +github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg= github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0= github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4= -github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -255,15 +199,11 @@ go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= -go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= +go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -276,21 +216,19 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= -golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= +golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk= +golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= +golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= @@ -300,33 +238,27 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= +golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= -golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= +golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= +golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= -golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= +golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= +golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -339,8 +271,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= -golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= +golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE= +golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -361,33 +293,20 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.83.1 h1:HIO0+BEtBP6soyqvqC8sNUjZ7bTs+0hFQuFF+RAy++Y= -google.golang.org/grpc v1.83.1/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc= google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= @@ -396,14 +315,12 @@ gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.36.3 h1:NxB+05W2UGqXWFXcLO0RB5cnqnUPP5v5sVlaOH0Iz4w= -k8s.io/api v0.36.3/go.mod h1:JzLQKqRHC5+I8RVj/lS3lCg0mg6nWI9Fo/Sk3ElxHzg= -k8s.io/apiextensions-apiserver v0.36.0 h1:Wt7E8J+VBCbj4FjiBfDTK/neXDDjyJVJc7xfuOHImZ0= -k8s.io/apiextensions-apiserver v0.36.0/go.mod h1:kGDjH0msuiIB3tgsYRV0kS9GqpMYMUsQ3GHv7TApyug= -k8s.io/apimachinery v0.36.3 h1:PkzMRBRG8joFD8EhCuQAtNPvJlxb82FwplP26HIzvAM= -k8s.io/apimachinery v0.36.3/go.mod h1:cTSjBWgPe/6CQyBKzY/hDIRWCQQQeK0mfLbml0UYFHE= -k8s.io/client-go v0.36.3 h1:M4JdVzXxYcZk4fGpfDdYnxSwhLKWCFoQsHW6t+z8Hfg= -k8s.io/client-go v0.36.3/go.mod h1:gcPwr0c87vjjG6HB6pWEqOeuYVoXSsREjzux2j6GF30= +k8s.io/api v0.36.4 h1:RxrvqCL6vgH5/+UnTeu1IIFqYmGfy0hnyrod1rn35Oo= +k8s.io/api v0.36.4/go.mod h1:S2B3orCFBDhrgyWbLeuKcT2QdHIpQesBkCYSlWtwUOw= +k8s.io/apimachinery v0.36.4 h1:PT2UzkupGuAx/+xT5XjiMJ1WGpY3fn9/hdAvjweRet4= +k8s.io/apimachinery v0.36.4/go.mod h1:p2I2dipt7JHG+quVwQ1d02d28O4GdDi77RByQ13MTpk= +k8s.io/client-go v0.36.4 h1:MDvfDNvMSt0Br94SK8neviVlwL9qifw9B26hJCpD1K0= +k8s.io/client-go v0.36.4/go.mod h1:pNK4WKELbwlEDvtbE8l22lEZL5THYF61H5EealokZmA= k8s.io/cri-api v0.31.3 h1:dsZXzrGrCEwHjsTDlAV7rutEplpMLY8bfNRMIqrtXjo= k8s.io/cri-api v0.31.3/go.mod h1:Po3TMAYH/+KrZabi7QiwQI4a692oZcUOUThd/rqwxrI= k8s.io/cri-client v0.31.3 h1:9ZwddaNJomqkTBYQqSmB+Ccns3beY4HyYDwmRtWTCJM= @@ -414,8 +331,6 @@ k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hk k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0= k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU= k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= -sigs.k8s.io/controller-runtime v0.24.1 h1:miPEwrmirImAvgME1L9qebGHrOnGJoVmVdtOU9fRfo4= -sigs.k8s.io/controller-runtime v0.24.1/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= diff --git a/third_party/meshnet/manifests/base/daemonset.yaml b/third_party/meshnet/manifests/base/daemonset.yaml index c626af717..f5376582e 100644 --- a/third_party/meshnet/manifests/base/daemonset.yaml +++ b/third_party/meshnet/manifests/base/daemonset.yaml @@ -18,7 +18,7 @@ spec: hostIPC: true serviceAccountName: meshnet nodeSelector: - beta.kubernetes.io/arch: amd64 + kubernetes.io/arch: amd64 tolerations: - operator: Exists effect: NoSchedule diff --git a/topo/node/drivenets/drivenets.go b/topo/node/drivenets/drivenets.go index 56fb895a4..d0672a759 100644 --- a/topo/node/drivenets/drivenets.go +++ b/topo/node/drivenets/drivenets.go @@ -57,16 +57,24 @@ var ( // https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=gnmi 22: { Names: []string{"ssh"}, - Inside: 9339, + Inside: 22, }, 830: { Names: []string{"netconf"}, Inside: 830, }, 50051: { - Names: []string{"gnmi"}, + Names: []string{"grpc"}, Inside: 50051, }, + 51337: { + Names: []string{"gnmi"}, + Inside: 51337, + }, + 52443: { + Names: []string{"gnmi-ssl"}, + Inside: 52443, + }, }, Config: &tpb.Config{ ConfigFile: "default", @@ -121,7 +129,7 @@ var clientFn = func(c *rest.Config) (clientset.Interface, error) { } func (n *Node) Create(ctx context.Context) error { - if n.Impl.Proto.Model != modelCdnos { + if n.Proto.Model != modelCdnos { return fmt.Errorf("cannot create an instance of an unknown model") } return n.cdnosCreate(ctx) @@ -171,7 +179,7 @@ func (n *Node) cdnosCreate(ctx context.Context) error { ConfigFile: config.ConfigFile, InitImage: config.InitImage, Ports: ports, - InterfaceCount: len(nodeSpec.Interfaces), + InterfaceCount: len(nodeSpec.Interfaces) + 1, InitSleep: int(config.Sleep), Resources: node.ToResourceRequirements(nodeSpec.Constraints), Labels: nodeSpec.Labels, @@ -200,7 +208,7 @@ func (n *Node) cdnosCreate(ctx context.Context) error { } func (n *Node) Status(ctx context.Context) (node.Status, error) { - if n.Impl.Proto.Model != modelCdnos { + if n.Proto.Model != modelCdnos { return node.StatusUnknown, fmt.Errorf("invalid model specified") } return n.cdnosStatus(ctx) @@ -228,7 +236,7 @@ func (n *Node) cdnosStatus(ctx context.Context) (node.Status, error) { } func (n *Node) Delete(ctx context.Context) error { - if n.Impl.Proto.Model != modelCdnos { + if n.Proto.Model != modelCdnos { return fmt.Errorf("unknown model") } return n.cdnosDelete(ctx) diff --git a/topo/node/juniper/juniper.go b/topo/node/juniper/juniper.go index 3cd91c3ba..95ed2b515 100644 --- a/topo/node/juniper/juniper.go +++ b/topo/node/juniper/juniper.go @@ -225,6 +225,12 @@ func (n *Node) GRPCConfig() []string { } } +var junosErrorRegex = regexp.MustCompile(`(?im)(\berror:|\bcommit error\b|\bsyntax error\b)`) + +func isJunosError(result string) bool { + return junosErrorRegex.MatchString(result) +} + // Waits and retries until CLI config mode is up and config is applied func (n *Node) waitConfigInfraReadyAndPushConfigs(configs []string) error { log.Infof("Waiting for config to be pushed (timeout: %v) node %s", configModeTimeout, n.Name()) @@ -246,8 +252,8 @@ func (n *Node) waitConfigInfraReadyAndPushConfigs(configs []string) error { log.Infof("Config mode ready. Config commit done. Node %s", n.Name()) return nil } - if strings.Contains(resp.Result, "error:") { - log.Infof("Config mode not ready. Retrying in %v. Node %s Response %s", certGenRetrySleep, n.Name(), multiresp.JoinedResult()) + if isJunosError(resp.Result) { + log.Infof("Config mode not ready. Retrying in %v. Node %s Response %s", configModeRetrySleep, n.Name(), multiresp.JoinedResult()) } } } @@ -281,18 +287,38 @@ func (n *Node) waitCertInfraReadyAndPushCert() error { if err != nil { return fmt.Errorf("failed sending generate-self-signed commands: %v", err) } + if len(multiresp.Responses) < len(commands) { + log.Infof("Incomplete response count from device. Retrying in %v. Node %s", certGenRetrySleep, n.Name()) + time.Sleep(certGenRetrySleep) + continue + } + hasError := false for _, resp := range multiresp.Responses { if resp.Failed != nil { return resp.Failed } - if strings.Contains(resp.Result, "successfully") { - log.Infof("Cert Infra ready. Configured Certs. Node %s, Response %s", n.Name(), multiresp.JoinedResult()) - return nil - } - if strings.Contains(resp.Result, "error:") { + if isJunosError(resp.Result) && !strings.Contains(strings.ToLower(resp.Result), "already exists") { + hasError = true log.Infof("Cert infra isn't ready. Retrying in %v. Node %s Response %s", certGenRetrySleep, n.Name(), multiresp.JoinedResult()) + break } } + + // Dynamically locate the response for the generate-self-signed command + var certGenResult string + for i, cmd := range commands { + if strings.Contains(cmd, "generate-self-signed") && i < len(multiresp.Responses) { + certGenResult = multiresp.Responses[i].Result + break + } + } + + certGenSuccess := strings.Contains(strings.ToLower(certGenResult), "successfully") || strings.Contains(strings.ToLower(certGenResult), "already exists") + + if !hasError && certGenSuccess { + log.Infof("Cert Infra ready. Configured Certs. Node %s, Response %s", n.Name(), multiresp.JoinedResult()) + return nil + } time.Sleep(certGenRetrySleep) } diff --git a/topo/node/juniper/juniper_test.go b/topo/node/juniper/juniper_test.go index 87cab23ad..88278fe02 100644 --- a/topo/node/juniper/juniper_test.go +++ b/topo/node/juniper/juniper_test.go @@ -68,6 +68,31 @@ func removeCommentsFromConfig(t *testing.T, r io.Reader) io.Reader { return &buf } +func TestIsJunosError(t *testing.T) { + tests := []struct { + input string + want bool + }{ + {"error: Command aborted as key pair already exists", true}, + {"[edit]\nerror: Schema was updated in background, failing the commit", true}, + {"root@ncptx# commit\nerror: Commit failed: Schema mismatch/updated.", true}, + {"commit error", true}, + {"syntax error", true}, + {"ERROR: fatal error occurred", true}, + {"set interfaces et-0/0/0 description \"ignore-error\"", false}, + {"domain-name error.com", false}, + {"0 errors found in commit check", false}, + {"Self-signed certificate generated and loaded successfully", false}, + } + + for _, tt := range tests { + got := isJunosError(tt.input) + if got != tt.want { + t.Errorf("isJunosError(%q) = %v; want %v", tt.input, got, tt.want) + } + } +} + func TestGenerateSelfSigned(t *testing.T) { ki := fake.NewSimpleClientset(&corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ @@ -146,12 +171,19 @@ func TestGenerateSelfSigned(t *testing.T) { testFile: "testdata/generate_certificate_success", }, { - // device returns "Error: something bad happened" -- we expect to fail - desc: "failure", - wantErr: true, + // device returns "error: Command aborted as key pair/certificate already exists" -- expected to succeed idempotently + desc: "success cert already exists", + wantErr: false, ni: ni, testFile: "testdata/generate_certificate_failure", }, + { + // key pair generation succeeds with 'successfully' but self-signed cert generation fails + desc: "failure key success cert failure", + wantErr: true, + ni: ni, + testFile: "testdata/generate_certificate_key_success_cert_failure", + }, { // device returns config mode error but we eventually recover desc: "success config mode", @@ -973,10 +1005,10 @@ func TestCreate(t *testing.T) { Namespace: "test", KubeClient: ki, Proto: &tpb.Node{ - Name: "ncptx", - Model: "ncptx", - Vendor: tpb.Vendor_JUNIPER, - Config: cfg, + Name: "ncptx", + Model: "ncptx", + Vendor: tpb.Vendor_JUNIPER, + Config: cfg, Interfaces: map[string]*tpb.Interface{ "eth1": {Name: "et-0/0/0:0"}, }, diff --git a/topo/node/juniper/testdata/generate_certificate_key_success_cert_failure b/topo/node/juniper/testdata/generate_certificate_key_success_cert_failure new file mode 100644 index 000000000..4fea713e6 --- /dev/null +++ b/topo/node/juniper/testdata/generate_certificate_key_success_cert_failure @@ -0,0 +1,21 @@ +root@cptx2> + +root@cptx2> set cli screen-width 511 +Screen width set to 511 + +root@cptx2> set cli screen-length 0 +Screen length set to 0 + +root@cptx2> set cli complete-on-space off +Disabling complete-on-space + +root@cptx2> request security pki generate-key-pair certificate-id grpc-server-cert +Generated key pair grpc-server-cert successfully + +root@cptx2> request security pki local-certificate generate-self-signed certificate-id grpc-server-cert subject CN=abc domain-name google.com ip-address 1.2.3.4 email example@google.com +error: PKI service is not ready. Retry later. + +root@cptx2> +root@cptx2>exit + +root@cptx2> diff --git a/topo/node/nokia/nokia.go b/topo/node/nokia/nokia.go index a38e39bdf..72cef344a 100644 --- a/topo/node/nokia/nokia.go +++ b/topo/node/nokia/nokia.go @@ -20,11 +20,12 @@ import ( "google.golang.org/protobuf/proto" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/fields" - runtime "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/rest" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/dynamic" log "k8s.io/klog/v2" - ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" ) const ( @@ -39,9 +40,11 @@ var ( // ErrIncompatibleCliConn raised when an invalid scrapligo cli transport type is found. ErrIncompatibleCliConn = errors.New("incompatible cli connection in use") - // newSrlinuxClient returns a controller-runtime client for srlinux - // resources. This can be set to a fake for unit testing. - newSrlinuxClient = newSrlinuxClientWithSchema + srlGVR = schema.GroupVersionResource{ + Group: srlinuxv1.GroupVersion.Group, + Version: srlinuxv1.GroupVersion.Version, + Resource: "srlinuxes", + } defaultConstraints = node.Constraints{ CPU: "2000m", // 2000 milliCPUs @@ -114,19 +117,6 @@ func New(nodeImpl *node.Impl) (node.Node, error) { return n, nil } -// newSrlinuxClientWithSchema returns a controller-runtime client for srlinux and loads its schema. -func newSrlinuxClientWithSchema(c *rest.Config) (ctrlclient.Client, error) { - // initialize the controller-runtime client with srlinux scheme - scheme := runtime.NewScheme() - - err := srlinuxv1.AddToScheme(scheme) - if err != nil { - return nil, err - } - - return ctrlclient.New(c, ctrlclient.Options{Scheme: scheme}) -} - type Node struct { *node.Impl cliConn *scraplinetwork.Driver @@ -297,12 +287,18 @@ func (n *Node) Create(ctx context.Context) error { Version: n.GetProto().GetVersion(), }, } - c, err := newSrlinuxClient(n.RestConfig) + srlMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(srl) if err != nil { return err } + srlUnstructured := &unstructured.Unstructured{Object: srlMap} - if err := c.Create(ctx, srl); err != nil { + c, err := dynamic.NewForConfig(n.RestConfig) + if err != nil { + return err + } + + if _, err := c.Resource(srlGVR).Namespace(n.Namespace).Create(ctx, srlUnstructured, metav1.CreateOptions{}); err != nil { return err } @@ -368,16 +364,11 @@ func (n *Node) DefaultNodeConstraints() node.Constraints { } func (n *Node) Delete(ctx context.Context) error { - c, err := newSrlinuxClient(n.RestConfig) + c, err := dynamic.NewForConfig(n.RestConfig) if err != nil { return err } - err = c.Delete(ctx, &srlinuxv1.Srlinux{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: n.GetNamespace(), Name: n.Name(), - }, - }) - if err != nil { + if err := c.Resource(srlGVR).Namespace(n.Namespace).Delete(ctx, n.Name(), metav1.DeleteOptions{}); err != nil { return err } if err := n.DeleteService(ctx); err != nil { diff --git a/topo/node/openconfig/openconfig.go b/topo/node/openconfig/openconfig.go index 2f9cf5d84..18d94f64a 100644 --- a/topo/node/openconfig/openconfig.go +++ b/topo/node/openconfig/openconfig.go @@ -25,12 +25,15 @@ import ( tpb "github.com/openconfig/kne/proto/topo" "github.com/openconfig/kne/topo/node" - "github.com/openconfig/lemming/operator/api/clientset" lemmingv1 "github.com/openconfig/lemming/operator/api/lemming/v1alpha1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/dynamic" "k8s.io/client-go/rest" log "k8s.io/klog/v2" ) @@ -155,8 +158,14 @@ var ( _ node.Resetter = (*Node)(nil) ) -var clientFn = func(c *rest.Config) (clientset.Interface, error) { - return clientset.NewForConfig(c) +var lemmingGVR = schema.GroupVersionResource{ + Group: "lemming.openconfig.net", + Version: "v1alpha1", + Resource: "lemmings", +} + +var clientFn = func(c *rest.Config) (dynamic.Interface, error) { + return dynamic.NewForConfig(c) } func (n *Node) Create(ctx context.Context) error { @@ -194,6 +203,10 @@ func (n *Node) lemmingCreate(ctx context.Context) error { } dut := &lemmingv1.Lemming{ + TypeMeta: metav1.TypeMeta{ + APIVersion: lemmingv1.GroupVersion.String(), + Kind: "Lemming", + }, ObjectMeta: metav1.ObjectMeta{ Name: nodeSpec.Name, Namespace: n.Namespace, @@ -229,7 +242,11 @@ func (n *Node) lemmingCreate(ctx context.Context) error { if err != nil { return fmt.Errorf("failed to get kubernetes client: %v", err) } - if _, err := cs.LemmingV1alpha1().Lemmings(n.Namespace).Create(ctx, dut, metav1.CreateOptions{}); err != nil { + u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(dut) + if err != nil { + return fmt.Errorf("failed to convert lemming to unstructured: %w", err) + } + if _, err := cs.Resource(lemmingGVR).Namespace(n.Namespace).Create(ctx, &unstructured.Unstructured{Object: u}, metav1.CreateOptions{}); err != nil { return fmt.Errorf("failed to create lemming: %v", err) } return nil @@ -243,7 +260,7 @@ func (n *Node) Status(ctx context.Context) (node.Status, error) { case modelLemming: return n.lemmingStatus(ctx) default: - return node.StatusUnknown, fmt.Errorf("invalid model specified.") + return node.StatusUnknown, fmt.Errorf("invalid model specified") } } @@ -261,10 +278,14 @@ func (n *Node) lemmingStatus(ctx context.Context) (node.Status, error) { if err != nil { return node.StatusUnknown, err } - got, err := cs.LemmingV1alpha1().Lemmings(n.Namespace).Get(ctx, n.Name(), metav1.GetOptions{}) + unstruct, err := cs.Resource(lemmingGVR).Namespace(n.Namespace).Get(ctx, n.Name(), metav1.GetOptions{}) if err != nil { return node.StatusUnknown, err } + var got lemmingv1.Lemming + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstruct.Object, &got); err != nil { + return node.StatusUnknown, err + } switch got.Status.Phase { case lemmingv1.Running: return node.StatusRunning, nil @@ -294,7 +315,7 @@ func (n *Node) lemmingDelete(ctx context.Context) error { if err != nil { return err } - return cs.LemmingV1alpha1().Lemmings(n.Namespace).Delete(ctx, n.Name(), metav1.DeleteOptions{}) + return cs.Resource(lemmingGVR).Namespace(n.Namespace).Delete(ctx, n.Name(), metav1.DeleteOptions{}) } func (n *Node) ResetCfg(ctx context.Context) error { diff --git a/topo/node/openconfig/openconfig_test.go b/topo/node/openconfig/openconfig_test.go index c42de2ee9..aaf32747a 100644 --- a/topo/node/openconfig/openconfig_test.go +++ b/topo/node/openconfig/openconfig_test.go @@ -20,18 +20,20 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/openconfig/gnmi/errdiff" tpb "github.com/openconfig/kne/proto/topo" "github.com/openconfig/kne/topo/node" - "github.com/openconfig/lemming/operator/api/clientset" - "github.com/openconfig/lemming/operator/api/clientset/fake" lemmingv1 "github.com/openconfig/lemming/operator/api/lemming/v1alpha1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/testing/protocmp" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/dynamic" + fakedynamic "k8s.io/client-go/dynamic/fake" "k8s.io/client-go/rest" k8stesting "k8s.io/client-go/testing" ) @@ -101,6 +103,10 @@ func TestCreate(t *testing.T) { }, }, want: &lemmingv1.Lemming{ + TypeMeta: metav1.TypeMeta{ + APIVersion: lemmingv1.GroupVersion.String(), + Kind: "Lemming", + }, ObjectMeta: metav1.ObjectMeta{ Name: "test", Namespace: "default", @@ -122,11 +128,12 @@ func TestCreate(t *testing.T) { }} for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { - cs := fake.NewSimpleClientset() + s := runtime.NewScheme() + cs := fakedynamic.NewSimpleDynamicClient(s) cs.PrependReactor("create", "lemmings", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) { return tt.createErr != nil, nil, tt.createErr }) - clientFn = func(c *rest.Config) (clientset.Interface, error) { + clientFn = func(c *rest.Config) (dynamic.Interface, error) { return cs, tt.clientFnErr } @@ -137,11 +144,15 @@ func TestCreate(t *testing.T) { if tt.wantErr != "" { return } - got, err := cs.LemmingV1alpha1().Lemmings("default").Get(context.Background(), "test", metav1.GetOptions{}) + unstruct, err := cs.Resource(lemmingGVR).Namespace("default").Get(context.Background(), "test", metav1.GetOptions{}) if err != nil { t.Fatal(err) } - if d := cmp.Diff(tt.want, got); d != "" { + got := &lemmingv1.Lemming{} + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstruct.Object, got); err != nil { + t.Fatal(err) + } + if d := cmp.Diff(tt.want, got, cmpopts.EquateEmpty()); d != "" { t.Errorf("unexpected diff (-want +got):\n%s", d) } }) @@ -187,15 +198,17 @@ func TestLemmingStatus(t *testing.T) { }} for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { - cs := fake.NewSimpleClientset() + s := runtime.NewScheme() + cs := fakedynamic.NewSimpleDynamicClient(s) cs.PrependReactor("get", "lemmings", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) { - return true, &lemmingv1.Lemming{ + u, _ := runtime.DefaultUnstructuredConverter.ToUnstructured(&lemmingv1.Lemming{ Status: lemmingv1.LemmingStatus{ Phase: tt.inPhase, }, - }, tt.getErr + }) + return true, &unstructured.Unstructured{Object: u}, tt.getErr }) - clientFn = func(c *rest.Config) (clientset.Interface, error) { + clientFn = func(c *rest.Config) (dynamic.Interface, error) { return cs, tt.clientFnErr } n := &Node{&node.Impl{Proto: &tpb.Node{}}} @@ -259,11 +272,12 @@ func TestLemmingDelete(t *testing.T) { }} for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { - cs := fake.NewSimpleClientset() + s := runtime.NewScheme() + cs := fakedynamic.NewSimpleDynamicClient(s) cs.PrependReactor("delete", "lemmings", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) { return true, nil, tt.deleteErr }) - clientFn = func(c *rest.Config) (clientset.Interface, error) { + clientFn = func(c *rest.Config) (dynamic.Interface, error) { return cs, tt.clientFnErr } n := &Node{&node.Impl{Proto: &tpb.Node{}}} diff --git a/topo/sonic_topo_test.go b/topo/sonic_topo_test.go index 809e166ec..fff5e3a5f 100644 --- a/topo/sonic_topo_test.go +++ b/topo/sonic_topo_test.go @@ -5,13 +5,14 @@ import ( "testing" "time" - tfake "github.com/openconfig/kne/third_party/meshnet/api/clientset/v1beta1/fake" tpb "github.com/openconfig/kne/proto/topo" + topologyv1 "github.com/openconfig/kne/third_party/meshnet/api/types/v1beta1" "github.com/openconfig/kne/topo" _ "github.com/openconfig/kne/topo/node/sonic" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + dfake "k8s.io/client-go/dynamic/fake" kfake "k8s.io/client-go/kubernetes/fake" rest "k8s.io/client-go/rest" ktest "k8s.io/client-go/testing" @@ -20,10 +21,7 @@ import ( func TestCreateSonicNode(t *testing.T) { ctx := context.Background() - tf, err := tfake.NewSimpleClientset() - if err != nil { - t.Fatalf("cannot create fake topology clientset: %v", err) - } + tf := dfake.NewSimpleDynamicClient(topologyv1.Scheme) kf := kfake.NewSimpleClientset() kf.PrependReactor("get", "pods", func(action ktest.Action) (bool, runtime.Object, error) { @@ -54,7 +52,7 @@ func TestCreateSonicNode(t *testing.T) { opts := []topo.Option{ topo.WithClusterConfig(&rest.Config{}), topo.WithKubeClient(kf), - topo.WithTopoClient(tf), + topo.WithDynamicClient(tf), } m, err := topo.New(spec, opts...) diff --git a/topo/topo.go b/topo/topo.go index 05c91d734..b703d78a1 100644 --- a/topo/topo.go +++ b/topo/topo.go @@ -35,7 +35,6 @@ import ( cpb "github.com/openconfig/kne/proto/controller" epb "github.com/openconfig/kne/proto/event" tpb "github.com/openconfig/kne/proto/topo" - topologyclientv1 "github.com/openconfig/kne/third_party/meshnet/api/clientset/v1beta1" topologyv1 "github.com/openconfig/kne/third_party/meshnet/api/types/v1beta1" "github.com/openconfig/kne/topo/node" "google.golang.org/grpc/codes" @@ -44,7 +43,11 @@ import ( "google.golang.org/protobuf/encoding/prototext" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" @@ -76,6 +79,12 @@ var ( // Stubs for testing. kindClusterIsKind = kind.ClusterIsKind + + meshnetGVR = schema.GroupVersionResource{ + Group: topologyv1.GroupName, + Version: topologyv1.GroupVersion, + Resource: "topologies", + } ) // Manager is a topology manager for a cluster instance. @@ -85,7 +94,7 @@ type Manager struct { nodes map[string]node.Node kubecfg string kClient kubernetes.Interface - tClient topologyclientv1.Interface + dClient dynamic.Interface rCfg *rest.Config basePath string skipDeleteWait bool @@ -118,9 +127,9 @@ func WithKubeClient(c kubernetes.Interface) Option { } } -func WithTopoClient(c topologyclientv1.Interface) Option { +func WithDynamicClient(c dynamic.Interface) Option { return func(m *Manager) { - m.tClient = c + m.dClient = c } } @@ -199,12 +208,12 @@ func New(topo *tpb.Topology, opts ...Option) (*Manager, error) { } m.kClient = kClient } - if m.tClient == nil { - tClient, err := topologyclientv1.NewForConfig(m.rCfg) + if m.dClient == nil { + dClient, err := dynamic.NewForConfig(m.rCfg) if err != nil { return nil, err } - m.tClient = tClient + m.dClient = dClient } if err := m.load(); err != nil { return nil, fmt.Errorf("failed to load topology: %w", err) @@ -435,7 +444,7 @@ func (m *Manager) Show(ctx context.Context) (*cpb.ShowTopologyResponse, error) { } func (m *Manager) Watch(ctx context.Context) error { - watcher, err := m.tClient.Topology(m.topo.Name).Watch(ctx, metav1.ListOptions{}) + watcher, err := m.dClient.Resource(meshnetGVR).Namespace(m.topo.Name).Watch(ctx, metav1.ListOptions{}) if err != nil { return err } @@ -547,7 +556,7 @@ func setLinkPeer(nodeName string, podName string, link *topologyv1.Link, peerSpe for _, peerLink := range peerSpec.Spec.Links { // make sure self ifc and peer ifc belong to same link (and hence UID) but are not the same interfaces if peerLink.UID == link.UID && !(nodeName == link.PeerPod && peerLink.LocalIntf == link.LocalIntf) { - link.PeerPod = peerSpec.ObjectMeta.Name + link.PeerPod = peerSpec.Name link.PeerIntf = peerLink.LocalIntf return nil } @@ -584,7 +593,7 @@ func (m *Manager) topologySpecs(ctx context.Context) ([]*topologyv1.Topology, er return nil, fmt.Errorf("specs do not exist for node %s", link.PeerPod) } - if err := setLinkPeer(nodeName, spec.ObjectMeta.Name, link, peerSpecs); err != nil { + if err := setLinkPeer(nodeName, spec.Name, link, peerSpecs); err != nil { return nil, err } } @@ -700,7 +709,20 @@ func (m *Manager) createMeshnetTopologies(ctx context.Context) error { go func(topo *topologyv1.Topology) { defer wg.Done() log.Infof("Creating topology for meshnet node %s", topo.Name) - sT, err := m.tClient.Topology(m.topo.Name).Create(ctx, topo, metav1.CreateOptions{}) + topo.TypeMeta = metav1.TypeMeta{ + Kind: "Topology", + APIVersion: topologyv1.SchemeGroupVersion.String(), + } + obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(topo) + if err != nil { + mu.Lock() + if firstErr == nil { + firstErr = fmt.Errorf("could not convert topology for meshnet node %s to unstructured: %w", topo.Name, err) + } + mu.Unlock() + return + } + sT, err := m.dClient.Resource(meshnetGVR).Namespace(m.topo.Name).Create(ctx, &unstructured.Unstructured{Object: obj}, metav1.CreateOptions{}) if err != nil { mu.Lock() if firstErr == nil { @@ -724,8 +746,8 @@ func (m *Manager) deleteMeshnetTopologies(ctx context.Context) error { } var errs errlist.List for _, n := range nodes { - if err := m.tClient.Topology(m.topo.Name).Delete(ctx, n.ObjectMeta.Name, metav1.DeleteOptions{}); err != nil { - errs.Add(fmt.Errorf("failed to delete meshnet node %q: %w", n.ObjectMeta.Name, err)) + if err := m.dClient.Resource(meshnetGVR).Namespace(m.topo.Name).Delete(ctx, n.Name, metav1.DeleteOptions{}); err != nil { + errs.Add(fmt.Errorf("failed to delete meshnet node %q: %w", n.Name, err)) } } return errs.Err() @@ -851,14 +873,18 @@ func (m *Manager) Resources(ctx context.Context) (*Resources, error) { // topologyResources gets the topology CRDs for the cluster. func (m *Manager) topologyResources(ctx context.Context) ([]*topologyv1.Topology, error) { - topology, err := m.tClient.Topology(m.topo.Name).List(ctx, metav1.ListOptions{}) + unstructList, err := m.dClient.Resource(meshnetGVR).Namespace(m.topo.Name).List(ctx, metav1.ListOptions{}) if err != nil { return nil, fmt.Errorf("failed to get topology CRDs: %v", err) } - items := make([]*topologyv1.Topology, len(topology.Items)) - for i := range items { - items[i] = &topology.Items[i] + items := make([]*topologyv1.Topology, len(unstructList.Items)) + for i := range unstructList.Items { + item := &topologyv1.Topology{} + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructList.Items[i].UnstructuredContent(), item); err != nil { + return nil, fmt.Errorf("failed to decode topology CRD: %w", err) + } + items[i] = item } return items, nil diff --git a/topo/topo_test.go b/topo/topo_test.go index b95462005..3e2f83be9 100644 --- a/topo/topo_test.go +++ b/topo/topo_test.go @@ -25,8 +25,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - tfake "github.com/openconfig/kne/third_party/meshnet/api/clientset/v1beta1/fake" topologyv1 "github.com/openconfig/kne/third_party/meshnet/api/types/v1beta1" + dfake "k8s.io/client-go/dynamic/fake" "github.com/openconfig/gnmi/errdiff" cpb "github.com/openconfig/kne/proto/controller" epb "github.com/openconfig/kne/proto/event" @@ -161,14 +161,11 @@ func (nc *notCertable) GetProto() *tpb.Node { func TestNew(t *testing.T) { node.Vendor(tpb.Vendor(1001), NewConfigurable) node.Vendor(tpb.Vendor(1006), NewLoopbackable) - tf, err := tfake.NewSimpleClientset() - if err != nil { - t.Fatalf("cannot create fake topology clientset: %v", err) - } + tf := dfake.NewSimpleDynamicClient(topologyv1.Scheme) opts := []Option{ WithClusterConfig(&rest.Config{}), WithKubeClient(kfake.NewSimpleClientset()), - WithTopoClient(tf), + WithDynamicClient(tf), } tests := []struct { desc string @@ -661,10 +658,7 @@ func TestCreate(t *testing.T) { }} for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { - tf, err := tfake.NewSimpleClientset() - if err != nil { - t.Fatalf("cannot create fake topology clientset: %v", err) - } + tf := dfake.NewSimpleDynamicClient(topologyv1.Scheme) kf := kfake.NewSimpleClientset() kf.PrependReactor("get", "pods", func(action ktest.Action) (bool, runtime.Object, error) { gAction, ok := action.(ktest.GetAction) @@ -687,7 +681,7 @@ func TestCreate(t *testing.T) { opts := []Option{ WithClusterConfig(&rest.Config{}), WithKubeClient(kf), - WithTopoClient(tf), + WithDynamicClient(tf), } opts = append(opts, tt.opts...) m, err := New(tt.topo, opts...) @@ -1004,10 +998,7 @@ func TestDelete(t *testing.T) { }} for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { - tf, err := tfake.NewSimpleClientset() - if err != nil { - t.Fatalf("cannot create fake topology clientset: %v", err) - } + tf := dfake.NewSimpleDynamicClient(topologyv1.Scheme) kf := kfake.NewSimpleClientset(tt.k8sObjects...) kf.PrependWatchReactor("*", func(action ktest.Action) (bool, watch.Interface, error) { f := &fakeWatch{ @@ -1028,7 +1019,7 @@ func TestDelete(t *testing.T) { opts := []Option{ WithClusterConfig(&rest.Config{}), WithKubeClient(kf), - WithTopoClient(tf), + WithDynamicClient(tf), WithSkipDeleteWait(tt.skipWait), } m, err := New(tt.topo, opts...) @@ -1566,14 +1557,11 @@ func TestShow(t *testing.T) { }} for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { - tf, err := tfake.NewSimpleClientset() - if err != nil { - t.Fatalf("cannot create fake topology clientset: %v", err) - } + tf := dfake.NewSimpleDynamicClient(topologyv1.Scheme) opts := []Option{ WithClusterConfig(&rest.Config{}), WithKubeClient(kfake.NewSimpleClientset(tt.k8sObjects...)), - WithTopoClient(tf), + WithDynamicClient(tf), } tTopo := proto.Clone(topo).(*tpb.Topology) m, err := New(tTopo, opts...) @@ -1762,14 +1750,11 @@ func TestResources(t *testing.T) { }} for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { - tf, err := tfake.NewSimpleClientset(tt.topoObjects...) - if err != nil { - t.Fatalf("cannot create fake topology clientset: %v", err) - } + tf := dfake.NewSimpleDynamicClient(topologyv1.Scheme, tt.topoObjects...) opts := []Option{ WithClusterConfig(&rest.Config{}), WithKubeClient(kfake.NewSimpleClientset(tt.k8sObjects...)), - WithTopoClient(tf), + WithDynamicClient(tf), } tTopo := proto.Clone(topo).(*tpb.Topology) m, err := New(tTopo, opts...) @@ -2132,16 +2117,13 @@ func TestOptions(t *testing.T) { } func TestWatch(t *testing.T) { - tf, err := tfake.NewSimpleClientset(&topologyv1.Topology{ + tf := dfake.NewSimpleDynamicClient(topologyv1.Scheme, &topologyv1.Topology{ ObjectMeta: metav1.ObjectMeta{ Name: "test", }, }) - if err != nil { - t.Fatalf("cannot create fake topology clientset: %v", err) - } m := &Manager{ - tClient: tf, + dClient: tf, topo: &tpb.Topology{ Name: "test", },