import os import signal import sys from functools import wraps from subprocess import PIPE, Popen import dcoscli import docopt import pkg_resources from dcos import auth, constants, emitting, errors, http, subcommand, util from dcos.errors import DCOSException from dcoscli import analytics emitter = emitting.FlatEmitter() def main(): try: return _main() except DCOSException as e: emitter.publish(e) return 1 def _main(): signal.signal(signal.SIGINT, signal_handler) args = docopt.docopt( _doc(), version='dcos version {}'.format(dcoscli.version), options_first=True) log_level = args['--log-level'] if log_level and not _config_log_level_environ(log_level): return 1 if args['--debug']: os.environ[constants.DCOS_DEBUG_ENV] = 'true' util.configure_process_from_environ() if args[''] != 'config' and \ not auth.check_if_user_authenticated(): auth.force_auth() config = util.get_config() set_ssl_info_env_vars(config) command = args[''] http.silence_requests_warnings() if not command: command = "help" executable = subcommand.command_executables(command) subproc = Popen([executable, command] + args[''], stderr=PIPE) if dcoscli.version != 'SNAPSHOT': return analytics.wait_and_track(subproc) else: return analytics.wait_and_capture(subproc)[0] def _doc(): """ :rtype: str """ return pkg_resources.resource_string( 'dcoscli', 'data/help/dcos.txt').decode('utf-8') def _config_log_level_environ(log_level): """ :param log_level: Log level to set :type log_level: str :returns: True if the log level was configured correctly; False otherwise. :rtype: bool """ log_level = log_level.lower() if log_level in constants.VALID_LOG_LEVEL_VALUES: os.environ[constants.DCOS_LOG_LEVEL_ENV] = log_level return True msg = 'Log level set to an unknown value {!r}. Valid values are {!r}' emitter.publish(msg.format(log_level, constants.VALID_LOG_LEVEL_VALUES)) return False def signal_handler(signal, frame): emitter.publish( errors.DefaultError("User interrupted command with Ctrl-C")) sys.exit(0) def decorate_docopt_usage(func): """Handle DocoptExit exception :param func: function :type func: function :return: wrapped function :rtype: function """ @wraps(func) def wrapper(*args, **kwargs): try: result = func(*args, **kwargs) except docopt.DocoptExit as e: emitter.publish("Command not recognized\n") emitter.publish(e) return 1 return result return wrapper def set_ssl_info_env_vars(config): """Set SSL info from config to environment variable if enviornment variable doesn't exist :param config: config :type config: Toml :rtype: None """ if 'core.ssl_verify' in config and ( not os.environ.get(constants.DCOS_SSL_VERIFY_ENV)): os.environ[constants.DCOS_SSL_VERIFY_ENV] = str( config['core.ssl_verify'])