Exemplo n.º 1
0
def init(provider, reset_config):

    if provider is not None:
        return provider_common.provider_init(provider, reset_config)

    if os.path.exists(os.path.join(
            utils.get_cwd(),
            constants.CLOUDIFY_WD_SETTINGS_DIRECTORY_NAME,
            constants.CLOUDIFY_WD_SETTINGS_FILE_NAME)):
        if not reset_config:
            msg = 'Current directory is already initialized'
            error = exceptions.CloudifyCliError(msg)
            error.possible_solutions = [
                "Run 'cfy init -r' to force re-initialization "
                "(might overwrite existing "
                "configuration files if exist) "
            ]
            raise error
        else:
            shutil.rmtree(os.path.join(
                utils.get_cwd(),
                constants.CLOUDIFY_WD_SETTINGS_DIRECTORY_NAME))

    settings = utils.CloudifyWorkingDirectorySettings()
    utils.dump_cloudify_working_dir_settings(settings)
    utils.dump_configuration_file()
    configure_loggers()
    get_logger().info('Initialization completed successfully')
Exemplo n.º 2
0
def init(reset_config, skip_logging=False):
    if os.path.exists(
            os.path.join(utils.get_cwd(),
                         constants.CLOUDIFY_WD_SETTINGS_DIRECTORY_NAME,
                         constants.CLOUDIFY_WD_SETTINGS_FILE_NAME)):
        if not reset_config:
            msg = 'Current directory is already initialized'
            error = exceptions.CloudifyCliError(msg)
            error.possible_solutions = [
                "Run 'cfy init -r' to force re-initialization "
                "(might overwrite existing "
                "configuration files if exist) "
            ]
            raise error
        else:
            shutil.rmtree(
                os.path.join(utils.get_cwd(),
                             constants.CLOUDIFY_WD_SETTINGS_DIRECTORY_NAME))

    settings = utils.CloudifyWorkingDirectorySettings()
    utils.dump_cloudify_working_dir_settings(settings)
    utils.dump_configuration_file()
    configure_loggers()
    if not skip_logging:
        get_logger().info('Initialization completed successfully')
Exemplo n.º 3
0
    def test_get_existing_init_path_from_inner_dir(self):

        # first create the init
        init_path = os.path.join(utils.get_cwd(),
                                 constants.CLOUDIFY_WD_SETTINGS_DIRECTORY_NAME)
        os.mkdir(init_path)

        # switch working directory to inner one
        new_cwd = os.path.join(utils.get_cwd(), 'test_get_existing_init_path')
        os.mkdir(new_cwd)
        utils.get_cwd = lambda: new_cwd

        self.assertEqual(utils.get_init_path(), init_path)
Exemplo n.º 4
0
    def test_get_existing_init_path_from_inner_dir(self):

        # first create the init
        init_path = os.path.join(utils.get_cwd(),
                                 constants.CLOUDIFY_WD_SETTINGS_DIRECTORY_NAME)
        os.mkdir(init_path)

        # switch working directory to inner one
        new_cwd = os.path.join(utils.get_cwd(),
                               'test_get_existing_init_path')
        os.mkdir(new_cwd)
        utils.get_cwd = lambda: new_cwd

        self.assertEqual(utils.get_init_path(), init_path)
Exemplo n.º 5
0
 def test_init_existing_provider_config_no_overwrite(self):
     cli_runner.run_cli('cfy init -p mock_provider -v')
     os.remove(
         os.path.join(utils.get_cwd(), CLOUDIFY_WD_SETTINGS_DIRECTORY_NAME,
                      CLOUDIFY_WD_SETTINGS_FILE_NAME))
     self._assert_ex('cfy init -p mock_provider',
                     'already contains a provider configuration file')
Exemplo n.º 6
0
def install(blueprint_path, inputs, install_plugins, workflow_id, parameters,
            allow_custom_parameters, task_retries, task_retry_interval,
            task_thread_pool_size):

    # if no blueprint path was supplied, set it to a default value
    if not blueprint_path:
        blueprint_path = DEFAULT_BLUEPRINT_PATH

    # If no inputs were supplied, and there is a file named inputs.yaml in
    # the cwd, use it as the inputs file
    if not inputs:
        if os.path.isfile(
                os.path.join(utils.get_cwd(),
                             DEFAULT_INPUTS_PATH_FOR_INSTALL_COMMAND)):

            inputs = DEFAULT_INPUTS_PATH_FOR_INSTALL_COMMAND

    init(blueprint_path=blueprint_path,
         inputs=inputs,
         install_plugins=install_plugins)

    # if no workflow was supplied, execute the `install` workflow
    if not workflow_id:
        workflow_id = DEFAULT_INSTALL_WORKFLOW

    execute(workflow_id=workflow_id,
            parameters=parameters,
            allow_custom_parameters=allow_custom_parameters,
            task_retries=task_retries,
            task_retry_interval=task_retry_interval,
            task_thread_pool_size=task_thread_pool_size)
Exemplo n.º 7
0
 def test_status_command_from_inner_dir(self):
     self._create_cosmo_wd_settings()
     cwd = utils.get_cwd()
     new_dir = os.path.join(cwd, 'test_command_from_inner_dir')
     os.mkdir(new_dir)
     utils.get_cwd = lambda: new_dir
     cli_runner.run_cli('cfy status')
Exemplo n.º 8
0
def provider_init(provider, reset_config):
    logger = get_logger()

    provider_deprecation_notice()
    if os.path.exists(
            os.path.join(utils.get_cwd(),
                         constants.CLOUDIFY_WD_SETTINGS_DIRECTORY_NAME,
                         constants.CLOUDIFY_WD_SETTINGS_FILE_NAME)):
        if not reset_config:
            msg = ('Current directory is already initialized. '
                   'Use the "-r" flag to force '
                   'reinitialization (might overwrite '
                   'provider configuration files if exist).')
            raise exceptions.CloudifyCliError(msg)
        else:
            # resetting provider configuration
            logger.debug('resetting configuration...')
            _provider_init(provider, reset_config)
            logger.info("Configuration reset complete")
            return

    logger.info("Initializing Cloudify")
    provider_module_name = _provider_init(provider, reset_config)
    settings = utils.CloudifyWorkingDirectorySettings()
    settings.set_provider(provider_module_name)
    settings.set_is_provider_config(True)

    utils.dump_cloudify_working_dir_settings(settings)
    utils.dump_configuration_file()

    logger.info("Initialization complete")
