diff --git a/lib/ansible/modules/network/cnos/cnos_lldp.py b/lib/ansible/modules/network/cnos/cnos_lldp.py
new file mode 100644
index 00000000000..f98ac40d434
--- /dev/null
+++ b/lib/ansible/modules/network/cnos/cnos_lldp.py
@@ -0,0 +1,140 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+#
+# Copyright (C) 2019 Lenovo.
+# (c) 2017, Ansible by Red Hat, inc
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see .
+#
+# Module to work on Link Aggregation with Lenovo Switches
+# Lenovo Networking
+#
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': ['preview'],
+ 'supported_by': 'community'}
+
+DOCUMENTATION = """
+---
+module: cnos_lldp
+version_added: "2.8"
+author: "Anil Kumar Muraleedharan (@amuraleedhar)"
+short_description: Manage LLDP configuration on Lenovo CNOS network devices.
+description:
+ - This module provides declarative management of LLDP service
+ on Lenovc CNOS network devices.
+notes:
+ - Tested against CNOS 10.9.1
+options:
+ state:
+ description:
+ - State of the LLDP configuration. If value is I(present) lldp will be
+ enabled else if it is I(absent) it will be disabled.
+ default: present
+ choices: ['present', 'absent']
+"""
+
+EXAMPLES = """
+- name: Enable LLDP service
+ cnos_lldp:
+ state: present
+
+- name: Disable LLDP service
+ cnos_lldp:
+ state: absent
+"""
+
+RETURN = """
+commands:
+ description: The list of configuration mode commands to send to the device
+ returned: always, except for the platforms that use Netconf transport to
+ manage the device.
+ type: list
+ sample:
+ - lldp timer 1024
+ - lldp trap-interval 330
+"""
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.network.cnos.cnos import get_config, load_config
+from ansible.module_utils.network.cnos.cnos import cnos_argument_spec
+from ansible.module_utils.network.cnos.cnos import debugOutput, run_commands
+from ansible.module_utils.connection import exec_command
+
+
+def get_ethernet_range(module):
+ output = run_commands(module, ['show interface brief'])[0].split('\n')
+ maxport = None
+ last_interface = None
+ for line in output:
+ if line.startswith('Ethernet1/'):
+ last_interface = line.split(' ')[0]
+ if last_interface is not None:
+ eths = last_interface.split('/')
+ maxport = eths[1]
+ return maxport
+
+
+def main():
+ """ main entry point for module execution
+ """
+ argument_spec = dict(
+ state=dict(default='present',
+ choices=['present', 'absent'])
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec,
+ supports_check_mode=True)
+ warnings = list()
+ result = {'changed': False}
+ if warnings:
+ result['warnings'] = warnings
+
+ maxport = get_ethernet_range(module)
+ commands = []
+ prime_cmd = 'interface ethernet 1/1-' + maxport
+
+ if module.params['state'] == 'absent':
+ commands.append(prime_cmd)
+ commands.append('no lldp receive')
+ commands.append('no lldp transmit')
+ commands.append('exit')
+ commands.append('interface mgmt 0')
+ commands.append('no lldp receive')
+ commands.append('no lldp transmit')
+ commands.append('exit')
+ elif module.params['state'] == 'present':
+ commands.append(prime_cmd)
+ commands.append('lldp receive')
+ commands.append('lldp transmit')
+ commands.append('exit')
+ commands.append('interface mgmt 0')
+ commands.append('lldp receive')
+ commands.append('lldp transmit')
+ commands.append('exit')
+
+ result['commands'] = commands
+
+ if commands:
+ if not module.check_mode:
+ load_config(module, commands)
+
+ result['changed'] = True
+
+ module.exit_json(**result)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/integration/targets/cnos_lldp/aliases b/test/integration/targets/cnos_lldp/aliases
new file mode 100644
index 00000000000..be010d923f4
--- /dev/null
+++ b/test/integration/targets/cnos_lldp/aliases
@@ -0,0 +1,2 @@
+# No Lenovo Switch simulator yet, so not enabled
+unsupported
diff --git a/test/integration/targets/cnos_lldp/defaults/main.yaml b/test/integration/targets/cnos_lldp/defaults/main.yaml
new file mode 100644
index 00000000000..5f709c5aac1
--- /dev/null
+++ b/test/integration/targets/cnos_lldp/defaults/main.yaml
@@ -0,0 +1,2 @@
+---
+testcase: "*"
diff --git a/test/integration/targets/cnos_lldp/tasks/cli.yaml b/test/integration/targets/cnos_lldp/tasks/cli.yaml
new file mode 100644
index 00000000000..303af407622
--- /dev/null
+++ b/test/integration/targets/cnos_lldp/tasks/cli.yaml
@@ -0,0 +1,22 @@
+---
+- name: collect all cli test cases
+ find:
+ paths: "{{ role_path }}/tests/cli"
+ patterns: "{{ testcase }}.yaml"
+ register: test_cases
+ delegate_to: localhost
+
+- name: set test_items
+ set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
+
+- name: run test cases (connection=network_cli)
+ include: "{{ test_case_to_run }}"
+ with_items: "{{ test_items }}"
+ loop_control:
+ loop_var: test_case_to_run
+
+- name: run test case (connection=local)
+ include: "{{ test_case_to_run }} ansible_connection=local"
+ with_first_found: "{{ test_items }}"
+ loop_control:
+ loop_var: test_case_to_run
diff --git a/test/integration/targets/cnos_lldp/tasks/main.yaml b/test/integration/targets/cnos_lldp/tasks/main.yaml
new file mode 100644
index 00000000000..415c99d8b12
--- /dev/null
+++ b/test/integration/targets/cnos_lldp/tasks/main.yaml
@@ -0,0 +1,2 @@
+---
+- { include: cli.yaml, tags: ['cli'] }
diff --git a/test/integration/targets/cnos_lldp/tests/cli/basic.yaml b/test/integration/targets/cnos_lldp/tests/cli/basic.yaml
new file mode 100644
index 00000000000..f499ff43ac9
--- /dev/null
+++ b/test/integration/targets/cnos_lldp/tests/cli/basic.yaml
@@ -0,0 +1,44 @@
+---
+- debug: msg="START cnos_lldp cli/basic.yaml on connection={{ ansible_connection }}"
+
+- name: Enable LLDP service
+ cnos_lldp:
+ state: present
+ register: result
+
+- assert:
+ that:
+ - 'result.changed == true'
+ - '"lldp receive" in result.commands'
+ - '"lldp transmit" in result.commands'
+
+- name: Enable LLDP service again (idempotent)
+ cnos_lldp:
+ state: present
+ register: result
+
+- assert:
+ that:
+ - 'result.changed == true'
+
+- name: Disable LLDP service
+ cnos_lldp:
+ state: absent
+ register: result
+
+- assert:
+ that:
+ - 'result.changed == true'
+ - '"no lldp receive" in result.commands'
+ - '"no lldp transmit" in result.commands'
+
+- name: Disable LLDP service (idempotent)
+ cnos_lldp:
+ state: absent
+ register: result
+
+- assert:
+ that:
+ - 'result.changed == true'
+
+- debug: msg="END cnos_lldp cli/basic.yaml on connection={{ ansible_connection }}"
diff --git a/test/units/modules/network/cnos/test_cnos_lldp.py b/test/units/modules/network/cnos/test_cnos_lldp.py
new file mode 100644
index 00000000000..dd8f2dd5354
--- /dev/null
+++ b/test/units/modules/network/cnos/test_cnos_lldp.py
@@ -0,0 +1,104 @@
+#
+# (c) 2019 Lenovo.
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see .
+#
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import re
+import json
+
+from units.compat.mock import patch
+from ansible.modules.network.cnos import cnos_lldp
+from units.modules.utils import set_module_args
+from .cnos_module import TestCnosModule, load_fixture
+
+
+class TestCnosLldpModule(TestCnosModule):
+ module = cnos_lldp
+
+ def setUp(self):
+ super(TestCnosLldpModule, self).setUp()
+ self._patch_get_config = patch(
+ 'ansible.modules.network.cnos.cnos_lldp.get_config'
+ )
+ self._patch_load_config = patch(
+ 'ansible.modules.network.cnos.cnos_lldp.load_config'
+ )
+ self._patch_get_ethernet_range = patch(
+ 'ansible.modules.network.cnos.cnos_lldp.get_ethernet_range'
+ )
+
+ self._get_config = self._patch_get_config.start()
+ self._load_config = self._patch_load_config.start()
+ self._get_ethernet_range = self._patch_get_ethernet_range.start()
+
+ def tearDown(self):
+ super(TestCnosLldpModule, self).tearDown()
+ self._patch_get_config.stop()
+ self._patch_load_config.stop()
+ self._patch_get_ethernet_range.stop()
+
+ def load_fixtures(self, commands=None):
+ config_file = 'cnos_config_config.cfg'
+ self._get_config.return_value = load_fixture(config_file)
+ self._load_config.return_value = None
+ self._get_ethernet_range.return_value = '54'
+
+ def test_cnos_lldp_present(self, *args, **kwargs):
+ set_module_args(dict(
+ state='present'
+ ))
+ result = self.execute_module(changed=True)
+ self.assertEqual(
+ result,
+ {
+ 'commands': [
+ 'interface ethernet 1/1-54',
+ 'lldp receive',
+ 'lldp transmit',
+ 'exit',
+ 'interface mgmt 0',
+ 'lldp receive',
+ 'lldp transmit',
+ 'exit'
+ ],
+ 'changed': True
+ }
+ )
+
+ def test_cnos_lldp_absent(self, *args, **kwargs):
+ set_module_args(dict(
+ state='absent'
+ ))
+ result = self.execute_module(changed=True)
+ self.assertEqual(
+ result,
+ {
+ 'commands': [
+ 'interface ethernet 1/1-54',
+ 'no lldp receive',
+ 'no lldp transmit',
+ 'exit',
+ 'interface mgmt 0',
+ 'no lldp receive',
+ 'no lldp transmit',
+ 'exit'
+ ],
+ 'changed': True
+ }
+ )