def test(self):
        self.assertEqual(
            bundle_utils.short_id('45e0c477d3e5ea92aa8d85c0d8f3e25c'),
            '45e0c47')

        self.assertEqual(
            bundle_utils.short_id('c1ab77e63b722ef8c6ea8a1c274be053-3cc322b62e7608b5cdf37185240f7853'),
            'c1ab77e-3cc322b')
예제 #2
0
    def test(self):
        self.assertEqual(
            bundle_utils.short_id('45e0c477d3e5ea92aa8d85c0d8f3e25c'),
            '45e0c47')

        self.assertEqual(
            bundle_utils.short_id('c1ab77e63b722ef8c6ea8a1c274be053-3cc322b62e7608b5cdf37185240f7853'),
            'c1ab77e-3cc322b')
예제 #3
0
def stop(args):
    """`conduct stop` command"""

    log = logging.getLogger(__name__)
    path = 'bundles/{}?scale=0'.format(args.bundle)
    url = conduct_url.url(path, args)
    # 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.put(url,
                            timeout=DEFAULT_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'])

    log.info('Bundle stop request sent.')

    if not args.no_wait:
        bundle_scale.wait_for_scale(response_json['bundleId'], 0, args)

    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))

    return True
예제 #4
0
def get_acls_from_bundles(args, bundles):
    def is_started(bundle_executions):
        for execution in bundle_executions:
            if execution['isStarted']:
                return 'Running'
        return 'Starting'

    all_acls = [{
        'acl':
        acl,
        'bundle_id':
        bundle['bundleId']
        if args.long_ids else bundle_utils.short_id(bundle['bundleId']),
        'bundle_name':
        bundle['attributes']['bundleName'],
        'status':
        is_started(bundle['bundleExecutions'])
    } for bundle in bundles if bundle['bundleExecutions'] for endpoint_name,
                endpoint in bundle['bundleConfig']['endpoints'].items()
                if 'acls' in endpoint for acl in endpoint['acls']]

    http_acls = [acl for acl in all_acls if 'http' in acl['acl']]
    tcp_acls = [acl for acl in all_acls if 'tcp' in acl['acl']]

    return all_acls, http_acls, tcp_acls
예제 #5
0
def stop(args):
    """`conduct stop` command"""

    log = logging.getLogger(__name__)
    path = 'bundles/{}?scale=0'.format(args.bundle)
    url = conduct_url.url(path, args)
    # 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.put(url, timeout=DEFAULT_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'])

    log.info('Bundle stop request sent.')

    if not args.no_wait:
        bundle_scale.wait_for_scale(response_json['bundleId'], 0, args)

    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))

    return True
예제 #6
0
def stop(args):
    """`conduct stop` command"""

    log = logging.getLogger(__name__)
    path = "bundles/{}?scale=0".format(args.bundle)
    url = conduct_url.url(path, args)
    response = conduct_request.put(
        args.dcos_mode,
        conductr_host(args),
        url,
        auth=args.conductr_auth,
        verify=args.server_verification_file,
        timeout=DEFAULT_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"])

    log.info("Bundle stop request sent.")

    if not args.no_wait:
        bundle_scale.wait_for_scale(response_json["bundleId"], 0, args)

    if not args.disable_instructions:
        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))

    return True
예제 #7
0
def stop(args):
    """`conduct stop` command"""

    log = logging.getLogger(__name__)
    path = 'bundles/{}?scale=0'.format(args.bundle)
    url = conduct_url.url(path, args)
    response = conduct_request.put(args.dcos_mode,
                                   conductr_host(args),
                                   url,
                                   auth=args.conductr_auth,
                                   verify=args.server_verification_file,
                                   timeout=DEFAULT_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'])

    log.info('Bundle stop request sent.')

    if not args.no_wait:
        bundle_scale.wait_for_scale(response_json['bundleId'], 0, args)

    if not args.disable_instructions:
        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))

    return True
예제 #8
0
def request_deploy_confirmation(resolved_version, args):
    bundle_id = resolved_version['digest'] if args.long_ids else bundle_utils.short_id(resolved_version['digest'])
    user_input = input('Deploy {}:{}-{}? [Y/n]: '.format(resolved_version['package_name'],
                                                         resolved_version['compatibility_version'],
                                                         bundle_id))
    confirmation = (user_input if user_input else 'y').lower().strip()
    return confirmation == 'y' or confirmation == 'yes'
예제 #9
0
def services(args):
    """`conduct services` command"""

    log = logging.getLogger(__name__)
    url = conduct_url.url('bundles', args)
    # 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.get(url, timeout=DEFAULT_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))

    data = sorted([
                  (
                      {
                          'service': service,
                          'bundle_id': bundle['bundleId'] if args.long_ids else bundle_utils.short_id(
                              bundle['bundleId']),
                          'bundle_name': bundle['attributes']['bundleName'],
                          'status': 'Running' if execution['isStarted'] else 'Starting'
                      }
                  )
                  for bundle in json.loads(response.text)
                  for execution in bundle['bundleExecutions']
                  for endpoint_name, endpoint in bundle['bundleConfig']['endpoints'].items() if 'services' in endpoint
                  for service in endpoint['services']
                  ], key=lambda line: line['service'])

    service_endpoints = {}
    for service in data:
        url = urlparse(service['service'])
        if not (url.path == '' or url.path == '/'):
            try:
                service_endpoints[url.path] |= {service['service']}
            except KeyError:
                service_endpoints[url.path] = {service['service']}
    duplicate_endpoints = [service for (service, endpoint) in service_endpoints.items() if len(endpoint) > 1] \
        if len(service_endpoints) > 0 else []

    data.insert(0, {'service': 'SERVICE', 'bundle_id': 'BUNDLE ID', 'bundle_name': 'BUNDLE NAME', 'status': 'STATUS'})

    padding = 2
    column_widths = dict(screen_utils.calc_column_widths(data), **{'padding': ' ' * padding})
    for row in data:
        log.screen(
            '{service: <{service_width}}{padding}'
            '{bundle_id: <{bundle_id_width}}{padding}'
            '{bundle_name: <{bundle_name_width}}{padding}'
            '{status: <{status_width}}'.format(**dict(row, **column_widths)).rstrip())

    if len(duplicate_endpoints) > 0:
        log.screen('')
        log.warning('Multiple endpoints found for the following services: {}'.format(', '.join(duplicate_endpoints)))
        log.warning('Service resolution for these services is undefined.')

    return True
예제 #10
0
def run(args):
    """`conduct run` command"""

    log = logging.getLogger(__name__)

    if args.affinity is not None and args.api_version == '1':
        log.error('Affinity feature is only available for v1.1 onwards of ConductR')
        return
    elif args.affinity is not None:
        path = 'bundles/{}?scale={}&affinity={}'.format(args.bundle, args.scale, args.affinity)
    else:
        path = 'bundles/{}?scale={}'.format(args.bundle, args.scale)

    url = conduct_url.url(path, args)
    response = requests.put(url)
    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'])

    log.info('Bundle run request sent.')

    if not args.no_wait:
        bundle_scale.wait_for_scale(response_json['bundleId'], args.scale, args)

    log.info('Stop bundle with: conduct stop{} {}'.format(args.cli_parameters, bundle_id))
    log.info('Print ConductR info with: conduct info{}'.format(args.cli_parameters))

    return True
예제 #11
0
def request_deploy_confirmation(resolved_version, args):
    bundle_id = resolved_version[
        'digest'] if args.long_ids else bundle_utils.short_id(
            resolved_version['digest'])
    user_input = input('Deploy {}:{}-{}? [Y/n]: '.format(
        resolved_version['package_name'], resolved_version['tag'], bundle_id))
    confirmation = (user_input if user_input else 'y').lower().strip()
    return confirmation == 'y' or confirmation == 'yes'
예제 #12
0
def acls(args):
    """`conduct acls` command"""

    log = logging.getLogger(__name__)
    url = conduct_url.url('bundles', args)
    response = conduct_request.get(args.dcos_mode,
                                   conductr_host(args),
                                   url,
                                   timeout=DEFAULT_HTTP_TIMEOUT)
    validation.raise_for_status_inc_3xx(response)

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

    def get_system_version(bundle):
        if 'systemVersion' in bundle['attributes']:
            return bundle['attributes']['systemVersion']
        else:
            return bundle['attributes']['system'].split('-')[-1]

    def is_started(bundle_executions):
        for execution in bundle_executions:
            if execution['isStarted']:
                return 'Running'
        return 'Starting'

    all_acls = [{
        'acl':
        acl,
        'system':
        bundle['attributes']['system'],
        'system_version':
        get_system_version(bundle),
        'endpoint_name':
        endpoint_name,
        'bundle_id':
        bundle['bundleId']
        if args.long_ids else bundle_utils.short_id(bundle['bundleId']),
        'bundle_name':
        bundle['attributes']['bundleName'],
        'status':
        is_started(bundle['bundleExecutions'])
    } for bundle in json.loads(response.text) if bundle['bundleExecutions']
                for endpoint_name, endpoint in bundle['bundleConfig']
                ['endpoints'].items() if 'acls' in endpoint
                for acl in endpoint['acls']]

    if args.protocol_family == 'http':
        http_acls = [acl for acl in all_acls if 'http' in acl['acl']]
        display_http_acls(log, http_acls)

    elif args.protocol_family == 'tcp':
        tcp_acls = [acl for acl in all_acls if 'tcp' in acl['acl']]
        display_tcp_acls(log, tcp_acls)

    return True
예제 #13
0
def services(args):
    """`conduct services` command"""

    log = logging.getLogger(__name__)
    url = conduct_url.url('bundles', args)
    response = requests.get(url, timeout=DEFAULT_HTTP_TIMEOUT)
    validation.raise_for_status_inc_3xx(response)

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

    data = sorted([
                  (
                      {
                          'service': service,
                          'bundle_id': bundle['bundleId'] if args.long_ids else bundle_utils.short_id(
                              bundle['bundleId']),
                          'bundle_name': bundle['attributes']['bundleName'],
                          'status': 'Running' if execution['isStarted'] else 'Starting'
                      }
                  )
                  for bundle in json.loads(response.text)
                  for execution in bundle['bundleExecutions']
                  for endpoint_name, endpoint in bundle['bundleConfig']['endpoints'].items()
                  for service in endpoint['services']
                  ], key=lambda line: line['service'])

    service_endpoints = {}
    for service in data:
        url = urlparse(service['service'])
        if not (url.path == '' or url.path == '/'):
            try:
                service_endpoints[url.path] |= {service['service']}
            except KeyError:
                service_endpoints[url.path] = {service['service']}
    duplicate_endpoints = [service for (service, endpoint) in service_endpoints.items() if len(endpoint) > 1] \
        if len(service_endpoints) > 0 else []

    data.insert(0, {'service': 'SERVICE', 'bundle_id': 'BUNDLE ID', 'bundle_name': 'BUNDLE NAME', 'status': 'STATUS'})

    padding = 2
    column_widths = dict(screen_utils.calc_column_widths(data), **{'padding': ' ' * padding})
    for row in data:
        log.screen(
            '{service: <{service_width}}{padding}'
            '{bundle_id: <{bundle_id_width}}{padding}'
            '{bundle_name: <{bundle_name_width}}{padding}'
            '{status: <{status_width}}'.format(**dict(row, **column_widths)).rstrip())

    if len(duplicate_endpoints) > 0:
        log.screen('')
        log.warning('Multiple endpoints found for the following services: {}'.format(', '.join(duplicate_endpoints)))
        log.warning('Service resolution for these services is undefined.')

    return True
예제 #14
0
def acls(args):
    """`conduct acls` command"""

    log = logging.getLogger(__name__)
    url = conduct_url.url('bundles', args)
    # 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.get(url,
                            timeout=DEFAULT_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))

    def get_system_version(bundle):
        if 'systemVersion' in bundle['attributes']:
            return bundle['attributes']['systemVersion']
        else:
            return bundle['attributes']['system'].split('-')[-1]

    all_acls = [{
        'acl':
        acl,
        'system':
        bundle['attributes']['system'],
        'system_version':
        get_system_version(bundle),
        'endpoint_name':
        endpoint_name,
        'bundle_id':
        bundle['bundleId']
        if args.long_ids else bundle_utils.short_id(bundle['bundleId']),
        'bundle_name':
        bundle['attributes']['bundleName'],
        'status':
        'Running' if execution['isStarted'] else 'Starting'
    } for bundle in json.loads(response.text)
                for execution in bundle['bundleExecutions'] for endpoint_name,
                endpoint in bundle['bundleConfig']['endpoints'].items()
                if 'acls' in endpoint for acl in endpoint['acls']]

    if args.protocol_family == 'http':
        http_acls = [acl for acl in all_acls if 'http' in acl['acl']]
        display_http_acls(log, http_acls)

    elif args.protocol_family == 'tcp':
        tcp_acls = [acl for acl in all_acls if 'tcp' in acl['acl']]
        display_tcp_acls(log, tcp_acls)

    return True
예제 #15
0
def info(args):
    """`conduct info` command"""

    log = logging.getLogger(__name__)
    url = conduct_url.url("bundles", args)
    response = conduct_request.get(
        args.dcos_mode,
        conductr_host(args),
        url,
        auth=args.conductr_auth,
        verify=args.server_verification_file,
        timeout=DEFAULT_HTTP_TIMEOUT,
    )
    validation.raise_for_status_inc_3xx(response)

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

    data = [
        {
            "id": ("! " if bundle.get("hasError", False) else "")
            + (bundle["bundleId"] if args.long_ids else bundle_utils.short_id(bundle["bundleId"])),
            "name": bundle["attributes"]["bundleName"],
            "replications": len(bundle["bundleInstallations"]),
            "starting": sum([not execution["isStarted"] for execution in bundle["bundleExecutions"]]),
            "executions": sum([execution["isStarted"] for execution in bundle["bundleExecutions"]]),
        }
        for bundle in json.loads(response.text)
    ]
    data.insert(0, {"id": "ID", "name": "NAME", "replications": "#REP", "starting": "#STR", "executions": "#RUN"})

    padding = 2
    column_widths = dict(screen_utils.calc_column_widths(data), **{"padding": " " * padding})
    has_error = False
    for row in data:
        has_error |= "!" in row["id"]
        log.screen(
            """\
{id: <{id_width}}{padding}\
{name: <{name_width}}{padding}\
{replications: >{replications_width}}{padding}\
{starting: >{starting_width}}{padding}\
{executions: >{executions_width}}""".format(
                **dict(row, **column_widths)
            ).rstrip()
        )

    if has_error:
        log.screen("There are errors: use `conduct events` or `conduct logs` for further information")

    return True
예제 #16
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
예제 #17
0
def run(args):
    """`conduct run` command"""

    log = logging.getLogger(__name__)

    if args.affinity is not None and args.api_version == '1':
        log.error(
            'Affinity feature is only available for v1.1 onwards of ConductR')
        return
    elif args.affinity is not None:
        path = 'bundles/{}?scale={}&affinity={}'.format(
            args.bundle, args.scale, args.affinity)
    else:
        path = 'bundles/{}?scale={}'.format(args.bundle, args.scale)

    url = conduct_url.url(path, args)
    response = conduct_request.put(args.dcos_mode,
                                   conductr_host(args),
                                   url,
                                   auth=args.conductr_auth,
                                   verify=args.server_verification_file)
    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'])

    log.info('Bundle run request sent.')

    if not args.no_wait:
        bundle_scale.wait_for_scale(response_json['bundleId'],
                                    args.scale,
                                    wait_for_is_active=True,
                                    args=args)

    if not args.disable_instructions:
        log.info('Stop bundle with:         {} stop{} {}'.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))

    return True
예제 #18
0
def acls(args):
    """`conduct acls` command"""

    log = logging.getLogger(__name__)
    url = conduct_url.url('bundles', args)
    response = conduct_request.get(args.dcos_mode, conductr_host(args), url, timeout=DEFAULT_HTTP_TIMEOUT)
    validation.raise_for_status_inc_3xx(response)

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

    def get_system_version(bundle):
        if 'systemVersion' in bundle['attributes']:
            return bundle['attributes']['systemVersion']
        else:
            return bundle['attributes']['system'].split('-')[-1]

    def is_started(bundle_executions):
        for execution in bundle_executions:
            if execution['isStarted']:
                return 'Running'
        return 'Starting'

    all_acls = [
        {
            'acl': acl,
            'system': bundle['attributes']['system'],
            'system_version': get_system_version(bundle),
            'endpoint_name': endpoint_name,
            'bundle_id': bundle['bundleId'] if args.long_ids else bundle_utils.short_id(bundle['bundleId']),
            'bundle_name': bundle['attributes']['bundleName'],
            'status': is_started(bundle['bundleExecutions'])
        }
        for bundle in json.loads(response.text) if bundle['bundleExecutions']
        for endpoint_name, endpoint in bundle['bundleConfig']['endpoints'].items() if 'acls' in endpoint
        for acl in endpoint['acls']
    ]

    if args.protocol_family == 'http':
        http_acls = [acl for acl in all_acls if 'http' in acl['acl']]
        display_http_acls(log, http_acls)

    elif args.protocol_family == 'tcp':
        tcp_acls = [acl for acl in all_acls if 'tcp' in acl['acl']]
        display_tcp_acls(log, tcp_acls)

    return True
예제 #19
0
def acls(args):
    """`conduct acls` command"""

    log = logging.getLogger(__name__)
    url = conduct_url.url('bundles', args)
    # 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.get(url, timeout=DEFAULT_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))

    def get_system_version(bundle):
        if 'systemVersion' in bundle['attributes']:
            return bundle['attributes']['systemVersion']
        else:
            return bundle['attributes']['system'].split('-')[-1]

    all_acls = [
        {
            'acl': acl,
            'system': bundle['attributes']['system'],
            'system_version': get_system_version(bundle),
            'endpoint_name': endpoint_name,
            'bundle_id': bundle['bundleId'] if args.long_ids else bundle_utils.short_id(bundle['bundleId']),
            'bundle_name': bundle['attributes']['bundleName'],
            'status': 'Running' if execution['isStarted'] else 'Starting'
        }
        for bundle in json.loads(response.text)
        for execution in bundle['bundleExecutions']
        for endpoint_name, endpoint in bundle['bundleConfig']['endpoints'].items() if 'acls' in endpoint
        for acl in endpoint['acls']
    ]

    if args.protocol_family == 'http':
        http_acls = [acl for acl in all_acls if 'http' in acl['acl']]
        display_http_acls(log, http_acls)

    elif args.protocol_family == 'tcp':
        tcp_acls = [acl for acl in all_acls if 'tcp' in acl['acl']]
        display_tcp_acls(log, tcp_acls)

    return True
예제 #20
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
예제 #21
0
def stop(args):
    """`conduct stop` command"""

    path = "bundles/{}?scale=0".format(args.bundle)
    url = conduct_url.url(path, args)
    response = requests.put(url)
    conduct_logging.raise_for_status_inc_3xx(response)

    if args.verbose:
        conduct_logging.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"])

    print("Bundle stop request sent.")
    print("Unload bundle with: conduct unload{} {}".format(args.cli_parameters, bundle_id))
    print("Print ConductR info with: conduct info{}".format(args.cli_parameters))
예제 #22
0
def run(args):
    """`conduct run` command"""

    path = 'bundles/{}?scale={}'.format(args.bundle, args.scale)
    url = conduct_url.url(path, args)
    response = requests.put(url)
    conduct_logging.raise_for_status_inc_3xx(response)

    if args.verbose:
        conduct_logging.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'])

    print('Bundle run request sent.')
    print('Stop bundle with: conduct stop{} {}'.format(args.cli_parameters, bundle_id))
    print('Print ConductR info with: conduct info{}'.format(args.cli_parameters))
예제 #23
0
def run(args):
    """`conduct run` command"""

    log = logging.getLogger(__name__)

    if args.affinity is not None and args.api_version == '1':
        log.error(
            'Affinity feature is only available for v1.1 onwards of ConductR')
        return
    elif args.affinity is not None:
        path = 'bundles/{}?scale={}&affinity={}'.format(
            args.bundle, args.scale, args.affinity)
    else:
        path = 'bundles/{}?scale={}'.format(args.bundle, args.scale)

    url = conduct_url.url(path, args)
    # 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.put(url, 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'])

    log.info('Bundle run request sent.')

    if not args.no_wait:
        bundle_scale.wait_for_scale(response_json['bundleId'], args.scale,
                                    args)

    log.info('Stop bundle with: conduct stop{} {}'.format(
        args.cli_parameters, bundle_id))
    log.info('Print ConductR info with: conduct info{}'.format(
        args.cli_parameters))

    return True
예제 #24
0
def info(args):
    """`conduct info` command"""

    log = logging.getLogger(__name__)
    url = conduct_url.url('bundles', args)
    # 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.get(url, timeout=DEFAULT_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))

    data = [
        {
            'id': ('! ' if bundle.get('hasError', False) else '') +
                  (bundle['bundleId'] if args.long_ids else bundle_utils.short_id(bundle['bundleId'])),
            'name': bundle['attributes']['bundleName'],
            'replications': len(bundle['bundleInstallations']),
            'starting': sum([not execution['isStarted'] for execution in bundle['bundleExecutions']]),
            'executions': sum([execution['isStarted'] for execution in bundle['bundleExecutions']])
        } for bundle in json.loads(response.text)
    ]
    data.insert(0, {'id': 'ID', 'name': 'NAME', 'replications': '#REP', 'starting': '#STR', 'executions': '#RUN'})

    padding = 2
    column_widths = dict(screen_utils.calc_column_widths(data), **{'padding': ' ' * padding})
    has_error = False
    for row in data:
        has_error |= '!' in row['id']
        log.screen('''\
{id: <{id_width}}{padding}\
{name: <{name_width}}{padding}\
{replications: >{replications_width}}{padding}\
{starting: >{starting_width}}{padding}\
{executions: >{executions_width}}'''.format(**dict(row, **column_widths)).rstrip())

    if has_error:
        log.screen('There are errors: use `conduct events` or `conduct logs` for further information')

    return True
예제 #25
0
def info(args):
    """`conduct info` command"""

    log = logging.getLogger(__name__)
    url = conduct_url.url('bundles', args)
    response = conduct_request.get(args.dcos_mode, conductr_host(args), url, auth=args.conductr_auth,
                                   verify=args.server_verification_file, timeout=DEFAULT_HTTP_TIMEOUT)
    validation.raise_for_status_inc_3xx(response)

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

    data = [
        {
            'id': ('! ' if bundle.get('hasError', False) else '') +
                  (bundle['bundleId'] if args.long_ids else bundle_utils.short_id(bundle['bundleId'])),
            'name': bundle['attributes']['bundleName'],
            'replications': len(bundle['bundleInstallations']),
            'starting': sum([not execution['isStarted'] for execution in bundle['bundleExecutions']]),
            'executions': sum([execution['isStarted'] for execution in bundle['bundleExecutions']])
        } for bundle in json.loads(response.text)
    ]
    data.insert(0, {'id': 'ID', 'name': 'NAME', 'replications': '#REP', 'starting': '#STR', 'executions': '#RUN'})

    padding = 2
    column_widths = dict(screen_utils.calc_column_widths(data), **{'padding': ' ' * padding})
    has_error = False
    for row in data:
        has_error |= '!' in row['id']
        log.screen('''\
{id: <{id_width}}{padding}\
{name: <{name_width}}{padding}\
{replications: >{replications_width}}{padding}\
{starting: >{starting_width}}{padding}\
{executions: >{executions_width}}'''.format(**dict(row, **column_widths)).rstrip())

    if has_error:
        log.screen('There are errors: use `conduct events` or `conduct logs` for further information')

    return True
예제 #26
0
def load(args):
    """`conduct load` command"""

    print('Retrieving bundle...')
    bundle_name, bundle_url = get_url(args.bundle)
    bundle_file, bundle_headers = urlretrieve(bundle_url)

    configuration_file, configuration_headers, configuration_name = (None, None, None)
    if args.configuration is not None:
        print('Retrieving configuration...')
        configuration_name, configuration_url = get_url(args.configuration)
        configuration_file, configuration_headers = urlretrieve(configuration_url)

    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(args.api_version, bundle_name, bundle_file, with_bundle_configurations)
    if configuration_file is not None:
        files.append(('configuration', (configuration_name, open(configuration_file, 'rb'))))

    print('Loading bundle to ConductR...')
    response = requests.post(url, files=files)
    conduct_logging.raise_for_status_inc_3xx(response)

    if args.verbose:
        conduct_logging.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'])

    print('Bundle loaded.')
    print('Start bundle with: conduct run{} {}'.format(args.cli_parameters, bundle_id))
    print('Unload bundle with: conduct unload{} {}'.format(args.cli_parameters, bundle_id))
    print('Print ConductR info with: conduct info{}'.format(args.cli_parameters))
예제 #27
0
def run(args):
    """`conduct run` command"""

    log = logging.getLogger(__name__)

    if args.affinity is not None and args.api_version == '1':
        log.error('Affinity feature is only available for v1.1 onwards of ConductR')
        return
    elif args.affinity is not None:
        path = 'bundles/{}?scale={}&affinity={}'.format(args.bundle, args.scale, args.affinity)
    else:
        path = 'bundles/{}?scale={}'.format(args.bundle, args.scale)

    url = conduct_url.url(path, args)
    # 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.put(url, 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'])

    log.info('Bundle run request sent.')

    if not args.no_wait:
        bundle_scale.wait_for_scale(response_json['bundleId'], args.scale, args)

    log.info('Stop bundle with: conduct stop{} {}'.format(args.cli_parameters, bundle_id))
    log.info('Print ConductR info with: conduct info{}'.format(args.cli_parameters))

    return True
예제 #28
0
def stop(args):
    """`conduct stop` command"""

    log = logging.getLogger(__name__)
    path = 'bundles/{}?scale=0'.format(args.bundle)
    url = conduct_url.url(path, args)
    response = requests.put(url, timeout=DEFAULT_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'])

    log.info('Bundle stop request sent.')

    if not args.no_wait:
        bundle_scale.wait_for_scale(response_json['bundleId'], 0, args)

    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))

    return True
예제 #29
0
 def display_bundle_id(bundle_id):
     return bundle_id if args.long_ids else bundle_utils.short_id(bundle_id)
예제 #30
0
def info(args):
    """`conduct info` command"""

    url = conduct_url.url('bundles', args)
    response = requests.get(url)
    conduct_logging.raise_for_status_inc_3xx(response)

    if args.verbose:
        conduct_logging.pretty_json(response.text)

    data = [
        {
            'id': ('! ' if bundle.get('hasError', False) else '') + (bundle['bundleId'] if args.long_ids else bundle_utils.short_id(bundle['bundleId'])),
            'name': bundle['attributes']['bundleName'],
            'replications': len(bundle['bundleInstallations']),
            'starting': sum([not execution['isStarted'] for execution in bundle['bundleExecutions']]),
            'executions': sum([execution['isStarted'] for execution in bundle['bundleExecutions']])
        } for bundle in json.loads(response.text)
    ]
    data.insert(0, {'id': 'ID', 'name': 'NAME', 'replications': '#REP', 'starting': '#STR', 'executions': '#RUN'})

    padding = 2
    column_widths = dict(calc_column_widths(data), **{'padding': ' ' * padding})
    has_error = False
    for row in data:
        has_error |= '!' in row['id']
        print('''\
{id: <{id_width}}{padding}\
{name: <{name_width}}{padding}\
{replications: >{replications_width}}{padding}\
{starting: >{starting_width}}{padding}\
{executions: >{executions_width}}'''.format(**dict(row, **column_widths)))

    if has_error:
        print('There are errors: use `conduct events` or `conduct logs` for further information')
예제 #31
0
def info(args):
    """`conduct info` command"""

    log = logging.getLogger(__name__)
    url = conduct_url.url('bundles', args)
    # 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.get(url,
                            timeout=DEFAULT_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))

    data = [{
        'id': ('! ' if bundle.get('hasError', False) else '') +
        (bundle['bundleId']
         if args.long_ids else bundle_utils.short_id(bundle['bundleId'])),
        'name':
        bundle['attributes']['bundleName'],
        'replications':
        len(bundle['bundleInstallations']),
        'starting':
        sum([
            not execution['isStarted']
            for execution in bundle['bundleExecutions']
        ]),
        'executions':
        sum([
            execution['isStarted'] for execution in bundle['bundleExecutions']
        ])
    } for bundle in json.loads(response.text)]
    data.insert(
        0, {
            'id': 'ID',
            'name': 'NAME',
            'replications': '#REP',
            'starting': '#STR',
            'executions': '#RUN'
        })

    padding = 2
    column_widths = dict(screen_utils.calc_column_widths(data),
                         **{'padding': ' ' * padding})
    has_error = False
    for row in data:
        has_error |= '!' in row['id']
        log.screen('''\
{id: <{id_width}}{padding}\
{name: <{name_width}}{padding}\
{replications: >{replications_width}}{padding}\
{starting: >{starting_width}}{padding}\
{executions: >{executions_width}}'''.format(
            **dict(row, **column_widths)).rstrip())

    if has_error:
        log.screen(
            'There are errors: use `conduct events` or `conduct logs` for further information'
        )

    return True
예제 #32
0
def display_bundle_id(args, bundle):
    bundle_id = bundle['bundleId'] if args.long_ids else bundle_utils.short_id(
        bundle['bundleId'])
    has_error_display = '! ' if bundle.get('hasError', False) else ''
    return '{}{}'.format(has_error_display, bundle_id)
예제 #33
0
def service_names(args):
    """`conduct service-names` command"""

    log = logging.getLogger(__name__)
    url = conduct_url.url('bundles', args)
    response = conduct_request.get(args.dcos_mode, conductr_host(args), url, timeout=DEFAULT_HTTP_TIMEOUT)
    validation.raise_for_status_inc_3xx(response)

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

    def execution_status(bundle_executions):
        for execution in bundle_executions:
            if execution['isStarted']:
                return 'Running'
        return 'Starting'

    def get_service_name_from_service_uri(service_uri):
        paths = urlparse(service_uri).path.split('/')
        if len(paths) > 1:
            return paths[1]
        else:
            return ''

    data_from_service_uri = [
        (
            {
                'service_name': get_service_name_from_service_uri(service_uri),
                'service_uri': service_uri,
                'bundle_id': bundle['bundleId'] if args.long_ids else bundle_utils.short_id(
                    bundle['bundleId']),
                'bundle_name': bundle['attributes']['bundleName'],
                'status': execution_status(bundle['bundleExecutions'])
            }
        )
        for bundle in json.loads(response.text) if bundle['bundleExecutions']
        for endpoint_name, endpoint in bundle['bundleConfig']['endpoints'].items() if 'services' in endpoint
        for service_uri in endpoint['services']
    ]

    data_from_service_name = [
        (
            {
                'service_name': endpoint['serviceName'],
                'service_uri': None,
                'bundle_id': bundle['bundleId'] if args.long_ids else bundle_utils.short_id(
                    bundle['bundleId']),
                'bundle_name': bundle['attributes']['bundleName'],
                'status': execution_status(bundle['bundleExecutions'])
            }
        )
        for bundle in json.loads(response.text) if bundle['bundleExecutions']
        for endpoint_name, endpoint in bundle['bundleConfig']['endpoints'].items() if 'serviceName' in endpoint
    ]

    data = data_from_service_uri + data_from_service_name
    data = sorted([entry for entry in data if entry['service_name']], key=lambda line: line['service_name'])

    service_endpoints = {}
    for service in data:
        url = urlparse(service['service_uri'])
        if not (url.path == '' or url.path == '/'):
            try:
                service_endpoints[url.path] |= {service['service_uri']}
            except KeyError:
                service_endpoints[url.path] = {service['service_uri']}
    duplicate_endpoints = [service for (service, endpoint) in service_endpoints.items() if len(endpoint) > 1] \
        if len(service_endpoints) > 0 else []

    data.insert(0, {'service_name': 'SERVICE NAME', 'bundle_id': 'BUNDLE ID', 'bundle_name': 'BUNDLE NAME', 'status': 'STATUS'})

    padding = 2
    column_widths = dict(screen_utils.calc_column_widths(data), **{'padding': ' ' * padding})
    for row in data:
        log.screen(
            '{service_name: <{service_name_width}}{padding}'
            '{bundle_id: <{bundle_id_width}}{padding}'
            '{bundle_name: <{bundle_name_width}}{padding}'
            '{status: <{status_width}}'.format(**dict(row, **column_widths)).rstrip())

    if len(duplicate_endpoints) > 0:
        log.screen('')
        log.warning('Multiple endpoints found for the following services: {}'.format(', '.join(duplicate_endpoints)))
        log.warning('Service resolution for these services is undefined.')

    return True
예제 #34
0
 def display_bundle_id(bundle_id):
     return bundle_id if args.long_ids else bundle_utils.short_id(bundle_id)
예제 #35
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
예제 #36
0
def get_service_names_from_bundles(args, bundles):
    def execution_status(bundle_executions):
        for execution in bundle_executions:
            if execution['isStarted']:
                return 'Running'
        return 'Starting'

    def get_service_name_from_service_uri(service_uri):
        paths = urlparse(service_uri).path.split('/')
        if len(paths) > 1:
            return paths[1]
        else:
            return ''

    data_from_service_uri = [({
        'service_name':
        get_service_name_from_service_uri(service_uri),
        'service_uri':
        service_uri,
        'bundle_id':
        bundle['bundleId']
        if args.long_ids else bundle_utils.short_id(bundle['bundleId']),
        'bundle_name':
        bundle['attributes']['bundleName'],
        'status':
        execution_status(bundle['bundleExecutions'])
    }) for bundle in bundles if bundle['bundleExecutions']
                             for endpoint_name, endpoint in
                             bundle['bundleConfig']['endpoints'].items()
                             if 'services' in endpoint
                             for service_uri in endpoint['services']]

    data_from_service_name = [({
        'service_name':
        endpoint['serviceName'],
        'service_uri':
        None,
        'bundle_id':
        bundle['bundleId']
        if args.long_ids else bundle_utils.short_id(bundle['bundleId']),
        'bundle_name':
        bundle['attributes']['bundleName'],
        'status':
        execution_status(bundle['bundleExecutions'])
    }) for bundle in bundles if bundle['bundleExecutions']
                              for endpoint_name, endpoint in
                              bundle['bundleConfig']['endpoints'].items()
                              if 'serviceName' in endpoint]

    data = data_from_service_uri + data_from_service_name
    data = sorted([entry for entry in data if entry['service_name']],
                  key=lambda line: line['service_name'])

    service_endpoints = {}
    for service in data:
        url = urlparse(service['service_uri'])
        if not (url.path == '' or url.path == '/'):
            try:
                service_endpoints[url.path] |= {service['service_uri']}
            except KeyError:
                service_endpoints[url.path] = {service['service_uri']}
    duplicate_endpoints = [service for (service, endpoint) in service_endpoints.items() if len(endpoint) > 1] \
        if len(service_endpoints) > 0 else []

    return data, duplicate_endpoints
예제 #37
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
예제 #38
0
def services(args):
    """`conduct services` command"""

    log = logging.getLogger(__name__)
    url = conduct_url.url('bundles', args)
    # 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.get(url,
                            timeout=DEFAULT_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))

    data = sorted([({
        'service':
        service,
        'bundle_id':
        bundle['bundleId']
        if args.long_ids else bundle_utils.short_id(bundle['bundleId']),
        'bundle_name':
        bundle['attributes']['bundleName'],
        'status':
        'Running' if execution['isStarted'] else 'Starting'
    }) for bundle in json.loads(response.text)
                   for execution in bundle['bundleExecutions']
                   for endpoint_name, endpoint in bundle['bundleConfig']
                   ['endpoints'].items() if 'services' in endpoint
                   for service in endpoint['services']],
                  key=lambda line: line['service'])

    service_endpoints = {}
    for service in data:
        url = urlparse(service['service'])
        if not (url.path == '' or url.path == '/'):
            try:
                service_endpoints[url.path] |= {service['service']}
            except KeyError:
                service_endpoints[url.path] = {service['service']}
    duplicate_endpoints = [service for (service, endpoint) in service_endpoints.items() if len(endpoint) > 1] \
        if len(service_endpoints) > 0 else []

    data.insert(
        0, {
            'service': 'SERVICE',
            'bundle_id': 'BUNDLE ID',
            'bundle_name': 'BUNDLE NAME',
            'status': 'STATUS'
        })

    padding = 2
    column_widths = dict(screen_utils.calc_column_widths(data),
                         **{'padding': ' ' * padding})
    for row in data:
        log.screen('{service: <{service_width}}{padding}'
                   '{bundle_id: <{bundle_id_width}}{padding}'
                   '{bundle_name: <{bundle_name_width}}{padding}'
                   '{status: <{status_width}}'.format(
                       **dict(row, **column_widths)).rstrip())

    if len(duplicate_endpoints) > 0:
        log.screen('')
        log.warning(
            'Multiple endpoints found for the following services: {}'.format(
                ', '.join(duplicate_endpoints)))
        log.warning('Service resolution for these services is undefined.')

    return True
예제 #39
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