Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix variables when title has (), add device ping, generate bootstrap and notifications #141

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 63 additions & 2 deletions vmanage/api/device.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Cisco vManage Device Inventory API Methods.
"""

import re
from vmanage.api.http_methods import HttpMethods
from vmanage.data.parse_methods import ParseMethods
from vmanage.utils import list_to_dict
Expand Down Expand Up @@ -28,6 +29,30 @@ def __init__(self, session, host, port=443):
self.port = port
self.base_url = f'https://{self.host}:{self.port}/dataservice/'

def generate_bootstrap(self, uuid):
"""Generate a bootstrap file for a device

Args:
uuid (str): uuid of device

Returns:
result (dict): All bootstrap data
"""

url = f"{self.base_url}system/device/bootstrap/device/{uuid}?configtype=cloudinit"
response = HttpMethods(self.session, url).request('GET')
#result = ParseMethods.parse_data(response)
#bootstrap_config = result.json['bootstrapConfig']
bootstrap_config = response['json']['bootstrapConfig']
regex = re.compile(r'otp : (?P<otp>[a-z0-9]+)[^a-z0-9]')
match = regex.search(bootstrap_config)
if match:
otp = match.groups('otp')[0]
else:
otp = None
return_dict = {'bootstrapConfig': bootstrap_config, 'otp': otp, 'uuid': uuid}
return return_dict

def get_device_list(self, category):
"""Obtain a list of specified device type

Expand Down Expand Up @@ -59,6 +84,34 @@ def post_device_cli_mode(self, deviceId, deviceType):
result = ParseMethods.parse_status(response)
return result

def get_device_ping(self, systemip, vpn, sourceip, destip):
"""Ping a specified destination ip address

Args:
systemip (str): systemip of source device
vpn (str): vpn id of source
sourceip (str): source ip address
destip (str): destination ip address


Returns:
result (str): ping response time
"""

#api = f"device/tools/nping/{systemip}"
#url = self.base_url + api
url = f"{self.base_url}device/tools/nping/{systemip}"
payload = f"{{'host':'{destip}', 'vpn':'{vpn}', 'source':'{sourceip}', 'probetype':'icmp'}}"
response = HttpMethods(self.session, url).request('POST', payload=payload)
if response['json']:
#if response['status_code']==200:
result = response['json']
else:
result = response['details']
return result
#result = ParseMethods.parse_data(response)
#return result

def get_device_status_list(self):
"""Obtain a list of specified device type

Expand Down Expand Up @@ -211,12 +264,20 @@ def post_device(self, device_ip, personality, username, password):
"""Add control plane device

Args:
device_id (str): uuid for device object
device_ip (str): device interface IP
personality (str): controller type (vmanage, vsmart, vbond)
username (str): device username
password (str): device password

Returns:
result (list): Device status
"""

url = f"{self.base_url}system/device"
payload = f"{{'deviceIP':'{device_ip}','username':'{username}','password':'{password}','personality':'{personality}','generateCSR':'false'}}"
response = HttpMethods(self.session, url).request('POST', payload=payload,timeout=35)
result = ParseMethods.parse_status(response)
return result

def post_reset_interface(self, device_ip, vpn_id, ifname):
"""Reset an Interface
Args:
Expand Down
10 changes: 6 additions & 4 deletions vmanage/api/device_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,15 @@ def get_template_input(self, template_id, device_id_list=None):
if 'header' in response['json'] and 'columns' in response['json']['header']:
column_list = response['json']['header']['columns']

regex = re.compile(r'\((?P<variable>[^(]+)\)')
prod1 = re.compile(r"(?P<titlename>.*)\((?P<titledesc>.*)\)")

for column in column_list:
if column['editable']:
match = regex.search(column['title'])
if match:
variable = match.groups('variable')[0]
m = prod1.match(column['title'])
if m:
intdict = m.groupdict()
titledesc = intdict['titledesc']
variable = titledesc
else:
# If the variable is not found, use toolTip as variable name
variable = column.get("toolTip")
Expand Down
41 changes: 41 additions & 0 deletions vmanage/api/notifications.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""Cisco vManage Notifications API Methods.
"""

from vmanage.api.http_methods import HttpMethods
from vmanage.data.parse_methods import ParseMethods


class Notifications(object):
"""Access to Notificaton rules.

vManage can generate notificatons. This class allows you to
read these notifications.

"""
def __init__(self, session, host, port=443):
"""Initialize Notifications object with session parameters.

Args:
session (obj): Requests Session object
host (str): hostname or IP address of vManage
port (int): default HTTPS 443

"""

self.session = session
self.host = host
self.port = port
self.base_url = f'https://{self.host}:{self.port}/dataservice/'

def get_notification_rules(self):
"""Provides notification rules

Returns:
result (dict): All data associated with a response.
"""

api = "notifications/rules"
url = self.base_url + api
response = HttpMethods(self.session, url).request('GET')
result = ParseMethods.parse_data(response)
return result
6 changes: 3 additions & 3 deletions vmanage/cli/deactivate/central_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
@click.option('--name', '-n', help="Name of policy to deactivate.")
@click.option('--id', '-i', help="Id of policy to deactivate.")
@click.pass_obj
def central_policy(ctx, name, id):
def central_policy(ctx, name, cpid):
"""
deactivate Central Policy
"""

vmanage_central_policy = CentralPolicy(ctx.auth, ctx.host, ctx.port)
vmanage_utilities = Utilities(ctx.auth, ctx.host, ctx.port)
central_policy_dict = vmanage_central_policy.get_central_policy_dict(remove_key=True)
if id:
vmanage_central_policy.deactivate_central_policy(id)
if cpid:
vmanage_central_policy.deactivate_central_policy(cpid)
elif name:
if name in central_policy_dict:
click.echo(f'Deactivating Central Policy {name}')
Expand Down
6 changes: 3 additions & 3 deletions vmanage/cli/decommission/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
@click.command('device')
@click.argument('device', required=True)
@click.pass_obj
def device(ctx, device):
def device(ctx, decommdevice):
"""
Decommission device
"""

vmanage_device = Device(ctx.auth, ctx.host, ctx.port)
status = vmanage_device.get_device_status(device, key='host-name')
status = vmanage_device.get_device_status(decommdevice, key='host-name')
if 'uuid' in status:
vmanage_device.put_device_decommission(status['uuid'])
else:
click.secho(f'Cannot find UUID for device {device}', fg="red")
click.secho(f'Cannot find UUID for device {decommdevice}', fg="red")
1 change: 0 additions & 1 deletion vmanage/cli/reset/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from vmanage.cli.reset.interface import interface



@click.group('reset')
def reset():
"""
Expand Down
4 changes: 4 additions & 0 deletions vmanage/data/policy_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ def convert_list_id_to_name(self, id_list):
id_list (list): Object

"""
#print("DEBUG:",id_list)
if isinstance(id_list, dict):
for key, value in list(id_list.items()):
if key.endswith(
Expand Down Expand Up @@ -211,6 +212,7 @@ def convert_list_id_to_name(self, id_list):
id_list['listType'] = policy_list['type']
id_list.pop('ref')
else:
#print("DEBUG:",id_list)
raise RuntimeError(f"Could not find name for list {id_list['ref']}")
elif key == 'class':
policy_list = self.policy_lists.get_policy_list_by_id(id_list['class'])
Expand Down Expand Up @@ -340,6 +342,8 @@ def export_policy_definition_list(self, definition_type='all'):
policy_definition_list = self.policy_definitions.get_policy_definition_list(definition_type)
export_definition_list = []
for policy_definition in policy_definition_list:
#print("DEBUG: ",policy_definition)
#print("")
definition_detail = self.policy_definitions.get_policy_definition(policy_definition['type'],
policy_definition['definitionId'])
converted_policy_definition = self.convert_policy_definition_to_name(definition_detail)
Expand Down
13 changes: 11 additions & 2 deletions vmanage/data/template_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,16 +337,25 @@ def import_attachment_list(self, attachment_list, check_mode=False, update=False
# the input changed, so we make an API call to get the input on last attach
existing_template_input = self.device_templates.get_template_input(
device_template_dict[attachment['template']]['templateId'], [device_uuid])
current_variables = existing_template_input['data'][0]
#current_variables = existing_template_input['data'][0]
current_variables = {}
data = existing_template_input['data'][0]
for column in existing_template_input['columns']:
current_variables[column['variable']] = data[column['property']]
#print("DEBUG: current_variables: ",current_variables)
# haven't changed variables from properties to variables
#
changed = False
for property_name in attachment['variables']:
# Check to see if any of the passed in varibles have changed from what is
#print("DEBUG: checking: ",property_name)
# Check to see if any of the passed in variables have changed from what is
# already on the attachment. We are are not checking to see if the
# correct variables are here. That will be done on attachment.
if ((property_name in current_variables) and
(str(attachment['variables'][property_name]) != str(current_variables[property_name]))):
changed = True
if changed:
print("Changed!!!")
if not check_mode and update:
template_device_map.setdefault(template_id, []).append({
"config_type": config_type,
Expand Down