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

CLI to show 'system ready' message when the system is ready take config commands #693

Open
wants to merge 3 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
139 changes: 139 additions & 0 deletions config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
import netaddr
import re
import syslog
import logging
import swsssdk
Comment on lines +11 to +12
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These modules are not used. Remove?

import getpass
import uuid

import sonic_device_util
import ipaddress
Expand All @@ -17,6 +21,12 @@

import aaa
import mlnx
import traceback
import base64
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from Crypto import Random
import time

CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help', '-?'])

Expand Down Expand Up @@ -1579,5 +1589,134 @@ def del_ntp_server(ctx, ntp_ip_address):
except SystemExit as e:
ctx.fail("Restart service ntp-config failed with error {}".format(e))

g_ext_cfg = {}

@config.group('export', invoke_without_command=False)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 'export' group does not appear to be relevant to the 'system ready' changes as stated in the PR title and description. Can these be removed and a separate PR created for them?

@click.pass_context
def export(ctx):
pass

@export.command('enable')
@click.pass_context
def export_enable(ctx):
"""Enable the tech-support export service"""
config_db = ConfigDBConnector()
config_db.connect()
cfg_entry = config_db.get_entry('EXPORT', 'export')

if 'servername' in cfg_entry:
cfg_entry['config'] = 'enable'
config_db.set_entry('EXPORT', 'export',cfg_entry)
else:
print "export is not configured\n"

@export.command('disable')
@click.pass_context
def export_disable(ctx):
"""Disable the tech-support export service"""
config_db = ConfigDBConnector()
config_db.connect()
cfg_entry = config_db.get_entry('EXPORT', 'export')

if 'servername' in cfg_entry:
cfg_entry['config'] = 'disable'
config_db.set_entry('EXPORT', 'export',cfg_entry)
else:
print "export is not configured\n"



class BasedIntParamType(click.ParamType):

def convert(self, value, param, ctx):
minval=30
maxval=1440
try:
if int (value) == 0:
return int(value)

if ( int(value) >= minval and int(value) <= maxval) :
return int(value)
else:
print "Invalid interval range, valid values[ 0(disable), {}-{} minutes]".format(minval, maxval)
except Exception as e:
print str(e)

BASED_INT = BasedIntParamType()

@export.command('interval')
#@click.argument('interval', metavar='<interval in secs>', nargs=1, required=True, type=click.IntRange(0,1800,86400))
@click.argument('interval', metavar='<interval in minutes>', nargs=1, required=True, type=BASED_INT)
@click.pass_context
def export_interval(ctx, interval):
"""Configure the tech-support export interval """
config_db = ConfigDBConnector()
config_db.connect()
cfg_entry = config_db.get_entry('EXPORT', 'export')

if 'servername' in cfg_entry:
cfg_entry['interval'] = interval
config_db.set_entry('EXPORT', 'export',cfg_entry)
else:
print "export is not configured\n"


def encrypt(key, source, encode=True):
key = key.ljust(16,'F')
obj = AES.new(key, AES.MODE_CFB, 'A287AJSHJKHJS562')
data = obj.encrypt(source)
return base64.b64encode(data).decode("latin-1") if encode else data


@export.group('server')
@click.pass_context
def export_server(ctx):
"""Configure the remote server name to connect"""
pass

@export_server.group('username', invoke_without_command=False)
@click.pass_context
def export_user(ctx):
"""Configure the remote server user name to upload"""
pass

@export_user.group('destdir', invoke_without_command=False)
@click.pass_context
def export_destdir(ctx):
"""Configure the remote server directory to save the tech-support data"""
pass


@export_destdir.command('protocol')
@click.argument('servername', metavar='<server name>', nargs=1, required=True)
@click.argument('username', metavar='<user name>', required=True)
@click.argument('destdir', metavar='<destination directory>', required=True)
@click.argument('protocol', metavar='<protocol: scp/sftp>', required=True, type=click.Choice(["scp", "sftp"]))
@click.pass_context
def export_protocol(ctx, servername, username, destdir, protocol ):
"""
Configures the export service to upload the tech-support data to a remote server \n
<server name> - Configure the remote server name to connect \n
<user name> - Configure the remote server user name to upload \n
<dest dir> - Configure the remote server directory to save
the tech-support data \n
<protocol> - Configure the protocol type[scp/sftp] to upload
the tech-support data \n
"""
g_ext_cfg['servername'] = servername
g_ext_cfg['username'] = username
g_ext_cfg['destdir'] = destdir
g_ext_cfg['protocol'] = protocol

try:
g_ext_cfg['password'] = getpass.getpass('Password:')
g_ext_cfg['password'] = encrypt(str(uuid.getnode()), g_ext_cfg['password'])
except:
print "Input reading error!"
traceback.print_exc(file=sys.stdout)

config_db = ConfigDBConnector()
config_db.connect()
config_db.set_entry('EXPORT', 'export', g_ext_cfg)
if __name__ == '__main__':
config()
4 changes: 3 additions & 1 deletion scripts/generate_dump
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ DO_COMPRESS=true
CMD_PREFIX=
SINCE_DATE="@0" # default is set to January 1, 1970 at 00:00:00 GMT
REFERENCE_FILE=/tmp/reference
BASE=sonic_dump_`hostname`_`date +%Y%m%d_%H%M%S`
BASE=${BASE:-sonic_dump_`hostname`_`date +%Y%m%d_%H%M%S`}
DUMPDIR=/var/dump
TARDIR=$DUMPDIR/$BASE
TARFILE=$DUMPDIR/$BASE.tar
LOGDIR=$DUMPDIR/$BASE/dump
HOME=${HOME:-/root}
USER=${USER:-root}

###############################################################################
# Runs a comamnd and saves its output to the incrementally built tar.
Expand Down
92 changes: 92 additions & 0 deletions show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2088,5 +2088,97 @@ def tablelize(keys, data, enable_table_keys, prefix):
click.echo(tabulate(tablelize(keys, data, enable_table_keys, prefix), header))
state_db.close(state_db.STATE_DB)

@cli.command('export')
def export():
""" show tech-support export configurations """
config_db = ConfigDBConnector()
config_db.connect()
cfg_entry = config_db.get_entry('EXPORT', 'export')

if 'servername' in cfg_entry:
del cfg_entry['password']
print "Export Info : {}".format(cfg_entry)
else:
print "Export info is not configured/enabled"


def get_process_state(service):
command = "systemctl status {} |grep running".format(service)

try:
#print "Command :"+command
proc = subprocess.Popen(command,
stdout=subprocess.PIPE,
shell=True,
stderr=subprocess.STDOUT)
stdout = proc.communicate()[0]
proc.wait()
result = stdout.rstrip('\n')

except OSError, e:
raise OSError("Cannot detect routing-stack")

#print "Result :["+ result+"]"
return (result)


@cli.group('system', invoke_without_command=False)
def system():
pass

@system.command('status')
def system_status():

service_list = [
'swss',
'bgp',
'teamd',
'pmon',
'syncd',
'database',
]


app_db = SonicV2Connector(host="127.0.0.1")
app_db.connect(app_db.APPL_DB)




#services()
pstate = "System is ready"
for service in service_list:
try:

state = get_process_state(service)
if state == "":
pstate=None
break
except Exception as e:
print str(e)

if pstate is not None:
pstate = app_db.get(app_db.APPL_DB, 'PORT_TABLE:PortInitDone', 'lanes')
else:
print "System is not ready - Core services are not up"
for service in service_list:
try:

state = get_process_state(service)
if state == "":
print "\t{0:<10} : Down".format(service)
else:
print "\t{0:<10} : Up".format(service)
except Exception as e:
pass
return

if pstate is not None:
print "System is ready"
else:
print "System is not ready - Ports are not up"



if __name__ == '__main__':
cli()