Skip to content

Commit

Permalink
Merge pull request #124 from madhansansel/main
Browse files Browse the repository at this point in the history
Adding new intent modules for inventory, discovery and device credentials
  • Loading branch information
fmunozmiranda authored Nov 13, 2023
2 parents ebbc7b3 + a4e3698 commit 77d0aba
Show file tree
Hide file tree
Showing 22 changed files with 4,631 additions and 786 deletions.
9 changes: 9 additions & 0 deletions changelogs/changelog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -720,3 +720,12 @@ releases:
minor_changes:
- A new intent module for network settings to support Global IP Pool, Reserve IP Pool, Global servers, TimeZone, Message of the Day and telemetry servers.
- By inheriting DNAC base class, changes done to Swim, Template, PnP intent modules.
6.8.0:
release_date: "2023-11-10"
changes:
release_summary: Several changes to modules.
minor_changes:
- A new intent module to perform inventory for Adding, Deleting, Resyncing, Updating Devices etc. for all types of devices.
- A new intent module to Create, Update and Delete Global Device Credentials and Assign Credentials to a sites.
- A new intent module to discover the devices.
- Minor changes to swim intent module.
95 changes: 95 additions & 0 deletions playbooks/PnP.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
- name: Manage operations - Add, claim, and delete devices of Onboarding Configuration (PnP)
hosts: localhost
connection: local
gather_facts: no

vars_files:
- "{{ CLUSTERFILE }}"

vars:
dnac_login: &dnac_login
dnac_host: "{{ dnac_host }}"
dnac_username: "{{ dnac_username }}"
dnac_password: "{{ dnac_password }}"
dnac_verify: "{{ dnac_verify }}"
dnac_port: "{{ dnac_port }}"
dnac_version: "{{ dnac_version }}"
dnac_debug: "{{ dnac_debug }}"

tasks:

- name: Add a new device only
cisco.dnac.pnp_intent:
<<: *dnac_login
dnac_log: True
state: merged
config:
- deviceInfo:
add_device_method: Single
serialNumber: FJC2330E0IK
hostname: Test-9300-6
state: Unclaimed
pid: c9300-24P
isSudiRequired: True

- name: Add a new device and claim it
cisco.dnac.pnp_intent:
<<: *dnac_login
dnac_log: True
state: merged
config:
- site_name: Global/USA/San Francisco/BGL_18
deviceInfo:
add_device_method: Single
serialNumber: FJC2330E0IK
hostname: Test-9300-6
state: Unclaimed
pid: c9300-24P
isSudiRequired: True

- name: Claim an added Switch with template and image upgrade to a site only
cisco.dnac.pnp_intent:
<<: *dnac_login
dnac_log: True
state: merged
config:
- site_name: Global/USA/San Francisco/BGL_18
template_name: "Ansible_PNP_Switch"
image_name: cat9k_iosxe_npe.17.03.07.SPA.bin
project_name: Onboarding Configuration
deviceInfo:
serialNumber: FJC271924EQ
hostname: Switch
state: Unclaimed
pid: C9300-48UXM

- name: Claim an added Wireless Controller with template and image upgrade to a site only
cisco.dnac.pnp_intent:
<<: *dnac_login
dnac_log: True
state: merged
config:
- site_name: Global/USA/San Francisco/BGL_18
pnp_type: CatalystWLC
template_name: "Ansible_PNP_WLC"
image_name: C9800-40-universalk9_wlc.17.12.01.SPA.bin
deviceInfo:
serialNumber: FOX2639PAY7
hostname: WLC
state: Unclaimed
pid: C9800-CL-K9
gateway: 204.192.101.1
ipInterfaceName: TenGigabitEthernet0/0/0
staticIP: 204.192.101.10
subnetMask: 255.255.255.0
vlanId: 1101

- name: Delete an added device from the Pnp dashboard
cisco.dnac.pnp_intent:
<<: *dnac_login
dnac_log: True
state: deleted
config:
- deviceInfo:
serialNumber: FJC2330E0IK
85 changes: 85 additions & 0 deletions playbooks/device_credential_intent.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
- hosts: dnac_servers
vars_files:
- credentials_245.yml
gather_facts: no
connection: local
tasks:
#
# Project Info Section
#

