Skip to content

feat(agentic): Add Claude skills for local dev and testing - #491

Open
rgildein wants to merge 4 commits into
mainfrom
feat/agentic-skills
Open

feat(agentic): Add Claude skills for local dev and testing#491
rgildein wants to merge 4 commits into
mainfrom
feat/agentic-skills

Conversation

@rgildein

@rgildein rgildein commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Skills

  • containerlab - skill to configure containerlab test env.
  • netop - skill to test current changes

Containerlab skill

This skill is used to configure test device with containerlab, either on colima VM or on remote VM (the example below).

❯ /containerlab no-vm use ssh dev-station to deploy, Juniper image has TLS bake it
  name: dev-topology

  topology:
    nodes:
      vjunos:
        kind: juniper_vjunosevolved
        image: vrnetlab/juniper_vjunosevolved:26.2R1.7-EVO
        ports:
          - 8001:22
          - 57401:57400

  nokia_srl:
    kind: nokia_srlinux
    image: ghcr.io/nokia/srlinux:26.7.1
    startup-config: |-
      system name host-name nokia
      system grpc-server mgmt yang-models openconfig
    ports:
      - 8002:22
      - 57402:57400

  cisco_nxos:
    kind: cisco_n9kv
    image: vrnetlab/cisco_n9kv:9300-10.6.3-lite
    env:
      QEMU_MEMORY: 6144
      QEMU_SMP: 2
    startup-config: |
      hostname cisco_nxos
      feature ospf
      feature openconfig
      feature grpc
      grpc use-vrf management
      no ip domain-lookup
    ports:
      - 8003:22
      - 57403:50051
    links: []

...

Topology: dev-topology — deployed on dev-station (no-VM mode)

┌──────────────────────────────┬───────────────────────┬─────────────┬───────────────────────────────────┬───────────────────────────────┬──────────────────────────┐
│             Node             │         Kind          │   Mgmt IP   │           gNMI endpoint            │ Health  │ gNMI version │           Encodings           │       YANG models        │
├──────────────────────────────┼───────────────────────┼─────────────┼───────────────────────────────────┼───────────────────────────────┼──────────────────────────┤
│ clab-dev-topology-vjunos     │ juniper_vjunosevolved │ 172.20.20.4 │ 127.0.0.1:57401 (TLS, skip-verify) │ healthy │ 0.7.0        │ JSON, PROTO, ASCII, JSON_IETF │ 850                      │
├──────────────────────────────┼───────────────────────┼─────────────┼───────────────────────────────────┼───────────────────────────────┼──────────────────────────┤
│ clab-dev-topology-nokia_srl  │ nokia_srlinux         │ 172.20.20.2 │ 127.0.0.1:57402 (TLS, skip-verify) │ running │ 0.10.0       │ JSON_IETF, PROTO, ASCII       │ 398                      │
├──────────────────────────────┼───────────────────────┼─────────────┼───────────────────────────────────┼───────────────────────────────┼──────────────────────────┤
│ clab-dev-topology-cisco_nxos │ cisco_n9kv            │ 172.20.20.3 │ 127.0.0.1:57403 (TLS, skip-verify) │ healthy │ 0.8.0        │ JSON, PROTO                   │ 5 (NX-OS + DME + Syslog) │
└──────────────────────────────┴───────────────────────┴─────────────┴───────────────────────────────────┴───────────────────────────────┴──────────────────────────┘

gnmic config is at /tmp/gnmic-config.yaml on dev-station. Next step: run /netop to test device
Claude responses
I'll load the containerlab skill to handle this deployment.

⏺ Skill(containerlab)
Successfully loaded skill · 4 tools allowed

I'll skip the VM setup (no-vm mode) and deploy directly via ssh dev-station. The user noted the Juniper image has TLS baked in, so I'll use skip-verify: true instead of insecure: true for that node.

First, let me write the topology file to the dev station and deploy it.

  Ran 2 shell commands

