Skip to content

Commit

Permalink
Merge pull request #64 from madhansansel/main
Browse files Browse the repository at this point in the history
Latest changes  - June 4th, 2024
  • Loading branch information
rukapse authored Jun 4, 2024
2 parents 8302b3e + ffc7ff8 commit 7f12a67
Show file tree
Hide file tree
Showing 5 changed files with 279 additions and 184 deletions.
3 changes: 2 additions & 1 deletion changelogs/changelog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -879,4 +879,5 @@ releases:
- provision_workflow_manager - Updated changes related to handle errors.
- site_workflow_manager - Updated changes in Site updation.
- network_settings_workflow_manager - Added attributes 'ipv4_global_pool_name'.
- template_workflow_manager - Removed attributes 'create_time', 'failure_policy', 'last_update_time', 'latest_version_time', 'parent_template_id', 'project_id', 'validation_errors', 'rollback_template_params' and 'rollback_template_content'.
- template_workflow_manager - Removed attributes 'create_time', 'failure_policy', 'last_update_time', 'latest_version_time', 'parent_template_id', 'project_id', 'validation_errors', 'rollback_template_params' and 'rollback_template_content'.
- ise_radius_integration_workflow_manager - Removed the attributes 'port' and 'subscriber_name'. Added the attribute 'ise_integration_wait_time'.
2 changes: 1 addition & 1 deletion playbooks/ise_radius_integration_workflow_manager.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@
password: abcd
fqdn: abc.cisco.com
ip_address: 10.195.243.59
subscriber_name: abcde
description: CISCO ISE
trusted_server: True
ise_integration_wait_time: 20

- name: Delete an ISE Server.
cisco.dnac.ise_radius_integration_workflow_manager:
Expand Down
11 changes: 6 additions & 5 deletions plugins/module_utils/dnac.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,11 +572,12 @@ def is_valid_server_address(self, server_address):

# Define the regex for a valid hostname
hostname_regex = re.compile(
r'^(?!-)' # Hostname must not start with a hyphen
r'[A-Za-z0-9-]{1,63}' # Hostname segment must be 1-63 characters long
r'(?!-)$' # Hostname segment must not end with a hyphen
r'(\.[A-Za-z0-9-]{1,63})*' # Each segment can be 1-63 characters long
r'(\.[A-Za-z]{2,6})$' # Top-level domain must be 2-6 alphabetic characters
r'^(' # Start of the string
r'([A-Za-z0-9]+([A-Za-z0-9-]*[A-Za-z0-9])?\.)+[A-Za-z]{2,6}|' # Domain name (e.g., example.com)
r'localhost|' # Localhost
r'(\d{1,3}\.)+\d{1,3}|' # Custom IPv4-like format (e.g., 2.2.3.31.3.4.4)
r'[A-Fa-f0-9:]+$' # IPv6 address (e.g., 2f8:192:3::40:41:41:42)
r')$' # End of the string
)

# Check if the address is a valid hostname
Expand Down
87 changes: 69 additions & 18 deletions plugins/modules/events_and_notifications_workflow_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@
type: bool
email_destination:
description: Configure settings to send out emails from Cisco Catalyst Center. Also we can create or configure email destination in Cisco Catalyst
Center only once then later we can just modify it.
Center only once then later we can just modify it. This one is just used to configure the Primary and Secondary SMTP server while configuring
the email destination. It's not related to email event subscription notification.
type: dict
suboptions:
primary_smtp_config:
Expand Down Expand Up @@ -1048,26 +1049,49 @@ def collect_snmp_playbook_params(self, snmp_details):
'snmpVersion': snmp_details.get('snmp_version')
}
server_address = snmp_details.get('server_address')
snmp_version = playbook_params.get("snmpVersion")

if snmp_version and snmp_version not in ["V2C", "V3"]:
self.status = "failed"
self.msg = "Invalid SNMP version '{0}' given in the playbook for configuring SNMP destination".format(snmp_version)
self.log(self.msg, "ERROR")
self.check_return_status()

if server_address and not self.is_valid_server_address(server_address):
self.status = "failed"
self.msg = "Invalid server address '{0}' given in the playbook for configuring SNMP destination".format(server_address)
self.log(self.msg, "ERROR")
self.check_return_status()

if playbook_params.get('snmpVersion') == "V2C":
if snmp_version == "V2C":
playbook_params['community'] = snmp_details.get('community')
elif playbook_params.get('snmpVersion') == "V3":
elif snmp_version == "V3":
playbook_params['userName'] = snmp_details.get('username')
playbook_params['snmpMode'] = snmp_details.get('mode')
mode = playbook_params['snmpMode']
auth_type = snmp_details.get('auth_type')

if playbook_params['snmpMode'] == "AUTH_PRIVACY":
playbook_params['snmpAuthType'] = snmp_details.get('auth_type')
if not mode or (mode not in ["AUTH_PRIVACY", "AUTH_NO_PRIVACY", "NO_AUTH_NO_PRIVACY"]):
self.status = "failed"
self.msg = """Invalid SNMP Mode '{0}' given in the playbook for configuring SNMP destination. Please select one of
the mode - AUTH_PRIVACY, AUTH_NO_PRIVACY, NO_AUTH_NO_PRIVACY in the playbook""".format(mode)
self.log(self.msg, "ERROR")
self.check_return_status()

if auth_type and auth_type not in ["SHA", "MD5"]:
self.status = "failed"
self.msg = """Invalid SNMP Authentication Type '{0}' given in the playbook for configuring SNMP destination. Please
select either SHA or MD5 as authentication type in the playbook""".format(auth_type)
self.log(self.msg, "ERROR")
self.check_return_status()

if playbook_params.get("snmpMode") == "AUTH_PRIVACY":
playbook_params['snmpAuthType'] = auth_type
playbook_params['authPassword'] = snmp_details.get('auth_password')
playbook_params['snmpPrivacyType'] = snmp_details.get('privacy_type', 'AES128')
playbook_params['privacyPassword'] = snmp_details.get('privacy_password')
elif playbook_params['snmpMode'] == "AUTH_NO_PRIVACY":
playbook_params['snmpAuthType'] = snmp_details.get('auth_type')
elif playbook_params.get("snmpMode") == "AUTH_NO_PRIVACY":
playbook_params['snmpAuthType'] = auth_type
playbook_params['authPassword'] = snmp_details.get('auth_password')

return playbook_params
Expand Down Expand Up @@ -1570,11 +1594,19 @@ def collect_email_playbook_params(self, email_details):

if email_details.get('primary_smtp_config'):
primary_smtp_details = email_details.get('primary_smtp_config')
primary_smtp_type = primary_smtp_details.get('smtp_type', "DEFAULT")
if primary_smtp_type not in ["DEFAULT", "TLS", "SSL"]:
self.status = "failed"
self.msg = """Invalid Primary SMTP Type '{0}' given in the playbook for configuring primary smtp server.
Please select one of the type - DEFAULT, TLS, SSL in the playbook""".format(primary_smtp_type)
self.log(self.msg, "ERROR")
self.check_return_status()

playbook_params['primarySMTPConfig'] = {}
playbook_params['primarySMTPConfig']['hostName'] = primary_smtp_details.get('server_address')
playbook_params['primarySMTPConfig']['smtpType'] = primary_smtp_details.get('smtp_type', "DEFAULT")
playbook_params['primarySMTPConfig']['smtpType'] = primary_smtp_type

if playbook_params['primarySMTPConfig']['smtpType'] == 'DEFAULT':
if primary_smtp_type == 'DEFAULT':
playbook_params['primarySMTPConfig']['port'] = "25"
else:
playbook_params['primarySMTPConfig']['port'] = primary_smtp_details.get('port')
Expand All @@ -1583,9 +1615,18 @@ def collect_email_playbook_params(self, email_details):

if email_details.get('secondary_smtp_config'):
secondary_smtp_details = email_details.get('secondary_smtp_config')
secondary_smtp_type = secondary_smtp_details.get('smtp_type', "DEFAULT")

if secondary_smtp_type and secondary_smtp_type not in ["DEFAULT", "TLS", "SSL"]:
self.status = "failed"
self.msg = """Invalid Secondary SMTP Type '{0}' given in the playbook for configuring secondary smtp server.
Please select one of the type - DEFAULT, TLS, SSL in the playbook""".format(secondary_smtp_type)
self.log(self.msg, "ERROR")
self.check_return_status()