- name: Create Credentials and assign it to a site.
cisco.dnac.device_credential_intent:
dnac_host: "{{ dnac_host }}"
dnac_port: "{{ dnac_port }}"
dnac_username: "{{ dnac_username }}"
dnac_password: "{{ dnac_password }}"
dnac_verify: "{{ dnac_verify }}"
dnac_debug: "{{ dnac_debug }}"
dnac_log: True
state: merged
config:
- GlobalCredentialDetails:
cliCredential:
- description: CLI
username: cli
password: "12345"
enablePassword: "12345"
# old_description:
# old_username:
# id: e448ea13-4de0-406b-bc6e-f72b57ed6746 # Use this for updation or deletion
snmpV2cRead:
- description: SNMPv2c Read # use this for deletion
readCommunity: "12345"
# old_description: # use this for updating the description
# id: 0ee7d677-8804-43f2-8b6c-599c5f18348f # Use this for updation or deletion
snmpV2cWrite:
- description: SNMPv2c Write # use this for deletion
writeCommunity: "12345"
# old_description: # use this for updating the description
# id: a96abc1b-1fd6-41f1-8a6d-a5569c17262d # Use this for updation or deletion
snmpV3:
- authPassword: "12345678" # Atleast 8 characters
authType: SHA # [SHA, MD5] (SHA is recommended)
snmpMode: AUTHPRIV # [AUTHPRIV, AUTHNOPRIV, NOAUTHNOPRIV]
privacyPassword: "12345678" # Atleast 8 characters
privacyType: AES128 # [AE128, AE192, AE256]
username: snmpV3
description: snmpV3
# old_description:
# id: d8974823-250a-41b0-8c9b-b27b2ae01472 # Use this for updation or deletion
httpsRead:
- description: HTTP Read
username: HTTP_Read
password: "12345"
port: 443
# old_description:
# old_username:
# id: a7ef9995-e404-4240-94ca-b5f37f65c19d # Use this for updation or deletion
httpsWrite:
- description: HTTP Write
username: HTTP_Write
password: "12345"
port: 443
# old_description:
# old_username:
# id: bec9818e-30cd-468b-bf75-292beefc2e20 # Use this for updation or deletion
AssignCredentialsToSite:
# cliDescription:
# cliUsername:
cliId: e448ea13-4de0-406b-bc6e-f72b57ed6746
# snmpV2ReadDescription:
snmpV2ReadId: 0ee7d677-8804-43f2-8b6c-599c5f18348f
# snmpV2WriteDescription:
snmpV2WriteId: a96abc1b-1fd6-41f1-8a6d-a5569c17262d
# snmpV3Description:
snmpV3Id: d8974823-250a-41b0-8c9b-b27b2ae01472
# httpReadDescription:
# httpReadUsername:
httpRead: d5d7af00-5a38-4ac1-9f55-03338d00c415
# httpWriteDescription:
# httpWriteUsername:
httpWrite: bec9818e-30cd-468b-bf75-292beefc2e20
siteName:
- Global/Chennai/Trill
- Global/Chennai/Tidel
40 changes: 40 additions & 0 deletions playbooks/inventory_device.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
- name: Configure device credentials on Cisco DNA Center
hosts: localhost
connection: local
gather_facts: no
vars_files:
- "input_inventory.yml"
- "credentials.yml"
tasks:
- name: Add/Update/Resync/Delete the devices in DNAC Inventory.
cisco.dnac.inventory_intent:
dnac_host: "{{dnac_host}}"
dnac_username: "{{dnac_username}}"
dnac_password: "{{dnac_password}}"
dnac_verify: "{{dnac_verify}}"
dnac_port: "{{dnac_port}}"
dnac_version: "{{dnac_version}}"
dnac_debug: "{{dnac_debug}}"
dnac_log: true
state: merged
config:
- enablePassword: "{{item.enablePassword}}"
password: "{{item.password}}"
ipAddress: "{{item.ipAddress}}"
snmpAuthPassphrase: "{{item.snmpAuthPassphrase}}"
snmpAuthProtocol: "{{item.snmpAuthProtocol}}"
snmpMode: "{{item.snmpMode}}"
snmpPrivPassphrase: "{{item.snmpPrivPassphrase}}"
snmpPrivProtocol: "{{item.snmpPrivProtocol}}"
snmpROCommunity: "{{item.snmpROCommunity}}"
snmpRWCommunity: "{{item.snmpRWCommunity}}"
snmpRetry: "{{item.snmpRetry}}"
snmpTimeout: "{{item.snmpTimeout}}"
snmpUserName: "{{item.snmpUserName}}"
userName: "{{item.userName}}"
device_resync: "{{item.resync}}"

with_items: "{{ device_details }}"
tags:
- inventory_device
38 changes: 38 additions & 0 deletions playbooks/swim_intent.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
- name: Configure device credentials on Cisco DNA Center
hosts: localhost
connection: local
gather_facts: no
vars_files:
- "input_swim.yml"
- "credentials.yml"
tasks:
- name: Import an image, tag it as golden and load it on device {{ item.device_serial_number }}
cisco.dnac.swim_intent:
dnac_host: "{{dnac_host}}"
dnac_username: "{{dnac_username}}"
dnac_password: "{{dnac_password}}"
dnac_verify: "{{dnac_verify}}"
dnac_port: "{{dnac_port}}"
dnac_version: "{{dnac_version}}"
dnac_debug: "{{dnac_debug}}"
dnac_log: true
config:
- importImageDetails:
type: "{{ item.type }}"
urlDetails:
payload: "{{ item.urlDetails.payload }}"
taggingDetails:
deviceRole: "{{ item.device_role }}"
deviceFamilyName: "{{ item.device_family_name }}"
tagging: true
imageDistributionDetails:
deviceSerialNumber: "{{ item.device_serial_number }}"
imageActivationDetails:
scehduleValidate: false
activateLowerImageVersion: true
deviceSerialNumber: "{{ item.device_serial_number }}"
distributeIfNeeded: true
with_items: "{{ image_details }}"
tags:
- swim
73 changes: 65 additions & 8 deletions plugins/module_utils/dnac.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ def __init__(self, module):

@abstractmethod
def validate_input(self):
pass
if not self.config:
self.msg = "config not available in playbook for validation"
self.status = "failed"
return self

def get_diff_merged(self):
# Implement logic to merge the resource configuration
Expand Down Expand Up @@ -129,21 +132,75 @@ def get_dnac_params(self, params):
return dnac_params

def get_task_details(self, task_id):
"""Check if the task performed is sucessfull or not"""
"""
Get the details of a specific task in Cisco DNA Center.
Args:
self (object): An instance of a class that provides access to Cisco DNA Center.
task_id (str): The unique identifier of the task for which you want to retrieve details.
Returns:
dict or None: A dictionary containing detailed information about the specified task,
or None if the task with the given task_id is not found.
Description:
If the task with the specified task ID is not found in Cisco DNA Center, this function will return None.
"""

result = None
response = self.dnac_apply['exec'](
response = self.dnac._exec(
family="task",
function="get_task_by_id",
params={"task_id": task_id},
function='get_task_by_id',
params={"task_id": task_id}
)

self.log(str(response))
if isinstance(response, dict):
result = response.get("response")
log(str(response))

if response and isinstance(response, dict):
result = response.get('response')

return result

def check_task_response_status(self, response, validation_string):
"""
Get the site id from the site name.
Parameters:
self - The current object details.
response (dict) - API response.
validation_string (string) - String used to match the progress status.
Returns:
self
"""

if not response:
self.msg = "response is empty"
self.status = "exited"
return self

if not isinstance(response, dict):
self.msg = "response is not a dictionary"
self.status = "exited"
return self

task_id = response.get("response").get("taskId")
while True:
task_details = self.get_task_details(task_id)
self.log(str(task_details))

if task_details.get("isError") is True:
self.msg = str(task_details.get("progress"))
self.status = "failed"
break

if validation_string in task_details.get("progress").lower():
self.result['changed'] = True
self.status = "success"
break

self.log("progress set to {0} for taskid: {1}"
.format(task_details.get('progress'), task_id))

return self

def reset_values(self):
"""Reset all neccessary attributes to default values"""

Expand Down
Loading

0 comments on commit 77d0aba

Please sign in to comment.