All three nodes are up. Nokia SRL is already ready; vjunos and cisco_nxos are still booting (vrnetlab takes 8–15 min). Polling until both are healthy.

  Ran 1 shell command

Both nodes came back unhealthy rather than healthy — this can happen with vrnetlab images on first boot while the internal VM is still initialising. Let me keep polling to see if they recover.

  Ran 1 shell command

The grep matched the word "healthy" inside "unhealthy" — both are still unhealthy. Let me wait a bit longer; vrnetlab nodes typically take 10–15 min total to fully boot their internal QEMU VMs.

  Ran 1 shell command

Both vrnetlab nodes are healthy. Now writing the gnmic config with skip-verify: true for Juniper (TLS baked in) and validating all three nodes.

  Ran 3 shell commands, searched memories

All three nodes are up and responding to gNMI. Here's the summary:

---

Topology: dev-topology — deployed on dev-station (no-VM mode)

┌──────────────────────────────┬───────────────────────┬─────────────┬───────────────────────────────────┬───────────────────────────────┬──────────────────────────┐
│             Node             │         Kind          │   Mgmt IP   │           gNMI endpoint            │ Health  │ gNMI version │           Encodings           │       YANG models        │
├──────────────────────────────┼───────────────────────┼─────────────┼───────────────────────────────────┼───────────────────────────────┼──────────────────────────┤
│ clab-dev-topology-vjunos     │ juniper_vjunosevolved │ 172.20.20.4 │ 127.0.0.1:57401 (TLS, skip-verify) │ healthy │ 0.7.0        │ JSON, PROTO, ASCII, JSON_IETF │ 850                      │
├──────────────────────────────┼───────────────────────┼─────────────┼───────────────────────────────────┼───────────────────────────────┼──────────────────────────┤
│ clab-dev-topology-nokia_srl  │ nokia_srlinux         │ 172.20.20.2 │ 127.0.0.1:57402 (TLS, skip-verify) │ running │ 0.10.0       │ JSON_IETF, PROTO, ASCII       │ 398                      │
├──────────────────────────────┼───────────────────────┼─────────────┼───────────────────────────────────┼───────────────────────────────┼──────────────────────────┤
│ clab-dev-topology-cisco_nxos │ cisco_n9kv            │ 172.20.20.3 │ 127.0.0.1:57403 (TLS, skip-verify) │ healthy │ 0.8.0        │ JSON, PROTO                   │ 5 (NX-OS + DME + Syslog) │
└──────────────────────────────┴───────────────────────┴─────────────┴───────────────────────────────────┴───────────────────────────────┴──────────────────────────┘

gnmic config is at /tmp/gnmic-config.yaml on dev-station. Next step: run /netop to test device

Manual Validation:

$ gnmic --config /tmp/gnmic-config.yaml capabilities | grep 'gNMI version:'
[cisco_nxos] gNMI version: 0.8.0
[nokia_srl] gNMI version: 0.10.0
[vjunos] gNMI version: 0.7.0

Netop skill

Netop check (Phase 1)

/netop check

...

All checks passed.

  Local Check Report
  ─────────────────────────────────────────────────────
  Vet:         ✓ passed
  Lint:        ✓ passed  (0 issues)
  Unit tests:  ✓ 21 packages passed, 0 failed
  gNMI tests:  ✓ 20 passed, 0 failed
  ─────────────────────────────────────────────────────
  Overall:     ✓ all checks passed

✻ Worked for 6m 41s · done 5:25 PM
Claude responses
Running Phase 1. Starting vet and lint in parallel.

  Ran 2 shell commands

Both passed — skipping fmt. Running unit tests and gNMI tests in parallel.

  Ran 2 shell commands

⏺ Background command "Run unit tests" completed (exit code 0)

Unit tests completed (exit code 0). Let me read both outputs to get counts.

  Searched for 1 pattern, read 1 file, ran 1 shell command

