From 556b3671637efab53ce089642b4802d16667e4b9 Mon Sep 17 00:00:00 2001
From: "Th.L" <thl-cmk@outlook.com>
Date: Mon, 12 Jul 2021 21:34:23 +0200
Subject: [PATCH] update project

---
 agent_based/inv_cisco_wlc_clients.py       | 359 +++++++++++++++++++++
 inv_cisco_wlc_clients.mkp                  | Bin 5023 -> 5438 bytes
 packages/inv_cisco_wlc_clients             |  27 +-
 web/plugins/views/inv_cisco_wlc_clients.py |  70 ++++
 web/plugins/wato/inv_cisco_wlc_clients.py  |  90 ++++++
 5 files changed, 537 insertions(+), 9 deletions(-)
 create mode 100644 agent_based/inv_cisco_wlc_clients.py
 create mode 100644 web/plugins/views/inv_cisco_wlc_clients.py
 create mode 100644 web/plugins/wato/inv_cisco_wlc_clients.py

diff --git a/agent_based/inv_cisco_wlc_clients.py b/agent_based/inv_cisco_wlc_clients.py
new file mode 100644
index 0000000..22cdf26
--- /dev/null
+++ b/agent_based/inv_cisco_wlc_clients.py
@@ -0,0 +1,359 @@
+# !/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# License: GNU General Public License v2
+#
+# Author: thl-cmk[at]outlook[dot]com
+# URL   : https://thl-cmk.hopto.org
+# Date  : 2016-04-08
+#
+# writen by: Th.L thl-cmk[at]outlook[dot]com
+#
+# 22.08.2016 : removed index column
+# 09.04.2017 : added wato enable/disable, remove columns
+# 04.09.2018 : changes for CMK 1.5.x (inv_tree --> inv_tree_list)
+#
+
+import re
+import time
+import binascii
+from typing import List, NamedTuple
+
+from cmk.base.plugins.agent_based.agent_based_api.v1 import (
+    OIDEnd,
+    OIDBytes,
+)
+from cmk.base.plugins.agent_based.agent_based_api.v1 import (
+    register,
+    SNMPTree,
+    TableRow,
+    contains,
+)
+from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
+    StringTable,
+    InventoryResult,
+)
+
+_enable_disable = {
+    0: 'N/A',
+    1: 'enabled',
+    2: 'disabled',
+}
+
+_isaclapplied = {
+    0: 'n/a',
+    1: 'true',
+    2: 'false',
+    3: 'notavailable',
+}
+
+_associationmode = {
+    0: 'n/a',
+    1: 'unknown',
+    2: 'wep',
+    3: 'wpa',
+    4: 'wpa2',
+}
+
+_authmode = {
+    0: 'none',
+    1: 'psk',
+    2: 'radius',
+    3: 'cckm',
+    4: 'wapipsk',
+    5: 'wapicert',
+    6: 'ftdot1x',
+    7: 'ftpsk',
+    8: 'pmfdot1x',
+    9: 'pmfpsk',
+}
+
+_reasoncode = {
+    0: 'n/a',
+    1: 'unspecified',
+    2: 'previousauthnotvalid',
+    3: 'deauthenticationleaving',
+    4: 'disassociationduetoinactivity',
+    5: 'disassociationapbusy',
+    6: 'class2framefromnonauthstation',
+    7: 'class2framefromnonassstation',
+    8: 'disassociationstahasleft',
+    9: 'stareqassociationwithoutauth',
+    10: 'invalidinformationelement',
+    11: 'groupcipherinvalid',
+    12: 'unicastcipherinvalid',
+    13: 'akmpinvalid',
+    14: 'unsupportedrsnversion',
+    15: 'invalidrsniecapabilities',
+    16: 'ciphersuiterejected',
+    17: 'missingreasoncode',
+    18: 'maxassociatedclientsreached',
+    19: 'maxassociatedclientsreachedonradio',
+    20: 'maxassociatedclientsreachedonwlan',
+    21: 'unspecifiedqosfailure',
+    22: 'qospolicymismatch',
+    23: 'insufficientbandwidth',
+    24: 'invalidqosparams',
+}
+
+_authentication = {
+    0: 'n/a',
+    1: 'unknown',
+    2: 'central',
+    3: 'local',
+}
+
+_dataswitching = {
+    0: 'n/a',
+    1: 'unknown',
+    2: 'central',
+    3: 'local',
+}
+
+_hreapapauth = {
+    0: 'n/a',
+    1: 'true',
+    2: 'false',
+    3: 'notapplicable',
+}
+
+_nacstate = {
+    0: 'n/a',
+    1: 'quarantine',
+    2: 'access',
+}
+
+_protocol = {
+    0: 'n/a',
+    1: '802.11a',
+    2: '802.11b',
+    3: '802.11g',
+    4: 'unknown',
+    5: 'mobile',
+    6: '802.11n 2,4Ghz',
+    7: '802.11n 5GHz',
+    8: 'ethernet',
+    9: 'dot3',
+    10: '802.11ac 5GHz'
+}
+
+_userauthtype = {
+    0: 'n/a',
+    1: 'open',
+    2: 'wepPsk',
+    3: 'portal',
+    4: 'simPeap',
+    5: 'other',
+}
+
+_wgbstatus = {
+    0: 'n/a',
+    1: 'wireless client',
+    2: 'wireless client via WGB',
+    3: 'WGB itself',
+}
+
+_clientstatus = {
+    0: 'n/a',
+    1: 'idle',
+    2: 'aaa Pending',
+    3: 'authenticated',
+    4: 'associated',
+    5: 'powersave',
+    6: 'disassociated',
+    7: 'to be deleted',
+    8: 'probing',
+    9: 'excluded',
+}
+
+_interfacetype = {
+    0: 'n/a',
+    1: '802.11bg',
+    2: '802.11a',
+    3: 'Ultra wideband',
+    4: '802.11abgn',
+    5: '802.11ac',
+    6: '802.11b',
+    7: '802.11g',
+    8: '802.11n 2.4GHz',
+    9: '802.11n 5GHz',
+    10: 'unknown',
+}
+
+_powersavemode = {
+    0: 'n/a',
+    1: 'active',
+    2: 'powersave',
+}
+
+
+def _render_mac_address(bytestring):
+    return ':'.join(['%02s' % hex(ord(m))[2:] for m in bytestring]).replace(' ', '0').upper()
+
+
+def parse_inv_cisco_wlc_clients(string_table: StringTable):
+    clients = []
+
+    for client in string_table:
+        macaddress, status, wlanprofilename, wgbstatus, wgbmacaddress, protocol, associationmode, \
+        apmacaddress, iftype, ipaddress, nacstate, quarantinevlan, accessvlan, logintime, uptime, \
+        powersavemode, currenttxrateset, datarateset, hreapapauth, ieee80211ucapable, posturestate, \
+        aclname, aclapplied, redirecturl, aaaoverrideaclname, aaaoverrideaclapplied, username, \
+        ssid, securitytagid, typekts, ipv6aclname, ipv6aclapplied, dataswitching, authentication, \
+        channel, authmode, reasoncode, sessionid, aproammacaddress, mdnsprofile, mdnsadvcount, \
+        policyname, aaarole, devicetype, userauthtype = client
+
+        clients.append({
+            'macaddress': _render_mac_address(macaddress),
+            'username': username,
+            'status_columns': {
+                'status': _clientstatus.get(int(status)),
+                'wlanprofilename': wlanprofilename,
+                'wgbstatus': _wgbstatus.get(int(wgbstatus)),
+                'wgbmacaddress': wgbmacaddress,
+                'protocol': _protocol.get(int(protocol)),
+                'associationmode': _associationmode.get(int(associationmode)),
+                'apmacaddress': _render_mac_address(apmacaddress),
+                'iftype': _interfacetype.get(int(iftype)),
+                'ipaddress': ipaddress,
+                'nacstate': _nacstate.get(int(nacstate)),
+                'quarantinevlan': quarantinevlan,
+                'accessvlan': accessvlan,
+                'logintime': logintime,
+                'uptime': uptime,
+                'powersavemode': _powersavemode.get(int(powersavemode)),
+                'currenttxrateset': currenttxrateset,
+                'datarateset': datarateset,
+                'hreapapauth': _hreapapauth.get(int(hreapapauth)),
+                'ieee80211ucapable': _enable_disable.get(int(ieee80211ucapable)),
+                'posturestate': _enable_disable.get(int(posturestate)),
+                'aclname': aclname,
+                'aclapplied': _isaclapplied.get(int(aclapplied)),
+                'redirecturl': redirecturl,
+                'aaaoverrideaclname': aaaoverrideaclname,
+                'aaaoverrideaclapplied': _isaclapplied.get(int(aaaoverrideaclapplied)),
+                'ssid': ssid,
+                'securitytagid': securitytagid,
+                'typekts': _enable_disable.get(int(typekts)),
+                'ipv6aclname': ipv6aclname,
+                'ipv6aclapplied': _isaclapplied.get(int(ipv6aclapplied)),
+                'dataswitching': _dataswitching.get(int(dataswitching)),
+                'authentication': _authentication.get(int(authentication)),
+                'channel': channel,
+                'authmode': _authmode.get(int(authmode)),
+                'reasoncode': _reasoncode.get(int(reasoncode)),
+                'sessionid': sessionid,
+                'aproammacaddress': _render_mac_address(aproammacaddress),
+                'mdnsprofile': mdnsprofile,
+                'mdnsadvcount': mdnsadvcount,
+                'policyname': policyname,
+                'aaarole': aaarole,
+                'devicetype': devicetype,
+                'userauthtype': _userauthtype.get(int(userauthtype)),
+            },
+        })
+
+    return clients
+
+
+def inventory_cisco_wlc_clients(params, section) -> InventoryResult:
+    removecolumns = []
+
+    if params:
+        removecolumns = params.get('removecolumns', removecolumns)
+
+    path = ['networking', 'wlan', 'controller', 'clients']
+
+    for client in section:
+        key_columns = {'username': client['username']}  # 'macaddress': client['macaddress'],
+
+        for key in key_columns.keys():
+            client.pop(key)
+
+        status_columns = client['status_columns']
+
+        client.pop('status_columns')
+
+        for entry in removecolumns:
+            try:
+                client.pop(entry)
+            except KeyError:
+                pass
+
+        for entry in removecolumns:
+            try:
+                status_columns.pop(entry)
+            except KeyError:
+                pass
+
+        yield TableRow(
+            path=path,
+            key_columns=key_columns,
+            inventory_columns=client,
+            status_columns=status_columns,
+        )
+
+
+register.snmp_section(
+    name='inv_cisco_wlc_clients',
+    parse_function=parse_inv_cisco_wlc_clients,
+    fetch=
+    SNMPTree(
+        base='.1.3.6.1.4.1.9.9.599.1.3.1.1',  # CISCO-LWAPP-DOT11-CLIENT-MIB::cldcClientEntry
+        oids=[
+            '1',  # cldcClientMacAddress
+            '2',  # cldcClientStatus
+            '3',  # cldcClientWlanProfileName
+            '4',  # cldcClientWgbStatus
+            '5',  # cldcClientWgbMacAddress
+            '6',  # cldcClientProtocol
+            '7',  # cldcAssociationMode
+            '8',  # cldcApMacAddress
+            '9',  # cldcIfType
+            '10',  # cldcClientIPAddress
+            '11',  # cldcClientNacState
+            '12',  # cldcClientQuarantineVLAN
+            '13',  # cldcClientAccessVLAN
+            '14',  # cldcClientLoginTime
+            '15',  # cldcClientUpTime
+            '16',  # cldcClientPowerSaveMode
+            '17',  # cldcClientCurrentTxRateSet
+            '18',  # cldcClientDataRateSet
+            '19',  # cldcClientHreapApAuth
+            '20',  # cldcClient80211uCapable
+            '21',  # cldcClientPostureState
+            '22',  # cldcClientAclName
+            '23',  # cldcClientAclApplied
+            '24',  # cldcClientRedirectUrl
+            '25',  # cldcClientAaaOverrideAclName
+            '26',  # cldcClientAaaOverrideAclApplied
+            '27',  # cldcClientUsername
+            '28',  # cldcClientSSID
+            '29',  # cldcClientSecurityTagId
+            '30',  # cldcClientTypeKTS
+            '31',  # cldcClientIpv6AclName
+            '32',  # cldcClientIpv6AclApplied
+            '33',  # cldcClientDataSwitching
+            '34',  # cldcClientAuthentication
+            '35',  # cldcClientChannel
+            '36',  # cldcClientAuthMode
+            '37',  # cldcClientReasonCode
+            '38',  # cldcClientSessionID
+            '39',  # cldcClientApRoamMacAddress
+            '40',  # cldcClientMdnsProfile
+            '41',  # cldcClientMdnsAdvCount
+            '42',  # cldcClientPolicyName
+            '43',  # cldcClientAAARole
+            '44',  # cldcClientDeviceType
+            '45',  # cldcUserAuthType
+        ]
+    ),
+    detect=contains('.1.3.6.1.2.1.1.1.0', 'Cisco Controller'),  # sysDescr
+)
+
+register.inventory_plugin(
+    name='inv_cisco_wlc_clients',
+    inventory_function=inventory_cisco_wlc_clients,
+    inventory_default_parameters={},
+    inventory_ruleset_name='inv_cisco_wlc_clients',
+)
diff --git a/inv_cisco_wlc_clients.mkp b/inv_cisco_wlc_clients.mkp
index 4facc63014381ee7aa769545352a359b3f0f3342..c535701f48a4109b599a77e834c6213f5d3ac7a6 100644
GIT binary patch
literal 5438
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

