-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRestartService.py
More file actions
executable file
·142 lines (141 loc) · 6.24 KB
/
RestartService.py
File metadata and controls
executable file
·142 lines (141 loc) · 6.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/python3 -O
"""
File: RestartService.py
Author: Leon McClatchey
Date: 2025-11-01
Desc: Manages Services on hosts (remote or local)
Uses hosts.yml and vault.yml in the Inventory folder
(Inventory defaultss to the data folder under the script folder
This is a rewrite of the Previous ServiceMgr.py
This current version only handles Linux Hosts
This is designed mainly to check the status of a service and restart it if it is not running
This should be executed in a python Virtual Environment:
source ~/.ansible-env/bin/activate && python /mnt/Mom/Scripts/Python/RestartService.py (entry for cron)
"""
# System Libraries
import argparse
import os, sys
import logging
import pathlib
import time
from datetime import datetime
from ansible_vault import Vault
# Initialize Global Strings
Config = {}
# Function to check the system Path => Common
def CheckSysPath(target):
npath = os.path.normcase(os.path.abspath(target))
for p in sys.path:
nsys = os.path.normcase(os.path.abspath(p))
if npath == nsys: return True
return False
# Function to get the Commandline arguments => Uses common initializer
def GetArguments():
global Config
script_path = os.path.abspath(sys.argv[0])
script_dir = os.path.dirname(script_path)
script_name = os.path.basename(script_path)
Config["Script"] = {"path":script_path,"folder":script_dir,"name":script_name}
MyScript = f"{os.path.splitext(script_name)[0]}"
ServiceOptions = ['status','stop','start','restart','verify']
parser = MyParser(
prog=f"{MyScript}",
description='Restarts the services on the specified host',
epilog='Inventory Files: hosts.yml and vault.yml overrides all defaults',
script=f"{MyScript}",
script_version='1.0.0',
include_python_version=True,
ansible_cfg=True,
usage = "%(prog)s [-e -f -v -H -P -l -L -u -k -a -s -T] \
\n(-h displays help, --version displays version)",
formatter_class=argparse.RawTextHelpFormatter
)
parser.add_argument("-c", '--command', dest='command', default='status', type=str, help=f"Command (default=status): must be:\n{ServiceOptions}")
parser.add_argument("-s", '--service',dest='service',type=str,required=True,help="Service (Required): Name of the Service being queried")
try:
known,unknown = parser.parse_known_args()
if '-h' in unknown or '--help' in unknown:
help_text = parser.get_help_text()
parser.print_help()
sys.exit(2)
args = vars(known)
args['log']=Tools.String2Dictionary(args['log'],'=')
args['host'] = NetTools.LocalHostName() if args['host'].lower().strip() == 'localhost' else args['host']
args['password'] = AnsibleTools.read_vault_password(args['password'],args['log']['path']) if os.path.isfile(args['password']) else args['password']
msg = None
if args['command'].lower() not in ServiceOptions:
msg = f"command must be one of {ServiceOptions} not {args['command']}!"
if msg is not None:
FileTools.WriteLog(msg,args['log']['path']) if args['log']['path'] is not None else print(msg)
raise argparse.ArgumentError(None,msg)
return args
except argparse.ArgumentError as e:
parser.error(str(e))
# Function to get the Host Configuration from the inventory data
def GetHostConfig():
global Config
yml = os.path.join(Config['Args']['inventory'],"hosts.yml")
log = Config['Args']['log']['path']
host = Config['Args']['host']
Ydata = AnsibleTools.LoadYaml(yml,log)
maps,counts = AnsibleTools.find_distro_groups(Ydata)
distro=Ydata['all']['children']['linux'][maps[host]]
port = Config['Args']['port'] if 'port' not in distro.keys() else distro['port']
FileTools.WriteLog("Reading ansible Vault for Credentials and Keys",log)
Vault = AnsibleTools.AnsibleCredentials(Config['Args']['inventory'],Config['Args']['password'],'all')
kPath = os.path.expanduser(Vault['key_path'])
services = Ydata['all']['children']['linux']['services']
Config['Host']={'distro':maps[host],'host':host,'port':port,'key':kPath,'sudo':Vault['sudo_pass']}
Config['Host']['service'] = {'name':Config['Args']['service'],'commands':services}
Config['Host']['log'] = Config['Args']['log']['path']
UpdateService(Config['Host'],'status')
# Function to Find the local Common folder and append it to the library path (Common)
def InitializeModules():
ScriptPath = pathlib.Path(__file__).parent.resolve()
LibPath = f"{ScriptPath}/Lib"
if not CheckSysPath(LibPath): sys.path.append(LibPath)
# Main Function
def main():
global Config
Config['Args'] = GetArguments()
FileTools.ArchiveLog(Config['Args']['log'])
logging.basicConfig(filename=Config['Args']['log']['path'],filemode='a',level=logging.WARNING)
GetHostConfig()
if Config['Host']['service']['active'] is False:
FileTools.WriteLog(f"Restarting {Config['Args']['service']} on {Config['Args']['host']}",Config['Args']['log']['path'],logging.WARNING)
UpdateService(Config['Host'],'restart')
time.sleep(3)
UpdateService(Config['Host'],'status')
# Function to Update the service by command
def UpdateService(dic,key):
log = dic['log']
host = dic['host']
port = dic['port']
dic['local'] = NetTools.isLocalHost(host)
args = {'host':host,'port':port,'log':log}
dic['online'] = True if dic['local'] is True else NetTools.isOnline(**args)
cmds = {
'execute':dic['service']['commands']['command'],
'parm': key if key not in dic['service']['commands'].keys() else dic['service']['commands'][key]
}
print(f"{key}: {dic['service']}\n{cmds}")
if dic['local'] is False and dic['online'] is True:
cmd = f'{cmds['execute']} {cmds['parm']} {dic['service']['name']}'
args.update({'user':'root','password':dic['sudo'],'key':dic['key'],'command':cmd})
rc = NetTools.RemoteTerminal(**args)
elif dic['local'] is True:
cmd = [ cmds['execute'], cmds['parm'], dic['service']['name'] ]
rc = NetTools.Sudo_Run(cmd,dic['sudo'])
else:
FileTools.WriteLog(f"{host} Current Online Status={dic['online']}",log,logging.WARN)
return
if key.lower() == 'status':
dic['service']['active']= True if rc['out'].strip() == 'active' and rc['code'] == 0 else False
FileTools.WriteLog(f"Executing {key} {rc['out'].strip()} for {dic['service']['name']} on {host} {'succeeded' if rc['code']==0 else 'failed'}",log)
# Preload with User Libraries -> Common to all scripts
InitializeModules()
import FileTools,NetTools,Tools,DbTools,AnsibleTools
from MyParser import MyParser
# Execute Script
if __name__ =="__main__":
main()