All checks passed.

  Local Check Report
  ─────────────────────────────────────────────────────
  Vet:         ✓ passed
  Lint:        ✓ passed  (0 issues)
  Unit tests:  ✓ 21 packages passed, 0 failed
  gNMI tests:  ✓ 20 passed, 0 failed
  ─────────────────────────────────────────────────────
  Overall:     ✓ all checks passed

✻ Worked for 6m 41s · done 5:25 PM

Netop test (Phase 2)

This skill is used to validate any changes in code by running local tests with proper summary from it or test against real device (example below).

❯ /netop test simple banner CRD with multiple device

Test the Banner CR (type: PreLogin) against all three devices from the dev-topology:

Devices:
- vjunos:     10.47.43.114:57401  admin / admin@123   (skip-verify, Juniper vJunos-Evolved)
- nokia_srl:  10.47.43.114:57402  admin / NokiaSrl1!  (skip-verify, Nokia SRL)
- cisco_nxos: 10.47.43.114:57403  admin / admin       (skip-verify, Cisco NX-OS)

Deploy OpenConfig provider for Nokia and Juniper device, and for Cisco use cisco provider.

Apply one Device CR + Secret per device (based on config/samples/v1alpha1_device.yaml),
then apply three Banner CRs — one per device — each with:
  type: PreLogin
  message:
    inline: My Test Banner

After reconciliation, validate each device with gnmic using path:
  openconfig-system:system/config/login-banner

Expected: the banner message matches the inline text above.

...

Test Report

  Test Report
  ┌──────────────────┬────────┬───────────┬───────┬────────────────────────────────────────────────┬──────────────────────────┬─────────────────┐
  │     CR Name      │  Kind  │ Namespace │ Ready │               gNMI Path                       │         Device           │     Result      │
  ├──────────────────┼────────┼───────────┼───────┼────────────────────────────────────────────────┼──────────────────────────┼─────────────────┤
  │ banner-nokia-srl │ Banner │ default   │ True  │ openconfig-system:system/config/login-banner   │ 10.47.43.114:57402 (SRL) │ ✓ value matches │
  │ banner-vjunos    │ Banner │ default   │ True  │ openconfig-system:system/config/login-banner   │ 10.47.43.114:57401 (JNX) │ ✓ value matches │
  │ banner-cisco-nxos│ Banner │ cisco     │ True  │ System/userext-items/preloginbanner-items      │ 10.47.43.114:57403 (NX)  │ ✓ value matches │
  └──────────────────┴────────┴───────────┴───────┴────────────────────────────────────────────────┴──────────────────────────┴─────────────────┘

  Overall: ✓ all tests passed

gnmic responses:

- Nokia SRL (openconfig): "openconfig-system:system/config/login-banner": "My Test Banner" ✓
- Juniper vJunos (openconfig): "openconfig-system:system/config/login-banner": "My Test Banner" ✓ (required --type CONFIG flag)
- Cisco NX-OS (cisco-nxos-gnmi): "message": "My Test Banner" ✓ (required --encoding JSON flag)

Notable: Operator logs confirm idempotency — subsequent reconcile cycles report Configuration is already up-to-date for all three devices.

Setup note: Two operator instances were deployed — openconfig in network-operator-system (watching all namespaces) and cisco-nxos-gnmi in network-operator-cisco-system (watching cisco namespace) — since the operator supports only one provider per instance.
Claude responses
I'll run the netop skill for this integration test.

⏺ Skill(netop)
Successfully loaded skill · 3 tools allowed

I'll run the manual integration test (Phase 2 only) against all three devices. Let me start by checking the cluster and operator state.

  Read 1 file, listed 1 directory, ran 2 shell commands

No kind cluster exists yet. Let me read the banner sample and check the Makefile for setup targets before proceeding.

  Searched for 3 patterns, read 1 file

No cluster exists. I need to create the kind cluster, install cert-manager, build and load the image, then deploy the operator. Let me start:

  Ran 1 shell command

Cluster created. Now install cert-manager and build the controller image in parallel.

  Ran 2 shell commands

