From 47aff5ef92e026e5f9aa0f613d430877e0d9a0a3 Mon Sep 17 00:00:00 2001 From: David Avnerson <85820962+davnerson-dn@users.noreply.github.com> Date: Sun, 31 Dec 2023 15:06:56 +0200 Subject: [PATCH] Adding Drivenets Vendor support --- README.md | 2 +- deploy/deploy.go | 53 ++ deploy/kne/external-multinode.yaml | 3 + deploy/kne/kind-bridge.yaml | 3 + docs/create_topology.md | 19 +- examples/drivenets/cdnos.pb.txt | 29 + examples/drivenets/cdnos1.cfg | 8 + examples/drivenets/cdnos2.cfg | 8 + .../drivenets/multivendor-drivenets.pb.txt | 35 + examples/drivenets/srlinux.cfg | 1 + manifests/controllers/cdnos/manifest.yaml | 608 ++++++++++++++ proto/controller.proto | 7 + proto/controller/controller.pb.go | 792 ++++++++++-------- proto/event.proto | 1 + proto/event/event.pb.go | 36 +- proto/topo.proto | 2 + topo/node/drivenets/drivenets.go | 391 +++++++++ topo/topo.go | 1 + 18 files changed, 1634 insertions(+), 365 deletions(-) create mode 100644 examples/drivenets/cdnos.pb.txt create mode 100644 examples/drivenets/cdnos1.cfg create mode 100644 examples/drivenets/cdnos2.cfg create mode 100644 examples/drivenets/multivendor-drivenets.pb.txt create mode 120000 examples/drivenets/srlinux.cfg create mode 100644 manifests/controllers/cdnos/manifest.yaml create mode 100644 topo/node/drivenets/drivenets.go diff --git a/README.md b/README.md index d4981a24..930e5222 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This is not an officially supported Google product. ## Goal For network emulation, there are many approaches using VM's for emulation of a -hardware router. Arista, Cisco, Juniper, and Nokia have multiple implementations +hardware router. Arista, Cisco, Juniper, Drivenets, and Nokia have multiple implementations of their network operating system and various generations of hardware emulation. These systems are very good for most validation of vendor control plane implementations and data plane for limited certifications. The idea of this diff --git a/deploy/deploy.go b/deploy/deploy.go index 388a391e..9669cfac 100644 --- a/deploy/deploy.go +++ b/deploy/deploy.go @@ -152,6 +152,8 @@ func (d *Deployment) event() *epb.Cluster { c.Controllers = append(c.Controllers, epb.Cluster_CONTROLLER_TYPE_SRLINUX) case *LemmingSpec: c.Controllers = append(c.Controllers, epb.Cluster_CONTROLLER_TYPE_LEMMING) + case *CdnosSpec: + c.Controllers = append(c.Controllers, epb.Cluster_CONTROLLER_TYPE_CDNOS) } } return c @@ -1151,6 +1153,57 @@ func (i *IxiaTGSpec) Healthy(ctx context.Context) error { return deploymentHealthy(ctx, i.kClient, "ixiatg-op-system") } + +func init() { + load.Register("Cdnos", &load.Spec{ + Type: CdnosSpec{}, + Tag: "controllers", + }) +} + +type CdnosSpec struct { + ManifestDir string `yaml:"manifests"` + Operator string `yaml:"operator" kne:"yaml"` + OperatorData []byte + kClient kubernetes.Interface +} + +func (l *CdnosSpec) SetKClient(k kubernetes.Interface) { + l.kClient = k +} + +func (l *CdnosSpec) Deploy(ctx context.Context) error { + if l.OperatorData != nil { + f, err := os.CreateTemp("", "cdnos-operator-*.yaml") + if err != nil { + return err + } + defer os.Remove(f.Name()) + if _, err := f.Write(l.OperatorData); err != nil { + return err + } + if err := f.Close(); err != nil { + return err + } + l.Operator = f.Name() + } + if l.Operator == "" && l.ManifestDir != "" { + log.Errorf("Deploying Cdnos controller using the directory 'manifests' field (%v) is deprecated, instead provide the filepath of the operator file directly using the 'operator' field going forward", l.ManifestDir) + l.Operator = filepath.Join(l.ManifestDir, "manifest.yaml") + } + log.Infof("Deploying Cdnos controller from: %s", l.Operator) + if err := logCommand("kubectl", "apply", "-f", l.Operator); err != nil { + return fmt.Errorf("failed to deploy cdnos operator: %w", err) + } + log.Infof("Cdnos controller deployed") + return nil +} + +func (l *CdnosSpec) Healthy(ctx context.Context) error { + return deploymentHealthy(ctx, l.kClient, "cdnos-controller-system") +} + + func deploymentHealthy(ctx context.Context, c kubernetes.Interface, name string) error { log.Infof("Waiting on deployment %q to be healthy", name) w, err := c.AppsV1().Deployments(name).Watch(ctx, metav1.ListOptions{}) diff --git a/deploy/kne/external-multinode.yaml b/deploy/kne/external-multinode.yaml index 56665504..256496eb 100644 --- a/deploy/kne/external-multinode.yaml +++ b/deploy/kne/external-multinode.yaml @@ -28,3 +28,6 @@ controllers: - kind: Lemming spec: operator: ../../manifests/controllers/lemming/manifest.yaml + - kind: Cdnos + spec: + operator: ../../manifests/controllers/cdnos/manifest.yaml diff --git a/deploy/kne/kind-bridge.yaml b/deploy/kne/kind-bridge.yaml index 2ee89fa1..2199bdc2 100644 --- a/deploy/kne/kind-bridge.yaml +++ b/deploy/kne/kind-bridge.yaml @@ -34,3 +34,6 @@ controllers: - kind: Lemming spec: operator: ../../manifests/controllers/lemming/manifest.yaml + - kind: Cdnos + spec: + operator: ../../manifests/controllers/cdnos/manifest.yaml \ No newline at end of file diff --git a/docs/create_topology.md b/docs/create_topology.md index f3a7026c..efda22d4 100644 --- a/docs/create_topology.md +++ b/docs/create_topology.md @@ -117,9 +117,16 @@ Field | Type | Description Field | Type | Description ------ | --------- | ---------------------------------------------------- -`kind` | string | Name of the controller type. The current options currently are `IxiaTG`, `SRLinux`, `CEOSLab`, and `Lemming`. +`kind` | string | Name of the controller type. The current options currently are `Cdnos`, `IxiaTG`, `SRLinux`, `CEOSLab`, and `Lemming`. `spec` | yaml.Node | Fields that set the options for the controller type. +##### Cdnos + +Field | Type | Description +--------------- | ---------- | ----------- +`operator` | string | Path of the yaml file to create a Cdnos operator in the cluster. The validated operator for use with KNE can be found [here](https://github.com/openconfig/kne/tree/main/manifests/controllers/cdnos/manifest.yaml). +~~`manifests`~~ | ~~string~~ | ~~Path of the directory holding the manifests to create a CEOSLab operator in the cluster. The directory is expected to contain a file with the name `manifest.yaml`.~~ + ##### IxiaTG Field | Type | Description @@ -177,6 +184,7 @@ following vendors use a controller: - Keysight: `ixiatg` - Nokia: `srlinux` - Arista: `ceoslab` +- Drivenets: `cdnos` - OpenConfig: `lemming` These controllers can be deployed as part of [cluster @@ -224,6 +232,15 @@ kubectl apply -f manifests/controllers/ceoslab/manifest.yaml See more on the [arista-ceoslab-operator GitHub repo](https://github.com/aristanetworks/arista-ceoslab-operator). +### Cdnos Controller + +```bash +kubectl apply -f manifests/controllers/cdnos/manifest.yaml +``` + +See more on the +[cdnos-controller GitHub repo](https://github.com/drivenets/cdnos-controller). + #### lemming To manually apply the controller run the following command: diff --git a/examples/drivenets/cdnos.pb.txt b/examples/drivenets/cdnos.pb.txt new file mode 100644 index 00000000..905488b6 --- /dev/null +++ b/examples/drivenets/cdnos.pb.txt @@ -0,0 +1,29 @@ +name: "cdnos-demo" +nodes: { + name: "cdnos1" + vendor: DRIVENETS + config: { + config_file: "default" + config_path: "/config_load" + file: "cdnos1.cfg" + image: "registry.dev.drivenets.net/devops/cdnos_dev_v19_1:19.1.0.101_dev.dev_v19_1" + } + model: "CDNOS" +} +nodes: { + name: "cdnos2" + vendor: DRIVENETS + config: { + config_file: "default" + config_path: "/config_load" + file: "cdnos2.cfg" + image: "registry.dev.drivenets.net/devops/cdnos_dev_v19_1:19.1.0.101_dev.dev_v19_1" + } + model: "CDNOS" +} +links: { + a_node: "cdnos1" + a_int: "eno0" + z_node: "cdnos2" + z_int: "eno0" +} diff --git a/examples/drivenets/cdnos1.cfg b/examples/drivenets/cdnos1.cfg new file mode 100644 index 00000000..8c3c194c --- /dev/null +++ b/examples/drivenets/cdnos1.cfg @@ -0,0 +1,8 @@ +configure + interfaces + ge10-0/0/0 + ipv4-address 1.1.1.1/24 + admin-state enabled + ! + ! +commit \ No newline at end of file diff --git a/examples/drivenets/cdnos2.cfg b/examples/drivenets/cdnos2.cfg new file mode 100644 index 00000000..cd90cee8 --- /dev/null +++ b/examples/drivenets/cdnos2.cfg @@ -0,0 +1,8 @@ +configure + interfaces + ge10-0/0/0 + ipv4-address 1.1.1.2/24 + admin-state enabled + ! + ! +commit \ No newline at end of file diff --git a/examples/drivenets/multivendor-drivenets.pb.txt b/examples/drivenets/multivendor-drivenets.pb.txt new file mode 100644 index 00000000..2d04aec0 --- /dev/null +++ b/examples/drivenets/multivendor-drivenets.pb.txt @@ -0,0 +1,35 @@ +name: "cdnos-multivendor-demo" +nodes: { + name: "srl1" + vendor: NOKIA + model: "ixr6e" + config:{ + # when `image` is not specified under `config`, the "ghcr.io/nokia/srlinux:latest" container image is used by default + # SR Linux can accept both complete config files in JSON format, or partial/full config snippets in the CLI format. + # nodes are configured with a partial config snippet in CLI format that adds configuration relevant for this example lab. + file: "srlinux.cfg" + } + interfaces: { + key: "e1-1" + value: { + name: "ethernet-1/1" + } + } +} +nodes: { + name: "cdnos1" + vendor: DRIVENETS + config: { + config_path: "/config_load" + config_file: "default" + file: "cdnos2.cfg" + image: "registry.dev.drivenets.net/devops/cdnos_dev_v19_1:19.1.0.101_dev.dev_v19_1" + } + model: "CDNOS" +} +links: { + a_node: "srl1" + a_int: "e1-1" + z_node: "cdnos1" + z_int: "eno0" +} diff --git a/examples/drivenets/srlinux.cfg b/examples/drivenets/srlinux.cfg new file mode 120000 index 00000000..2e162531 --- /dev/null +++ b/examples/drivenets/srlinux.cfg @@ -0,0 +1 @@ +../multivendor/srlinux.cfg \ No newline at end of file diff --git a/manifests/controllers/cdnos/manifest.yaml b/manifests/controllers/cdnos/manifest.yaml new file mode 100644 index 00000000..a31edf12 --- /dev/null +++ b/manifests/controllers/cdnos/manifest.yaml @@ -0,0 +1,608 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/component: manager + app.kubernetes.io/created-by: cdnos-controller + app.kubernetes.io/instance: system + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: namespace + app.kubernetes.io/part-of: cdnos-controller + control-plane: controller-manager + name: cdnos-controller-system +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: cdnoss.cdnos.dev.drivenets.net +spec: + group: cdnos.dev.drivenets.net + names: + kind: Cdnos + listKind: CdnosList + plural: cdnoss + singular: cdnos + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Cdnos is the Schema for the cdnoss 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: CdnosSpec defines the desired state of Cdnos + properties: + args: + description: Args are the args to pass to the command. + items: + type: string + type: array + command: + description: Command is the name of the executable to run. + type: string + configFile: + description: ConfigFile is the default configuration file name for + the pod. + type: string + configPath: + description: ConfigPath is the mount point for configuration inside + the pod. + type: string + env: + description: Env are the environment variables to set for the container. + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + image: + description: Image to use for the CDNOS container + type: string + initImage: + description: InitImage is the docker image to use as an init container + for the pod. + type: string + initSleep: + description: InitSleep is the time sleep in the init container + type: integer + interfaceCount: + description: InterfaceCount is number of interfaces to be attached + to the pod. + type: integer + ports: + additionalProperties: + description: ServicePort describes an external L4 port on the device. + properties: + innerPort: + description: InnerPort is port on the container to expose. + format: int32 + type: integer + outerPort: + description: OuterPort is port on the container to expose. + format: int32 + type: integer + required: + - innerPort + - outerPort + type: object + description: Ports are ports to create on the service. + type: object + resources: + description: Resources are the K8s resources to allocate to cdnos + container. + properties: + claims: + description: "Claims lists the names of resources, defined in + spec.resourceClaims, that are used by this container. \n This + is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be set + for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims + of the Pod where this field is used. It makes that resource + available inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + tls: + description: TLS is the configuration the key/certs to use for management. + properties: + selfSigned: + description: SelfSigned generates a new self signed certificate. + properties: + commonName: + description: / Common name to set in the cert. + type: string + keySize: + description: RSA keysize to use for key generation. + type: integer + required: + - commonName + - keySize + type: object + type: object + type: object + status: + description: CdnosStatus defines the observed state of Cdnos + properties: + message: + description: Message describes why the Cdnos is in the current phase. + type: string + phase: + description: Phase is the overall status of the Cdnos. + type: string + required: + - message + - phase + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: cdnos-controller + app.kubernetes.io/instance: controller-manager-sa + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/part-of: cdnos-controller + name: cdnos-controller-controller-manager + namespace: cdnos-controller-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: cdnos-controller + app.kubernetes.io/instance: leader-election-role + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: role + app.kubernetes.io/part-of: cdnos-controller + name: cdnos-controller-leader-election-role + namespace: cdnos-controller-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 +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cdnos-controller-manager-role +rules: +- apiGroups: + - cdnos.dev.drivenets.net + resources: + - cdnoss + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - cdnos.dev.drivenets.net + resources: + - cdnoss/finalizers + verbs: + - update +- apiGroups: + - cdnos.dev.drivenets.net + resources: + - cdnoss/status + verbs: + - get + - patch + - update +- apiGroups: + - "" + resources: + - pods + - secrets + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: cdnos-controller + app.kubernetes.io/instance: metrics-reader + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrole + app.kubernetes.io/part-of: cdnos-controller + name: cdnos-controller-metrics-reader +rules: +- 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: cdnos-controller + app.kubernetes.io/instance: proxy-role + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrole + app.kubernetes.io/part-of: cdnos-controller + name: cdnos-controller-proxy-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: cdnos-controller + app.kubernetes.io/instance: leader-election-rolebinding + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: rolebinding + app.kubernetes.io/part-of: cdnos-controller + name: cdnos-controller-leader-election-rolebinding + namespace: cdnos-controller-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: cdnos-controller-leader-election-role +subjects: +- kind: ServiceAccount + name: cdnos-controller-controller-manager + namespace: cdnos-controller-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: cdnos-controller + app.kubernetes.io/instance: manager-rolebinding + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrolebinding + app.kubernetes.io/part-of: cdnos-controller + name: cdnos-controller-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cdnos-controller-manager-role +subjects: +- kind: ServiceAccount + name: cdnos-controller-controller-manager + namespace: cdnos-controller-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: cdnos-controller + app.kubernetes.io/instance: proxy-rolebinding + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrolebinding + app.kubernetes.io/part-of: cdnos-controller + name: cdnos-controller-proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cdnos-controller-proxy-role +subjects: +- kind: ServiceAccount + name: cdnos-controller-controller-manager + namespace: cdnos-controller-system +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: cdnos-controller + app.kubernetes.io/instance: controller-manager-metrics-service + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: service + app.kubernetes.io/part-of: cdnos-controller + control-plane: controller-manager + name: cdnos-controller-controller-manager-metrics-service + namespace: cdnos-controller-system +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: https + selector: + control-plane: controller-manager +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: manager + app.kubernetes.io/created-by: cdnos-controller + app.kubernetes.io/instance: controller-manager + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: deployment + app.kubernetes.io/part-of: cdnos-controller + control-plane: controller-manager + name: cdnos-controller-controller-manager + namespace: cdnos-controller-system +spec: + replicas: 1 + selector: + matchLabels: + control-plane: controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + 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: gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0 + 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: public.ecr.aws/dn/cdnos-controller:1.4 + 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: cdnos-controller-controller-manager + terminationGracePeriodSeconds: 10 diff --git a/proto/controller.proto b/proto/controller.proto index a7661e39..d1c8b644 100644 --- a/proto/controller.proto +++ b/proto/controller.proto @@ -88,6 +88,7 @@ message ControllerSpec { SRLinuxSpec srlinux = 2; CEOSLabSpec ceoslab = 3; LemmingSpec lemming = 4; + CdnosSpec cdnos = 5; } } @@ -130,6 +131,12 @@ message LemmingSpec { Manifest operator = 2; } +// CdnosSpec specifications +message CdnosSpec { + string manifest_dir = 1 [deprecated = true]; + Manifest operator = 2; +} + message Manifest { oneof manifest_data { // Byte data for the manifest. diff --git a/proto/controller/controller.pb.go b/proto/controller/controller.pb.go index 22c05581..aeecb597 100644 --- a/proto/controller/controller.pb.go +++ b/proto/controller/controller.pb.go @@ -453,6 +453,7 @@ type ControllerSpec struct { // *ControllerSpec_Srlinux // *ControllerSpec_Ceoslab // *ControllerSpec_Lemming + // *ControllerSpec_Cdnos Spec isControllerSpec_Spec `protobuf_oneof:"spec"` } @@ -523,6 +524,13 @@ func (x *ControllerSpec) GetLemming() *LemmingSpec { return nil } +func (x *ControllerSpec) GetCdnos() *CdnosSpec { + if x, ok := x.GetSpec().(*ControllerSpec_Cdnos); ok { + return x.Cdnos + } + return nil +} + type isControllerSpec_Spec interface { isControllerSpec_Spec() } @@ -543,6 +551,10 @@ type ControllerSpec_Lemming struct { Lemming *LemmingSpec `protobuf:"bytes,4,opt,name=lemming,proto3,oneof"` } +type ControllerSpec_Cdnos struct { + Cdnos *CdnosSpec `protobuf:"bytes,5,opt,name=cdnos,proto3,oneof"` +} + func (*ControllerSpec_Ixiatg) isControllerSpec_Spec() {} func (*ControllerSpec_Srlinux) isControllerSpec_Spec() {} @@ -551,6 +563,8 @@ func (*ControllerSpec_Ceoslab) isControllerSpec_Spec() {} func (*ControllerSpec_Lemming) isControllerSpec_Spec() {} +func (*ControllerSpec_Cdnos) isControllerSpec_Spec() {} + // IxiaTG specifications type IxiaTGSpec struct { state protoimpl.MessageState @@ -921,6 +935,64 @@ func (x *LemmingSpec) GetOperator() *Manifest { return nil } +// CdnosSpec specifications +type CdnosSpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Deprecated: Do not use. + ManifestDir string `protobuf:"bytes,1,opt,name=manifest_dir,json=manifestDir,proto3" json:"manifest_dir,omitempty"` + Operator *Manifest `protobuf:"bytes,2,opt,name=operator,proto3" json:"operator,omitempty"` +} + +func (x *CdnosSpec) Reset() { + *x = CdnosSpec{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CdnosSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CdnosSpec) ProtoMessage() {} + +func (x *CdnosSpec) ProtoReflect() protoreflect.Message { + mi := &file_controller_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CdnosSpec.ProtoReflect.Descriptor instead. +func (*CdnosSpec) Descriptor() ([]byte, []int) { + return file_controller_proto_rawDescGZIP(), []int{11} +} + +// Deprecated: Do not use. +func (x *CdnosSpec) GetManifestDir() string { + if x != nil { + return x.ManifestDir + } + return "" +} + +func (x *CdnosSpec) GetOperator() *Manifest { + if x != nil { + return x.Operator + } + return nil +} + type Manifest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -936,7 +1008,7 @@ type Manifest struct { func (x *Manifest) Reset() { *x = Manifest{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[11] + mi := &file_controller_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -949,7 +1021,7 @@ func (x *Manifest) String() string { func (*Manifest) ProtoMessage() {} func (x *Manifest) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[11] + mi := &file_controller_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -962,7 +1034,7 @@ func (x *Manifest) ProtoReflect() protoreflect.Message { // Deprecated: Use Manifest.ProtoReflect.Descriptor instead. func (*Manifest) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{11} + return file_controller_proto_rawDescGZIP(), []int{12} } func (m *Manifest) GetManifestData() isManifest_ManifestData { @@ -1029,7 +1101,7 @@ type CreateClusterRequest struct { func (x *CreateClusterRequest) Reset() { *x = CreateClusterRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[12] + mi := &file_controller_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1042,7 +1114,7 @@ func (x *CreateClusterRequest) String() string { func (*CreateClusterRequest) ProtoMessage() {} func (x *CreateClusterRequest) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[12] + mi := &file_controller_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1055,7 +1127,7 @@ func (x *CreateClusterRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateClusterRequest.ProtoReflect.Descriptor instead. func (*CreateClusterRequest) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{12} + return file_controller_proto_rawDescGZIP(), []int{13} } func (m *CreateClusterRequest) GetClusterSpec() isCreateClusterRequest_ClusterSpec { @@ -1163,7 +1235,7 @@ type CreateClusterResponse struct { func (x *CreateClusterResponse) Reset() { *x = CreateClusterResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[13] + mi := &file_controller_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1176,7 +1248,7 @@ func (x *CreateClusterResponse) String() string { func (*CreateClusterResponse) ProtoMessage() {} func (x *CreateClusterResponse) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[13] + mi := &file_controller_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1189,7 +1261,7 @@ func (x *CreateClusterResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateClusterResponse.ProtoReflect.Descriptor instead. func (*CreateClusterResponse) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{13} + return file_controller_proto_rawDescGZIP(), []int{14} } func (x *CreateClusterResponse) GetName() string { @@ -1218,7 +1290,7 @@ type DeleteClusterRequest struct { func (x *DeleteClusterRequest) Reset() { *x = DeleteClusterRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[14] + mi := &file_controller_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1231,7 +1303,7 @@ func (x *DeleteClusterRequest) String() string { func (*DeleteClusterRequest) ProtoMessage() {} func (x *DeleteClusterRequest) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[14] + mi := &file_controller_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1244,7 +1316,7 @@ func (x *DeleteClusterRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteClusterRequest.ProtoReflect.Descriptor instead. func (*DeleteClusterRequest) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{14} + return file_controller_proto_rawDescGZIP(), []int{15} } func (x *DeleteClusterRequest) GetName() string { @@ -1264,7 +1336,7 @@ type DeleteClusterResponse struct { func (x *DeleteClusterResponse) Reset() { *x = DeleteClusterResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[15] + mi := &file_controller_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1277,7 +1349,7 @@ func (x *DeleteClusterResponse) String() string { func (*DeleteClusterResponse) ProtoMessage() {} func (x *DeleteClusterResponse) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[15] + mi := &file_controller_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1290,7 +1362,7 @@ func (x *DeleteClusterResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteClusterResponse.ProtoReflect.Descriptor instead. func (*DeleteClusterResponse) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{15} + return file_controller_proto_rawDescGZIP(), []int{16} } // Request message to show cluster by name. @@ -1305,7 +1377,7 @@ type ShowClusterRequest struct { func (x *ShowClusterRequest) Reset() { *x = ShowClusterRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[16] + mi := &file_controller_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1318,7 +1390,7 @@ func (x *ShowClusterRequest) String() string { func (*ShowClusterRequest) ProtoMessage() {} func (x *ShowClusterRequest) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[16] + mi := &file_controller_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1331,7 +1403,7 @@ func (x *ShowClusterRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShowClusterRequest.ProtoReflect.Descriptor instead. func (*ShowClusterRequest) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{16} + return file_controller_proto_rawDescGZIP(), []int{17} } func (x *ShowClusterRequest) GetName() string { @@ -1354,7 +1426,7 @@ type ShowClusterResponse struct { func (x *ShowClusterResponse) Reset() { *x = ShowClusterResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[17] + mi := &file_controller_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1367,7 +1439,7 @@ func (x *ShowClusterResponse) String() string { func (*ShowClusterResponse) ProtoMessage() {} func (x *ShowClusterResponse) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[17] + mi := &file_controller_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1380,7 +1452,7 @@ func (x *ShowClusterResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ShowClusterResponse.ProtoReflect.Descriptor instead. func (*ShowClusterResponse) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{17} + return file_controller_proto_rawDescGZIP(), []int{18} } func (x *ShowClusterResponse) GetState() ClusterState { @@ -1410,7 +1482,7 @@ type CreateTopologyRequest struct { func (x *CreateTopologyRequest) Reset() { *x = CreateTopologyRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[18] + mi := &file_controller_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1423,7 +1495,7 @@ func (x *CreateTopologyRequest) String() string { func (*CreateTopologyRequest) ProtoMessage() {} func (x *CreateTopologyRequest) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[18] + mi := &file_controller_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1436,7 +1508,7 @@ func (x *CreateTopologyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateTopologyRequest.ProtoReflect.Descriptor instead. func (*CreateTopologyRequest) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{18} + return file_controller_proto_rawDescGZIP(), []int{19} } func (x *CreateTopologyRequest) GetTopology() *topo.Topology { @@ -1466,7 +1538,7 @@ type CreateTopologyResponse struct { func (x *CreateTopologyResponse) Reset() { *x = CreateTopologyResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[19] + mi := &file_controller_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1479,7 +1551,7 @@ func (x *CreateTopologyResponse) String() string { func (*CreateTopologyResponse) ProtoMessage() {} func (x *CreateTopologyResponse) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[19] + mi := &file_controller_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1492,7 +1564,7 @@ func (x *CreateTopologyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateTopologyResponse.ProtoReflect.Descriptor instead. func (*CreateTopologyResponse) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{19} + return file_controller_proto_rawDescGZIP(), []int{20} } func (x *CreateTopologyResponse) GetTopologyName() string { @@ -1521,7 +1593,7 @@ type DeleteTopologyRequest struct { func (x *DeleteTopologyRequest) Reset() { *x = DeleteTopologyRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[20] + mi := &file_controller_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1534,7 +1606,7 @@ func (x *DeleteTopologyRequest) String() string { func (*DeleteTopologyRequest) ProtoMessage() {} func (x *DeleteTopologyRequest) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[20] + mi := &file_controller_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1547,7 +1619,7 @@ func (x *DeleteTopologyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteTopologyRequest.ProtoReflect.Descriptor instead. func (*DeleteTopologyRequest) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{20} + return file_controller_proto_rawDescGZIP(), []int{21} } func (x *DeleteTopologyRequest) GetTopologyName() string { @@ -1567,7 +1639,7 @@ type DeleteTopologyResponse struct { func (x *DeleteTopologyResponse) Reset() { *x = DeleteTopologyResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[21] + mi := &file_controller_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1580,7 +1652,7 @@ func (x *DeleteTopologyResponse) String() string { func (*DeleteTopologyResponse) ProtoMessage() {} func (x *DeleteTopologyResponse) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[21] + mi := &file_controller_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1593,7 +1665,7 @@ func (x *DeleteTopologyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteTopologyResponse.ProtoReflect.Descriptor instead. func (*DeleteTopologyResponse) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{21} + return file_controller_proto_rawDescGZIP(), []int{22} } // Request message to view topology info. @@ -1608,7 +1680,7 @@ type ShowTopologyRequest struct { func (x *ShowTopologyRequest) Reset() { *x = ShowTopologyRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[22] + mi := &file_controller_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1621,7 +1693,7 @@ func (x *ShowTopologyRequest) String() string { func (*ShowTopologyRequest) ProtoMessage() {} func (x *ShowTopologyRequest) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[22] + mi := &file_controller_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1634,7 +1706,7 @@ func (x *ShowTopologyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShowTopologyRequest.ProtoReflect.Descriptor instead. func (*ShowTopologyRequest) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{22} + return file_controller_proto_rawDescGZIP(), []int{23} } func (x *ShowTopologyRequest) GetTopologyName() string { @@ -1657,7 +1729,7 @@ type ShowTopologyResponse struct { func (x *ShowTopologyResponse) Reset() { *x = ShowTopologyResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[23] + mi := &file_controller_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1670,7 +1742,7 @@ func (x *ShowTopologyResponse) String() string { func (*ShowTopologyResponse) ProtoMessage() {} func (x *ShowTopologyResponse) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[23] + mi := &file_controller_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1683,7 +1755,7 @@ func (x *ShowTopologyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ShowTopologyResponse.ProtoReflect.Descriptor instead. func (*ShowTopologyResponse) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{23} + return file_controller_proto_rawDescGZIP(), []int{24} } func (x *ShowTopologyResponse) GetState() TopologyState { @@ -1714,7 +1786,7 @@ type PushConfigRequest struct { func (x *PushConfigRequest) Reset() { *x = PushConfigRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[24] + mi := &file_controller_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1727,7 +1799,7 @@ func (x *PushConfigRequest) String() string { func (*PushConfigRequest) ProtoMessage() {} func (x *PushConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[24] + mi := &file_controller_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1740,7 +1812,7 @@ func (x *PushConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PushConfigRequest.ProtoReflect.Descriptor instead. func (*PushConfigRequest) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{24} + return file_controller_proto_rawDescGZIP(), []int{25} } func (x *PushConfigRequest) GetTopologyName() string { @@ -1774,7 +1846,7 @@ type PushConfigResponse struct { func (x *PushConfigResponse) Reset() { *x = PushConfigResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[25] + mi := &file_controller_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1787,7 +1859,7 @@ func (x *PushConfigResponse) String() string { func (*PushConfigResponse) ProtoMessage() {} func (x *PushConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[25] + mi := &file_controller_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1800,7 +1872,7 @@ func (x *PushConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PushConfigResponse.ProtoReflect.Descriptor instead. func (*PushConfigResponse) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{25} + return file_controller_proto_rawDescGZIP(), []int{26} } // Request message to reset config. @@ -1816,7 +1888,7 @@ type ResetConfigRequest struct { func (x *ResetConfigRequest) Reset() { *x = ResetConfigRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[26] + mi := &file_controller_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1829,7 +1901,7 @@ func (x *ResetConfigRequest) String() string { func (*ResetConfigRequest) ProtoMessage() {} func (x *ResetConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[26] + mi := &file_controller_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1842,7 +1914,7 @@ func (x *ResetConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResetConfigRequest.ProtoReflect.Descriptor instead. func (*ResetConfigRequest) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{26} + return file_controller_proto_rawDescGZIP(), []int{27} } func (x *ResetConfigRequest) GetTopologyName() string { @@ -1869,7 +1941,7 @@ type ResetConfigResponse struct { func (x *ResetConfigResponse) Reset() { *x = ResetConfigResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[27] + mi := &file_controller_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1882,7 +1954,7 @@ func (x *ResetConfigResponse) String() string { func (*ResetConfigResponse) ProtoMessage() {} func (x *ResetConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[27] + mi := &file_controller_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1895,7 +1967,7 @@ func (x *ResetConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResetConfigResponse.ProtoReflect.Descriptor instead. func (*ResetConfigResponse) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{27} + return file_controller_proto_rawDescGZIP(), []int{28} } // Request message to apply kubeyaml to a cluster. @@ -1911,7 +1983,7 @@ type ApplyClusterRequest struct { func (x *ApplyClusterRequest) Reset() { *x = ApplyClusterRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[28] + mi := &file_controller_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1924,7 +1996,7 @@ func (x *ApplyClusterRequest) String() string { func (*ApplyClusterRequest) ProtoMessage() {} func (x *ApplyClusterRequest) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[28] + mi := &file_controller_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1937,7 +2009,7 @@ func (x *ApplyClusterRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyClusterRequest.ProtoReflect.Descriptor instead. func (*ApplyClusterRequest) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{28} + return file_controller_proto_rawDescGZIP(), []int{29} } func (x *ApplyClusterRequest) GetName() string { @@ -1964,7 +2036,7 @@ type ApplyClusterResponse struct { func (x *ApplyClusterResponse) Reset() { *x = ApplyClusterResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controller_proto_msgTypes[29] + mi := &file_controller_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1977,7 +2049,7 @@ func (x *ApplyClusterResponse) String() string { func (*ApplyClusterResponse) ProtoMessage() {} func (x *ApplyClusterResponse) ProtoReflect() protoreflect.Message { - mi := &file_controller_proto_msgTypes[29] + mi := &file_controller_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1990,7 +2062,7 @@ func (x *ApplyClusterResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyClusterResponse.ProtoReflect.Descriptor instead. func (*ApplyClusterResponse) Descriptor() ([]byte, []int) { - return file_controller_proto_rawDescGZIP(), []int{29} + return file_controller_proto_rawDescGZIP(), []int{30} } var File_controller_proto protoreflect.FileDescriptor @@ -2044,7 +2116,7 @@ var file_controller_proto_rawDesc = []byte{ 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, 0xe9, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, + 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, @@ -2058,216 +2130,226 @@ var file_controller_proto_rawDesc = []byte{ 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, 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, + 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, 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, 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, 0xd7, 0x02, 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, 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, 0x6c, 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, 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, 0x6e, - 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, 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, 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, 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, + 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, 0x64, 0x0a, 0x09, 0x43, 0x64, 0x6e, 0x6f, 0x73, 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, 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, 0xd7, 0x02, 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, 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, 0x6c, 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, 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, 0x6e, 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, 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, + 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, 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, 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, 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, 0x94, 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, + 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, 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, 0x94, 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, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, + 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, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, + 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, 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, 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, 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, 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, + 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, 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, 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, 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 ( @@ -2283,7 +2365,7 @@ func file_controller_proto_rawDescGZIP() []byte { } var file_controller_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_controller_proto_msgTypes = make([]protoimpl.MessageInfo, 31) +var file_controller_proto_msgTypes = make([]protoimpl.MessageInfo, 32) var file_controller_proto_goTypes = []interface{}{ (ClusterState)(0), // 0: controller.ClusterState (TopologyState)(0), // 1: controller.TopologyState @@ -2298,77 +2380,80 @@ var file_controller_proto_goTypes = []interface{}{ (*SRLinuxSpec)(nil), // 10: controller.SRLinuxSpec (*CEOSLabSpec)(nil), // 11: controller.CEOSLabSpec (*LemmingSpec)(nil), // 12: controller.LemmingSpec - (*Manifest)(nil), // 13: controller.Manifest - (*CreateClusterRequest)(nil), // 14: controller.CreateClusterRequest - (*CreateClusterResponse)(nil), // 15: controller.CreateClusterResponse - (*DeleteClusterRequest)(nil), // 16: controller.DeleteClusterRequest - (*DeleteClusterResponse)(nil), // 17: controller.DeleteClusterResponse - (*ShowClusterRequest)(nil), // 18: controller.ShowClusterRequest - (*ShowClusterResponse)(nil), // 19: controller.ShowClusterResponse - (*CreateTopologyRequest)(nil), // 20: controller.CreateTopologyRequest - (*CreateTopologyResponse)(nil), // 21: controller.CreateTopologyResponse - (*DeleteTopologyRequest)(nil), // 22: controller.DeleteTopologyRequest - (*DeleteTopologyResponse)(nil), // 23: controller.DeleteTopologyResponse - (*ShowTopologyRequest)(nil), // 24: controller.ShowTopologyRequest - (*ShowTopologyResponse)(nil), // 25: controller.ShowTopologyResponse - (*PushConfigRequest)(nil), // 26: controller.PushConfigRequest - (*PushConfigResponse)(nil), // 27: controller.PushConfigResponse - (*ResetConfigRequest)(nil), // 28: controller.ResetConfigRequest - (*ResetConfigResponse)(nil), // 29: controller.ResetConfigResponse - (*ApplyClusterRequest)(nil), // 30: controller.ApplyClusterRequest - (*ApplyClusterResponse)(nil), // 31: controller.ApplyClusterResponse - nil, // 32: controller.KindSpec.ContainerImagesEntry - (*topo.Topology)(nil), // 33: topo.Topology + (*CdnosSpec)(nil), // 13: controller.CdnosSpec + (*Manifest)(nil), // 14: controller.Manifest + (*CreateClusterRequest)(nil), // 15: controller.CreateClusterRequest + (*CreateClusterResponse)(nil), // 16: controller.CreateClusterResponse + (*DeleteClusterRequest)(nil), // 17: controller.DeleteClusterRequest + (*DeleteClusterResponse)(nil), // 18: controller.DeleteClusterResponse + (*ShowClusterRequest)(nil), // 19: controller.ShowClusterRequest + (*ShowClusterResponse)(nil), // 20: controller.ShowClusterResponse + (*CreateTopologyRequest)(nil), // 21: controller.CreateTopologyRequest + (*CreateTopologyResponse)(nil), // 22: controller.CreateTopologyResponse + (*DeleteTopologyRequest)(nil), // 23: controller.DeleteTopologyRequest + (*DeleteTopologyResponse)(nil), // 24: controller.DeleteTopologyResponse + (*ShowTopologyRequest)(nil), // 25: controller.ShowTopologyRequest + (*ShowTopologyResponse)(nil), // 26: controller.ShowTopologyResponse + (*PushConfigRequest)(nil), // 27: controller.PushConfigRequest + (*PushConfigResponse)(nil), // 28: controller.PushConfigResponse + (*ResetConfigRequest)(nil), // 29: controller.ResetConfigRequest + (*ResetConfigResponse)(nil), // 30: controller.ResetConfigResponse + (*ApplyClusterRequest)(nil), // 31: controller.ApplyClusterRequest + (*ApplyClusterResponse)(nil), // 32: controller.ApplyClusterResponse + nil, // 33: controller.KindSpec.ContainerImagesEntry + (*topo.Topology)(nil), // 34: topo.Topology } var file_controller_proto_depIdxs = []int32{ - 32, // 0: controller.KindSpec.container_images:type_name -> controller.KindSpec.ContainerImagesEntry - 13, // 1: controller.MetallbSpec.manifest:type_name -> controller.Manifest - 13, // 2: controller.MeshnetSpec.manifest:type_name -> controller.Manifest + 33, // 0: controller.KindSpec.container_images:type_name -> controller.KindSpec.ContainerImagesEntry + 14, // 1: controller.MetallbSpec.manifest:type_name -> controller.Manifest + 14, // 2: controller.MeshnetSpec.manifest:type_name -> controller.Manifest 7, // 3: controller.ControllerSpec.ixiatg:type_name -> controller.IxiaTGSpec 10, // 4: controller.ControllerSpec.srlinux:type_name -> controller.SRLinuxSpec 11, // 5: controller.ControllerSpec.ceoslab:type_name -> controller.CEOSLabSpec 12, // 6: controller.ControllerSpec.lemming:type_name -> controller.LemmingSpec - 8, // 7: controller.IxiaTGSpec.config_map:type_name -> controller.IxiaTGConfigMap - 13, // 8: controller.IxiaTGSpec.operator:type_name -> controller.Manifest - 13, // 9: controller.IxiaTGSpec.cfg_map:type_name -> controller.Manifest - 9, // 10: controller.IxiaTGConfigMap.images:type_name -> controller.IxiaTGImage - 13, // 11: controller.SRLinuxSpec.operator:type_name -> controller.Manifest - 13, // 12: controller.CEOSLabSpec.operator:type_name -> controller.Manifest - 13, // 13: controller.LemmingSpec.operator:type_name -> controller.Manifest - 2, // 14: controller.CreateClusterRequest.kind:type_name -> controller.KindSpec - 3, // 15: controller.CreateClusterRequest.external:type_name -> controller.ExternalSpec - 4, // 16: controller.CreateClusterRequest.metallb:type_name -> controller.MetallbSpec - 5, // 17: controller.CreateClusterRequest.meshnet:type_name -> controller.MeshnetSpec - 6, // 18: controller.CreateClusterRequest.controller_specs:type_name -> controller.ControllerSpec - 0, // 19: controller.CreateClusterResponse.state:type_name -> controller.ClusterState - 0, // 20: controller.ShowClusterResponse.state:type_name -> controller.ClusterState - 33, // 21: controller.CreateTopologyRequest.topology:type_name -> topo.Topology - 1, // 22: controller.CreateTopologyResponse.state:type_name -> controller.TopologyState - 1, // 23: controller.ShowTopologyResponse.state:type_name -> controller.TopologyState - 33, // 24: controller.ShowTopologyResponse.topology:type_name -> topo.Topology - 20, // 25: controller.TopologyManager.CreateTopology:input_type -> controller.CreateTopologyRequest - 22, // 26: controller.TopologyManager.DeleteTopology:input_type -> controller.DeleteTopologyRequest - 24, // 27: controller.TopologyManager.ShowTopology:input_type -> controller.ShowTopologyRequest - 14, // 28: controller.TopologyManager.CreateCluster:input_type -> controller.CreateClusterRequest - 16, // 29: controller.TopologyManager.DeleteCluster:input_type -> controller.DeleteClusterRequest - 18, // 30: controller.TopologyManager.ShowCluster:input_type -> controller.ShowClusterRequest - 26, // 31: controller.TopologyManager.PushConfig:input_type -> controller.PushConfigRequest - 28, // 32: controller.TopologyManager.ResetConfig:input_type -> controller.ResetConfigRequest - 30, // 33: controller.TopologyManager.ApplyCluster:input_type -> controller.ApplyClusterRequest - 21, // 34: controller.TopologyManager.CreateTopology:output_type -> controller.CreateTopologyResponse - 23, // 35: controller.TopologyManager.DeleteTopology:output_type -> controller.DeleteTopologyResponse - 25, // 36: controller.TopologyManager.ShowTopology:output_type -> controller.ShowTopologyResponse - 15, // 37: controller.TopologyManager.CreateCluster:output_type -> controller.CreateClusterResponse - 17, // 38: controller.TopologyManager.DeleteCluster:output_type -> controller.DeleteClusterResponse - 19, // 39: controller.TopologyManager.ShowCluster:output_type -> controller.ShowClusterResponse - 27, // 40: controller.TopologyManager.PushConfig:output_type -> controller.PushConfigResponse - 29, // 41: controller.TopologyManager.ResetConfig:output_type -> controller.ResetConfigResponse - 31, // 42: controller.TopologyManager.ApplyCluster:output_type -> controller.ApplyClusterResponse - 34, // [34:43] is the sub-list for method output_type - 25, // [25:34] is the sub-list for method input_type - 25, // [25:25] is the sub-list for extension type_name - 25, // [25:25] is the sub-list for extension extendee - 0, // [0:25] is the sub-list for field type_name + 13, // 7: controller.ControllerSpec.cdnos:type_name -> controller.CdnosSpec + 8, // 8: controller.IxiaTGSpec.config_map:type_name -> controller.IxiaTGConfigMap + 14, // 9: controller.IxiaTGSpec.operator:type_name -> controller.Manifest + 14, // 10: controller.IxiaTGSpec.cfg_map:type_name -> controller.Manifest + 9, // 11: controller.IxiaTGConfigMap.images:type_name -> controller.IxiaTGImage + 14, // 12: controller.SRLinuxSpec.operator:type_name -> controller.Manifest + 14, // 13: controller.CEOSLabSpec.operator:type_name -> controller.Manifest + 14, // 14: controller.LemmingSpec.operator:type_name -> controller.Manifest + 14, // 15: controller.CdnosSpec.operator:type_name -> controller.Manifest + 2, // 16: controller.CreateClusterRequest.kind:type_name -> controller.KindSpec + 3, // 17: controller.CreateClusterRequest.external:type_name -> controller.ExternalSpec + 4, // 18: controller.CreateClusterRequest.metallb:type_name -> controller.MetallbSpec + 5, // 19: controller.CreateClusterRequest.meshnet:type_name -> controller.MeshnetSpec + 6, // 20: controller.CreateClusterRequest.controller_specs:type_name -> controller.ControllerSpec + 0, // 21: controller.CreateClusterResponse.state:type_name -> controller.ClusterState + 0, // 22: controller.ShowClusterResponse.state:type_name -> controller.ClusterState + 34, // 23: controller.CreateTopologyRequest.topology:type_name -> topo.Topology + 1, // 24: controller.CreateTopologyResponse.state:type_name -> controller.TopologyState + 1, // 25: controller.ShowTopologyResponse.state:type_name -> controller.TopologyState + 34, // 26: controller.ShowTopologyResponse.topology:type_name -> topo.Topology + 21, // 27: controller.TopologyManager.CreateTopology:input_type -> controller.CreateTopologyRequest + 23, // 28: controller.TopologyManager.DeleteTopology:input_type -> controller.DeleteTopologyRequest + 25, // 29: controller.TopologyManager.ShowTopology:input_type -> controller.ShowTopologyRequest + 15, // 30: controller.TopologyManager.CreateCluster:input_type -> controller.CreateClusterRequest + 17, // 31: controller.TopologyManager.DeleteCluster:input_type -> controller.DeleteClusterRequest + 19, // 32: controller.TopologyManager.ShowCluster:input_type -> controller.ShowClusterRequest + 27, // 33: controller.TopologyManager.PushConfig:input_type -> controller.PushConfigRequest + 29, // 34: controller.TopologyManager.ResetConfig:input_type -> controller.ResetConfigRequest + 31, // 35: controller.TopologyManager.ApplyCluster:input_type -> controller.ApplyClusterRequest + 22, // 36: controller.TopologyManager.CreateTopology:output_type -> controller.CreateTopologyResponse + 24, // 37: controller.TopologyManager.DeleteTopology:output_type -> controller.DeleteTopologyResponse + 26, // 38: controller.TopologyManager.ShowTopology:output_type -> controller.ShowTopologyResponse + 16, // 39: controller.TopologyManager.CreateCluster:output_type -> controller.CreateClusterResponse + 18, // 40: controller.TopologyManager.DeleteCluster:output_type -> controller.DeleteClusterResponse + 20, // 41: controller.TopologyManager.ShowCluster:output_type -> controller.ShowClusterResponse + 28, // 42: controller.TopologyManager.PushConfig:output_type -> controller.PushConfigResponse + 30, // 43: controller.TopologyManager.ResetConfig:output_type -> controller.ResetConfigResponse + 32, // 44: controller.TopologyManager.ApplyCluster:output_type -> controller.ApplyClusterResponse + 36, // [36:45] is the sub-list for method output_type + 27, // [27:36] is the sub-list for method input_type + 27, // [27:27] is the sub-list for extension type_name + 27, // [27:27] is the sub-list for extension extendee + 0, // [0:27] is the sub-list for field type_name } func init() { file_controller_proto_init() } @@ -2510,7 +2595,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Manifest); i { + switch v := v.(*CdnosSpec); i { case 0: return &v.state case 1: @@ -2522,7 +2607,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateClusterRequest); i { + switch v := v.(*Manifest); i { case 0: return &v.state case 1: @@ -2534,7 +2619,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateClusterResponse); i { + switch v := v.(*CreateClusterRequest); i { case 0: return &v.state case 1: @@ -2546,7 +2631,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteClusterRequest); i { + switch v := v.(*CreateClusterResponse); i { case 0: return &v.state case 1: @@ -2558,7 +2643,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteClusterResponse); i { + switch v := v.(*DeleteClusterRequest); i { case 0: return &v.state case 1: @@ -2570,7 +2655,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ShowClusterRequest); i { + switch v := v.(*DeleteClusterResponse); i { case 0: return &v.state case 1: @@ -2582,7 +2667,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ShowClusterResponse); i { + switch v := v.(*ShowClusterRequest); i { case 0: return &v.state case 1: @@ -2594,7 +2679,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateTopologyRequest); i { + switch v := v.(*ShowClusterResponse); i { case 0: return &v.state case 1: @@ -2606,7 +2691,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateTopologyResponse); i { + switch v := v.(*CreateTopologyRequest); i { case 0: return &v.state case 1: @@ -2618,7 +2703,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteTopologyRequest); i { + switch v := v.(*CreateTopologyResponse); i { case 0: return &v.state case 1: @@ -2630,7 +2715,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteTopologyResponse); i { + switch v := v.(*DeleteTopologyRequest); i { case 0: return &v.state case 1: @@ -2642,7 +2727,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ShowTopologyRequest); i { + switch v := v.(*DeleteTopologyResponse); i { case 0: return &v.state case 1: @@ -2654,7 +2739,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ShowTopologyResponse); i { + switch v := v.(*ShowTopologyRequest); i { case 0: return &v.state case 1: @@ -2666,7 +2751,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PushConfigRequest); i { + switch v := v.(*ShowTopologyResponse); i { case 0: return &v.state case 1: @@ -2678,7 +2763,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PushConfigResponse); i { + switch v := v.(*PushConfigRequest); i { case 0: return &v.state case 1: @@ -2690,7 +2775,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResetConfigRequest); i { + switch v := v.(*PushConfigResponse); i { case 0: return &v.state case 1: @@ -2702,7 +2787,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResetConfigResponse); i { + switch v := v.(*ResetConfigRequest); i { case 0: return &v.state case 1: @@ -2714,7 +2799,7 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApplyClusterRequest); i { + switch v := v.(*ResetConfigResponse); i { case 0: return &v.state case 1: @@ -2726,6 +2811,18 @@ func file_controller_proto_init() { } } file_controller_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApplyClusterRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ApplyClusterResponse); i { case 0: return &v.state @@ -2743,12 +2840,13 @@ func file_controller_proto_init() { (*ControllerSpec_Srlinux)(nil), (*ControllerSpec_Ceoslab)(nil), (*ControllerSpec_Lemming)(nil), + (*ControllerSpec_Cdnos)(nil), } - file_controller_proto_msgTypes[11].OneofWrappers = []interface{}{ + file_controller_proto_msgTypes[12].OneofWrappers = []interface{}{ (*Manifest_Data)(nil), (*Manifest_File)(nil), } - file_controller_proto_msgTypes[12].OneofWrappers = []interface{}{ + file_controller_proto_msgTypes[13].OneofWrappers = []interface{}{ (*CreateClusterRequest_Kind)(nil), (*CreateClusterRequest_External)(nil), (*CreateClusterRequest_Metallb)(nil), @@ -2760,7 +2858,7 @@ func file_controller_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controller_proto_rawDesc, NumEnums: 2, - NumMessages: 31, + NumMessages: 32, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/event.proto b/proto/event.proto index cc64a2fc..b7ff48d6 100644 --- a/proto/event.proto +++ b/proto/event.proto @@ -81,6 +81,7 @@ message Cluster { CONTROLLER_TYPE_SRLINUX = 2; CONTROLLER_TYPE_CEOSLAB = 3; CONTROLLER_TYPE_LEMMING = 4; + CONTROLLER_TYPE_CDNOS = 5; } repeated ControllerType controllers = 4; } diff --git a/proto/event/event.pb.go b/proto/event/event.pb.go index 3aaee516..614bb712 100644 --- a/proto/event/event.pb.go +++ b/proto/event/event.pb.go @@ -185,6 +185,7 @@ const ( Cluster_CONTROLLER_TYPE_SRLINUX Cluster_ControllerType = 2 Cluster_CONTROLLER_TYPE_CEOSLAB Cluster_ControllerType = 3 Cluster_CONTROLLER_TYPE_LEMMING Cluster_ControllerType = 4 + Cluster_CONTROLLER_TYPE_CDNOS Cluster_ControllerType = 5 ) // Enum value maps for Cluster_ControllerType. @@ -195,6 +196,7 @@ var ( 2: "CONTROLLER_TYPE_SRLINUX", 3: "CONTROLLER_TYPE_CEOSLAB", 4: "CONTROLLER_TYPE_LEMMING", + 5: "CONTROLLER_TYPE_CDNOS", } Cluster_ControllerType_value = map[string]int32{ "CONTROLLER_TYPE_UNSPECIFIED": 0, @@ -202,6 +204,7 @@ var ( "CONTROLLER_TYPE_SRLINUX": 2, "CONTROLLER_TYPE_CEOSLAB": 3, "CONTROLLER_TYPE_LEMMING": 4, + "CONTROLLER_TYPE_CDNOS": 5, } ) @@ -794,7 +797,7 @@ var file_event_proto_rawDesc = []byte{ 0x08, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x22, 0x29, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x45, 0x6e, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x22, 0xe8, 0x04, 0x0a, 0x07, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x72, 0x72, 0x6f, 0x72, 0x22, 0x83, 0x05, 0x0a, 0x07, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x63, @@ -822,7 +825,7 @@ var file_event_proto_rawDesc = []byte{ 0x07, 0x43, 0x4e, 0x49, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4e, 0x49, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x4e, 0x49, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, - 0x45, 0x53, 0x48, 0x4e, 0x45, 0x54, 0x10, 0x01, 0x22, 0xa4, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, + 0x45, 0x53, 0x48, 0x4e, 0x45, 0x54, 0x10, 0x01, 0x22, 0xbf, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x4c, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, @@ -832,20 +835,21 @@ var file_event_proto_rawDesc = []byte{ 0x4e, 0x55, 0x58, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x4c, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x45, 0x4f, 0x53, 0x4c, 0x41, 0x42, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x4c, 0x45, 0x52, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x45, 0x4d, 0x4d, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x22, - 0x4c, 0x0a, 0x08, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x21, 0x0a, 0x05, 0x6e, - 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x1d, - 0x0a, 0x0a, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x42, 0x0a, - 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0c, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x2e, 0x56, 0x65, 0x6e, - 0x64, 0x6f, 0x72, 0x52, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, - 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, - 0x6c, 0x42, 0x27, 0x5a, 0x25, 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, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x45, 0x4d, 0x4d, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, + 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x4c, 0x45, 0x52, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x43, 0x44, 0x4e, 0x4f, 0x53, 0x10, 0x05, 0x22, 0x4c, 0x0a, 0x08, 0x54, 0x6f, + 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x21, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x4e, 0x6f, + 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x69, 0x6e, + 0x6b, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6c, + 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x42, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, + 0x12, 0x24, 0x0a, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x0c, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x2e, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x52, 0x06, + 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x42, 0x27, 0x5a, 0x25, + 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, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/topo.proto b/proto/topo.proto index 0a4ce165..166c7c62 100644 --- a/proto/topo.proto +++ b/proto/topo.proto @@ -42,6 +42,7 @@ enum Vendor { NOKIA = 9; OPENCONFIG = 10; ALPINE = 11; + DRIVENETS = 12; } // Node is a single container inside the topology @@ -63,6 +64,7 @@ message Node { CISCO_XRD = 12; CISCO_E8000 = 13; LEMMING = 14; + CDNOS = 15; } string name = 1; // Name of the node in the topology. Must be unique. Type type = 2 [deprecated = true]; diff --git a/topo/node/drivenets/drivenets.go b/topo/node/drivenets/drivenets.go new file mode 100644 index 00000000..a5503853 --- /dev/null +++ b/topo/node/drivenets/drivenets.go @@ -0,0 +1,391 @@ +/* +Copyright 2023 nhadar-dn. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package drivenets implmements node definitions for nodes from the +// Drivenets vendor. It implements both a device (model: cdnos) and +// an ATE (model: magna). +package drivenets + +import ( + "context" + "fmt" + "io" + "os" + "path/filepath" + + cdnosv1 "github.com/drivenets/cdnos-controller/api/v1" + "github.com/drivenets/cdnos-controller/api/v1/clientset" + tpb "github.com/openconfig/kne/proto/topo" + "github.com/openconfig/kne/topo/node" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/rest" + log "k8s.io/klog/v2" +) + +const ( + // modelMagna is a string used in the topology to specify that a magna (github.com/openconfig/magna) + // ATE instance should be created. + modelMagna string = "MAGNA" + // modelCdnos is a string used in the topology to specify that a cdnos + // device instance should be created. + modelCdnos string = "CDNOS" +) + +// New creates a new instance of a node based on the specified model. +func New(nodeImpl *node.Impl) (node.Node, error) { + if nodeImpl == nil { + return nil, fmt.Errorf("nodeImpl cannot be nil") + } + if nodeImpl.Proto == nil { + return nil, fmt.Errorf("nodeImpl.Proto cannot be nil") + } + + var cfg *tpb.Node + switch nodeImpl.Proto.Model { + case modelCdnos: + cfg = cdnosDefaults(nodeImpl.Proto) + case modelMagna: + cfg = magnaDefaults(nodeImpl.Proto) + default: + return nil, fmt.Errorf("a model must be specified") + } + + nodeImpl.Proto = cfg + n := &Node{ + Impl: nodeImpl, + } + return n, nil +} + +type Node struct { + *node.Impl +} + +// Add validations for interfaces the node provides +var ( + _ node.Certer = (*Node)(nil) + _ node.ConfigPusher = (*Node)(nil) + _ node.Resetter = (*Node)(nil) +) + +var clientFn = func(c *rest.Config) (clientset.Interface, error) { + return clientset.NewForConfig(c) +} + +func (n *Node) Create(ctx context.Context) error { + switch n.Impl.Proto.Model { + case modelCdnos: + return n.cdnosCreate(ctx) + case modelMagna: + // magna uses the standard pod creation as though it were a host. + return n.Impl.Create(ctx) + default: + return fmt.Errorf("cannot create an instance of an unknown model") + } +} + +// cdnosCreate implements the Create function for the cdnos model devices. +func (n *Node) cdnosCreate(ctx context.Context) error { + log.Infof("Creating Cdnos node resource %s", n.Name()) + + if _, err := n.CreateConfig(ctx); err != nil { + return fmt.Errorf("node %s failed to create config-map %w", n.Name(), err) + } + log.Infof("Created Cdnos %s configmap", n.Name()) + + nodeSpec := n.GetProto() + config := nodeSpec.GetConfig() + log.Infof("create cdnos %q", nodeSpec.Name) + + ports := map[string]cdnosv1.ServicePort{} + + for k, v := range n.Proto.Services { + ports[v.Name] = cdnosv1.ServicePort{ + InnerPort: int32(v.Inside), + OuterPort: int32(k), + } + } + + dut := &cdnosv1.Cdnos{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeSpec.Name, + Namespace: n.Namespace, + Labels: nodeSpec.Labels, + }, + Spec: cdnosv1.CdnosSpec{ + Image: config.Image, + Command: config.Command[0], + Args: config.Args, + Env: node.ToEnvVar(config.Env), + ConfigPath: config.ConfigPath, + ConfigFile: config.ConfigFile, + InitImage: config.InitImage, + Ports: ports, + InterfaceCount: len(nodeSpec.Interfaces) + 1, + InitSleep: int(config.Sleep), + Resources: node.ToResourceRequirements(nodeSpec.Constraints), + Labels: nodeSpec.Labels, + }, + } + if config.Cert != nil { + switch tls := config.Cert.Config.(type) { + case *tpb.CertificateCfg_SelfSigned: + dut.Spec.TLS = &cdnosv1.TLSSpec{ + SelfSigned: &cdnosv1.SelfSignedSpec{ + CommonName: tls.SelfSigned.CommonName, + KeySize: int(tls.SelfSigned.KeySize), + }, + } + } + } + + cs, err := clientFn(n.RestConfig) + if err != nil { + return fmt.Errorf("failed to get kubernetes client: %v", err) + } + if _, err := cs.CdnosV1alpha1().Cdnoss(n.Namespace).Create(ctx, dut, metav1.CreateOptions{}); err != nil { + return fmt.Errorf("failed to create cdnos: %v", err) + } + return nil +} + +func (n *Node) Status(ctx context.Context) (node.Status, error) { + switch n.Impl.Proto.Model { + case modelMagna: + // magna's status uses the standard underlying node implementation. + return n.Impl.Status(ctx) + case modelCdnos: + return n.cdnosStatus(ctx) + default: + return node.StatusUnknown, fmt.Errorf("invalid model specified.") + } +} + +func (n *Node) cdnosStatus(ctx context.Context) (node.Status, error) { + cs, err := clientFn(n.RestConfig) + if err != nil { + return node.StatusUnknown, err + } + got, err := cs.CdnosV1alpha1().Cdnoss(n.Namespace).Get(ctx, n.Name(), metav1.GetOptions{}) + if err != nil { + return node.StatusUnknown, err + } + switch got.Status.Phase { + case cdnosv1.Running: + return node.StatusRunning, nil + case cdnosv1.Failed: + return node.StatusFailed, nil + case cdnosv1.Pending: + return node.StatusPending, nil + default: + return node.StatusUnknown, nil + } +} + +func (n *Node) Delete(ctx context.Context) error { + switch n.Impl.Proto.Model { + case modelMagna: + // magna's implementation uses the standard underlying node implementation. + return n.Impl.Delete(ctx) + case modelCdnos: + return n.cdnosDelete(ctx) + default: + return fmt.Errorf("unknown model") + } +} + +func (n *Node) cdnosDelete(ctx context.Context) error { + cs, err := clientFn(n.RestConfig) + if err != nil { + return err + } + return cs.CdnosV1alpha1().Cdnoss(n.Namespace).Delete(ctx, n.Name(), metav1.DeleteOptions{}) +} + +func (n *Node) ResetCfg(ctx context.Context) error { + log.Info("ResetCfg is a noop.") + return nil +} + +func (n *Node) ConfigPush(context.Context, io.Reader) error { + return status.Errorf(codes.Unimplemented, "config push is not implemented using gNMI to configure device") +} + +func (n *Node) GenerateSelfSigned(context.Context) error { + return status.Errorf(codes.Unimplemented, "certificate generation is not supported") +} + +func cdnosDefaults(pb *tpb.Node) *tpb.Node { + if pb.Config == nil { + pb.Config = &tpb.Config{} + } + if pb.Config.Image == "" { + pb.Config.Image = "pr-registry.dev.drivenets.net/cdnos_pr_61485:19.1.0.1_priv.61485.1ca7037408b5f7a975949e0912d743498b1f49b5" + } + if pb.Config.InitImage == "" { + pb.Config.InitImage = node.DefaultInitContainerImage + } + if len(pb.GetConfig().GetCommand()) == 0 { + pb.Config.Command = []string{"/define_notif_net.sh"} + } + if pb.Config.EntryCommand == "" { + pb.Config.EntryCommand = fmt.Sprintf("kubectl exec -it %s -- /bin/bash", pb.Name) + } + if pb.Config.Cert == nil { + pb.Config.Cert = &tpb.CertificateCfg{ + Config: &tpb.CertificateCfg_SelfSigned{ + SelfSigned: &tpb.SelfSignedCertCfg{ + CommonName: pb.Name, + KeySize: 2048, + }, + }, + } + } + if pb.Constraints == nil { + pb.Constraints = map[string]string{} + } + if pb.Constraints["cpu"] == "" { + pb.Constraints["cpu"] = "0.5" + } + if pb.Constraints["memory"] == "" { + pb.Constraints["memory"] = "1Gi" + } + if pb.Labels == nil { + pb.Labels = map[string]string{} + } + if pb.Labels["vendor"] == "" { + pb.Labels["vendor"] = tpb.Vendor_DRIVENETS.String() + } + + // Always explicitly specify that cdnos is a DUT, this cannot be overridden by the user. + pb.Labels[node.OndatraRoleLabel] = node.OndatraRoleDUT + + if pb.Services == nil { + pb.Services = map[uint32]*tpb.Service{ + // https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=gnmi + 9339: { + Name: "gnmi", + Inside: 9339, + }, + 9340: { + Name: "gribi", + Inside: 9340, + }, + 9341: { + Name: "gnsi", + Inside: 9339, + }, + 9342: { + Name: "gnoi", + Inside: 9339, + }, + } + } + return pb +} + +func magnaDefaults(pb *tpb.Node) *tpb.Node { + if pb.Config == nil { + pb.Config = &tpb.Config{} + } + if pb.Services == nil { + pb.Services = map[uint32]*tpb.Service{} + } + if len(pb.GetConfig().GetCommand()) == 0 { + pb.Config.Command = []string{ + "/app/magna", + "-v=2", + "-alsologtostderr", + "-port=40051", + "-telemetry_port=50051", + "-certfile=/data/cert.pem", + "-keyfile=/data/key.pem", + } + } + if pb.Config.EntryCommand == "" { + pb.Config.EntryCommand = fmt.Sprintf("kubectl exec -it %s -- sh", pb.Name) + } + if pb.Config.Image == "" { + // TODO(robjs): add public container location once the first iteration is pushed. + // Currently, this image can be built from github.com/openconfig/magna. + pb.Config.Image = "magna:latest" + } + + if _, ok := pb.Services[40051]; !ok { + pb.Services[40051] = &tpb.Service{ + Name: "grpc", + Inside: 40051, + Outside: 40051, + } + } + + if _, ok := pb.Services[50051]; !ok { + pb.Services[50051] = &tpb.Service{ + Name: "gnmi", + Inside: 50051, + Outside: 50051, + } + } + + if pb.Labels == nil { + pb.Labels = map[string]string{ + "vendor": tpb.Vendor_DRIVENETS.String(), + } + } + + // Always explicitly specify that magna nodes are ATEs, this cannot be overridden by the user. + pb.Labels[node.OndatraRoleLabel] = node.OndatraRoleATE + + return pb +} + +func init() { + node.Vendor(tpb.Vendor_DRIVENETS, New) +} + +func (n *Node) CreateConfig(ctx context.Context) (*corev1.Volume, error) { + pb := n.Proto + var data []byte + switch v := pb.Config.GetConfigData().(type) { + case *tpb.Config_File: + var err error + data, err = os.ReadFile(filepath.Join(n.BasePath, v.File)) + if err != nil { + return nil, err + } + case *tpb.Config_Data: + data = v.Data + } + if data != nil { + cm := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-config", pb.Name), + }, + Data: map[string]string{ + pb.Config.ConfigFile: string(data), + }, + } + sCM, err := n.KubeClient.CoreV1().ConfigMaps(n.Namespace).Create(ctx, cm, metav1.CreateOptions{}) + if err != nil { + return nil, err + } + log.V(1).Infof("Server Config Map:\n%v\n", sCM) + } + return nil, nil +} diff --git a/topo/topo.go b/topo/topo.go index 5846d24d..9ad05aeb 100644 --- a/topo/topo.go +++ b/topo/topo.go @@ -50,6 +50,7 @@ import ( _ "github.com/openconfig/kne/topo/node/alpine" _ "github.com/openconfig/kne/topo/node/arista" _ "github.com/openconfig/kne/topo/node/cisco" + _ "github.com/openconfig/kne/topo/node/drivenets" _ "github.com/openconfig/kne/topo/node/gobgp" _ "github.com/openconfig/kne/topo/node/host" _ "github.com/openconfig/kne/topo/node/juniper"