Esempio n. 1
0
    def test_wait_for_installation(self):
        count_installations_mock = MagicMock(side_effect=[0, 1])
        url_mock = MagicMock(return_value='/bundle-events/endpoint')
        get_events_mock = MagicMock(return_value=[
            create_test_event(None),
            create_test_event('bundleInstallationAdded'),
            create_test_event('bundleInstallationAdded')
        ])

        stdout = MagicMock()

        bundle_id = 'a101449418187d92c789d1adc240b6d6'
        args = MagicMock(**{'wait_timeout': 10})
        with patch('conductr_cli.conduct_url.url', url_mock), \
                patch('conductr_cli.bundle_installation.count_installations', count_installations_mock), \
                patch('conductr_cli.sse_client.get_events', get_events_mock):
            logging_setup.configure_logging(args, stdout)
            bundle_installation.wait_for_installation(bundle_id, args)

        self.assertEqual(count_installations_mock.call_args_list,
                         [call(bundle_id, args),
                          call(bundle_id, args)])

        url_mock.assert_called_with('bundles/events', args)

        self.assertEqual(
            strip_margin(
                """|Bundle a101449418187d92c789d1adc240b6d6 waiting to be installed
                                         |Bundle a101449418187d92c789d1adc240b6d6 installed
                                         |"""), self.output(stdout))
    def test_wait_for_installation(self):
        count_installations_mock = MagicMock(side_effect=[0, 1])
        url_mock = MagicMock(return_value='/bundle-events/endpoint')
        get_events_mock = MagicMock(return_value=[
            create_test_event(None),
            create_test_event('bundleInstallationAdded'),
            create_test_event('bundleInstallationAdded')
        ])

        stdout = MagicMock()

        bundle_id = 'a101449418187d92c789d1adc240b6d6'
        args = MagicMock(**{
            'wait_timeout': 10
        })
        with patch('conductr_cli.conduct_url.url', url_mock), \
                patch('conductr_cli.bundle_installation.count_installations', count_installations_mock), \
                patch('conductr_cli.sse_client.get_events', get_events_mock):
            logging_setup.configure_logging(args, stdout)
            bundle_installation.wait_for_installation(bundle_id, args)

        self.assertEqual(count_installations_mock.call_args_list, [
            call(bundle_id, args),
            call(bundle_id, args)
        ])

        url_mock.assert_called_with('bundles/events', args)

        self.assertEqual(strip_margin("""|Bundle a101449418187d92c789d1adc240b6d6 waiting to be installed
                                         |Bundle a101449418187d92c789d1adc240b6d6 installed
                                         |"""), self.output(stdout))
    def test_return_immediately_if_installed(self):
        count_installations_mock = MagicMock(side_effect=[3])
        conductr_host = '10.0.0.1'
        conductr_host_mock = MagicMock(return_value=conductr_host)
        get_events_mock = MagicMock(return_value=[])
        stdout = MagicMock()

        bundle_id = 'a101449418187d92c789d1adc240b6d6'
        args = MagicMock(**{
            'wait_timeout': 10,
            'conductr_auth': self.conductr_auth,
            'server_verification_file': self.server_verification_file
        })
        with patch('conductr_cli.bundle_installation.count_installations', count_installations_mock), \
                patch('conductr_cli.conduct_url.conductr_host', conductr_host_mock), \
                patch('conductr_cli.sse_client.get_events', get_events_mock):
            logging_setup.configure_logging(args, stdout)
            bundle_installation.wait_for_installation(bundle_id, args)

        self.assertEqual(count_installations_mock.call_args_list, [
            call(bundle_id, args)
        ])

        conductr_host_mock.assert_not_called()
        get_events_mock.assert_not_called()

        self.assertEqual(strip_margin("""|Bundle a101449418187d92c789d1adc240b6d6 is installed
                                         |"""), self.output(stdout))
    def test_return_immediately_if_installed(self):
        count_installations_mock = MagicMock(side_effect=[3])
        conductr_host = '10.0.0.1'
        conductr_host_mock = MagicMock(return_value=conductr_host)
        get_events_mock = MagicMock(return_value=[])
        stdout = MagicMock()

        bundle_id = 'a101449418187d92c789d1adc240b6d6'
        args = MagicMock(**{
            'wait_timeout': 10,
            'conductr_auth': self.conductr_auth,
            'server_verification_file': self.server_verification_file
        })
        with patch('conductr_cli.bundle_installation.count_installations', count_installations_mock), \
                patch('conductr_cli.conduct_url.conductr_host', conductr_host_mock), \
                patch('conductr_cli.sse_client.get_events', get_events_mock):
            logging_setup.configure_logging(args, stdout)
            bundle_installation.wait_for_installation(bundle_id, args)

        self.assertEqual(count_installations_mock.call_args_list, [
            call(bundle_id, args)
        ])

        conductr_host_mock.assert_not_called()
        get_events_mock.assert_not_called()

        self.assertEqual(strip_margin("""|Bundle a101449418187d92c789d1adc240b6d6 is installed
                                         |"""), self.output(stdout))
    def test_periodic_check_between_events(self):
        count_installations_mock = MagicMock(side_effect=[0, 0, 1])
        url_mock = MagicMock(return_value='/bundle-events/endpoint')
        conductr_host = '10.0.0.1'
        conductr_host_mock = MagicMock(return_value=conductr_host)
        get_events_mock = MagicMock(return_value=[
            create_heartbeat_event(),
            create_test_event('bundleInstallationAdded'),
            create_heartbeat_event(),
            create_heartbeat_event(),
            create_heartbeat_event(),
            create_test_event('bundleInstallationAdded')
        ])

        stdout = MagicMock()
        is_tty_mock = MagicMock(return_value=True)

        bundle_id = 'a101449418187d92c789d1adc240b6d6'
        dcos_mode = True
        args = MagicMock(**{
            'dcos_mode': dcos_mode,
            'wait_timeout': 10,
            'conductr_auth': self.conductr_auth,
            'server_verification_file': self.server_verification_file
        })
        with patch('conductr_cli.conduct_url.url', url_mock), \
                patch('conductr_cli.conduct_url.conductr_host', conductr_host_mock), \
                patch('conductr_cli.bundle_installation.count_installations', count_installations_mock), \
                patch('conductr_cli.sse_client.get_events', get_events_mock), \
                patch('sys.stdout.isatty', is_tty_mock):
            logging_setup.configure_logging(args, stdout)
            bundle_installation.wait_for_installation(bundle_id, args)

        self.assertEqual(count_installations_mock.call_args_list, [
            call(bundle_id, args),
            call(bundle_id, args),
            call(bundle_id, args)
        ])

        url_mock.assert_called_with('bundles/events', args)

        conductr_host_mock.assert_called_with(args)

        get_events_mock.assert_called_with(dcos_mode, conductr_host, '/bundle-events/endpoint', auth=self.conductr_auth,
                                           verify=self.server_verification_file)

        self.assertEqual(stdout.method_calls, [
            call.write('Bundle a101449418187d92c789d1adc240b6d6 waiting to be installed'),
            call.write('\n'),
            call.flush(),
            call.write('Bundle a101449418187d92c789d1adc240b6d6 still waiting to be installed\r'),
            call.write(''),
            call.flush(),
            call.write('Bundle a101449418187d92c789d1adc240b6d6 still waiting to be installed\n'),
            call.write(''),
            call.flush(),
            call.write('Bundle a101449418187d92c789d1adc240b6d6 installed'),
            call.write('\n'),
            call.flush(),
        ])
    def test_periodic_check_between_events(self):
        count_installations_mock = MagicMock(side_effect=[0, 0, 1])
        url_mock = MagicMock(return_value='/bundle-events/endpoint')
        conductr_host = '10.0.0.1'
        conductr_host_mock = MagicMock(return_value=conductr_host)
        get_events_mock = MagicMock(return_value=[
            create_heartbeat_event(),
            create_test_event('bundleInstallationAdded'),
            create_heartbeat_event(),
            create_heartbeat_event(),
            create_heartbeat_event(),
            create_test_event('bundleInstallationAdded')
        ])

        stdout = MagicMock()

        bundle_id = 'a101449418187d92c789d1adc240b6d6'
        dcos_mode = True
        args = MagicMock(**{
            'dcos_mode': dcos_mode,
            'wait_timeout': 10,
            'conductr_auth': self.conductr_auth,
            'server_verification_file': self.server_verification_file
        })
        with patch('conductr_cli.conduct_url.url', url_mock), \
                patch('conductr_cli.conduct_url.conductr_host', conductr_host_mock), \
                patch('conductr_cli.bundle_installation.count_installations', count_installations_mock), \
                patch('conductr_cli.sse_client.get_events', get_events_mock):
            logging_setup.configure_logging(args, stdout)
            bundle_installation.wait_for_installation(bundle_id, args)

        self.assertEqual(count_installations_mock.call_args_list, [
            call(bundle_id, args),
            call(bundle_id, args),
            call(bundle_id, args)
        ])

        url_mock.assert_called_with('bundles/events', args)

        conductr_host_mock.assert_called_with(args)

        get_events_mock.assert_called_with(dcos_mode, conductr_host, '/bundle-events/endpoint', auth=self.conductr_auth,
                                           verify=self.server_verification_file)

        self.assertEqual(stdout.method_calls, [
            call.write('Bundle a101449418187d92c789d1adc240b6d6 waiting to be installed'),
            call.write('\n'),
            call.flush(),
            call.write('Bundle a101449418187d92c789d1adc240b6d6 still waiting to be installed\r'),
            call.write(''),
            call.flush(),
            call.write('Bundle a101449418187d92c789d1adc240b6d6 still waiting to be installed\n'),
            call.write(''),
            call.flush(),
            call.write('Bundle a101449418187d92c789d1adc240b6d6 installed'),
            call.write('\n'),
            call.flush(),
        ])
Esempio n. 7
0
def load_v2(args):
    log = logging.getLogger(__name__)

    log.info('Retrieving bundle...')
    custom_settings = args.custom_settings
    resolve_cache_dir = args.resolve_cache_dir
    bundle_name, bundle_file = resolver.resolve_bundle(custom_settings, resolve_cache_dir, args.bundle)
    bundle_conf = bundle_utils.zip_entry('bundle.conf', bundle_file)

    if bundle_conf is None:
        raise MalformedBundleError('Unable to find bundle.conf within the bundle file')
    else:
        configuration_name, configuration_file, bundle_conf_overlay = (None, None, None)
        if args.configuration is not None:
            log.info('Retrieving configuration...')
            configuration_name, configuration_file = resolver.resolve_bundle(custom_settings, resolve_cache_dir,
                                                                             args.configuration)
            bundle_conf_overlay = bundle_utils.zip_entry('bundle.conf', configuration_file)

        files = [('bundleConf', ('bundle.conf', bundle_conf))]
        if bundle_conf_overlay is not None:
            files.append(('bundleConfOverlay', ('bundle.conf', bundle_conf_overlay)))
        files.append(('bundle', (bundle_name, open(bundle_file, 'rb'))))
        if configuration_file is not None:
            files.append(('configuration', (configuration_name, open(configuration_file, 'rb'))))

        url = conduct_url.url('bundles', args)

        log.info('Loading bundle to ConductR...')
        response = requests.post(url, files=files, timeout=LOAD_HTTP_TIMEOUT)
        validation.raise_for_status_inc_3xx(response)

        if log.is_verbose_enabled():
            log.verbose(validation.pretty_json(response.text))

        response_json = json.loads(response.text)
        bundle_id = response_json['bundleId'] if args.long_ids else bundle_utils.short_id(response_json['bundleId'])

        if not args.no_wait:
            bundle_installation.wait_for_installation(response_json['bundleId'], args)

        log.info('Bundle loaded.')
        log.info('Start bundle with: conduct run{} {}'.format(args.cli_parameters, bundle_id))
        log.info('Unload bundle with: conduct unload{} {}'.format(args.cli_parameters, bundle_id))
        log.info('Print ConductR info with: conduct info{}'.format(args.cli_parameters))

        if not log.is_info_enabled() and log.is_quiet_enabled():
            log.quiet(response_json['bundleId'])

    return True
Esempio n. 8
0
def load_v1(args):
    log = logging.getLogger(__name__)

    log.info('Retrieving bundle...')
    custom_settings = args.custom_settings
    resolve_cache_dir = args.resolve_cache_dir
    bundle_name, bundle_file = resolver.resolve_bundle(custom_settings, resolve_cache_dir, args.bundle)

    configuration_name, configuration_file = (None, None)
    if args.configuration is not None:
        log.info('Retrieving configuration...')
        configuration_name, configuration_file = resolver.resolve_bundle(custom_settings, resolve_cache_dir, args.configuration)

    bundle_conf = ConfigFactory.parse_string(bundle_utils.conf(bundle_file))
    overlay_bundle_conf = None if configuration_file is None else \
        ConfigFactory.parse_string(bundle_utils.conf(configuration_file))

    with_bundle_configurations = partial(apply_to_configurations, bundle_conf, overlay_bundle_conf)

    url = conduct_url.url('bundles', args)
    files = get_payload(bundle_name, bundle_file, with_bundle_configurations)
    if configuration_file is not None:
        files.append(('configuration', (configuration_name, open(configuration_file, 'rb'))))

    log.info('Loading bundle to ConductR...')
    response = requests.post(url, files=files, timeout=LOAD_HTTP_TIMEOUT)
    validation.raise_for_status_inc_3xx(response)

    if log.is_verbose_enabled():
        log.verbose(validation.pretty_json(response.text))

    response_json = json.loads(response.text)
    bundle_id = response_json['bundleId'] if args.long_ids else bundle_utils.short_id(response_json['bundleId'])

    if not args.no_wait:
        bundle_installation.wait_for_installation(response_json['bundleId'], args)

    log.info('Bundle loaded.')
    log.info('Start bundle with: conduct run{} {}'.format(args.cli_parameters, bundle_id))
    log.info('Unload bundle with: conduct unload{} {}'.format(args.cli_parameters, bundle_id))
    log.info('Print ConductR info with: conduct info{}'.format(args.cli_parameters))

    if not log.is_info_enabled() and log.is_quiet_enabled():
        log.quiet(response_json['bundleId'])

    return True
Esempio n. 9
0
    def test_return_immediately_if_installed(self):
        count_installations_mock = MagicMock(side_effect=[3])

        stdout = MagicMock()

        bundle_id = 'a101449418187d92c789d1adc240b6d6'
        args = MagicMock(**{'wait_timeout': 10})
        with patch('conductr_cli.bundle_installation.count_installations',
                   count_installations_mock):
            logging_setup.configure_logging(args, stdout)
            bundle_installation.wait_for_installation(bundle_id, args)

        self.assertEqual(count_installations_mock.call_args_list,
                         [call(bundle_id, args)])

        self.assertEqual(
            strip_margin(
                """|Bundle a101449418187d92c789d1adc240b6d6 is installed
                                         |"""), self.output(stdout))
    def test_return_immediately_if_installed(self):
        count_installations_mock = MagicMock(side_effect=[3])

        stdout = MagicMock()

        bundle_id = 'a101449418187d92c789d1adc240b6d6'
        args = MagicMock(**{
            'wait_timeout': 10
        })
        with patch('conductr_cli.bundle_installation.count_installations', count_installations_mock):
            logging_setup.configure_logging(args, stdout)
            bundle_installation.wait_for_installation(bundle_id, args)

        self.assertEqual(count_installations_mock.call_args_list, [
            call(bundle_id, args)
        ])

        self.assertEqual(strip_margin("""|Bundle a101449418187d92c789d1adc240b6d6 is installed
                                         |"""), self.output(stdout))
Esempio n. 11
0
def load_v1(args):
    log = logging.getLogger(__name__)

    log.info('Retrieving bundle...')
    custom_settings = args.custom_settings
    resolve_cache_dir = args.resolve_cache_dir
    bundle_name, bundle_file = resolver.resolve_bundle(custom_settings,
                                                       resolve_cache_dir,
                                                       args.bundle)

    configuration_name, configuration_file = (None, None)
    if args.configuration is not None:
        log.info('Retrieving configuration...')
        configuration_name, configuration_file = resolver.resolve_bundle(
            custom_settings, resolve_cache_dir, args.configuration)

    bundle_conf = ConfigFactory.parse_string(bundle_utils.conf(bundle_file))
    overlay_bundle_conf = None if configuration_file is None else \
        ConfigFactory.parse_string(bundle_utils.conf(configuration_file))

    with_bundle_configurations = partial(apply_to_configurations, bundle_conf,
                                         overlay_bundle_conf)

    url = conduct_url.url('bundles', args)
    files = get_payload(bundle_name, bundle_file, with_bundle_configurations)
    if configuration_file is not None:
        files.append(('configuration', (configuration_name,
                                        open(configuration_file, 'rb'))))

    log.info('Loading bundle to ConductR...')
    # At the time when this comment is being written, we need to pass the Host header when making HTTP request due to
    # a bug with requests python library not working properly when IPv6 address is supplied:
    # https://github.com/kennethreitz/requests/issues/3002
    # The workaround for this problem is to explicitly set the Host header when making HTTP request.
    # This fix is benign and backward compatible as the library would do this when making HTTP request anyway.
    response = requests.post(url,
                             files=files,
                             timeout=LOAD_HTTP_TIMEOUT,
                             headers=conduct_url.request_headers(args))
    validation.raise_for_status_inc_3xx(response)

    if log.is_verbose_enabled():
        log.verbose(validation.pretty_json(response.text))

    response_json = json.loads(response.text)
    bundle_id = response_json[
        'bundleId'] if args.long_ids else bundle_utils.short_id(
            response_json['bundleId'])

    if not args.no_wait:
        bundle_installation.wait_for_installation(response_json['bundleId'],
                                                  args)

    log.info('Bundle loaded.')
    log.info('Start bundle with: conduct run{} {}'.format(
        args.cli_parameters, bundle_id))
    log.info('Unload bundle with: conduct unload{} {}'.format(
        args.cli_parameters, bundle_id))
    log.info('Print ConductR info with: conduct info{}'.format(
        args.cli_parameters))

    if not log.is_info_enabled() and log.is_quiet_enabled():
        log.quiet(response_json['bundleId'])

    return True
Esempio n. 12
0
def load_v1(args):
    log = logging.getLogger(__name__)

    log.info('Retrieving bundle..')
    custom_settings = args.custom_settings
    bundle_resolve_cache_dir = args.bundle_resolve_cache_dir
    configuration_cache_dir = args.configuration_resolve_cache_dir

    validate_cache_dir_permissions(bundle_resolve_cache_dir,
                                   configuration_cache_dir, log)

    initial_bundle_file_name, bundle_file = resolver.resolve_bundle(
        custom_settings, bundle_resolve_cache_dir, args.bundle,
        args.offline_mode)

    configuration_file_name, configuration_file = (None, None)
    if args.configuration is not None:
        log.info('Retrieving configuration..')
        configuration_file_name, configuration_file = \
            resolver.resolve_bundle_configuration(custom_settings, configuration_cache_dir,
                                                  args.configuration, args.offline_mode)

    bundle_conf_text = bundle_utils.conf(bundle_file)

    bundle_conf = ConfigFactory.parse_string(bundle_conf_text)

    bundle_file_name, bundle_open_file = open_bundle(initial_bundle_file_name,
                                                     bundle_file,
                                                     bundle_conf_text)

    overlay_bundle_conf = None if configuration_file is None else \
        ConfigFactory.parse_string(bundle_utils.conf(configuration_file))

    with_bundle_configurations = partial(apply_to_configurations, bundle_conf,
                                         overlay_bundle_conf)

    url = conduct_url.url('bundles', args)
    files = get_payload(bundle_file_name, bundle_open_file,
                        with_bundle_configurations)
    if configuration_file is not None:
        open_configuration_file, config_digest = bundle_utils.digest_extract_and_open(
            configuration_file)
        files.append(('configuration', (configuration_file_name,
                                        open_configuration_file)))

    # TODO: Delete the bundle configuration file.
    # Currently, this results into a permission error on Windows.
    # Therefore, the deletion is disabled for now.
    # Issue: https://github.com/typesafehub/conductr-cli/issues/175
    # if configuration_file and os.path.exists(configuration_file):
    #    os.remove(configuration_file)

    log.info('Loading bundle to ConductR..')
    multipart = create_multipart(log, files)
    response = conduct_request.post(
        args.dcos_mode,
        conductr_host(args),
        url,
        data=multipart,
        auth=args.conductr_auth,
        verify=args.server_verification_file,
        headers={'Content-Type': multipart.content_type})
    validation.raise_for_status_inc_3xx(response)

    if log.is_verbose_enabled():
        log.verbose(validation.pretty_json(response.text))

    response_json = json.loads(response.text)
    bundle_id = response_json[
        'bundleId'] if args.long_ids else bundle_utils.short_id(
            response_json['bundleId'])

    if not args.no_wait:
        bundle_installation.wait_for_installation(response_json['bundleId'],
                                                  args)

    cleanup_old_bundles(bundle_resolve_cache_dir,
                        bundle_file_name,
                        excluded=bundle_file)

    log.info('Bundle loaded.')
    if not args.disable_instructions:
        log.info('Start bundle with:        {} run{} {}'.format(
            args.command, args.cli_parameters, bundle_id))
        log.info('Unload bundle with:       {} unload{} {}'.format(
            args.command, args.cli_parameters, bundle_id))
        log.info('Print ConductR info with: {} info{}'.format(
            args.command, args.cli_parameters))
        log.info('Print bundle info with:   {} info{} {}'.format(
            args.command, args.cli_parameters, bundle_id))

    if not log.is_info_enabled() and log.is_quiet_enabled():
        log.quiet(response_json['bundleId'])

    return True
Esempio n. 13
0
def load_v1(args):
    log = logging.getLogger(__name__)

    log.info('Retrieving bundle..')
    custom_settings = args.custom_settings
    resolve_cache_dir = args.resolve_cache_dir

    validate_cache_dir_permissions(resolve_cache_dir, log)

    bundle_file_name, bundle_file = resolver.resolve_bundle(custom_settings, resolve_cache_dir, args.bundle)

    configuration_file_name, configuration_file = (None, None)
    if args.configuration is not None:
        log.info('Retrieving configuration..')
        configuration_file_name, configuration_file = resolver.resolve_bundle_configuration(custom_settings,
                                                                                            resolve_cache_dir,
                                                                                            args.configuration)

    bundle_conf = ConfigFactory.parse_string(bundle_utils.conf(bundle_file))
    overlay_bundle_conf = None if configuration_file is None else \
        ConfigFactory.parse_string(bundle_utils.conf(configuration_file))

    with_bundle_configurations = partial(apply_to_configurations, bundle_conf, overlay_bundle_conf)

    url = conduct_url.url('bundles', args)
    files = get_payload(bundle_file_name, bundle_file, with_bundle_configurations)
    if configuration_file is not None:
        files.append(('configuration', (configuration_file_name, open(configuration_file, 'rb'))))

    # TODO: Delete the bundle configuration file.
    # Currently, this results into a permission error on Windows.
    # Therefore, the deletion is disabled for now.
    # Issue: https://github.com/typesafehub/conductr-cli/issues/175
    # if configuration_file and os.path.exists(configuration_file):
    #    os.remove(configuration_file)

    log.info('Loading bundle to ConductR..')
    multipart = create_multipart(log, files)
    response = conduct_request.post(args.dcos_mode, conductr_host(args), url,
                                    data=multipart,
                                    auth=args.conductr_auth,
                                    verify=args.server_verification_file,
                                    headers={'Content-Type': multipart.content_type})
    validation.raise_for_status_inc_3xx(response)

    if log.is_verbose_enabled():
        log.verbose(validation.pretty_json(response.text))

    response_json = json.loads(response.text)
    bundle_id = response_json['bundleId'] if args.long_ids else bundle_utils.short_id(response_json['bundleId'])

    if not args.no_wait:
        bundle_installation.wait_for_installation(response_json['bundleId'], args)

    cleanup_old_bundles(resolve_cache_dir, bundle_file_name, excluded=bundle_file)

    log.info('Bundle loaded.')
    if not args.disable_instructions:
        log.info('Start bundle with: {} run{} {}'.format(args.command, args.cli_parameters, bundle_id))
        log.info('Unload bundle with: {} unload{} {}'.format(args.command, args.cli_parameters, bundle_id))
        log.info('Print ConductR info with: {} info{}'.format(args.command, args.cli_parameters))

    if not log.is_info_enabled() and log.is_quiet_enabled():
        log.quiet(response_json['bundleId'])

    return True