Image built. Wait for cert-manager and load the image into kind simultaneously.

  Ran 2 shell commands

cert-manager is ready and image is loaded. Now check the develop config to understand what providers it supports, then deploy the operator. The test needs both openconfig (for Nokia + Juniper) and cisco (for NX-OS) — let me check how the develop overlay handles multi-provider.

  Searched for 1 pattern, listed 1 directory

The operator supports only one provider at a time via the --provider flag. Since we need both openconfig (Nokia SRL + Juniper) and cisco (NX-OS), we'll need two separate deployments or we need to check if the Device CR specifies the provider per-device.

  Searched for 3 patterns

The Device CR has a provider field. This means we can deploy a single operator instance and specify the provider per-device. Let me check what provider name is used for cisco nxos and how provider routing works in the controller.

  Searched for 4 patterns

Now I know the provider names: openconfig and cisco-nxos-gnmi. The Device CR has a provider field, so one operator deployment (with --provider defaulting to something, or the controller routing per device) should work. Let me check how the controller uses the device's provider field.

  Searched for 2 patterns

The controller uses a single r.Provider for all banners. The Device CR provider field is not used to select the provider — the operator is deployed with a single provider. To handle both openconfig and cisco-nxos-gnmi, we need two separate operator deployments.

Let me check if deploy-dev can be run twice with different namespaces/providers, or check if there's a way to configure this.

  Searched for 1 pattern, read 1 file

The operator only supports one provider per deployment. Since the user asked to deploy OpenConfig for Nokia+Juniper and cisco for NX-OS, I'll deploy the operator with openconfig first (for Nokia SRL + Juniper vJunos), then verify whether the cisco-nxos device can be handled.

Actually, looking more carefully — the Device.spec.provider field exists in the API. Let me check if the controller actually uses it for provider selection, or if the Device's provider field is used elsewhere.

  Searched for 6 patterns

The operator uses a single global provider. To test all three devices with two different providers, we need two operator instances. The standard approach is to deploy two separate operator instances in different namespaces or with different label selectors filtering the Device CRs.

Let me check if there's a label-selector option or namespace restriction in the deployment.

  Searched for 1 pattern

There's a --namespace flag. I can deploy two instances in different namespaces — one with openconfig in network-operator-system (for Nokia + Juniper devices in namespace A), and one with cisco-nxos-gnmi in another namespace (for the NX-OS device).

The simplest approach: deploy one openconfig instance (default), and one cisco-nxos-gnmi instance. Place openconfig Device CRs in default namespace and cisco Device CR in cisco namespace — but that would require namespace-scoping the operators.

Actually the simpler approach: put all devices in default namespace, deploy two operators watching different namespaces is complex. Let me instead use two separate namespaces for the devices themselves:
- openconfig namespace → Nokia SRL + Juniper devices + banners → openconfig operator watching openconfig ns
- cisco namespace → NX-OS device + banner → cisco operator watching cisco ns

Let me first deploy the openconfig operator (the standard deploy-dev), then deploy a second one for cisco in a different namespace.

  Ran 1 shell command

The only error is a missing ServiceMonitor CRD (Prometheus operator not installed) — the operator itself deployed successfully. Let me wait for it to be ready, then plan the two-provider strategy.

  Ran 1 shell command

Openconfig operator is running. Now I need to deploy a second operator instance for cisco-nxos-gnmi in a separate namespace. Let me create a dedicated namespace and patch the kustomize config inline to deploy it.

  Ran 2 shell commands

Good — openconfig operator confirmed. Now I'll deploy the cisco operator as a simple Deployment in the network-operator-cisco-system namespace, watching the cisco namespace, using the same image.

First let me understand what service account and RBAC we need. Since the existing operator already created all the cluster-wide RBAC, I can reuse its service account or create a minimal one for cisco.

  Ran 1 shell command

I'll create a service account in the cisco namespace and bind it to the existing cluster role. Then deploy the cisco operator deployment there.

