From bb91e6e4a42e8fc2151bafbcdbbde2d0f23ca27a Mon Sep 17 00:00:00 2001 From: David Avnerson Date: Sun, 17 Mar 2024 17:33:03 +0200 Subject: [PATCH] modified after review --- deploy/deploy.go | 5 - deploy/deploy_test.go | 167 +++++++++++++++++++++++ deploy/kne/external-multinode-cdnos.yaml | 33 +++++ deploy/kne/external-multinode.yaml | 3 - deploy/kne/kind-bridge-cdnos.yaml | 39 ++++++ deploy/kne/kind-bridge.yaml | 3 - docs/create_topology.md | 9 +- examples/drivenets/srlinux.cfg | 109 ++++++++++++++- proto/controller.proto | 1 - proto/topo.proto | 1 - 10 files changed, 348 insertions(+), 22 deletions(-) create mode 100644 deploy/kne/external-multinode-cdnos.yaml create mode 100644 deploy/kne/kind-bridge-cdnos.yaml mode change 120000 => 100644 examples/drivenets/srlinux.cfg diff --git a/deploy/deploy.go b/deploy/deploy.go index a113930a..9e2911cd 100644 --- a/deploy/deploy.go +++ b/deploy/deploy.go @@ -1141,7 +1141,6 @@ func init() { } type CdnosSpec struct { - ManifestDir string `yaml:"manifests"` Operator string `yaml:"operator" kne:"yaml"` OperatorData []byte kClient kubernetes.Interface @@ -1166,10 +1165,6 @@ func (c *CdnosSpec) Deploy(ctx context.Context) error { } c.Operator = f.Name() } - if c.Operator == "" && c.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", c.ManifestDir) - c.Operator = filepath.Join(c.ManifestDir, "manifest.yaml") - } log.Infof("Deploying Cdnos controller from: %s", c.Operator) if err := run.LogCommand("kubectl", "apply", "-f", c.Operator); err != nil { return fmt.Errorf("failed to deploy cdnos operator: %w", err) diff --git a/deploy/deploy_test.go b/deploy/deploy_test.go index 9b0d1a6b..7f9e1070 100644 --- a/deploy/deploy_test.go +++ b/deploy/deploy_test.go @@ -1843,6 +1843,173 @@ func TestLemmingSpec(t *testing.T) { } } +func TestCdnosSpec(t *testing.T) { + canceledCtx, cancel := context.WithCancel(context.Background()) + cancel() + deploymentName := "foo" + deploymentNS := "cdnos-operator" + var replicas int32 = 2 + d := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: deploymentName, + Namespace: deploymentNS, + }, + } + tests := []struct { + desc string + cdnos *CdnosSpec + resp []fexec.Response + dErr string + hErr string + ctx context.Context + mockKClient func(*fake.Clientset) + }{{ + desc: "1 replica", + cdnos: &CdnosSpec{}, + resp: []fexec.Response{ + {Cmd: "kubectl", Args: []string{"apply", "-f", ""}}, + }, + + mockKClient: func(k *fake.Clientset) { + reaction := func(action ktest.Action) (handled bool, ret watch.Interface, err error) { + f := newFakeWatch([]watch.Event{{ + Type: watch.Added, + Object: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: deploymentName, + Namespace: deploymentNS, + }, + Status: appsv1.DeploymentStatus{ + AvailableReplicas: 0, + ReadyReplicas: 0, + Replicas: 0, + UnavailableReplicas: 1, + UpdatedReplicas: 0, + }, + }, + }, { + Type: watch.Modified, + Object: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: deploymentName, + Namespace: deploymentNS, + }, + Status: appsv1.DeploymentStatus{ + AvailableReplicas: 1, + ReadyReplicas: 1, + Replicas: 1, + UnavailableReplicas: 0, + UpdatedReplicas: 1, + }, + }, + }}) + return true, f, nil + } + k.PrependWatchReactor("deployments", reaction) + }, + }, { + desc: "2 replicas - data over file", + cdnos: &CdnosSpec{ + OperatorData: []byte("some fake data"), + }, + resp: []fexec.Response{ + {Cmd: "kubectl", Args: []string{"apply", "-f", ".*.yaml"}}, + }, + mockKClient: func(k *fake.Clientset) { + reaction := func(action ktest.Action) (handled bool, ret watch.Interface, err error) { + f := newFakeWatch([]watch.Event{{ + Type: watch.Added, + Object: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: deploymentName, + Namespace: deploymentNS, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &replicas, + }, + Status: appsv1.DeploymentStatus{ + AvailableReplicas: 0, + ReadyReplicas: 0, + Replicas: 0, + UnavailableReplicas: replicas, + UpdatedReplicas: 0, + }, + }, + }, { + Type: watch.Modified, + Object: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: deploymentName, + Namespace: deploymentNS, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &replicas, + }, + Status: appsv1.DeploymentStatus{ + AvailableReplicas: replicas, + ReadyReplicas: replicas, + Replicas: replicas, + UnavailableReplicas: 0, + UpdatedReplicas: replicas, + }, + }, + }}) + return true, f, nil + } + k.PrependWatchReactor("deployments", reaction) + }, + }, { + desc: "operator deploy error", + cdnos: &CdnosSpec{}, + resp: []fexec.Response{ + {Cmd: "kubectl", Args: []string{"apply", "-f", ""}, Err: "failed to apply operator"}, + }, + + dErr: "failed to apply operator", + }, { + desc: "context canceled", + cdnos: &CdnosSpec{}, + resp: []fexec.Response{ + {Cmd: "kubectl", Args: []string{"apply", "-f", ""}}, + }, + + ctx: canceledCtx, + hErr: "context canceled", + }} + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + if verbose { + fexec.LogCommand = func(s string) { + t.Logf("%s: %s", tt.desc, s) + } + } + cmds := fexec.Commands(tt.resp) + kexec.Command = cmds.Command + defer checkCmds(t, cmds) + + ki := fake.NewSimpleClientset(d) + if tt.mockKClient != nil { + tt.mockKClient(ki) + } + tt.cdnos.SetKClient(ki) + err := tt.cdnos.Deploy(context.Background()) + if s := errdiff.Substring(err, tt.dErr); s != "" { + t.Fatalf("unexpected error: %s", s) + } + if err != nil { + return + } + if tt.ctx == nil { + tt.ctx = context.Background() + } + err = tt.cdnos.Healthy(tt.ctx) + if s := errdiff.Substring(err, tt.hErr); s != "" { + t.Fatalf("unexpected error: %s", s) + } + }) + } +} + func checkCmds(t *testing.T, cmds *fexec.Command) { t.Helper() if err := cmds.Done(); err != nil { diff --git a/deploy/kne/external-multinode-cdnos.yaml b/deploy/kne/external-multinode-cdnos.yaml new file mode 100644 index 00000000..256496eb --- /dev/null +++ b/deploy/kne/external-multinode-cdnos.yaml @@ -0,0 +1,33 @@ +# external-multinode.yaml cluster config file sets up ingress, cni, and controllers in an existing k8 cluster. +# This spec instructs Metallb to use a docker network named multinode. +# The "external" cluster lifecycle is not managed by the KNE deployment. +cluster: + kind: External + spec: + network: multinode +ingress: + kind: MetalLB + spec: + manifest: ../../manifests/metallb/manifest.yaml + ip_count: 200 +cni: + kind: Meshnet + spec: + manifest: ../../manifests/meshnet/grpc/manifest.yaml +controllers: + - kind: IxiaTG + spec: + operator: ../../manifests/keysight/ixiatg-operator.yaml + configMap: ../../manifests/keysight/ixiatg-configmap.yaml + - kind: SRLinux + spec: + operator: ../../manifests/controllers/srlinux/manifest.yaml + - kind: CEOSLab + spec: + operator: ../../manifests/controllers/ceoslab/manifest.yaml + - kind: Lemming + spec: + operator: ../../manifests/controllers/lemming/manifest.yaml + - kind: Cdnos + spec: + operator: ../../manifests/controllers/cdnos/manifest.yaml diff --git a/deploy/kne/external-multinode.yaml b/deploy/kne/external-multinode.yaml index 256496eb..56665504 100644 --- a/deploy/kne/external-multinode.yaml +++ b/deploy/kne/external-multinode.yaml @@ -28,6 +28,3 @@ 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-cdnos.yaml b/deploy/kne/kind-bridge-cdnos.yaml new file mode 100644 index 00000000..2199bdc2 --- /dev/null +++ b/deploy/kne/kind-bridge-cdnos.yaml @@ -0,0 +1,39 @@ +# kind-bridge.yaml cluster config file sets up a kind cluster where default PTP CNI plugin +# is swapped with the Bridge CNI plugin. +# Bridge CNI plugin is required by some Network OSes to operate. +cluster: + kind: Kind + spec: + name: kne + recycle: True + version: v0.17.0 + image: kindest/node:v1.26.0 + config: ../../manifests/kind/config.yaml + additionalManifests: + - ../../manifests/kind/bridge.yaml +ingress: + kind: MetalLB + spec: + manifest: ../../manifests/metallb/manifest.yaml + ip_count: 100 +cni: + kind: Meshnet + spec: + manifest: ../../manifests/meshnet/grpc/manifest.yaml +controllers: + - kind: IxiaTG + spec: + operator: ../../manifests/keysight/ixiatg-operator.yaml + configMap: ../../manifests/keysight/ixiatg-configmap.yaml + - kind: SRLinux + spec: + operator: ../../manifests/controllers/srlinux/manifest.yaml + - kind: CEOSLab + spec: + operator: ../../manifests/controllers/ceoslab/manifest.yaml + - 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/deploy/kne/kind-bridge.yaml b/deploy/kne/kind-bridge.yaml index 2199bdc2..2ee89fa1 100644 --- a/deploy/kne/kind-bridge.yaml +++ b/deploy/kne/kind-bridge.yaml @@ -34,6 +34,3 @@ 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 79dc817e..00dd641b 100644 --- a/docs/create_topology.md +++ b/docs/create_topology.md @@ -117,16 +117,9 @@ Field | Type | Description Field | Type | Description ------ | --------- | ---------------------------------------------------- -`kind` | string | Name of the controller type. The current options currently are `Cdnos`, `IxiaTG`, `SRLinux`, `CEOSLab`, and `Lemming`. +`kind` | string | Name of the controller type. The current options currently are `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 diff --git a/examples/drivenets/srlinux.cfg b/examples/drivenets/srlinux.cfg deleted file mode 120000 index 2e162531..00000000 --- a/examples/drivenets/srlinux.cfg +++ /dev/null @@ -1 +0,0 @@ -../multivendor/srlinux.cfg \ No newline at end of file diff --git a/examples/drivenets/srlinux.cfg b/examples/drivenets/srlinux.cfg new file mode 100644 index 00000000..1494b3d3 --- /dev/null +++ b/examples/drivenets/srlinux.cfg @@ -0,0 +1,108 @@ +system { + management { + openconfig { + admin-state enable + } + } + lldp { + admin-state enable + } + gnmi-server { + admin-state enable + rate-limit 65000 + trace-options [ + request + response + common + ] + network-instance mgmt { + admin-state enable + yang-models openconfig + tls-profile kne-profile + } + unix-socket { + admin-state enable + } + } + tls { + server-profile kne-profile { + key $aes$02OxmuD5O2kk=$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 + certificate "-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgIUXlOp1PeztJmBG2MsGPBkJG5M05swDQYJKoZIhvcNAQEL +BQAwMDEVMBMGA1UEChMMY29udGFpbmVybGFiMRcwFQYDVQQDEw5rbmUtc3JsIGxh +YiBDQTAeFw0yMzAzMTIwOTI3MDBaFw0yNDAzMTEwOTI3MDBaMDAxFTATBgNVBAoT +DGNvbnRhaW5lcmxhYjEXMBUGA1UEAxMOc3JsLmtuZS1zcmwuaW8wggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCnLZqbmeM82O3cPFTzJ/QIQwNScpKujVbM +pdRNvbxmSfridFxLn+/eCTN6HNE8TOdaJEzX1pRbY3DcpDr10Md4DiKCb/QKuYuE +cvF1ruhneVrqKZhHwMwGpBTi4h9rYdLfBCxYxi4ptXupbiQAfk6clPsPXlkhZKRJ +50GqrisQEi+oYC0TG7YtMTscrfY8Pxg8lngRzH7a8eiWdSMnX0ljja1K4bgZ6jdh +wvsT0NJKs1ao01OLt51rndgywqs+xb7V6S2EbUmMCCF4lTxEqUhu/a05XgpeqL+v +snmbfuh7MuK5BwQ0FbC8EHXohYPZ1vrzMUaw0Wh+fk1vlN90/uTfAgMBAAGjgbIw +ga8wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD +AjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTJ0a23nACfVfQLARYwQ0ufzL+0+DAf +BgNVHSMEGDAWgBQMZiIkEzdwrX0L+0N+ISOX47DhvDAwBgNVHREEKTAnggNzcmyC +EGNsYWIta25lLXNybC1zcmyCDnNybC5rbmUtc3JsLmlvMA0GCSqGSIb3DQEBCwUA +A4IBAQAMG2mSg1STaFKpOet7tAK0sMV/HSeSNYyKrf8SN76+7D0RHredVTFMRX+K +EvwKtxGGG/0E/w3DGpS1t+QAZUJz9EoJC/e3AXBRf84jPRoiAy3cmkw4uXDaW4ud +ZU9TnrWJl5hxDyyWfkDZiZ1muQPf+ZUNvV8Qn9G57jv8Wacpkx+2EeFLH7GeTZsF +9ICindYy3VjJuGIZuAkYqlKMW2RPJLRkAOnQfXRizB0wKXQ6X2OcqRDzd/jLj4W1 +wqzCZrqq3V1A8CpmUWL8P63EFO5W8s2h620KDLRwEmfisQiEP46kn9mCX/F2SqEs +ufJifhmpItpy3mkUCLEJ33ex2AA6 +-----END CERTIFICATE----- +" + } + } + gribi-server { + admin-state enable + network-instance mgmt { + admin-state enable + tls-profile kne-profile + } + } + json-rpc-server { + admin-state enable + network-instance mgmt { + http { + admin-state enable + } + https { + admin-state enable + tls-profile kne-profile + } + } + } + banner { + login-banner "................................................................ +: Welcome to Nokia SR Linux! : +: Open Network OS for the NetOps era. : +: : +: This is a freely distributed official container image. : +: Use it - Share it : +: : +: Get started: https://learn.srlinux.dev : +: Container: https://go.srlinux.dev/container-image : +: Docs: https://doc.srlinux.dev/22-11 : +: Rel. notes: https://doc.srlinux.dev/rn22-11-2 : +: YANG: https://yang.srlinux.dev/v22.11.2 : +: Discord: https://go.srlinux.dev/discord : +: Contact: https://go.srlinux.dev/contact-sales : +................................................................ +" + } + p4rt-server { + admin-state enable + network-instance mgmt { + admin-state enable + tls-profile kne-profile + } + } +} +network-instance DEFAULT { +} +network-instance mgmt { + protocols { + gribi { + admin-state enable + } + } +} diff --git a/proto/controller.proto b/proto/controller.proto index d1c8b644..8d3c77c3 100644 --- a/proto/controller.proto +++ b/proto/controller.proto @@ -133,7 +133,6 @@ message LemmingSpec { // CdnosSpec specifications message CdnosSpec { - string manifest_dir = 1 [deprecated = true]; Manifest operator = 2; } diff --git a/proto/topo.proto b/proto/topo.proto index 166c7c62..0712a029 100644 --- a/proto/topo.proto +++ b/proto/topo.proto @@ -64,7 +64,6 @@ 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];