literal 5023
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
B#W4T?

diff --git a/packages/inv_cisco_wlc_clients b/packages/inv_cisco_wlc_clients
index d20a3f7..654f42d 100644
--- a/packages/inv_cisco_wlc_clients
+++ b/packages/inv_cisco_wlc_clients
@@ -1,12 +1,21 @@
-{'author': u'Th.L. (thl-cmk[at]outlook[dot]com)',
- 'description': u'SNMP inventory of Cisco WLC clients.\n\nVia WATO you can:\n - enable/disable this inventory\n - can add/remove some fields\n\nTested with Cisco WLC 5520/5505/2504.\n\n2020-03.15: added support for CMK1.6x\n',
+{'author': 'Th.L. (thl-cmk[at]outlook[dot]com)',
+ 'description': 'SNMP inventory of Cisco WLC clients.\n'
+                '\n'
+                'Via WATO you can:\n'
+                ' - can add/remove some fields\n'
+                '\n'
+                'Tested with Cisco WLC 5520/5505/2504.\n'
+                '\n'
+                '2020-03.15: added support for CMK1.6x\n'
+                '2021-07-12: rewritten for CMK 2.0\n',
  'download_url': 'http://thl-cmk.hopto.org',
- 'files': {'inventory': ['snmp_cisco_wlc_clients'],
-           'web': ['plugins/views/inv_wlc_clients.py',
-                   'plugins/wato/inv_wlc_clients.py']},
+ 'files': {'agent_based': ['inv_cisco_wlc_clients.py'],
+           'web': ['plugins/views/inv_cisco_wlc_clients.py',
+                   'plugins/wato/inv_cisco_wlc_clients.py']},
  'name': 'inv_cisco_wlc_clients',
  'num_files': 3,
- 'title': u'inventory of cisco WLC clients',
- 'version': '20200513.v0.2c',
- 'version.min_required': '1.4.0p1',
- 'version.packaged': '1.6.0p8'}
\ No newline at end of file
+ 'title': 'inventory of cisco WLC clients',
+ 'version': '20210712.v0.3',
+ 'version.min_required': '2.0.0',
+ 'version.packaged': '2021.04.10',
+ 'version.usable_until': None}
\ No newline at end of file
diff --git a/web/plugins/views/inv_cisco_wlc_clients.py b/web/plugins/views/inv_cisco_wlc_clients.py
new file mode 100644
index 0000000..b8796ed
--- /dev/null
+++ b/web/plugins/views/inv_cisco_wlc_clients.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+import cmk.gui.utils
+from cmk.gui.plugins.views import (
+    inventory_displayhints,)
+from cmk.gui.i18n import _
+
+
+inventory_displayhints.update({
+    '.networking.wlan.controller.clients:': {'title'   : _('WLC clients'),
+                                             'keyorder': ['username', 'uptime', 'ipaddress', 'apmacaddress', 'ssid',
+                                                          'channel', 'accessvlan', 'devicetype', 'protocol', 'status',
+                                                          ],
+                                             'view'    : 'invwlcclients_of_host'},
+
+    '.networking.wlan.controller.clients:*.macaddress'            : { 'title' : _('MAC Addresse'), },
+    '.networking.wlan.controller.clients:*.status'                : { 'title' : _('Status'), },
+    '.networking.wlan.controller.clients:*.wlanprofilename'       : { 'title' : _('WLAN profile name'), },
+    '.networking.wlan.controller.clients:*.wgbstatus'             : { 'title' : _('WGB status'), },
+    '.networking.wlan.controller.clients:*.wgbmacaddress'         : { 'title' : _('WGB MAC address'), },
+    '.networking.wlan.controller.clients:*.protocol'              : { 'title' : _('Protocol'), },
+    '.networking.wlan.controller.clients:*.associationmode'       : { 'title' : _('Association mode'), },
+    '.networking.wlan.controller.clients:*.apmacaddress'          : { 'title' : _('AP MAC address'), },
+    '.networking.wlan.controller.clients:*.iftype'                : { 'title' : _('Interface type'), },
+    '.networking.wlan.controller.clients:*.ipaddress'             : { 'title' : _('IP address'), },
+    '.networking.wlan.controller.clients:*.nacstate'              : { 'title' : _('NAC state'), },
+    '.networking.wlan.controller.clients:*.quarantinevlan'        : { 'title' : _('Quarantine VLAN'), },
+    '.networking.wlan.controller.clients:*.accessvlan'            : { 'title' : _('Access VLAN'), },
+    '.networking.wlan.controller.clients:*.logintime'             : { 'title' : _('Login time'), },
+    '.networking.wlan.controller.clients:*.uptime'                : { 'title' : _('Uptime'), },
+    '.networking.wlan.controller.clients:*.powersavemode'         : { 'title' : _('Power save mode'), },
+    '.networking.wlan.controller.clients:*.currenttxrateset'      : { 'title' : _('Current TX rate (MBit/s)'), },
+    '.networking.wlan.controller.clients:*.datarateset'           : { 'title' : _('Data rate set'), },
+    '.networking.wlan.controller.clients:*.hreapapauth'           : { 'title' : _('HREAP AP auth'), },
+    '.networking.wlan.controller.clients:*.ieee80211ucapable'     : { 'title' : _('802.11u capable'), },
+    '.networking.wlan.controller.clients:*.posturestate'          : { 'title' : _('Posture state'), },
+    '.networking.wlan.controller.clients:*.aclname'               : { 'title' : _('ACL name'), },
+    '.networking.wlan.controller.clients:*.aclapplied'            : { 'title' : _('ACL applied'), },
+    '.networking.wlan.controller.clients:*.redirecturl'           : { 'title' : _('Redirect URL'), },
+    '.networking.wlan.controller.clients:*.aaaoverrideaclname'    : { 'title' : _('AAA overide ACL name'), },
+    '.networking.wlan.controller.clients:*.aaaoverrideaclapplied' : { 'title' : _('AAA overide ACL applied'), },
+    '.networking.wlan.controller.clients:*.username'              : { 'title' : _('Username'), },
+    '.networking.wlan.controller.clients:*.ssid'                  : { 'title' : _('SSID'), },
+    '.networking.wlan.controller.clients:*.securitytagid'         : { 'title' : _('Security tag ID'), },
+    '.networking.wlan.controller.clients:*.typekts'               : { 'title' : _('NEC KTS SIP client'), },
+    '.networking.wlan.controller.clients:*.ipv6aclname'           : { 'title' : _('IPv6 ACL name'), },
+    '.networking.wlan.controller.clients:*.ipv6aclapplied'        : { 'title' : _('IPv6 ACL applied'), },
+    '.networking.wlan.controller.clients:*.dataswitching'         : { 'title' : _('Data switching'), },
+    '.networking.wlan.controller.clients:*.authentication'        : { 'title' : _('Authentication'), },
+    '.networking.wlan.controller.clients:*.channel'               : { 'title' : _('Channel'), },
+    '.networking.wlan.controller.clients:*.authmode'              : { 'title' : _('Auth mode'), },
+    '.networking.wlan.controller.clients:*.reasoncode'            : { 'title' : _('Reason code'), },
+    '.networking.wlan.controller.clients:*.sessionid'             : { 'title' : _('Session ID'), },
+    '.networking.wlan.controller.clients:*.aproammacaddress'      : { 'title' : _('AP roam MAC address'), },
+    '.networking.wlan.controller.clients:*.mdnsprofile'           : { 'title' : _('mDNS profile'), },
+    '.networking.wlan.controller.clients:*.mdnsadvcount'          : { 'title' : _('mDNS adv count'), },
+    '.networking.wlan.controller.clients:*.policyname'            : { 'title' : _('Policy name'), },
+    '.networking.wlan.controller.clients:*.aaarole'               : { 'title' : _('AAA role'), },
+    '.networking.wlan.controller.clients:*.devicetype'            : { 'title' : _('Device type'), },
+    '.networking.wlan.controller.clients:*.userauthtype'          : { 'title' : _('User auth type'), },
+
+#    '.networking.wlan.controller.clients:*.certificate_type'     : { 'title' : _('Certificate type'),    'short' : _('Cert type'), 'filter' : visuals.FilterInvtableWLCCertType, 'paint' : 'wlc_cert_type' },
+
+})
+
+
+from cmk.gui.plugins.views.inventory import declare_invtable_view
+
+declare_invtable_view('invwlcclients',   '.networking.wlan.controller.clients:',  _('WLC clients'), _('WLC clients'))
diff --git a/web/plugins/wato/inv_cisco_wlc_clients.py b/web/plugins/wato/inv_cisco_wlc_clients.py
new file mode 100644
index 0000000..f56883d
--- /dev/null
+++ b/web/plugins/wato/inv_cisco_wlc_clients.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+#
+from cmk.gui.i18n import _
+from cmk.gui.plugins.wato import (
+    HostRulespec,
+    rulespec_registry,
+)
+from cmk.gui.valuespec import (
+    Dictionary,
+    ListChoice,
+)
+
+from cmk.gui.plugins.wato.inventory import (
+    RulespecGroupInventory,
+)
+
+removecolumns = [
+    ('ieee80211ucapable', '802.11u capable'),
+    ('aaaoverrideaclapplied', 'AAA overide ACL applied'),
+    ('aaaoverrideaclname', 'AAA overide ACL name'),
+    ('aaarole', 'AAA role'),
+    ('accessvlan', 'Access VLAN'),
+    ('aclapplied', 'ACL applied'),
+    ('aclname', 'ACL name'),
+    #    ('apmacaddress'          ,'AP MAC address'),
+    ('aproammacaddress', 'AP roam MAC address'),
+    ('associationmode', 'Association mode'),
+    ('authentication', 'Authentication'),
+    ('authmode', 'Auth mode'),
+    #    ('channel'               ,'Channel'),
+    ('currenttxrateset', 'Current TX rate (MBit/s)'),
+    ('datarateset', 'Data rate set'),
+    ('dataswitching', 'Data switching'),
+    #    ('devicetype'            ,'Device type'),
+    ('hreapapauth', 'HREAP AP auth'),
+    ('iftype', 'Interface type'),
+    #    ('ipaddress'             ,'IP address'),
+    ('ipv6aclapplied', 'IPv6 ACL applied'),
+    ('ipv6aclname', 'IPv6 ACL name'),
+    ('logintime', 'Login time'),
+    ('macaddress', 'MAC Addresse'),
+    ('mdnsadvcount', 'mDNS adv count'),
+    ('mdnsprofile', 'mDNS profile'),
+    ('nacstate', 'NAC state'),
+    ('policyname', 'Policy name'),
+    ('posturestate', 'Posture state'),
+    ('powersavemode', 'Power save mode'),
+    #    ('protocol'              ,'Protocol'),
+    ('quarantinevlan', 'Quarantine VLAN'),
+    ('reasoncode', 'Reason code'),
+    ('redirecturl', 'Redirect URL'),
+    ('securitytagid', 'Security tag ID'),
+    ('sessionid', 'Session ID'),
+    #    ('ssid'                  ,'SSID'),
+    #    ('status'                ,'Status'),
+    ('typekts', 'NEC KTS SIP client'),
+    #    ('uptime'                ,'Uptime'),
+    ('userauthtype', 'User auth type'),
+    #    ('username'              ,'Username'),
+    ('wgbmacaddress', 'WGB MAC address'),
+    ('wgbstatus', 'WGB status'),
+    ('wlanprofilename', 'WLAN profile name'),
+]
+
+
+def _valuespec_inv_cisco_wlc_clients():
+    return Dictionary(
+        title=_('Cisco WLC Client inventory'),
+        elements=[
+            ('removecolumns',
+             ListChoice(
+                 title=_('list of columns to remove'),
+                 help=_('information to remove from inventory'),
+                 choices=removecolumns,
+                 default_value=[
+                 ],
+             )),
+        ],
+    )
+
+
+rulespec_registry.register(
+    HostRulespec(
+        group=RulespecGroupInventory,
+        match_type='dict',
+        name='inv_cisco_wlc_clients',
+        valuespec=_valuespec_inv_cisco_wlc_clients,
+    ))
-- 
GitLab