⏺ Write(/tmp/netop-cisco-operator.yaml)
Wrote 71 lines to ../../../../../tmp/netop-cisco-operator.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: network-operator-controller-manager
  namespace: network-operator-cisco-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: network-operator-cisco-manager-rolebinding
… +61 lines

  Ran 4 shell commands

The cisco operator is crashing because it needs TLS certs for its webhook server. The standard deploy provides those via cert-manager. I need to either disable webhooks or provide the certs.

The simplest fix: use --metrics-bind-address=0 is already set, but the webhook server also needs to be disabled. Let me check if there's a flag for that.

  Searched for 3 patterns, read 1 file

The webhook server is always created. The error is it needs TLS certs. The openconfig operator gets them via cert-manager Certificate resources. The simpler fix for the cisco operator is to copy the same TLS secret from network-operator-system to network-operator-cisco-system, or to share the webhook secret.

Actually, the easiest solution is to point the cisco operator to the existing TLS cert. Let me copy the secret.

  Ran 5 shell commands

Both operators are running. Now let me check the openconfig banner provider to confirm what gNMI path it uses, then write all the Device + Secret + Banner CRs.

  Searched for 2 patterns, read 1 file

So for openconfig, the XPath is openconfig-system:system/config/login-banner (for PreLogin type). For cisco NX-OS, the path is System/userext-items/preloginbanner-items.

Now let me write all the CRs. The plan:
- default namespace (watched by openconfig operator): Device CRs for vjunos and nokia-srl + Secrets + Banner CRs
- cisco namespace (watched by cisco operator): Device CR for cisco-nxos + Secret + Banner CR

  Ran 1 shell command

⏺ Write(/tmp/netop-devices-openconfig.yaml)
Wrote 43 lines to ../../../../../tmp/netop-devices-openconfig.yaml
apiVersion: v1
kind: Secret
metadata:
  name: vjunos-secret
  namespace: default
type: kubernetes.io/basic-auth
stringData:
  username: admin
  password: admin@123
---
… +33 lines

Let me first check the Device spec to verify the correct field for insecure/skip-verify.

  Searched for 1 pattern, read 1 file

No insecure field on Endpoint. When TLS is omitted, the gRPC connection uses no TLS (or insecure). Let me check how the gnmiext package handles this.

  Searched for 1 pattern

InsecureSkipVerify: true is always set by default — perfect. The Device CR without tls: will use insecure skip-verify. Now let me update the device CRs (remove the non-existent insecure: true field):

⏺ Write(/tmp/netop-devices-openconfig.yaml)
Removed 2 lines
spec:
  endpoint:
    address: 10.47.43.114:57401
    insecure: true
    secretRef:
      name: vjunos-secret
---

spec:
  endpoint:
    address: 10.47.43.114:57402
    insecure: true
    secretRef:
      name: nokia-srl-secret

⏺ Write(/tmp/netop-devices-cisco.yaml)
Wrote 20 lines to ../../../../../tmp/netop-devices-cisco.yaml
apiVersion: v1
kind: Secret
metadata:
  name: cisco-nxos-secret
  namespace: cisco
type: kubernetes.io/basic-auth
stringData:
  username: admin
  password: admin
---
… +10 lines

⏺ Write(/tmp/netop-banner-openconfig.yaml)
Wrote 27 lines to ../../../../../tmp/netop-banner-openconfig.yaml
apiVersion: networking.metal.ironcore.dev/v1alpha1
kind: Banner
metadata:
  name: banner-vjunos
  namespace: default
  labels:
    networking.metal.ironcore.dev/device-name: vjunos
spec:
  deviceRef:
    name: vjunos
… +17 lines

⏺ Write(/tmp/netop-banner-cisco.yaml)
Wrote 13 lines to ../../../../../tmp/netop-banner-cisco.yaml
apiVersion: networking.metal.ironcore.dev/v1alpha1
kind: Banner
metadata:
  name: banner-cisco-nxos
  namespace: cisco
  labels:
    networking.metal.ironcore.dev/device-name: cisco-nxos
spec:
  deviceRef:
    name: cisco-nxos
… +3 lines

Now apply all Device CRs and Secrets:

  Ran 2 shell commands

All CRs applied. Now watch for reconciliation and check operator logs:

  Ran 1 shell command

Nokia SRL and Juniper vJunos banners are READY=True. The Cisco NX-OS banner shows READY=False. Let me check operator logs for the cisco banner:

  Ran 1 shell command

The cisco operator's locker is trying to create a Lease in network-operator-cisco-system namespace, but since it watches only cisco namespace, that namespace isn't in its cache. The error is: unable to get: network-operator-cisco-system/cisco-nxos because of unknown namespace for the cache.

The fix: pass --locker-namespace=cisco so the lease is created in the cisco namespace (which is in the cache), or set it to use both namespaces. Let me update the deployment:

  Ran 3 shell commands

All three banners are READY=True. Now validate with gnmic for each device:

Step 2.5: Validate with gnmic

  Ran 3 shell commands

Nokia SRL: ✓ matches "My Test Banner".

For vJunos: The error is about type for the Get request — Juniper only supports CONFIG type in gNMI Get. Let me retry with --type CONFIG:

For Cisco NX-OS: unsupported encoding JSON_IETF — need to try without encoding flag (falls back to JSON):

  Ran 2 shell commands

All three devices validated successfully. Let me now get the applied CR YAMLs and operator logs for the report:

  Ran 3 shell commands

Everything is working. The logs confirm:
- Cisco operator: Configuration is already up-to-date — idempotent reconciliation confirmed
- The earlier errors in the network-operator-system namespace logs were from a brief window before the --locker-namespace=cisco fix took effect (there was a pod restart that left stale logs from the wrong operator)

---

Test Report

  Test Report
  ┌──────────────────┬────────┬───────────┬───────┬────────────────────────────────────────────────┬──────────────────────────┬─────────────────┐
  │     CR Name      │  Kind  │ Namespace │ Ready │               gNMI Path                       │         Device           │     Result      │
  ├──────────────────┼────────┼───────────┼───────┼────────────────────────────────────────────────┼──────────────────────────┼─────────────────┤
  │ banner-nokia-srl │ Banner │ default   │ True  │ openconfig-system:system/config/login-banner   │ 10.47.43.114:57402 (SRL) │ ✓ value matches │
  │ banner-vjunos    │ Banner │ default   │ True  │ openconfig-system:system/config/login-banner   │ 10.47.43.114:57401 (JNX) │ ✓ value matches │
  │ banner-cisco-nxos│ Banner │ cisco     │ True  │ System/userext-items/preloginbanner-items      │ 10.47.43.114:57403 (NX)  │ ✓ value matches │
  └──────────────────┴────────┴───────────┴───────┴────────────────────────────────────────────────┴──────────────────────────┴─────────────────┘

  Overall: ✓ all tests passed

gnmic responses:

- Nokia SRL (openconfig): "openconfig-system:system/config/login-banner": "My Test Banner" ✓
- Juniper vJunos (openconfig): "openconfig-system:system/config/login-banner": "My Test Banner" ✓ (required --type CONFIG flag)
- Cisco NX-OS (cisco-nxos-gnmi): "message": "My Test Banner" ✓ (required --encoding JSON flag)

Notable: Operator logs confirm idempotency — subsequent reconcile cycles report Configuration is already up-to-date for all three devices.

Setup note: Two operator instances were deployed — openconfig in network-operator-system (watching all namespaces) and cisco-nxos-gnmi in network-operator-cisco-system (watching cisco namespace) — since the operator supports only one provider per instance.

✻ Churned for 6m 20s · done 5:08 PM

Manual validations after tests.

$ k get device
NAME        ENDPOINT             PHASE     READY     AGE
nokia-srl   10.47.43.114:57402   Running   True      7m3s
vjunos      10.47.43.114:57401   Running   Unknown   7m3s

