This commit is contained in:
ROTTLER Tamas 2023-02-28 01:36:25 +01:00
parent 5249fe0d10
commit 5557063b78
7 changed files with 92 additions and 10 deletions

View File

@ -14,8 +14,8 @@
{{ routerbackup_bin }}/routerbackup --difflog --diffprint --logfile {{ routerbackup_log }}
--backupdir {{ routerbackup_dir }} --type {{ devtype }}
--host {{ inventory_hostname }} --address {{ ansible_host }} --user {{ ansible_user }}
{% if ansible_private_key_file is defined %}-i {{ ansible_private_key_file }}{% endif %}
{% if ansible_ssh_pass is defined %}-p {{ ansible_ssh_pass }}{% endif %}
{% if ansible_private_key_file is defined %} --sshkey {{ ansible_private_key_file }}{% endif %}
{% if ansible_ssh_pass is defined %} --password {{ ansible_ssh_pass }}{% endif %}
delegate_to: localhost
changed_when: false
register: diff
@ -32,7 +32,7 @@
- name: fill diff into file
lineinfile:
path: "{{ routerbackup_diff }}"
line: "{{ diff.stdout }}\n\n==============================================================================\n"
line: "\n{{ diff.stdout }}\n\n=============================================================================="
delegate_to: localhost
when:
- "routerbackup_diff is defined"

41
ansible-routerbackup Executable file
View File

@ -0,0 +1,41 @@
#!/bin/bash
BACKUP=0
CHECK=0
while getopts "bc" opt; do
case $opt in
b)
BACKUP=1
;;
c)
CHECK=1
;;
\?)
echo "usage: $0 [-c] [-f]" >&2
exit 1
esac
done
if [[ $BACKUP = 0 && $CHECK = 0 ]]; then
echo "no action" >&2
exit 1
fi
cd /etc/ansible
outfilter=bin/ansible_outfilter
if [[ $BACKUP > 0 ]]; then
DIFF=/tmp/routerbackup.diff.$$
ansible-playbook -f 10 -e routerbackup_diff=$DIFF routerbackup.yml | $outfilter
cat $DIFF
rm -f $DIFF
fi
if [[ $CHECK > 0 ]]; then
CHECKFILE=/tmp/routerbackup.check.$$
ansible-playbook -t check -e routerbackup_checkfile=$CHECKFILE routerbackup.yml | $outfilter
cat $CHECKFILE
rm -f $CHECKFILE
fi
# vim: set tabstop=4 shiftwidth=4 expandtab smarttab:

24
install.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
function run() {
echo "$@"
"$@"
}
function createlink() {
if [[ ! -e $2 ]]; then
run ln -sr $1 $2
else
if [[ -h $2 ]]; then
run ln -sfr $1 $2
else
echo "WARNING: not overwriting $2: is not a symlink!"
fi
fi
}
createlink routerbackup.yml /etc/ansible/routerbackup.yml
createlink ansible-role /etc/ansible/roles/routerbackup
createlink ansible-routerbackup /etc/ansible/bin/routerbackup
# vim: set tabstop=4 shiftwidth=4 expandtab smarttab:

View File

@ -95,7 +95,14 @@ class Config:
self.ssh.connect(self.host, username=self.user,
password=self.passwd, key_filename=self.sshkey)
def prepare_config_for_diff(self, configlines):
def is_bad_config(self):
if not self.config:
return 'is None.'
if len(self.config) < 200:
return 'lenght < 200 characters.'
return False # is not bad
def _prepare_config_for_diff(self, configlines):
return configlines
@ -120,7 +127,7 @@ class Config:
contents = {}
for cf, n in ((self.oldconfig, 'old'), (self.config, 'new')):
contents[n] = self.prepare_config_for_diff(cf.splitlines(keepends=True))
contents[n] = self._prepare_config_for_diff(cf.splitlines(keepends=True))
has_changed = False
for line in difflib.unified_diff(
@ -264,7 +271,7 @@ class RouterosConfig(Config):
self.extra['iproute']['content'] = '\n'.join(iproute)
self.extra['backup']['content'] = backup
def prepare_config_for_diff(self, configlines):
def _prepare_config_for_diff(self, configlines):
prepared = []
for line in configlines:
if re.match('/ip[ /]ipsec[ /]policy[ /]add', line):
@ -301,7 +308,13 @@ class IosConfig(Config):
self.config = '\n'.join(shrun)
self.extra['iproute']['content'] = '\n'.join(iproute)
def prepare_config_for_diff(self, configlines):
def is_bad_config(self):
super().is_bad_config()
if not re.search('end\s*$', self.config):
return "does not end with 'end'."
return False
def _prepare_config_for_diff(self, configlines):
prepared = []
for line in configlines:
if not re.search('\S', line):
@ -386,10 +399,14 @@ def main():
cf = AsaConfig(workdir=args.backupdir)
address = args.address or args.host
log.info(f'Connecting to {args.type}: {args.user}@{address}')
log.info(f'Connecting to {args.type}: {args.user}@{address} with{" password" if args.password else""}{" ssh-key" if args.sshkey else""}')
start = time.time()
cf.connect(address, args.user, args.password, args.sshkey)
os.environ['HOME'] = '/' # prevent paramiko from searching private keys
cf.connect(address, args.user, args.password, args.sshkey or '')
cf.get_config()
if reason := cf.is_bad_config():
log.warning(f'Bad configuration: {reason}')
return
filename = args.host
log.debug(f'Backup filename base: {filename}')
@ -398,7 +415,7 @@ def main():
if has_changed:
cf.backup_old(filename)
# overwrite unchanged config, too, to update modification time and
# also store changes that get skipped by prepare_config_for_diff():
# also store changes that get skipped by _prepare_config_for_diff():
cf.write_to_disk(filename, has_changed)
log.info(f'Finished in {time.time()-start:.1f}s.')
except KeyboardInterrupt: