zahodi.ansible-mikrotik/pythonlibs/mt_common.py
2017-06-14 10:33:25 -07:00

232 lines
7.3 KiB
Python

#!/usr/bin/env python
import mt_api
import re
if 'policy' in ansible_scheduler_params:
dif_list = []
if 'policy' in mikrotik_scheduler_task:
policy = mikrotik_scheduler_task['policy'].split(',')
dif_list = set(ansible_scheduler_params['policy']) & set(policy)
if dif_list == []:
list_to_string = ""
list_to_string = ','.join(map(str, ansible_scheduler_params['policy']))
scheduler_diff_keys['policy'] = list_to_string
for key in ansible_scheduler_params:
if key != 'policy':
if key in mikrotik_scheduler_task:
if ansible_scheduler_params[key] != mikrotik_scheduler_task[key]:
scheduler_diff_keys[key] = ansible_scheduler_params[key]
else:
scheduler_diff_keys[key] = ansible_scheduler_params[key]
if scheduler_diff_keys != {}:
scheduler_diff_keys['numbers'] = client_id
if not check_mode:
mk.api_edit(base_path=api_path, params=scheduler_diff_keys)
changed = True
changed_message.append(
"Changed scheduler task : " + ansible_scheduler_params['name']
)
def list_string(ansible_list, mikrotik_string):
list_to_string = ""
list_to_string = ','.join(map(str, ansible_scheduler_params['policy']))
scheduler_diff_keys['policy'] = list_to_string
def clean_params(params):
'''
remove keys with empty values
modify keys with '_' to match mikrotik parameters
convert yes/no to true/false
'''
if isinstance(params, dict):
for key in list(params):
if params[key] is None:
del params[key]
continue
new_key = re.sub('_', '-', key)
if new_key != key:
params[new_key] = str(params[key])
del params[key]
continue
if params[key] == "yes":
params[key] = "true"
if params[key] == "no":
params[key] = "false"
else:
print("Must be a dictionary")
class MikrotikIdempotent():
'''
MikrotikIdempotent Class
- A helper class for Ansible modules to abstract common functions.
Example Usage:
mt_obj = MikrotikIdempotent(
hostname = params['hostname'],
username = params['username'],
password = params['password'],
state = None,
desired_params = params['settings'],
idempotent_param= 'name',
api_path = '/interface/ethernet',
)
mt_obj.sync_state()
'''
def __init__(
self, hostname, username, password, desired_params, api_path,
state, idempotent_param, check_mode=False):
self.hostname = hostname
self.username = username
self.password = password
self.state = state
self.desired_params = desired_params
self.idempotent_param = idempotent_param
self.current_params = {}
self.api_path = api_path
self.check_mode = check_mode
self.login_success = False
self.changed = False
self.changed_msg = []
self.failed = False
self.failed_msg = []
self.login()
def login(self):
self.mk = mt_api.Mikrotik(
self.hostname,
self.username,
self.password,
)
try:
self.mk.login()
self.login_success = True
except:
self.failed_msg = "Could not log into Mikrotik device." + " Check the username and password.",
def get_current_params(self):
clean_params(self.desired_params)
self.param_id = None
self.current_param = None
self.current_params = self.mk.api_print(base_path=self.api_path)
# When state and idempotent_param is None we are working
# on editable params only and we are grabbing the only item from response
if self.state is None and self.idempotent_param is None:
self.current_param = self.current_params[0][1]
# Else we iterate over every item in the list until we find the matching
# params
# We also set the param_id here to reference later for editing or removal
else:
for current_param in self.current_params:
if self.idempotent_param in current_param[1]:
if self.desired_params[self.idempotent_param] == current_param[1][self.idempotent_param]:
self.current_param = current_param[1]
self.param_id = current_param[1]['.id']
# current_param now is a dict, something like:
# {
# ".id": "*1",
# "full-duplex": "true",
# "mac-address": "08:00:27:6F:4C:22",
# "mtu": "1500",
# "name": "ether1",
# ...
# }
def add(self):
# When current_param is empty we need to call api_add method to add
# all the parameters in the desired_params
if self.current_param is None:
self.new_params = self.desired_params
self.old_params = ""
if not self.check_mode:
self.mk.api_add(
base_path = self.api_path,
params = self.desired_params,
)
self.changed = True
# Else we need to determing what the difference between the currently
# and the desired
else:
self.edit()
def rem(self):
# if param_id is set this means there is currently a matching item
# which we will remove
if self.param_id:
self.new_params = "item removed"
self.old_params = self.desired_params
if not self.check_mode:
self.mk.api_remove(
base_path=self.api_path,
remove_id=self.param_id,
)
self.changed = True
def edit(self):
out_params = {}
old_params = {} #used to store values of params we change
# iterate over items in desired params and match against items in current_param
# to figure out the difference
for desired_param in self.desired_params:
self.desired_params[desired_param] = str(self.desired_params[desired_param])
if desired_param in self.current_param:
if self.current_param[desired_param] != self.desired_params[desired_param]:
out_params[desired_param] = self.desired_params[desired_param]
old_params[desired_param] = self.current_param[desired_param]
else:
out_params[desired_param] = self.desired_params[desired_param]
if desired_param in self.current_param:
old_params[desired_param] = self.current_param[desired_param]
# When out_params has been set it means we found our diff
# and will set it on the mikrotik
if out_params:
if self.param_id is not None:
out_params['.id'] = self.current_param['.id']
if not self.check_mode:
self.mk.api_edit(
base_path = self.api_path,
params = out_params,
)
# we don't need to show the .id in the changed message
if '.id' in out_params:
del out_params['.id']
self.changed_msg.append({
"new_params": out_params,
"old_params": old_params,
})
self.new_params = out_params
self.old_params = old_params
self.changed = True
def sync_state(self):
self.get_current_params()
# When state and idempotent_param are not set we are working
# on editable parameters only that we can't add or remove
if self.state is None and self.idempotent_param is None:
self.edit()
elif self.state == "absent":
self.rem()
elif self.state == "present" or self.idempotent_param:
self.add()