apiVersion: mesh.community/v1
kind: NetworkService
metadata:
  name: northside-community-mesh
  region: ca-toronto
  labels:
    operator: northside-mesh-cooperative
    environment: production

spec:
  autonomousSystem:
    number: 65042
    routerId: 10.42.0.1
    routingProtocol: babel
    upstreams:
      - name: community-ix
        interface: wan0
        peerAddress: 198.51.100.9
        localPreference: 200
      - name: transit-backup
        interface: wan1
        peerAddress: 203.0.113.17
        localPreference: 100

  addressPools:
    meshIPv4: 10.42.0.0/16
    subscriberIPv4: 100.64.0.0/10
    meshIPv6: fd42:42::/48
    delegatedIPv6Prefix: 2001:db8:4200::/40
    customerPrefixLength: 56

  gateways:
    - name: library-rooftop
      site: central-library
      managementAddress: 10.42.0.10
      uplinkCapacityMbps: 2500
      interfaces:
        - name: mesh-east
          band: 5ghz
          channelWidthMHz: 40
          txPowerDbm: 23
        - name: mesh-west
          band: 6ghz
          channelWidthMHz: 80
          txPowerDbm: 20
    - name: community-centre
      site: westside-community-centre
      managementAddress: 10.42.0.11
      uplinkCapacityMbps: 1000
      interfaces:
        - name: mesh-roof
          band: 5ghz
          channelWidthMHz: 40
          txPowerDbm: 23

  routing:
    metric: airtime
    helloIntervalSeconds: 4
    routeExpirySeconds: 120
    defaultRoutePolicy:
      minimumGatewayAvailability: 0.98
      maximumLatencyMs: 45
      failoverGracePeriodSeconds: 15
    clientIsolation: true
    allowNodeTransit: true

  dns:
    searchDomain: mesh.example.net
    resolvers:
      - 10.42.0.53
      - fd42:42::53
    blocklists:
      malware: true
      tracking: false
    cache:
      enabled: true
      maximumTtlSeconds: 86400

  dhcp:
    leaseDuration: 12h
    reservations:
      - hostname: library-sensor-hub
        macAddress: "02:42:ac:11:00:10"
        address: 10.42.20.10
      - hostname: community-radio
        macAddress: "02:42:ac:11:00:20"
        address: 10.42.20.20

  subscriberPlans:
    - name: community-basic
      downstreamMbps: 50
      upstreamMbps: 20
      monthlyDataCapGb: null
      priority: standard
    - name: community-plus
      downstreamMbps: 200
      upstreamMbps: 100
      monthlyDataCapGb: null
      priority: high
    - name: sponsored-access
      downstreamMbps: 25
      upstreamMbps: 10
      monthlyDataCapGb: null
      priority: standard
      eligibilityTag: subsidy-approved

  qualityOfService:
    scheduler: cake
    perSubscriberFairness: true
    overheadBytes: 22
    trafficClasses:
      realtime:
        dscp: EF
        maximumSharePercent: 30
      interactive:
        dscp: AF21
        maximumSharePercent: 60
      bulk:
        dscp: CS1
        maximumSharePercent: 40

  services:
    captivePortal:
      enabled: true
      url: https://portal.mesh.example.net
      sessionTimeout: 24h
    nodeRegistry:
      enabled: true
      url: https://registry.mesh.example.net
      approvalRequired: true
    firmwareUpdates:
      channel: stable
      rolloutBatchPercent: 10
      rollbackOnFailure: true

  security:
    wirelessEncryption: wpa3-sae
    managementVpn: wireguard
    rotateNodeKeysEveryDays: 90
    managementCidrs:
      - 10.42.240.0/20
      - fd42:42:ffff::/64
    firewall:
      defaultInboundPolicy: deny
      defaultForwardPolicy: allow-established
      permittedInboundServices:
        - protocol: udp
          port: 6696
          source: mesh
        - protocol: udp
          port: 51820
          source: management

  monitoring:
    metrics:
      enabled: true
      scrapeIntervalSeconds: 30
      retentionDays: 90
    healthChecks:
      packetLossWarningPercent: 5
      packetLossCriticalPercent: 15
      latencyWarningMs: 50
      latencyCriticalMs: 100
    alerts:
      receiver: noc-oncall
      channels:
        - email
        - sms
      maintenanceWindow:
        day: Tuesday
        start: "02:00"
        durationMinutes: 120
        timezone: America/Toronto

  privacy:
    retainSubscriberFlowLogsDays: 7
    retainAuthenticationLogsDays: 30
    anonymizeClientAddresses: true
    exportTelemetry: false

  contacts:
    networkOperations: noc@mesh.example.net
    abuse: abuse@mesh.example.net
    memberSupport: support@mesh.example.net