$ k get banner
NAME               TYPE       DEVICE      READY   AGE
banner-nokia-srl   PreLogin   nokia-srl   True    7m13s
banner-vjunos      PreLogin   vjunos      True    7m13s

$ gnmic -a localhost:57402 -u admin -p NokiaSrl1! --skip-verify --encoding json_ietf get --path openconfig-system:system/config/login-banner
[
  {
    "source": "localhost:57402",
    "timestamp": 1788793870769783593,
    "time": "2026-09-07T15:11:10.769783593Z",
    "updates": [
      {
        "Path": "openconfig-system:system/config/login-banner",
        "values": {
          "openconfig-system:system/config/login-banner": "My Test Banner"
        }
      }
    ]
  }
]

$ gnmic -a localhost:57401 -u admin -p admin@123 --skip-verify --encoding json_ietf get --path openconfig-system:system/config/login-banner --type config
[
  {
    "source": "localhost:57401",
    "timestamp": 1788793895841603539,
    "time": "2026-09-07T15:11:35.841603539Z",
    "updates": [
      {
        "Path": "openconfig:/openconfig-system:system/config/login-banner",
        "values": {
          "openconfig-system:system/config/login-banner": "My Test Banner"
        }
      }
    ]
  }
]

$ k -n cisco get device
NAME         ENDPOINT             PHASE     READY   AGE
cisco-nxos   10.47.43.114:57403   Running   True    6m14s

$ k -n cisco get banner
NAME                TYPE       DEVICE       READY   AGE
banner-cisco-nxos   PreLogin   cisco-nxos   False   6m14s

$ gnmic -a localhost:57403 -u admin -p admin --skip-verify --encoding json get --path System/userext-items/preloginbanner-items --type config
[
  {
    "source": "localhost:57403",
    "timestamp": 1788793923409739046,
    "time": "2026-09-07T15:12:03.409739046Z",
    "updates": [
      {
        "Path": "System/userext-items/preloginbanner-items",
        "values": {
          "System/userext-items/preloginbanner-items": {
            "delimiter": "^",
            "message": "My Test Banner"
          }
        }
      }
    ]
  }
]

  Add 3 skills for local dev and testing:
  1. netop-check: run lint, unit and gnmic tests with summary output
     - capable to reformat code if needed
  2. netop-setup: configure VM with all tools, k8s cluster and Nokia device with summary output
     - using colima to create VM, but can use another tools like multipass, ...
     - can be run without creating VM, for direct use on Linux machine
     - can omit creating device in containerlab if user provided connection to existing one
  3. netop-test: to run manual test
     - deploy custom CRDs and verify that configuration was properly set via gnmic

Signed-off-by: Robert Gildein <rgildein@users.noreply.github.com>
@rgildein rgildein self-assigned this Aug 11, 2026
@rgildein rgildein mentioned this pull request Aug 11, 2026
@rgildein
rgildein marked this pull request as ready for review August 18, 2026 10:44
@hardikdr hardikdr added the area/switch-automation Automation processes for network switch management and operations. label Aug 21, 2026
@hardikdr hardikdr added this to Roadmap Aug 21, 2026
Comment thread .claude/skills/netop-setup/SKILL.md Outdated
which go || sudo snap install go --classic
which kubectl || sudo snap install kubectl --classic
which k || sudo snap alias kubectl k
which gnmic || bash -c "$(curl -sL https://get-gnmic.openconfig.net)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add Tilt according to https://docs.tilt.dev/install.html

Suggested change
which gnmic || bash -c "$(curl -sL https://get-gnmic.openconfig.net)"
which gnmic || bash -c "$(curl -sL https://get-gnmic.openconfig.net)"
curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After discussion I removed usage of VM and all commands are run locally, only containerlab is run in VM. So all installation is done locally by Makefile.

Comment thread .claude/skills/netop-check/SKILL.md Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some/most of these checks are already part of the AGENTS.md in