Exemplo n.º 9
0
def provider_init(provider, reset_config):
    logger = get_logger()

    provider_deprecation_notice()
    if os.path.exists(os.path.join(
            utils.get_cwd(),
            constants.CLOUDIFY_WD_SETTINGS_DIRECTORY_NAME,
            constants.CLOUDIFY_WD_SETTINGS_FILE_NAME)):
        if not reset_config:
            msg = ('Current directory is already initialized. '
                   'Use the "-r" flag to force '
                   'reinitialization (might overwrite '
                   'provider configuration files if exist).')
            raise exceptions.CloudifyCliError(msg)
        else:
            # resetting provider configuration
            logger.debug('resetting configuration...')
            _provider_init(provider, reset_config)
            logger.info("Configuration reset complete")
            return

    logger.info("Initializing Cloudify")
    provider_module_name = _provider_init(provider, reset_config)
    settings = utils.CloudifyWorkingDirectorySettings()
    settings.set_provider(provider_module_name)
    settings.set_is_provider_config(True)

    utils.dump_cloudify_working_dir_settings(settings)
    utils.dump_configuration_file()

    logger.info("Initialization complete")
Exemplo n.º 10
0
 def test_init_existing_provider_config_no_overwrite(self):
     cli_runner.run_cli('cfy init -p mock_provider -v')
     os.remove(os.path.join(utils.get_cwd(),
                            CLOUDIFY_WD_SETTINGS_DIRECTORY_NAME,
                            CLOUDIFY_WD_SETTINGS_FILE_NAME))
     self._assert_ex(
         'cfy init -p mock_provider',
         'already contains a provider configuration file')
Exemplo n.º 11
0
    def test_get_existing_init_path_from_init_dir(self):

        # first create the init
        init_path = os.path.join(utils.get_cwd(),
                                 constants.CLOUDIFY_WD_SETTINGS_DIRECTORY_NAME)
        os.mkdir(init_path)

        self.assertEqual(utils.get_init_path(), init_path)
Exemplo n.º 12
0
 def test_status_command_from_inner_dir(self):
     self.client.manager.get_status = MagicMock()
     self._create_cosmo_wd_settings()
     cwd = utils.get_cwd()
     new_dir = os.path.join(cwd, 'test_command_from_inner_dir')
     os.mkdir(new_dir)
     utils.get_cwd = lambda: new_dir
     cli_runner.run_cli('cfy status')
Exemplo n.º 13
0
    def test_get_existing_init_path_from_init_dir(self):

        # first create the init
        init_path = os.path.join(utils.get_cwd(),
                                 constants.CLOUDIFY_WD_SETTINGS_DIRECTORY_NAME)
        os.mkdir(init_path)

        self.assertEqual(utils.get_init_path(), init_path)
Exemplo n.º 14
0
 def test_status_command_from_outer_dir(self):
     self._create_cosmo_wd_settings()
     cwd = utils.get_cwd()
     new_dir = os.path.dirname(cwd)
     utils.get_cwd = lambda: new_dir
     self._assert_ex('cfy status',
                     'Cannot find .cloudify in {0}, '
                     'or in any of its parent directories'
                     .format(new_dir))
Exemplo n.º 15
0
def _load_env():
    if not os.path.isdir(_storage_dir()):
        error = exceptions.CloudifyCliError(
            '{0} has not been initialized with a blueprint.'.format(
                utils.get_cwd()))

        # init was probably not executed.
        # suggest solution.

        error.possible_solutions = ["Run 'cfy local init' in this directory"]
        raise error
    return local.load_env(name=_NAME, storage=_storage())
Exemplo n.º 16
0
    def test_get_init_path_from_outside_dir(self):

        # first create the init
        init_path = os.path.join(utils.get_cwd(),
                                 constants.CLOUDIFY_WD_SETTINGS_DIRECTORY_NAME)
        os.mkdir(init_path)

        # switch working directory to outer one
        new_cwd = os.path.dirname(os.path.dirname(init_path))
        utils.get_cwd = lambda: new_cwd

        self.assertRaises(CloudifyCliError, utils.get_context_path)
Exemplo n.º 17
0
    def test_get_init_path_from_outside_dir(self):

        # first create the init
        init_path = os.path.join(utils.get_cwd(),
                                 constants.CLOUDIFY_WD_SETTINGS_DIRECTORY_NAME)
        os.mkdir(init_path)

        # switch working directory to outer one
        new_cwd = os.path.dirname(os.path.dirname(init_path))
        utils.get_cwd = lambda: new_cwd

        self.assertRaises(CloudifyCliError, utils.get_context_path)
Exemplo n.º 18
0
def _provider_init(provider, reset_config):
    """
    initializes a provider by copying its config files to the cwd.
    First, will look for a module named cloudify_#provider#.
    If not found, will look for #provider#.
    If install is True, will install the supplied provider and perform
    the search again.

    :param string provider: the provider's name
    :param bool reset_config: if True, overrides the current config.
    :rtype: `string` representing the provider's module name
    """

    logger = get_logger()

    provider_module_name, provider = get_provider_by_name(provider)

    target_file = os.path.join(utils.get_cwd(), constants.CONFIG_FILE_NAME)
    if not reset_config and os.path.exists(target_file):
        msg = ('Target directory {0} already contains a '
               'provider configuration file; '
               'use the "-r" flag to '
               'reset it back to its default values.'
               .format(os.path.dirname(target_file)))
        raise exceptions.CloudifyCliError(msg)
    else:
        # try to get the path if the provider is a module
        try:
            provider_dir = provider.__path__[0]
        # if not, assume it's in the package's dir
        except:
            provider_dir = os.path.dirname(provider.__file__)
        files_path = os.path.join(provider_dir, constants.CONFIG_FILE_NAME)
        logger.debug('Copying provider files from {0} to {1}'
                     .format(files_path, utils.get_cwd()))
        shutil.copy(files_path, utils.get_cwd())

    return provider_module_name
Exemplo n.º 19
0
def _provider_init(provider, reset_config):
    """
    initializes a provider by copying its config files to the cwd.
    First, will look for a module named cloudify_#provider#.
    If not found, will look for #provider#.
    If install is True, will install the supplied provider and perform
    the search again.

    :param string provider: the provider's name
    :param bool reset_config: if True, overrides the current config.
    :rtype: `string` representing the provider's module name
    """

    logger = get_logger()

    provider_module_name, provider = get_provider_by_name(provider)

    target_file = os.path.join(utils.get_cwd(), constants.CONFIG_FILE_NAME)
    if not reset_config and os.path.exists(target_file):
        msg = ('Target directory {0} already contains a '
               'provider configuration file; '
               'use the "-r" flag to '
               'reset it back to its default values.'.format(
                   os.path.dirname(target_file)))
        raise exceptions.CloudifyCliError(msg)
    else:
        # try to get the path if the provider is a module
        try:
            provider_dir = provider.__path__[0]
        # if not, assume it's in the package's dir
        except:
            provider_dir = os.path.dirname(provider.__file__)
        files_path = os.path.join(provider_dir, constants.CONFIG_FILE_NAME)
        logger.debug('Copying provider files from {0} to {1}'.format(
            files_path, utils.get_cwd()))
        shutil.copy(files_path, utils.get_cwd())

    return provider_module_name
Exemplo n.º 20
0
def _load_env():
    if not os.path.isdir(_storage_dir()):
        error = exceptions.CloudifyCliError(
            '{0} has not been initialized with a blueprint.'
            .format(utils.get_cwd()))

        # init was probably not executed.
        # suggest solution.

        error.possible_solutions = [
            "Run 'cfy local init' in this directory"
        ]
        raise error
    return local.load_env(name=_NAME,
                          storage=_storage())
Exemplo n.º 21
0
    def test_default_inputs_file_path(self, *_):

        # create an `inputs.yaml` file in the cwd.
        inputs_path = os.path.join(utils.get_cwd(), 'inputs.yaml')
        os.mknod(inputs_path)

        command = \
            'cfy install -n {0} --archive-location={1} ' \
            '-b {2} -d {3}' \
            .format(STUB_BLUEPRINT_FILENAME, STUB_ARCHIVE_LOCATION,
                    STUB_BLUEPRINT_ID, STUB_DEPLOYMENT_ID)

        self.assert_method_called(
            cli_command=command,
            module=commands.deployments,
            function_name='create',
            args=[STUB_BLUEPRINT_ID,
                  STUB_DEPLOYMENT_ID,
                  DEFAULT_INPUTS_PATH_FOR_INSTALL_COMMAND]
        )
Exemplo n.º 22
0
    def test_default_blueprint_path_does_not_exist(self, *_):

        start_of_file_does_not_exist_message = \
            'Your blueprint was not found in the path:'

        self.assertRaisesRegexp(CloudifyCliError,
                                start_of_file_does_not_exist_message,
                                cli_runner.run_cli,
                                'cfy install')

        tmp_blueprint_path = os.path.join(utils.get_cwd(),
                                          DEFAULT_BLUEPRINT_PATH)

        start_of_permission_denied_message = \
            'A problem was encountered while trying to open'

        open(tmp_blueprint_path, 'w').close()
        os.chmod(tmp_blueprint_path, 0)

        self.assertRaisesRegexp(CloudifyCliError,
                                start_of_permission_denied_message,
                                cli_runner.run_cli,
                                'cfy install')
Exemplo n.º 23
0
 def test_init_overwrite_existing_provider_config(self):
     cli_runner.run_cli('cfy init -p mock_provider')
     shutil.rmtree(
         os.path.join(utils.get_cwd(), CLOUDIFY_WD_SETTINGS_DIRECTORY_NAME))
     cli_runner.run_cli('cfy init -p mock_provider -r')
Exemplo n.º 24
0
def _storage_dir():
    return os.path.join(utils.get_cwd(), _STORAGE_DIR_NAME)
Exemplo n.º 25
0
def install(blueprint_path, blueprint_id, validate_blueprint, archive_location,
            blueprint_filename, deployment_id, inputs, workflow_id, parameters,
            allow_custom_parameters, timeout, include_logs,
            auto_generate_ids, json):

    # First, make sure the `blueprint_path` wasn't supplied with
    # `archive_location` or with `blueprint_filename`
    _check_for_mutually_exclusive_arguments(blueprint_path,
                                            archive_location,
                                            blueprint_filename)

    # The presence of the `archive_location` argument is used to distinguish
    # between `install` in 'blueprints upload' mode,
    # and `install` in 'blueprints publish archive' mode.
    if archive_location:
        blueprints.check_if_archive_type_is_supported(archive_location)

        if not blueprint_filename:
            blueprint_filename = DEFAULT_BLUEPRINT_FILE_NAME

        # If blueprint_id wasn't supplied, assign it to the name of the archive
        if not blueprint_id:
            (archive_location, archive_location_type) = \
                blueprints.determine_archive_type(archive_location)
            # if the archive is a local path, assign blueprint_id the name of
            # the archive file without the extension
            if archive_location_type == 'path':
                filename, ext = os.path.splitext(
                    os.path.basename(archive_location))
                blueprint_id = filename
            # if the archive is a url, assign blueprint_id name of the file
            # that the url leads to, without the extension.
            # e.g. http://example.com/path/archive.zip?para=val#sect -> archive
            elif archive_location_type == 'url':
                path = urlparse.urlparse(archive_location).path
                archive_file = path.split('/')[-1]
                archive_name = archive_file.split('.')[0]
                blueprint_id = archive_name
            else:
                raise CloudifyCliError("The archive's source is not a local "
                                       'file path nor a web url')

        # auto-generate blueprint id if necessary
        if _auto_generate_ids(auto_generate_ids):
            blueprint_id = _generate_suffixed_id(blueprint_id)

        blueprints.publish_archive(archive_location,
                                   blueprint_filename,
                                   blueprint_id)
    else:
        blueprint_path_supplied = bool(blueprint_path)
        if not blueprint_path:
            blueprint_path = os.path.join(utils.get_cwd(),
                                          DEFAULT_BLUEPRINT_PATH)

        # If blueprint_id wasn't supplied, assign it to the name of
        # folder containing the application's blueprint file.
        if not blueprint_id:
            blueprint_id = os.path.basename(
                os.path.dirname(
                    os.path.abspath(blueprint_path)))

        # Try opening `blueprint_path`, since `blueprints.upload` expects the
        # `blueprint_path` argument to be a file.
        # (The reason for this is beyond me. That's just the way it is)

        if _auto_generate_ids(auto_generate_ids):
            blueprint_id = _generate_suffixed_id(blueprint_id)

        try:
            with open(blueprint_path) as blueprint_file:
                blueprints.upload(blueprint_file,
                                  blueprint_id,
                                  validate_blueprint)
        except IOError as e:

            # No such file or directory
            if not blueprint_path_supplied and e.errno == errno.ENOENT:
                raise CloudifyCliError(
                    'Your blueprint was not found in the path: {0}.\n\n'
                    'Consider providing an explicit path to your blueprint '
                    'using the `-p`/`--blueprint-path` flag, like so:\n'
                    '`cfy install -p /path/to/blueprint_file.yaml`\n'
                    .format(blueprint_path)
                )
            else:
                raise CloudifyCliError(
                    'A problem was encountered while trying to open '
                    '{0}.\n({1})'.format(blueprint_path, e))

    # If deployment_id wasn't supplied, use the same name as the blueprint id.
    if not deployment_id:
        deployment_id = blueprint_id

    # generate deployment-id suffix if necessary
    if _auto_generate_ids(auto_generate_ids):
        deployment_id = _generate_suffixed_id(deployment_id)

    # If no inputs were supplied, and there is a file named inputs.yaml in
    # the cwd, use it as the inputs file
    if not inputs:
        if os.path.isfile(
            os.path.join(utils.get_cwd(),
                         DEFAULT_INPUTS_PATH_FOR_INSTALL_COMMAND)):

            inputs = DEFAULT_INPUTS_PATH_FOR_INSTALL_COMMAND

    deployments.create(blueprint_id,
                       deployment_id,
                       inputs)

    # although the `install` command does not need the `force` argument,
    # we *are* using the `executions start` handler as a part of it.
    # as a result, we need to provide it with a `force` argument, which is
    # defined below.
    force = False

    # if no workflow was supplied, execute the `install` workflow
    if not workflow_id:
        workflow_id = DEFAULT_INSTALL_WORKFLOW

    executions.start(workflow_id=workflow_id,
                     deployment_id=deployment_id,
                     timeout=timeout,
                     force=force,
                     allow_custom_parameters=allow_custom_parameters,
                     include_logs=include_logs,
                     parameters=parameters,
                     json=json)
Exemplo n.º 26
0
 def test_init_overwrite_existing_provider_config(self):
     cli_runner.run_cli('cfy init -p mock_provider')
     shutil.rmtree(os.path.join(utils.get_cwd(),
                                CLOUDIFY_WD_SETTINGS_DIRECTORY_NAME))
     cli_runner.run_cli('cfy init -p mock_provider -r')
Exemplo n.º 27
0
def _storage_dir():
    return os.path.join(utils.get_cwd(), _STORAGE_DIR_NAME)
Exemplo n.º 28
0
def parser_config():
    return {
        'description': 'Manages Cloudify in different Cloud Environments',
        'arguments': {
            '--version': {
                'help': 'Show version information and exit',
                'action': cfy.version
            }
        },
        'commands': {
            'logs': {
                'help': 'Handles Cloudify Manager logs',
                'sub_commands': {
                    'get': {
                        'arguments': {
                            '-d,--destination-path': {
                                'dest': 'destination_path',
                                'help': 'Destination path of the downloaded archive',
                                'default': utils.get_cwd(),
                            }
                        },
                        'help': "Retrieves an archive containing a Manager's logs (defaults to cwd)",
                        'handler': cfy.logs.get
                    },
                    'purge': {
                        'arguments': {
                            '-f,--force': {
                                'dest': 'force',
                                'help': 'Force purge. This flag is mandatory',
                                'required': True,
                                'action': 'store_true',
                            },
                            '--backup-first': {
                                'dest': 'backup_first',
                                'help': 'Whether to backup before purging.'
                                        'Backup will be in tar.gz format.',
                                'action': 'store_true',
                            }
                        },
                        'help': "Delete a Manager's logs",
                        'handler': cfy.logs.purge
                    },
                    'backup': {
                        'help': "Backs up a Manager's logs",
                        'handler': cfy.logs.backup
                    }
                }
            },
            'install': {
                'help': 'Install an application on a Cloudify Manager',
                'arguments': {
                    '-p,--blueprint-path':
                        make_optional(
                                remove_type(
                                        manager_blueprint_path_argument())
                        ),
                    '-b,--blueprint-id': remove_completer(
                            make_optional(blueprint_id_argument(
                            ))
                        ),
                    '--validate': validate_blueprint_argument(),
                    '-l,--archive-location': make_optional(
                            archive_location_argument()),
                    '-n,--blueprint-filename': {
                        'dest': 'blueprint_filename',
                        'help': "The name of the archive's main "
                                "blueprint file. Default: `{0}`"
                                .format(DEFAULT_BLUEPRINT_FILE_NAME)
                        },
                    '-d,--deployment-id': deployment_id_argument(
                            hlp='The id of the deployed blueprint'
                        ),
                    '-i,--inputs':
                        inputs_argument('Inputs file/string for the deployment'
                                        ' creation ({0}). Default: {1}'
                                        .format(FORMAT_INPUT_AS_YAML_OR_DICT,
                                                DEFAULT_INPUTS_PATH_FOR_INSTALL_COMMAND)
                                        ),
                    '-w,--workflow': make_optional(workflow_id_argument(
                            hlp='The workflow to start '
                                '(default: `{0}`)'
                                .format(DEFAULT_INSTALL_WORKFLOW)
                            )
                        ),
                    '--parameters': parameters_argument(),
                    '--allow-custom-parameters':
                        allow_custom_parameters_argument(),
                    '--timeout': timeout_argument(),
                    '--include-logs': include_logs_argument(),
                    '-g,--auto-generate-ids': auto_generate_ids_argument()
                },
                'handler': cfy.install
            },
            'uninstall': {
                'help': 'Uninstall an existing application '
                        'from the Cloudify Manager',
                'arguments': {
                    '-d,--deployment-id': make_required(
                            deployment_id_argument(
                                hlp='The id of the deployment you wish to '
                                    'uninstall'
                            )
                        ),
                    '-w,--workflow': make_optional(workflow_id_argument(
                            hlp='The workflow to start (default: `{0}`'
                                .format(DEFAULT_UNINSTALL_WORKFLOW))
                        ),
                    '--parameters': parameters_argument(),
                    '--allow-custom-parameters':
                        allow_custom_parameters_argument(),
                    '--timeout': timeout_argument(),
                    '-l,--include-logs': include_logs_argument()
                },
                'handler': cfy.uninstall
            },
            'plugins': {
                'help': "Manage Cloudify's plugins",
                'sub_commands': {
                    'upload': {
                        'arguments': {
                            '-p,--plugin-path': {
                                'metavar': 'PLUGIN_FILE',
                                'dest': 'plugin_path',
                                'type': argparse.FileType(),
                                'required': True,
                                'help': 'Path to a plugin Wagon (`.wgn` file)',
                                'completer': completion_utils.yaml_files_completer
                            }
                        },
                        'help': 'Upload a plugin to the management server',
                        'handler': cfy.plugins.upload
                    },
                    'get': {
                        'arguments': {
                            '-p,--plugin-id': plugin_id_argument(
                                hlp='Plugin id')
                        },
                        'help': 'List all modules according to their plugin id',
                        'handler': cfy.plugins.get
                    },
                    'download': {
                        'arguments': {
                            '-p,--plugin-id': plugin_id_argument(
                                hlp='Plugin id'),
                            '-o,--output': {
                                'help': 'Path for the downloaded plugin',
                                'dest': 'output',

                            }
                        },
                        'help': 'Download a plugin from the Manager',
                        'handler': cfy.plugins.download
                    },
                    'list': {
                        'help': 'List all the plugins on the Manager',
                        'handler': cfy.plugins.ls
                    },
                    'delete': {
                        'arguments': {
                            '-p,--plugin-id': plugin_id_argument(
                                hlp='The plugin id')
                        },
                        'help': 'Delete a plugin from the manager',
                        'handler': cfy.plugins.delete
                    }
                }
            },
            'blueprints': {
                'help': "Manage Cloudify's Blueprints",
                'sub_commands': {
                    'upload': {
                        'arguments': {
                            '-p,--blueprint-path':
                                manager_blueprint_path_argument(),
                            '-b,--blueprint-id': remove_completer(
                                    blueprint_id_argument()),
                            '--validate': validate_blueprint_argument()
                        },
                        'help': 'Upload a blueprint to the Manager',
                        'handler': cfy.blueprints.upload
                    },
                    'publish-archive': {
                        'arguments': {
                            '-l,--archive-location': archive_location_argument(),
                            '-n,--blueprint-filename': {
                                'dest': 'blueprint_filename',
                                'help': "The name of the archive's main "
                                        "blueprint file"
                            },
                            '-b,--blueprint-id': remove_completer(blueprint_id_argument())
                        },
                        'help': 'Publish a blueprint archive from a path or '
                                'a URL to the Manager',
                        'handler': cfy.blueprints.publish_archive
                    },
                    'download': {
                        'arguments': {
                            '-b,--blueprint-id': blueprint_id_argument(),
                            '-o,--output': {
                                'help': 'The output file path of the blueprint to be downloaded',
                                'dest': 'output',
                            }
                        },
                        'help': 'Download a blueprint from the Manager',
                        'handler': cfy.blueprints.download
                    },
                    'list': {
                        'help': 'List all blueprints on the '
                                'Manager',
                        'handler': cfy.blueprints.ls
                    },
                    'delete': {
                        'arguments': {
                            '-b,--blueprint-id': blueprint_id_argument()
                        },
                        'help': 'Delete a blueprint from the manager',
                        'handler': cfy.blueprints.delete
                    },
                    'validate': {
                        'arguments': {
                            '-p,--blueprint-path':
                                manager_blueprint_path_argument(),
                        },
                        'help': 'Validate a blueprint',
                        'handler': cfy.blueprints.validate
                    },
                    'get': {
                        'arguments': {
                            '-b,--blueprint-id': blueprint_id_argument()
                        },
                        'help': 'Get a blueprint by its id',
                        'handler': cfy.blueprints.get
                    },
                    'inputs': {
                        'arguments': {
                            '-b,--blueprint-id': blueprint_id_argument()
                        },
                        'help': "List a blueprint's inputs",
                        'handler': cfy.blueprints.inputs
                    }
                }
            },
            'snapshots': {
                'help': "Manages Cloudify's Snapshots",
                'sub_commands': {
                    'create': {
                        'arguments': {
                            '-s,--snapshot-id': remove_completer(
                                snapshot_id_argument(
                                    hlp='A unique id that will be assigned to the created snapshot'
                                )
                            ),
                            '--include-metrics': {
                                'dest': 'include_metrics',
                                'action': 'store_true',
                                'help': 'Include metrics data'
                                        'in the snapshot'
                            },
                            '--exclude-credentials': {
                                'dest': 'exclude_credentials',
                                'action': 'store_true',
                                'help': 'Do not store credentials in snapshot'
                            }
                        },
                        'help': 'Create a new snapshot',
                        'handler': cfy.snapshots.create
                    },
                    'upload': {
                        'arguments': {
                            '-p,--snapshot-path': {
                                'metavar': 'SNAPSHOT_FILE',
                                'dest': 'snapshot_path',
                                'type': argparse.FileType(),
                                'required': True,
                                'help': "Path to the manager's snapshot file",
                                'completer': completion_utils.yaml_files_completer
                            },
                            '-s,--snapshot-id': remove_completer(snapshot_id_argument('The id of the snapshot'))
                        },
                        'help': 'Upload a snapshot to the Manager',
                        'handler': cfy.snapshots.upload
                    },
                    'download': {
                        'arguments': {
                            '-s,--snapshot-id': snapshot_id_argument('The id of the snapshot'),
                            '-o,--output': {
                                'help': 'The output file path of the snapshot to be downloaded',
                                'dest': 'output',

                            }
                        },
                        'help': 'Download a snapshot from the Manager',
                        'handler': cfy.snapshots.download
                    },
                    'list': {
                        'help': 'List all snapshots on the Manager',
                        'handler': cfy.snapshots.ls
                    },
                    'delete': {
                        'arguments': {
                            '-s,--snapshot-id': snapshot_id_argument('The id of the snapshot')
                        },
                        'help': 'Delete a snapshot from the manager',
                        'handler': cfy.snapshots.delete
                    },
                    'restore': {
                        'arguments': {
                            '-s,--snapshot-id': snapshot_id_argument('The id of the snapshot'),
                            '--without-deployments-envs': {
                                'dest': 'without_deployments_envs',
                                'action': 'store_true',
                                'help': 'Restore snapshot without deployment environments'
                            },
                            '-f,--force':
                                force_argument(
                                        hlp='Force restoring the snapshot on '
                                            'a Manager with existing blueprints'
                                            'and/or deployments')
                        },
                        'help': 'Restore manager state to a specific snapshot',
                        'handler': cfy.snapshots.restore
                    }
                }
            },
            'agents': {
                'help': "Manages Cloudify's Agents",
                'sub_commands': {
                    'install': {
                        'arguments': {
                            '-d,--deployment-id': deployment_id_argument(
                                hlp='The id of the deployment to install '
                                    'agents for. If omitted, this will '
                                    'install agents for all deployments'
                            ),
                            '-l,--include-logs': include_logs_argument()
                        },
                        'help':'Install agents on deployments',
                        'handler': cfy.agents.install
                    }
                }
            },
            'deployments': {
                'help': "Manage Cloudify's Deployments",
                'sub_commands': {
                    'create': {
                        'arguments': {
                            '-d,--deployment-id': remove_completer(
                                deployment_id_argument(
                                    hlp='A unique id that will be assigned to '
                                        'the created deployment'
                                )
                            ),
                            '-b,--blueprint-id': blueprint_id_argument(),
                            '-i,--inputs': inputs_argument(
                                hlp='Inputs file/string for the deployment'
                                    'creation ({0})'
                                    .format(FORMAT_INPUT_AS_YAML_OR_DICT))
                        },
                        'help': 'Create a deployment from a blueprint',
                        'handler': cfy.deployments.create
                    },
                    'delete': {
                        'arguments': {
                            '-d,--deployment-id': deployment_id_argument(
                                hlp='The id of the deployment to delete'),
                            '-f,--ignore-live-nodes': {
                                'dest': 'ignore_live_nodes',
                                'action': 'store_true',
                                'help': 'Delete the deployment even if '
                                        'there are existing live nodes for it'
                            }
                        },
                        'help': 'Delete a deployment from the manager',
                        'handler': cfy.deployments.delete
                    },
                    'list': {
                        'arguments': {
                            '-b,--blueprint-id': make_optional(
                                blueprint_id_argument()
                            )
                        },
                        'help': 'List the all deployments on the manager, '
                                'or all deployments of a specific blueprint',
                        'handler': cfy.deployments.ls
                    },
                    'outputs': {
                        'arguments': {
                            '-d,--deployment-id': deployment_id_argument(
                                hlp='The id of the deployment to get outputs '
                                    'for'
                            )
                        },
                        'help': 'Get outputs for a specific deployment',
                        'handler': cfy.deployments.outputs
                    }
                }
            },
            'events': {
                'help': "Manage Cloudify's events",
                'sub_commands': {
                    'list': {
                        'arguments': {
                            '-l,--include-logs': include_logs_argument(),
                            '-e,--execution-id': execution_id_argument(
                                hlp='The id of the execution to list events for'
                            ),
                            '--tail': {
                                'dest': 'tail',
                                'action': 'store_true',
                                'help': 'Tail the events of the specified execution until it ends'
                            }
                        },
                        'help': 'Display Events for different executions',
                        'handler': cfy.events.ls
                    }
                }
            },
            'executions': {
                'help': "Manage Cloudify's Executions",
                'sub_commands': {
                    'get': {
                        'arguments': {
                            '-e,--execution-id': execution_id_argument(
                                hlp='The id of the execution to get'
                            )
                        },
                        'help': 'Get an execution by its id',
                        'handler': cfy.executions.get
                    },
                    'list': {
                        'arguments': {
                            '-d,--deployment-id': deployment_id_argument(
                                hlp='The Deployment id to list executions for'
                            ),
                            '--system-workflows': {
                                'dest': 'include_system_workflows',
                                'action': 'store_true',
                                'help': 'Include executions of '
                                        'system workflows'
                            },
                        },
                        'help': 'List all running executions, or all '
                                'executions for a specific deployment',
                        'handler': cfy.executions.ls
                    },
                    'start': {
                        'arguments': {
                            '-w,--workflow': workflow_id_argument(
                                hlp='The workflow to start'),
                            '-p,--parameters': parameters_argument(),
                            '--allow-custom-parameters':
                                allow_custom_parameters_argument(),
                            '--timeout': timeout_argument(),
                            '-f,--force':
                                force_argument(
                                        hlp='Execute the workflow even if '
                                            'there is an ongoing execution for'
                                            'the given deployment'
                                ),
                            '-l,--include-logs': include_logs_argument(),
                            '-d,--deployment-id': deployment_id_argument(
                                hlp='The deployment id')
                        },
                        'help': 'Start executing a workflow '
                                'on a given deployment',
                        'handler': cfy.executions.start
                    },
                    'cancel': {
                        'arguments': {
                            '-e,--execution-id': execution_id_argument(
                                hlp='The id of the execution to cancel'
                            ),
                            '-f,--force': force_argument(
                                    hlp='Terminate the execution abruptly, '
                                        'rather than request an orderly '
                                        'termination')
                        },
                        'help': 'Cancel an execution by its id',
                        'handler': cfy.executions.cancel
                    }
                }
            },
            'nodes': {
                'help': 'Manage nodes',
                'sub_commands': {
                    'get': {
                        'arguments': {
                            '--node-id': {
                                'dest': 'node_id',
                                'required': True,
                                'help': "The node's id"
                            },
                            '-d,--deployment-id': make_required(
                                    deployment_id_argument(
                                            hlp='The deployment id to which '
                                                'the node is related'))
                        },
                        'help': 'Get information about a specific node',
                        'handler': cfy.nodes.get
                    },
                    'list': {
                        'arguments': {
                            '-d,--deployment-id': deployment_id_argument(
                                    hlp='The id of the deployment to list '
                                        'nodes for. If omitted, this will '
                                        'list nodes for all deployments')
                        },
                        'help': 'List nodes for all deployments, or for a '
                                'specific deployment',
                        'handler': cfy.nodes.ls
                    }
                }
            },
            'node-instances': {
                'help': 'Manage node instances',
                'sub_commands': {
                    'get': {
                        'arguments': {
                            '--node-instance-id': {
                                'dest': 'node_instance_id',
                                'required': True,
                                'help': 'The ID of the node instance to get'
                            }
                        },
                        'help': "Get a node instance according to its ID",
                        'handler': cfy.node_instances.get
                    },
                    'list': {
                        'arguments': {
                            '-d,--deployment-id': deployment_id_argument(
                                    hlp='The id of the deployment to list '
                                        'node instances for. If omitted, '
                                        'this will list node instances'
                                        'for all deployments)'),
                            '--node-name': {
                                'dest': 'node_name',
                                'help': "The node's name"
                            }
                        },
                        'help': 'List node instances for all deployments,'
                                'or for a specific deployment',
                        'handler': cfy.node_instances.ls
                    }
                }
            },
            'workflows': {
                'help': 'Manage Deployment Workflows',
                'sub_commands': {
                    'get': {
                        'arguments': {
                            '-d,--deployment-id': deployment_id_argument(
                                hlp='The id of the deployment to which the '
                                    'workflow belongs'
                            ),
                            '-w,--workflow': workflow_id_argument(
                                hlp='The id of the workflow to get'
                            )
                        },
                        'help': 'Get a workflow by its name and deployment',
                        'handler': cfy.workflows.get
                    },
                    'list': {
                        'arguments': {
                            '-d,--deployment-id': deployment_id_argument(
                                hlp='The id of the deployment whose workflows '
                                    'to list'
                            )
                        },
                        'help': 'List workflows for a deployment',
                        'handler': cfy.workflows.ls
                    }
                }
            },
            'local': {
                'help': 'Manage local workflows',
                'sub_commands': {
                    'install': {
                        'help': 'Install an application',
                        'arguments': {
                            '-p,--blueprint-path':
                                make_optional(
                                        local_blueprint_path_argument(
                                                hlp="Path to the application's"
                                                    "blueprint file. Default: "
                                                    "`{0}`".format(DEFAULT_BLUEPRINT_PATH)
                                        )
                                ),
                            '-i,--inputs':
                                inputs_argument('Inputs file/string for the '
                                                'deployment creation ({0}). '
                                                'Default: {1}'
                                                .format(FORMAT_INPUT_AS_YAML_OR_DICT,
                                                        DEFAULT_INPUTS_PATH_FOR_INSTALL_COMMAND)
                                                ),
                            '--install-plugins': install_plugins_argument(),
                            '-w,--workflow': make_optional(
                                    workflow_id_argument(
                                            hlp='The workflow to start '
                                                '(default: `{0}`'
                                                .format(DEFAULT_INSTALL_WORKFLOW)
                                    )
                                ),
                            '--parameters': parameters_argument(),
                            '--allow-custom-parameters':
                                allow_custom_parameters_argument(),
                            '--task-retries': task_retries_argument(0),
                            '--task-retry-interval':
                                task_retry_interval_argument(1),
                            '--task-thread-pool-size':
                                task_thread_pool_size_argument()
                        },
                        'handler': cfy.local.install
                    },
                    'uninstall': {
                        'help': 'Uninstall an application',
                        'arguments': {
                            '-w,--workflow': make_optional(
                                    workflow_id_argument(
                                            hlp='The workflow to start '
                                                '(default: `{0}`'
                                                .format(DEFAULT_UNINSTALL_WORKFLOW)
                                    )
                                ),
                            '--parameters': parameters_argument(),
                            '--allow-custom-parameters':
                                allow_custom_parameters_argument(),
                            '--task-retries': task_retries_argument(0),
                            '--task-retry-interval':
                                task_retry_interval_argument(1),
                            '--task-thread-pool-size':
                                task_thread_pool_size_argument()
                        },
                        'handler': cfy.local.uninstall
                    },
                    'init': {
                        'help': 'Init a local workflow execution environment '
                                'in the current working directory',
                        'arguments': {
                            '-p,--blueprint-path':
                                local_blueprint_path_argument(
                                        hlp='Path to a blueprint'
                                ),
                            '-i,--inputs': inputs_argument(
                                    hlp='Inputs file/string for the local '
                                        'workflow creation ({0})'
                                        .format(FORMAT_INPUT_AS_YAML_OR_DICT)
                                ),
                            '--install-plugins': install_plugins_argument()
                        },
                        'handler': cfy.local.init
                    },
                    'install-plugins': {
                        'help': 'Install the necessary plugins for a given blueprint',
                        'arguments': {
                            '-p,--blueprint-path':
                                local_blueprint_path_argument(
                                        hlp='Path to a blueprint'
                                ),
                        },
                        'handler': cfy.local.install_plugins
                    },
                    'create-requirements': {
                        'help': 'Create a pip-compliant requirements file for a given blueprint',
                        'arguments': {
                            '-p,--blueprint-path':
                                local_blueprint_path_argument(
                                        hlp='Path to a blueprint'
                                ),
                            '-o,--output': {
                                'metavar': 'REQUIREMENTS_OUTPUT',
                                'dest': 'output',
                                'help': 'Path to a file that will hold the '
                                        'requirements of the blueprint'
                            }
                        },
                        'handler': cfy.local.create_requirements
                    },
                    'execute': {
                        'help': 'Execute a workflow locally',
                        'arguments': {
                            '-w,--workflow':
                                remove_completer(
                                    workflow_id_argument(
                                        hlp='The workflow to execute locally'))
                            ,
                            '-p,--parameters': parameters_argument(),
                            '--allow-custom-parameters':
                                allow_custom_parameters_argument(),
                            '--task-retries': task_retries_argument(0),
                            '--task-retry-interval':
                                task_retry_interval_argument(1),
                            '--task-thread-pool-size':
                                task_thread_pool_size_argument()
                        },
                        'handler': cfy.local.execute
                    },
                    'outputs': {
                        'help': 'Display outputs',
                        'arguments': {},
                        'handler': cfy.local.outputs
                    },
                    'instances': {
                        'help': 'Display node instances',
                        'arguments': {
                            '--node-id': {
                                'dest': 'node_id',
                                'help': 'Display only node instances of this node id'
                            }
                        },
                        'handler': cfy.local.instances
                    }
                }
            },
            'status': {
                'help': "Show the Manager's status",
                'handler': cfy.status
            },
            'dev': {
                'help': 'Executes fabric tasks on the management machine',
                'arguments': {
                    '-t,--task': {
                        'dest': 'task',
                        'help': 'Name of fabric task to run',
                        'completer': completion_utils.dev_task_name_completer
                    },
                    '-a,--args': {
                        'nargs': argparse.REMAINDER,
                        'dest': 'args',
                        'help': 'Arguments for the fabric task'
                    },
                    '-p,--tasks-file': {
                        'dest': 'tasks_file',
                        'help': 'Path to a tasks file',
                    }
                },
                'handler': cfy.dev
            },
            'ssh': {
                'help': 'SSH to the machine the Manager is located on',
                'arguments': {
                    '-c,--command': {
                        'dest': 'ssh_command',
                        'metavar': 'COMMAND',
                        'help': 'Execute command over SSH'
                    },
                    '-p,--plain': {
                        'dest': 'ssh_plain_mode',
                        'action': 'store_true',
                        'help': 'Leave authentication to user'
                    }
                },
                'handler': cfy.ssh
            },
            'bootstrap': {
                'help': 'Bootstrap a Cloudify Manager',
                'arguments': {
                    '-p,--blueprint-path':
                        local_blueprint_path_argument(
                                hlp='Path to a blueprint'
                        ),
                    '-i,--inputs': inputs_argument(
                        hlp='Inputs file/string for a manager blueprint ({0})'
                            .format(FORMAT_INPUT_AS_YAML_OR_DICT)
                    ),
                    '--keep-up-on-failure': {
                        'dest': 'keep_up',
                        'action': 'store_true',
                        'help': 'If the bootstrap fails,'
                                ' the Manager will remain running'
                    },
                    '--skip-validations': {
                        'dest': 'skip_validations',
                        'action': 'store_true',
                        'help': 'Run bootstrap without '
                                'validating resources prior to bootstrapping the manager'
                    },
                    '--validate-only': {
                        'dest': 'validate_only',
                        'action': 'store_true',
                        'help': 'Run validations without '
                                'actually performing the bootstrap process'
                    },
                    '--install-plugins': install_plugins_argument(),
                    '--task-retries': task_retries_argument(5),
                    '--task-retry-interval': task_retry_interval_argument(30),
                    '--task-thread-pool-size':
                        task_thread_pool_size_argument()
                },
                'handler': cfy.bootstrap
            },
            'teardown': {
                'help': 'Teardown Cloudify',
                'arguments': {
                    '--ignore-deployments': {
                        'dest': 'ignore_deployments',
                        'action': 'store_true',
                        'help': 'Perform teardown even if deployments'
                                'exist on the manager'
                    },
                    '-f,--force': force_argument(
                            hlp='Confirmation for the teardown request')
                },
                'handler': cfy.teardown
            },
            'recover': {
                'help': 'Perform recovery of the management machine '
                        'and all its contained nodes',
                'arguments': {
                    '-f,--force': force_argument(
                            hlp='Confirmation for the recovery request'
                    ),
                    '--task-retries': task_retries_argument(5),
                    '--task-retry-interval': task_retry_interval_argument(30),
                    '--task-thread-pool-size':
                        task_thread_pool_size_argument(),
                    '-s,--snapshot-path': {
                        'dest': 'snapshot_path',
                        'type': argparse.FileType(),
                        'help': 'Path to the snapshot that will be restored'
                    }
                },
                'handler': cfy.recover
            },
            'use': {
                'help': 'Use/switch to a specific Cloudify Manager',
                'arguments': {
                    '-t,--management-ip': {
                        'help': "The Cloudify Manager ip's address",
                        'dest': 'management_ip',
                        'required': True
                    },
                    '--port': {
                        'help': "The rest server's port",
                        'default': DEFAULT_REST_PORT,
                        'type': int,
                        'dest': 'rest_port'
                    }
                },
                'handler': cfy.use
            },
            'init': {
                'help': 'Initialize cfy work environment',
                'arguments': {
                    '-r,--reset-config': {
                        'dest': 'reset_config',
                        'action': 'store_true',
                        'help': 'Overwriting existing configuration is allowed'
                    },
                },
                'handler': cfy.init
            }
        }
    }