playbook_params['secondarySMTPConfig'] = {}
playbook_params['secondarySMTPConfig']['hostName'] = secondary_smtp_details.get('server_address')
playbook_params['secondarySMTPConfig']['smtpType'] = secondary_smtp_details.get('smtp_type', "DEFAULT")
playbook_params['secondarySMTPConfig']['smtpType'] = secondary_smtp_type

if playbook_params['secondarySMTPConfig']['smtpType'] == 'DEFAULT':
playbook_params['secondarySMTPConfig']['port'] = "25"
Expand Down Expand Up @@ -2167,18 +2208,23 @@ def get_diff_merged(self, config):
return self

regex_pattern = re.compile(
r'^https://' # Ensure the URL starts with "https://" like https://webhook.cisco.com
r'(([A-Za-z0-9-]+\.)+[A-Za-z]{2,6}|' # Domain name (e.g., example.com, webhook.cisco.com)
r'^https://' # Ensure the URL starts with "https://"
r'('
r'(([A-Za-z0-9-*.&@]+\.)+[A-Za-z]{2,6})|' # Domain name with wildcards and special characters
r'localhost|' # Localhost
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|' # IPv4 address (e.g., 192.168.0.1)
r'\[?[A-Fa-f0-9:]+\]?)' # IPv6 address (e.g., [2001:db8::1])
r'(:\d+)?' # Optional port (e.g., :8080)
r'(\/[A-Za-z0-9._~:/?#[@!$&\'()*+,;=-]*)?$' # Path and query (optional)
r'(?:(?:\d{1,3}\.){3}\d{1,3}\b\.?)' # Partial or complete IPv4 address with optional trailing dot
r'(\[[A-Fa-f0-9:]+\])?' # Optional IPv6 address in square brackets (e.g., [2001:db8::1])
r'|' # Alternation for different valid segments
r'([A-Za-z-_.&@]+)' # Hostname with allowed special characters
r')'
r'(:\d+)?' # Optional port
r'(\/[A-Za-z0-9._~:/?#[@!$&\'()*+,;=-]*)?' # Optional path
r'$' # End of the string
)
url = webhook_params.get('url')

# Check if the input string matches the pattern
if url and not re.match(regex_pattern, url):
if url and not regex_pattern.match(url):
self.status = "failed"
self.msg = """Given url '{0}' is invalid url for Creating/Updating Webhook destination. It must starts with 'https://' and
follow the valid https url format.""".format(url)
Expand Down Expand Up @@ -2286,7 +2332,7 @@ def get_diff_merged(self, config):

if server_address and not self.is_valid_server_address(server_address):
self.status = "failed"
self.msg = "Invalid server address '{0}' given in the playbook for configuring syslog destination".format(server_address)
self.msg = "Invalid server address '{0}' given in the playbook for configuring Syslog destination".format(server_address)
self.log(self.msg, "ERROR")
return self

Expand Down Expand Up @@ -2477,25 +2523,30 @@ def get_diff_deleted(self, config):
self.msg = "Deleting the Webhook destination is not supported in Cisco Catalyst Center because of API limitations"
self.log(self.msg, "ERROR")
self.result['changed'] = False
return self

if config.get('email_destination'):
self.status = "failed"
self.msg = "Deleting the Email destination is not supported in Cisco Catalyst Center because of API limitations"
self.log(self.msg, "ERROR")
self.result['changed'] = False
return self

if config.get('syslog_destination'):
self.status = "failed"
self.msg = "Deleting the Syslog destination is not supported in Cisco Catalyst Center because of API limitations"
self.log(self.msg, "ERROR")
self.result['changed'] = False
return self

if config.get('snmp_destination'):
self.status = "failed"
self.msg = "Deleting the SNMP destination is not supported in Cisco Catalyst Center because of API limitations"
self.log(self.msg, "ERROR")
self.result['changed'] = False
return self

# Delete ITSM Integration setting from Cisco Catalyst Center
if config.get('itsm_setting'):
itsm_details = self.want.get('itsm_details')
itsm_name = itsm_details.get('instance_name')
Expand Down
Loading

0 comments on commit 7f12a67

Please sign in to comment.