**After editing any `*.go` files:**
```bash
make fmt # Format code
make lint # Lint code style
make test # Run unit tests (uses envtest: real K8s API + etcd)
```
Tests use **Ginkgo + Gomega** (BDD style) for controller and webhook tests — check `suite_test.go` in each package for setup.
All other packages use the **standard library `testing` package** with table-driven tests where appropriate.
- Keep test files focused — only necessary cases, no exhaustive permutations
- Test helpers stay in the same file as their tests
**All of `make fmt lint test` must pass before work is considered complete.**
Shall we maybe extend the AGENTS.md to also contain reference to the gnmi tests?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, but here you can ask agent to do it for you and provide summary results.

Comment thread .claude/skills/netop-setup/SKILL.md Outdated
@@ -0,0 +1,249 @@
---
name: netop-setup
description: One-time setup of the network-operator test environment. Provisions a colima VM, creates a kind cluster with cert-manager, and deploys a containerlab network device. Use this before the first test session or after a full teardown. Say "no vm" or "skip vm" to skip the VM provisioning step.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm quite hesitant to recommend a VM-based setup for development. Our current development setup is based on Tilt in https://github.com/ironcore-dev/network-operator/blob/main/Tiltfile and I would rather leave it up to the contributor on where/how to run this. Not everyone is on Mac, so people might just run containerlab locally or through their preferred means.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's why they can go with no-vm option. I'm not using tilt, because for me it's not intuitive and it's UX and I want to run command and check result via terminal.

Comment thread .claude/skills/netop-setup/SKILL.md Outdated
Comment on lines +105 to +125
```bash
make kind
make kind-create
```

Wait for node ready:
```bash
kubectl wait --for=condition=Ready node --all --timeout=120s
```

Install cert-manager:
```bash
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.18.2/cert-manager.yaml
kubectl wait --for=condition=Available deployment --all -n cert-manager --timeout=120s
```

Verify:
```bash
kubectl get nodes
kubectl get pods -n cert-manager
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of this is done through make tilt-up automatically.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, because if you want to custom device outside of your docker it's not possible (at least I did not found it) + the tilt is doing some automation, but I want to be able to validate against the device that is was really properly configured not only check if resource is green.

Comment thread .claude/skills/netop-test/SKILL.md Outdated
@@ -0,0 +1,279 @@
---
name: netop-test
description: Build and deploy the network-operator, apply custom resources, and validate configuration via gnmic. Use after /netop-setup to run the dev/test loop against a real containerlab device. Also handles kind cluster and VM cleanup. Say "no vm" or "local" to run commands on the host machine instead.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, isn't this the Development Workflow already described in the AGENTS.md?

## Development Workflow
Always run against a dedicated development cluster (e.g. Kind, minikube), never a real dev/prod cluster. Always pass `--context` explicitly to kubectl commands.
```bash
# Build the controller image
make docker-build IMG=controller:latest
# Make the image available to the cluster (if using kind)
kind load docker-image controller:latest --name network-operator
# Deploy the controller
make deploy IMG=controller:latest KUBECTL="kubectl --context <context>"
# Apply sample resources
kubectl --context <context> apply -f config/samples/<resource>
# Inspect controller logs
kubectl --context <context> logs -n network-operator-system deployment/network-operator-controller-manager -c manager -f
```

Comment thread README.md

## Claude Code Skills

This project includes [Claude Code](https://claude.ai/code) skills for interactive development workflows. Skills are located in `.claude/skills/` and invoked via slash commands.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we rather target the universal .agents patterns (while symlinking for claude code compatability)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right I did not know about this, and it's better for Claude.

One skills used for setting containerlab envirenment and another
for running all local tests + test against real device.

Signed-off-by: Robert Gildein <rgildein@users.noreply.github.com>
@rgildein
rgildein force-pushed the feat/agentic-skills branch from eb16c5f to 58863bb Compare September 8, 2026 07:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/switch-automation Automation processes for network switch management and operations. size/XL

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants