text: #
  # Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
  #
  
  import sys
  
  import argparse
  from vnc_api.vnc_api import *
  from pysandesh.sandesh_base import Sandesh, SandeshSystem, SandeshConfig
  from pysandesh.gen_py.sandesh.ttypes import SandeshLevel
  from sandesh_common.vns.constants import (HttpPortKubeManager,ApiServerPort,\
      DiscoveryServerPort)
  from enum import Enum
  
  class MandatoryArgs(Enum):
      """
      Enum of mandatory arguments to kube-manager.
      Kube-manager arguments will be validated against these arguments to
      enforce the presence of these mandatory arguments and optionally to
      enforce the correctness/validity of the supplied value for an argument.
  
      Each mandatory argument is represented by an enum member and the following
      info is captured for each argument, as a dictionary:
      a. arg_str - String which identifies the argument in config file.
      b. validatefn (optional) - Pointer to function that validates configured
                                 value for an argument.
  
      A validate function (if specified) can be any custom function that returns
      a value that evaluates to bool True when validation is successful.
      It should return bool False if its validation fails.
  
      Example:
  
      An argumennt "foo" is configured in the config file as follows:
  
          foo = foo_value
  
      It can be enforced as mandatory argument by added the following member to
      this enum.
  
          FOO = {"arg_str": "foo", "validatefn": foo_fn()}
  
      If a validation function is not required then:
  
          FOO = {"arg_str": "foo"}
  
      """
      POD_SUBNET = {
          "arg_str": "pod_subnets",
          "validatefn": lambda x: x
      }
  
      SERVICE_SUBNET = {
          "arg_str": "service_subnets",
          "validatefn": lambda x: x
      }
  
      IP_FABRIC_SUBNET = {
          "arg_str": "ip_fabric_subnets",
          "validatefn": lambda x: x
      }
  
  def parse_args(args_str=None):
      if not args_str:
          args_str = sys.argv[1:]
      conf_parser = argparse.ArgumentParser(add_help=False)
      conf_parser.add_argument("-c", "--config-file", action='append',
          help="Specify config file", metavar="FILE")
      args, remaining_argv = conf_parser.parse_known_args(args_str)
  
      defaults = {
          'http_server_port': HttpPortKubeManager,
          'worker_id': '0',
          'collectors': '',
          'logger_class': None,
          'logging_conf': '',
          'log_local': False,
          'log_category': '',
          'use_syslog': False,
          'syslog_facility': Sandesh._DEFAULT_SYSLOG_FACILITY,
          'kube_object_cache': 'True',
          'disc_server_ip': 'localhost',
          'disc_server_port': DiscoveryServerPort,
          'log_level': SandeshLevel.SYS_DEBUG,
          'log_file': '/var/log/contrail/contrail-kube-manager.log',
          'api_service_link_local' : 'True',
          'orchestrator' : 'kubernetes',
          'token' : '',
          'nested_mode': '0',
          'global_tags': '1',
          'aps_name': '',
          'kube_timer_interval': '60',
          'secure_project': 'True'
      }
      defaults.update(SandeshConfig.get_default_options(['DEFAULTS']))
  
      vnc_opts = {
          'rabbit_server': 'localhost',
          'rabbit_port': '5672',
          'rabbit_user': 'guest',
          'rabbit_password': 'guest',
          'rabbit_vhost': None,
          'rabbit_ha_mode': False,
          'rabbit_use_ssl': False,
          'kombu_ssl_version': '',
          'kombu_ssl_keyfile': '',
          'kombu_ssl_certfile': '',
          'kombu_ssl_ca_certs': '',
          'cassandra_user': None,
          'cassandra_password': None,
          'cassandra_server_list': '',
          'cluster_id': '',
          'vnc_endpoint_ip': '[127.0.0.1]',
          'vnc_endpoint_port': ApiServerPort,
          'admin_user' : '',
          'admin_password' : '',
          'admin_tenant' : '',
          'public_fip_pool': '{}',
          'zk_server_ip': '127.0.0.1:2181',
      }
  
      k8s_opts = {
          'kubernetes_api_server': 'localhost',
          'kubernetes_api_port': '8080',
          'kubernetes_api_secure_port': 8443,
          'kubernetes_service_name': 'kubernetes',
          MandatoryArgs.SERVICE_SUBNET.value['arg_str']: None,
          MandatoryArgs.POD_SUBNET.value['arg_str']: None,
          MandatoryArgs.IP_FABRIC_SUBNET.value['arg_str']: None,
          'kubernetes_cluster_owner': 'k8s',
          'kubernetes_cluster_domain' : 'default-domain',
          'cluster_name': None,
          'cluster_project' : "{}",
          'cluster_network' : "{}",
          'cluster_pod_network' : None,
          'cluster_service_network' : None,
          'ip_fabric_forwarding': False,
          'ip_fabric_snat': False,
      }
  
      sandesh_opts = SandeshConfig.get_default_options()
  
      auth_opts = {
          'auth_token_url': None,
          'auth_user': 'admin',
          'auth_password': 'admin',
          'auth_tenant': 'admin',
      }
  
      config = ConfigParser.SafeConfigParser()
      if args.config_file:
          config.read(args.config_file)
          if 'VNC' in config.sections():
              vnc_opts.update(dict(config.items("VNC")))
          if 'KUBERNETES' in config.sections():
              k8s_opts.update(dict(config.items("KUBERNETES")))
          SandeshConfig.update_options(sandesh_opts, config)
          if 'AUTH' in config.sections():
              auth_opts.update(dict(config.items("AUTH")))
          if 'DEFAULTS' in config.sections():
              defaults.update(dict(config.items("DEFAULTS")))
  
      parser = argparse.ArgumentParser(
          parents=[conf_parser],
          description=__doc__,
          formatter_class=argparse.RawDescriptionHelpFormatter,
      )
      defaults.update(vnc_opts)
      defaults.update(k8s_opts)
      defaults.update(sandesh_opts)
      defaults.update(auth_opts)
      parser.set_defaults(**defaults)
      args = parser.parse_args(args_str)
  
      if type(args.cassandra_server_list) is str:
          args.cassandra_server_list = args.cassandra_server_list.split()
      if type(args.collectors) is str:
          args.collectors = args.collectors.split()
      if type(args.pod_subnets) is str:
          args.pod_subnets = args.pod_subnets.split()
      if type(args.service_subnets) is str:
          args.service_subnets = args.service_subnets.split()
      if type(args.ip_fabric_subnets) is str:
          args.ip_fabric_subnets = args.ip_fabric_subnets.split()
      if type(args.ip_fabric_forwarding) is str:
          if args.ip_fabric_forwarding.lower() == 'true':
              args.ip_fabric_forwarding = True
          else:
              args.ip_fabric_forwarding = False
      if type(args.ip_fabric_snat) is str:
          if args.ip_fabric_snat.lower() == 'true':
              args.ip_fabric_snat = True
          else:
              args.ip_fabric_snat = False
      args.sandesh_config = SandeshConfig.from_parser_arguments(args)
  
      # Validate input argumnents.
      validate_mandatory_args(args)
  
      return args
  
  
  def rabbitmq_args(args):
      return {
          'servers': args.rabbit_server, 'port': args.rabbit_port,
          'user': args.rabbit_user, 'password': args.rabbit_password,
          'vhost': args.rabbit_vhost, 'ha_mode': args.rabbit_ha_mode,
          'use_ssl': args.rabbit_use_ssl,
          'ssl_version': args.kombu_ssl_version,
          'ssl_keyfile': args.kombu_ssl_keyfile,
          'ssl_certfile': args.kombu_ssl_certfile,
          'ssl_ca_certs': args.kombu_ssl_ca_certs
      }
  
  def validate_mandatory_args(args):
      for mandatory_arg in MandatoryArgs:
          arg_name = mandatory_arg.value['arg_str']
          if not hasattr(args, arg_name):
              print("Mandatory Argument %s not found in config"
                  % arg_name)
              sys.exit("Mandatory argument [%s] not found in config" % arg_name)
  
          validatefn = mandatory_arg.value.get('validatefn', None)
          arg_value = getattr(args, arg_name)
          if validatefn and not validatefn(arg_value):
              sys.exit("Validation of mandatory argument [%s] configured with"\
                  " value [%s] failed." % (arg_name, arg_value))
  