#!/usr/bin/python
# Copyright 2015-2017 VMware, Inc.  All rights reserved.
# -*- mode: Python; coding: utf-8 -*-
'''
For VMware Appliances not using appliancesh

see https://www.vmware.com/support/developer/vcli/vcli41/doc/reference/vicfg-snmp.html
    https://pubs.vmware.com/vsphere-51/index.jsp?topic=%2Fcom.vmware.vcli.ref.doc%2Fvicfg-snmp.html
vicfg-snmp [<connection_options>]
        [--communities <comm_list> |
        --disable |
        --enable |
        --help |
        --port <port_number> |
        --reset |
        --show |
        --notraps |
        --targets <targets> |
        --test |
'''
__author__ = "VMware, Inc."

import sys
sys.path.append('/opt/vmware/snmp/lib')
import cfg
from optparse import OptionParser
import logging
import datetime
import time

def get_options():
    """
    Supports the command-line arguments listed below
    """

    parser = OptionParser()
    parser.add_option("-c", "--communities",
                      help="Specifies communities, separated by commas. The settings specified using this option overwrite any previous settings. The settings specified using this flag overwrite any previous settings. ")
    parser.add_option("-D", "--disable",
                      action="store_true",
                      help="Stops the SNMP service on the host.")
    parser.add_option("-e", "--enable",
                      action="store_true",
                      help="Starts the SNMP service on the host.")
    parser.add_option("-p", "--port",
                      help="Sets the port used by the SNMP agent. The default is UDP 161. This is the port that the SNMP service uses to listen on for polling requests, such as GET requests. You can also configure the port that the SNMP agent sends data to on the target system using the --targets option. That port is UDP 162 by default.")
    parser.add_option("-l", "--loglevel",
                      help="System Agent syslog logging level: debug|info|warning|error")
    parser.add_option("-r", "--reset",
                      action="store_true",
                      help="Clears all previously-specified communities and targets.")
    parser.add_option("-s", "--show",
                      action="store_true",
                      help="Displays the current SNMP configuration.")
    parser.add_option("-S", "--stats",
                      action="store_true",
                      help="Displays the current SNMP agent runtime performance metrics.")
    parser.add_option("-t", "--targets",
                      help="Sets the destination for (notifications) traps. You can specify multiple targets, separated by commas. The settings specified using this flag overwrite any previous settings. ")
    parser.add_option("-n", "--notraps",
                      help="Comma separated list of trap oids for traps not to be sent by agent. Use value 'reset' to clear setting.")
    parser.add_option("-C", "--syscontact",
                      help="System contact string as presented in sysContact.0. Up to 255 characters")
    parser.add_option("-L", "--syslocation",
                      help="System location string as presented in sysLocation.0. Up to 255 characters.")
    parser.add_option("-E", "--engineid",
                      help="System location string as presented in sysLocation.0. Up to 255 characters.")
    parser.add_option("-a", "--authentication",
                      help="Set default authentication protocol. Values: none, MD5, SHA1")
    parser.add_option("-x", "--privacy",
                      help="Set default privacy protocol. Values: none, AES128")
    parser.add_option("-u", "--users",
                      help="Set up to five local users. Format is: user/-|auth-hash/-|priv-hash/model[,...] Where user is 32 chars max. '-' indicates no hash. Model is one of (none|auth|priv).")
    parser.add_option("-i", "--v3targets",
                      help="Set up to three SNMPv3 notification targets. Format is: ip-or-hostname[@port]/remote-user/security-level/trap|inform[,...].")
    parser.add_option("-T", "--test",
                      action="store_true",
                      help="Sends a test notification that can be used to validate the SNMP configuration to the configured target or targets.")
    parser.add_option("-g", "--debug",
                      action="store_true",
                      help="turn on pdb debugger, for technical support only.")
    parser.add_option("-2", "--v2c",
                      help="If enabled, SNMPv2c traps are sent instead of SNMPv1 Values: (true|false). Default false.")
    (options, _) = parser.parse_args()
    return options;

def main():
   opts = get_options()
   if opts.debug:
      import pdb
      pdb.set_trace()

   if opts.show:
      kvp = cfg.show()
      lver = "V2c" if kvp['v2c'] else "V1"
      # todo match esxcli output format
      print("Current SNMP agent setting")
      print("Enabled                 : %s" %  kvp['enable'])
      print("UDP port                : %s" % kvp['port'])
      print("V1/V2c Communities      : %s" % ' '.join(kvp['communities']))
      print("%s Notification targets : %s" % (lver, ' '.join(kvp['targets'])))
      if 'EventFilter' in kvp:
         print("Notification filter oids: %s" % ' '.join(kvp['EventFilter']))
      if 'v3targets' in kvp:
         print("V3 Notification targets : %s" % ' '.join(kvp['v3targets']))
      print("Contact                 : %s" % kvp['syscontact'])
      print("Location                : %s" % kvp['syslocation'])
      print("Engine ID               : %s" % kvp['engineid'])
      print("Auth Protocol           : %s" % kvp['authProtocol'])
      print("Priv Protocol           : %s" % kvp['privProtocol'])
      print("V3 Users                : %s" % ' '.join(kvp['v3users']))
      print("Log level               : %s" % kvp['loglevel'])
      print("Process ID              : %s" % kvp['state'])
      #print "V3 Notification targets" % kvp['v3targets']
      print("INFO: listing complete.")
   elif opts.stats:
       stats = cfg.stats()
       try:
          stats.sysUpTime = stats.sysUpTime.split()[0] / 100
       except:
           stats.sysUptime = 0
       try:
          the_date = int(stats.worstrtimelast)
       except:
          the_date = 0
       if the_date == 0:
          the_date = "n/a";
       else:
          try:
              the_date = datetime.fromtimestamp(the_date)
          except:
              the_date = time.gmtime(int(the_date))
              the_date = time.strftime("%FT%TZ", the_date)
       stats.worstrtimelast = the_date
       print("SNMP agent protocol statistics")
       for item in sorted(stats.__dict__.keys()):
          print("%s: %s" % (item, stats.__dict__[item]))
   elif opts.enable:
    cfg.enable_agent()
   elif opts.disable:
    cfg.disable_agent()
   elif opts.syscontact:
    cfg.set_contact(opts.syscontact)
   elif opts.syslocation:
    cfg.set_location(opts.syslocation)
   elif opts.engineid:
    cfg.set_engineid(opts.engineid)
   elif opts.authentication:
    cfg.set_authentication(opts.authentication)
   elif opts.privacy:
    cfg.set_privacy(opts.privacy)
   elif opts.users:
    cfg.set_users(opts.users)
   elif opts.v3targets:
    cfg.set_v3targets(opts.v3targets)
   elif opts.communities:
    cfg.set_communities(opts.communities)
   elif opts.targets:
    cfg.set_targets(opts.targets)
   elif opts.loglevel:
    cfg.set_loglevel(opts.loglevel)
   elif opts.notraps:
    cfg.set_filter(opts.notraps)
   elif opts.port:
    cfg.set_port(opts.port)
   elif opts.v2c:
    cfg.set_v2c(opts.v2c)
   elif opts.reset:
      cfg.reset()
   elif opts.test:
      results = cfg.test()
      keys = sorted(results)
      for item in keys:
          print("%-28s : %s" % (item, results[item]))
      rc = 0
      if results['success'] == False:
         rc = 1
      sys.exit(rc)

# Start program
if __name__ == "__main__":
   try:
      logging.basicConfig()
      main()
   except SystemExit as err:
       sys.exit(err)
   except Exception as msg:
      print("ERROR: %s " % msg)
      sys.exit(1)
# end of file
