def test_lazy_loading():
    patch_method = 'ambariclient.client.HttpClient.request'
    with patch(patch_method, MagicMock(return_value={})) as http_request:
        client = Ambari('localhost')

        clusters = client.clusters
        assert http_request.call_count == 0, "Sent a request prior to inflation"

        clusters.inflate()
        assert http_request.call_count == 1, "inflating collection didn't hit the server"

        clusters('testcluster')
        assert http_request.call_count == 1, "getting a single cluster hit the server again"

        clusters('testcluster').inflate()
        assert http_request.call_count == 2, "inflating model didn't hit the server"

    with patch(patch_method, MagicMock(return_value={})) as http_request:
        client = Ambari('localhost')

        cluster = client.clusters('testcluster')
        assert http_request.call_count == 0, "getting model inflated collection"

        cluster.hosts
        assert http_request.call_count == 1, "accessing relationship on model didn't inflate it"

        cluster.hosts.to_dict()
        assert http_request.call_count == 2, "to_dict on relationship didn't inflate it"

    with patch(patch_method, MagicMock(return_value={})) as http_request:
        client = Ambari('localhost')

        cluster = client.clusters('testcluster')
        assert http_request.call_count == 0, "getting model inflated collection"

        cluster.cluster_name
        assert http_request.call_count == 0, "accessing prepopulated field on model inflated it"

        cluster.health_report
        assert http_request.call_count == 1, "accessing field on model didn't inflate it"
def test_lazy_loading():
    patch_method = 'ambariclient.client.HttpClient.request'
    with patch(patch_method, MagicMock(return_value={})) as http_request:
        client = Ambari('localhost')

        clusters = client.clusters
        assert http_request.call_count == 0, "Sent a request prior to inflation"

        clusters.inflate()
        assert http_request.call_count == 1, "inflating collection didn't hit the server"

        clusters('testcluster')
        assert http_request.call_count == 1, "getting a single cluster hit the server again"

        clusters('testcluster').inflate()
        assert http_request.call_count == 2, "inflating model didn't hit the server"

    with patch(patch_method, MagicMock(return_value={})) as http_request:
        client = Ambari('localhost')

        cluster = client.clusters('testcluster')
        assert http_request.call_count == 0, "getting model inflated collection"

        cluster.hosts
        assert http_request.call_count == 0, "accessing relationship on model inflated it"

        cluster.hosts.to_dict()
        assert http_request.call_count == 1, "to_dict on relationship didn't inflate it"

    with patch(patch_method, MagicMock(return_value={})) as http_request:
        client = Ambari('localhost')

        cluster = client.clusters('testcluster')
        assert http_request.call_count == 0, "getting model inflated collection"

        cluster.cluster_name
        assert http_request.call_count == 0, "accessing prepopulated field on model inflated it"

        cluster.health_report
        assert http_request.call_count == 1, "accessing field on model didn't inflate it"
Exemple #3
0
def main(args):
    quiet = not args.verbose
    print_topology_meta(args.topology)

    models.LOCALTIME_MOUNT = False
    models.PRIVILEGED_CONTAINER = True  # 'privileged' containers are needed to have systemd work with no issues

    os_major_version = (args.operating_system or
                        DEFAULT_OPERATING_SYSTEM)[6]  # always assume 'centosX'
    image = '{}/topology_nodebase:{}'.format(
        defaults['DEFAULT_REPOSITORY'], args.operating_system
        or DEFAULT_OPERATING_SYSTEM)
    primary_node = models.Node(hostname='node-1',
                               group='nodes',
                               image=image,
                               ports=[{
                                   AMBARI_PORT: AMBARI_PORT
                               }])
    secondary_node = models.Node(hostname='node-2', group='nodes', image=image)
    cluster = models.Cluster(primary_node, secondary_node)
    cluster.start(args.network)

    hdp_version_tuple = version_tuple(args.hdp_version)
    stack_version = '{}.{}'.format(hdp_version_tuple[0], hdp_version_tuple[1])
    stack_version_tuple = (hdp_version_tuple[0], hdp_version_tuple[1])
    DEFAULT_CLUSTER_HOST_MAPPING[0]['hosts'][0]['fqdn'] = primary_node.fqdn
    DEFAULT_CLUSTER_HOST_MAPPING[1]['hosts'][0]['fqdn'] = secondary_node.fqdn

    host_groups = DEFAULT_BASE_HOST_GROUPS
    if not args.bare:
        if hdp_version_tuple <= (2, 0, 13, 0):
            host_groups[0]['components'].extend(
                EXTRA_HOST_GROUPS_2_0_13_0[0]['components'])
            host_groups[1]['components'].extend(
                EXTRA_HOST_GROUPS_2_0_13_0[1]['components'])
        elif hdp_version_tuple <= (2, 4, 0, 0):
            host_groups[0]['components'].extend(
                EXTRA_HOST_GROUPS_2_4_0_0[0]['components'])
            host_groups[1]['components'].extend(
                EXTRA_HOST_GROUPS_2_4_0_0[1]['components'])
        elif hdp_version_tuple <= (2, 6, 4, 0):
            host_groups[0]['components'].extend(
                EXTRA_HOST_GROUPS_2_6_4_0[0]['components'])
            host_groups[1]['components'].extend(
                EXTRA_HOST_GROUPS_2_6_4_0[1]['components'])
        elif hdp_version_tuple <= (3, 1, 0, 0):
            host_groups[0]['components'].extend(
                EXTRA_HOST_GROUPS_3_1_0_0[0]['components'])
            host_groups[1]['components'].extend(
                EXTRA_HOST_GROUPS_3_1_0_0[1]['components'])
        else:
            host_groups[0]['components'].extend(
                DEFAULT_EXTRA_HOST_GROUPS[0]['components'])
            host_groups[1]['components'].extend(
                DEFAULT_EXTRA_HOST_GROUPS[1]['components'])

    if hdp_version_tuple <= (
            2, 0, 13,
            0):  # APP_TIMELINE_SERVER not applicable for this version
        host_groups[0]['components'] = list(
            filter(lambda x: x.get('name') != 'APP_TIMELINE_SERVER',
                   host_groups[0]['components']))

    repo_url_host = 'http://public-repo-1.hortonworks.com'
    ambari_repo_url = ('{}/ambari/centos{}/{}.x/updates/{}/'
                       'ambari.repo'.format(repo_url_host, os_major_version,
                                            args.ambari_version[0],
                                            args.ambari_version))
    hdp_repo_url = ('{}/HDP/centos{}/{}.x/updates/{}'.format(
        repo_url_host, os_major_version, args.hdp_version[0],
        args.hdp_version))

    for node in cluster:
        node.execute('wget -nv {} -O /etc/yum.repos.d/ambari.repo'.format(
            ambari_repo_url),
                     quiet=quiet)

    logger.info('Installing Ambari server and agents ...')
    primary_node.execute('yum -y install ambari-server', quiet=quiet)
    primary_node.execute('ambari-server setup -v -s', quiet=quiet)
    primary_node.execute('ambari-server start', quiet=quiet)

    for node in cluster:
        node.execute('yum -y install ambari-agent', quiet=quiet)
        ambari_agent_config = node.get_file(AMBARI_AGENT_CONFIG_FILE_PATH)
        node.put_file(
            AMBARI_AGENT_CONFIG_FILE_PATH,
            re.sub(r'(hostname)=.*', r'\1={}'.format(primary_node.fqdn),
                   ambari_agent_config))
        node.execute('ambari-agent start', quiet=quiet)

    mysql_config_commands = [
        ('wget -nv -O /tmp/mysql-connector-java.tar.gz '
         'https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.45.tar.gz'
         ), 'gzip -d /tmp/mysql-connector-java.tar.gz',
        'tar -xf /tmp/mysql-connector-java.tar -C /tmp',
        ('cp /tmp/mysql-connector-java-5.1.45/mysql-connector-java-5.1.45-bin.jar '
         '/tmp/mysql-connector-java.jar'),
        'ambari-server setup --jdbc-db=mysql --jdbc-driver=/tmp/mysql-connector-java.jar',
        'rm -rf /tmp/mysql-connector-java*'
    ]
    primary_node.execute(' && '.join(mysql_config_commands), quiet=quiet)

    # Docker for Mac exposes ports that can be accessed only with ``localhost:<port>`` so
    # use that instead of the hostname if the host name is ``moby``.
    hostname = ('localhost' if models.client.info().get('Name') == 'moby' else
                socket.getaddrinfo(
                    socket.gethostname(), 0, flags=socket.AI_CANONNAME)[0][3])
    port = primary_node.host_ports.get(AMBARI_PORT)
    server_url = 'http://{}:{}'.format(hostname, port)
    logger.info('Ambari server is now reachable at %s', server_url)

    ambari = Ambari(server_url,
                    username=DEFAULT_AMBARI_USERNAME,
                    password=DEFAULT_AMBARI_PASSWORD)

    logger.info('Waiting for all hosts to be visible in Ambari ...')

    def condition(ambari, cluster):
        cluster_hosts = {node.fqdn for node in cluster}
        ambari_hosts = {host.host_name for host in ambari.hosts}
        logger.debug('Cluster hosts: %s; Ambari hosts: %s', cluster_hosts,
                     ambari_hosts)
        return cluster_hosts == ambari_hosts

    wait_for_condition(condition=condition, condition_args=[ambari, cluster])

    logger.info('Updating install repo to use %s HDP version ...',
                args.hdp_version)
    # based off of release notes of https://bit.ly/2R06NKp
    if stack_version_tuple >= (2, 6):
        url = join_url_parts(hdp_repo_url, 'build.id')
        response = requests.get(url)
        response.raise_for_status()
        build_number = next(
            (int(item.split(':')[1].strip())
             for item in response.text.split('\n') if 'BUILD_NUMBER' in item),
            None)
        if not build_number:
            raise Exception(
                'Could not determine build number as required for repo setting. Build data found: ',
                response.text)

        # version_definitions not yet supported by Ambari client library - a TODO
        hdp_repo_version = '{}-{}'.format(args.hdp_version, build_number)
        version_definition = {
            'VersionDefinition': {
                'version_url':
                '{}/HDP-{}.xml'.format(hdp_repo_url, hdp_repo_version)
            }
        }
        url = join_url_parts(server_url, 'api', 'v1', 'version_definitions')
        data = json.dumps(version_definition)
        response = requests.post(
            url,
            data=data,
            auth=(DEFAULT_AMBARI_USERNAME, DEFAULT_AMBARI_PASSWORD),
            headers={'X-Requested-By': 'topology_hdp build'})
        response.raise_for_status()
    else:
        hdp_os = ambari.stacks('HDP').versions(
            stack_version).operating_systems('redhat6')
        hdp_os.repositories('HDP-{}'.format(stack_version)).update(
            base_url=hdp_repo_url, verify_base_url=False)
        hdp_repo_version = None
        build_number = None

    logger.info('Creating `cluster` with pre-defined components ...')
    ambari.blueprints('cluster').create(blueprint_name='cluster',
                                        stack_version=stack_version,
                                        stack_name='HDP',
                                        host_groups=host_groups)

    logger.info('Installing cluster components ...')
    hdp_cluster = ambari.clusters('cluster')
    # INSTALL_ONLY option not applicable for <= 2.0.13.0 ver, it will be install and start services.
    if hdp_version_tuple <= (2, 0, 13, 0):
        hdp_cluster = hdp_cluster.create(
            blueprint='cluster',
            default_password='******',
            host_groups=DEFAULT_CLUSTER_HOST_MAPPING)
    elif hdp_repo_version:
        hdp_cluster = hdp_cluster.create(
            blueprint='cluster',
            default_password='******',
            repository_version=hdp_repo_version,
            host_groups=DEFAULT_CLUSTER_HOST_MAPPING,
            provision_action='INSTALL_ONLY')
    else:
        hdp_cluster = hdp_cluster.create(
            blueprint='cluster',
            default_password='******',
            host_groups=DEFAULT_CLUSTER_HOST_MAPPING,
            provision_action='INSTALL_ONLY')

    time.sleep(
        30
    )  # Some versions of Ambari provide wrong status on wait. Need to slug some time.
    hdp_cluster.wait(timeout=5400, interval=30)

    logger.info('Waiting for all hosts to reach healthy state ...')

    def condition(ambari):
        health_report = hdp_cluster.health_report
        logger.debug('Ambari cluster health report: %s ...', health_report)
        return health_report.get('Host/host_state/HEALTHY') == len(
            list(ambari.hosts))

    wait_for_condition(condition=condition, condition_args=[ambari])

    logger.info('Waiting for components to be verified ...')

    def condition(ambari):
        comps = hdp_cluster.cluster.host_components.refresh()
        for comp in comps:
            if comp.state.upper() == 'UNKNOWN':
                logger.debug('Not ready with component `%s` ...',
                             comp.component_name)
                return False
        else:
            return True

    wait_for_condition(condition=condition, condition_args=[ambari])

    hdp_services_state = set(service['state']
                             for service in hdp_cluster.services.to_dict())
    if 'STARTED' in hdp_services_state or 'STARTING' in hdp_services_state:
        logger.info('Ambari task queued to stop services ...')
        hdp_cluster.cluster.services.stop().wait()

    logger.info('Stopping Ambari for saving to Docker image ...')
    for node in cluster:
        node.execute('ambari-agent stop', quiet=quiet)

    primary_node.execute('ambari-server stop', quiet=quiet)
    primary_node.execute('service postgresql stop', quiet=quiet)

    for node in cluster:
        node.execute('; '.join(
            ['yum clean all',
             'cat /dev/null > ~/.bash_history && history -c']),
                     quiet=quiet)

    repository = '{}/topology_hdp'.format(args.repository
                                          or defaults['DEFAULT_REPOSITORY'])
    tag_prefix = 'hdp{}_ambari{}'.format(args.hdp_version, args.ambari_version)
    primary_node_tag = '{}_{}'.format(tag_prefix, 'primary-node')
    secondary_node_tag = '{}_{}'.format(tag_prefix, 'secondary-node')

    logger.info('Committing the primary node container as %s %s',
                primary_node_tag,
                ('and pushing its image to {} ...'.format(repository)
                 if args.push else '...'))
    primary_node.commit(repository=repository,
                        tag=primary_node_tag,
                        push=args.push)
    logger.info('Committing the secondary node container as %s %s',
                secondary_node_tag,
                ('and pushing its image to {} ...'.format(repository)
                 if args.push else '...'))
    secondary_node.commit(repository=repository,
                          tag=secondary_node_tag,
                          push=args.push)

    if args.retain:
        logger.info('Starting Ambari ...')
        primary_node.execute('service postgresql start', quiet=quiet)
        primary_node.execute('ambari-server start', quiet=quiet)
        for node in cluster:
            node.execute('ambari-agent start', quiet=quiet)
    else:
        logger.info('Removing the containers ...')
        primary_node.stop()
        secondary_node.stop()
Exemple #4
0
def main(args):
    quiet = not args.verbose
    print_topology_meta(args.topology)

    if args.include_services and args.exclude_services:
        raise ValueError(
            'Cannot pass both --include-services and --exclude-services.')

    image_prefix = '{}/{}/topology_hdp:hdp{}_ambari{}'.format(
        args.registry, args.namespace or DEFAULT_NAMESPACE, args.hdp_version,
        args.ambari_version)
    primary_node_image = '{}_{}'.format(image_prefix, 'primary-node')
    secondary_node_image = '{}_{}'.format(image_prefix, 'secondary-node')

    clusterdock_config_host_dir = os.path.realpath(
        os.path.expanduser(args.clusterdock_config_directory))
    volumes = [{clusterdock_config_host_dir: CLUSTERDOCK_CLIENT_CONTAINER_DIR}]

    primary_node = Node(hostname=args.primary_node[0],
                        group='primary',
                        volumes=volumes,
                        image=primary_node_image,
                        ports=[{
                            AMBARI_PORT: AMBARI_PORT
                        } if args.predictable else AMBARI_PORT])

    secondary_nodes = [
        Node(hostname=hostname,
             group='secondary',
             volumes=volumes,
             image=secondary_node_image) for hostname in args.secondary_nodes
    ]

    cluster = Cluster(primary_node, *secondary_nodes)
    cluster.primary_node = primary_node
    cluster.secondary_nodes = secondary_nodes

    for node in cluster.nodes:
        node.volumes.append({'/sys/fs/cgroup': '/sys/fs/cgroup'})
        # do not use tempfile.mkdtemp, as systemd wont be able to bring services up when temp ends to be created in
        # /var/tmp/ directory
        node.volumes.append(['/run', '/run/lock'])

    cluster.start(args.network)

    hdp_version_tuple = version_tuple(args.hdp_version)

    logger.debug('Starting PostgreSQL for Ambari server ...')

    # Need this as init system in Docker misreports on postgres start initially
    # Check https://github.com/docker-library/postgres/issues/146 for more
    def condition():
        primary_node.execute('service postgresql restart', quiet=quiet)
        if '1 row' in primary_node.execute(
                'PGPASSWORD=bigdata psql ambari '
                '-U ambari -h localhost -c "select 1"',
                quiet=quiet).output:
            return True

    wait_for_condition(condition=condition, time_between_checks=2)

    def condition():
        if 'running' in primary_node.execute('service postgresql status',
                                             quiet=quiet).output:
            return True

    wait_for_condition(condition=condition)

    time.sleep(
        10
    )  # If images are set to start Ambari server/agents - give some time to recover the right status
    _update_node_names(cluster, quiet=quiet)

    # The HDP topology uses two pre-built images ('primary' and 'secondary'). If a cluster
    # larger than 2 nodes is started, some modifications need to be done.
    if len(secondary_nodes) > 1:
        _remove_files(nodes=secondary_nodes[1:],
                      files=['/hadoop/hdfs/data/current/*'],
                      quiet=quiet)

    logger.info('Starting Ambari server ...')
    primary_node.execute('ambari-server start', quiet=quiet)

    # Docker for Mac exposes ports that can be accessed only with ``localhost:<port>`` so
    # use that instead of the hostname if the host name is ``moby``.
    hostname = ('localhost'
                if client.info().get('Name') == 'moby' else socket.getaddrinfo(
                    socket.gethostname(), 0, flags=socket.AI_CANONNAME)[0][3])
    port = cluster.primary_node.host_ports.get(AMBARI_PORT)
    server_url = 'http://{}:{}'.format(hostname, port)
    logger.info('Ambari server is now reachable at %s', server_url)

    logger.info('Starting Ambari agents ...')
    for node in cluster:
        logger.debug('Starting Ambari agent on %s ...', node.fqdn)
        node.execute('ambari-agent start', quiet=quiet)

    ambari = Ambari(server_url, username='******', password='******')

    def condition(ambari, cluster):
        cluster_hosts = {node.fqdn for node in cluster}
        ambari_hosts = {host.host_name for host in ambari.hosts}
        logger.debug('Cluster hosts: %s; Ambari hosts: %s', cluster_hosts,
                     ambari_hosts)
        return cluster_hosts == ambari_hosts

    wait_for_condition(condition=condition, condition_args=[ambari, cluster])

    service_types_to_leave = (args.include_services.upper().split(',')
                              if args.include_services else [])
    service_types_to_remove = (args.exclude_services.upper().split(',')
                               if args.exclude_services else [])
    if service_types_to_leave or service_types_to_remove:
        for service in list(ambari.clusters(DEFAULT_CLUSTER_NAME).services):
            service_name = service.service_name.upper()
            if (service_name in service_types_to_remove
                    or (service_types_to_leave
                        and service_name not in service_types_to_leave)):
                logger.info('Removing cluster service (name = %s) ...',
                            service_name)
                service.delete()

    for node in secondary_nodes[1:]:
        logger.info('Adding %s to cluster ...', node.fqdn)
        ambari.clusters(DEFAULT_CLUSTER_NAME).hosts.create(node.fqdn)
        secondary_node = ambari.clusters(DEFAULT_CLUSTER_NAME).hosts(
            secondary_nodes[0].fqdn)
        for component in secondary_node.components:
            logger.debug('Adding component (%s) to cluster on host (%s) ...',
                         component.component_name, node.fqdn)
            host_components = ambari.clusters(DEFAULT_CLUSTER_NAME).hosts(
                node.fqdn).components
            host_components.create(component.component_name).wait()

        logger.debug('Installing all registered components on host (%s) ...',
                     node.fqdn)
        ambari.clusters(DEFAULT_CLUSTER_NAME).hosts(
            node.fqdn).components.install().wait()

    logger.info('Waiting for all hosts to reach healthy state ...')

    def condition(ambari):
        health_report = ambari.clusters(DEFAULT_CLUSTER_NAME).health_report
        logger.debug('Ambari cluster health report: %s ...', health_report)
        return health_report.get('Host/host_state/HEALTHY') == len(
            list(ambari.hosts))

    wait_for_condition(condition=condition, condition_args=[ambari])

    service_names = [
        service['service_name'] for service in ambari.clusters(
            DEFAULT_CLUSTER_NAME).services.to_dict()
    ]

    if 'ATLAS' in service_names:
        logger.info('Configuring Atlas required properties ...')
        _configure_atlas(ambari,
                         args.hdp_version,
                         atlas_server_host=cluster.primary_node.fqdn)

    if 'HIVE' in service_names:
        primary_node.execute('touch /etc/hive/sys.db.created', quiet=quiet)

    logger.info('Waiting for components to be ready ...')

    def condition(ambari):
        comps = ambari.clusters(
            DEFAULT_CLUSTER_NAME).cluster.host_components.refresh()
        for comp in comps:
            if comp.state.upper() == 'UNKNOWN':
                logger.debug('Not ready with component `%s` ...',
                             comp.component_name)
                return False
        else:
            return True

    wait_for_condition(condition=condition, condition_args=[ambari])

    if not args.dont_start_cluster:
        logger.info('Starting cluster services ...')
        ambari.clusters(DEFAULT_CLUSTER_NAME).services.start().wait(
            timeout=3600)

        if 'HBASE' in service_names:
            logger.info('Starting Thrift server ...')
            if hdp_version_tuple <= (2, 0, 13, 0):
                hbase_daemon_path = '/usr/lib/hbase/bin/hbase-daemon.sh'
            else:
                hbase_daemon_path = '/usr/hdp/current/hbase-master/bin/hbase-daemon.sh'
            primary_node.execute('{} start thrift -p {} '
                                 '--infoport {}'.format(
                                     hbase_daemon_path,
                                     HBASE_THRIFT_SERVER_PORT,
                                     HBASE_THRIFT_SERVER_INFO_PORT),
                                 quiet=quiet)
Exemple #5
0
def main(cm_fqhn, cm_port, cm_user_name, cm_user_password, cm_cluster_name, cm_tls_enabled):
  print  cm_fqhn, cm_port, cm_user_name, cm_user_password, cm_cluster_name, cm_tls_enabled
  
  cm_protocol = 'https'
  if cm_tls_enabled.lower() == 'false':
    cm_protocol = 'http'
  #print 'Protocol:', cm_protocol
  ambari_accessor = api_accessor(host=cm_fqhn, 
                                 login=cm_user_name, 
                                 password=cm_user_password, 
                                 protocol=cm_protocol, 
                                 port=cm_port)
    
  zookeeper_config = get_properties2(cluster=cm_cluster_name, 
                                     config_type=CONFIG_TYPE_MAP['zookeeper'],
                                     accessor=ambari_accessor)
  zk_client_port = zookeeper_config.get(CONFIG_PROPERTY_MAP['zk_client_port'])
  if zk_client_port != None:
        CONFIG_KEY_VALUE_MAP['ZOOKEEPER_PORT'] = zk_client_port

  hdfs_site_config = get_properties2(cluster=cm_cluster_name, 
                                     config_type=CONFIG_TYPE_MAP['hdfs'],
                                     accessor=ambari_accessor)
  #print "\nHDFS-SITE:\n", hdfs_site_config  
  hdfs_nn_ns = hdfs_site_config.get(CONFIG_PROPERTY_MAP['hdf_nn_ns'], None)
  hdfs_nn_rpc = hdfs_site_config.get(CONFIG_PROPERTY_MAP['hdf_nn_rpc'])
  print '\nHDFS-SITE:', hdfs_nn_ns, hdfs_nn_rpc
  if hdfs_nn_ns == None:
        CONFIG_KEY_VALUE_MAP['NAME_NODE'] = 'hdfs://' + hdfs_nn_rpc
  else:
        CONFIG_KEY_VALUE_MAP['NAME_NODE'] = hdfs_nn_ns

  yarn_site_config = get_properties2(cluster=cm_cluster_name, 
                                     config_type=CONFIG_TYPE_MAP['yarn'],
                                     accessor=ambari_accessor)
  #print "\nYARN-SITE:\n", yarn_site_config
  yarn_rm_address = yarn_site_config.get(CONFIG_PROPERTY_MAP['yarn_rm_address'])
  CONFIG_KEY_VALUE_MAP['JOB_TRACKER'] = yarn_rm_address  
    
  hbase_site_config = get_properties2(cluster=cm_cluster_name, 
                                     config_type=CONFIG_TYPE_MAP['hbase'],
                                     accessor=ambari_accessor)
  #print "\nHBASE-SITE:\n", hbase_site_config
                                                             
                                                             
  kafka_broker_config = get_properties2(cluster=cm_cluster_name, 
                                     config_type=CONFIG_TYPE_MAP['kafka'],
                                     accessor=ambari_accessor)
  #print "\nKAFAKA_BROKER:\n", kafka_broker_config
  kafka_client_security_protocol = kafka_broker_config.get(CONFIG_PROPERTY_MAP['kafka_client_security_protocol'])
  #print 'Kafka protocol:', kafka_client_security_protocol
  if kafka_client_security_protocol != None:
        CONFIG_KEY_VALUE_MAP['KAFKA_SECURITY_PROTOCOL'] = kafka_client_security_protocol
                                       
                                                             
  oozie_server_config = get_properties2(cluster=cm_cluster_name, 
                                       config_type=CONFIG_TYPE_MAP['oozie'],
                                       accessor=ambari_accessor)
  #print "\nOOZIE_SERVER:\n", oozie_server_config
  oozie_url = oozie_server_config.get(CONFIG_PROPERTY_MAP['oozie_base_url'])
  CONFIG_KEY_VALUE_MAP['OOZIE_URL'] = oozie_url 

  
    
  if cm_tls_enabled.lower() == 'false':
    api = Ambari(cm_fqhn, port=cm_port, username=cm_user_name, password=cm_user_password, validate_ssl=False)
  else:
    api = Ambari(cm_fqhn, port=cm_port, username=cm_user_name, password=cm_user_password, validate_ssl=False, protocol='https')
    
    
  # Get a list of all clusters
  cdh_cluster = None
  
  for c in api.clusters():
     if c.cluster_name == cm_cluster_name:
       print '\nCluster:', c.cluster_name
       cdh_cluster = c
       for x in cdh_cluster.hosts():
         HOST_MAP[x.host_name] =  x.host_name
       print '\nHost Name Mapping:'
       print HOST_MAP
       print '\nServices:'
       for x in cdh_cluster.services():
         print x.service_name
       #for x in cdh_cluster.configurations(): 
       #  print x.type
            
       
       #ZooKeeper
       zk_hosts = []
       zk_service  = cdh_cluster.services(SERVICE_NAME_MAP['zookeeper'])
       #print zk_service
       zk_server_cmps = zk_service.components(SERVICE_COMPONENT_NAME_MAP['zookeeper_server'])
       #print zk_server_cmps
       for x in zk_server_cmps.host_components:
         zk_hosts.append(x.host_name)
       #print 'ZOOKEEPER HOSTS:', zk_hosts
       if len(zk_hosts) > 0:
         CONFIG_KEY_VALUE_MAP['ZOOKEEPER_QUORUM'] = ' '.join(zk_hosts)
     
       #HDFS
       hdfs_nn_hosts = []
       hdfs_service  = cdh_cluster.services(SERVICE_NAME_MAP['hdfs'])
       hdfs_nn_cmps = hdfs_service.components(SERVICE_COMPONENT_NAME_MAP['namenode'])
       for x in hdfs_nn_cmps.host_components:
         hdfs_nn_hosts.append(x.host_name)
       
       
       #YARN RM
       yarn_rm_hosts = []
       yarn_service  = cdh_cluster.services(SERVICE_NAME_MAP['yarn'])
       yarn_rm_cmps = yarn_service.components(SERVICE_COMPONENT_NAME_MAP['resourcemanager'])
       for x in yarn_rm_cmps.host_components:
         yarn_rm_hosts.append(x.host_name)
       #print yarn_rm_hosts
    
    
       #OOZIE
       oozie_hosts = []
       oozie_service  = cdh_cluster.services(SERVICE_NAME_MAP['oozie'])
       oozie_server_cmps = oozie_service.components(SERVICE_COMPONENT_NAME_MAP['oozie_server'])
       for x in oozie_server_cmps.host_components:
         oozie_hosts.append(x.host_name)
       #print oozie_hosts
       
       #HBASE REST SERVER not managed by Ambari
       hbase_service  = cdh_cluster.services(SERVICE_NAME_MAP['hbase'])
       
       #KAFKA
       kafka_broker_hosts = []
       kafka_service  = cdh_cluster.services(SERVICE_NAME_MAP['kafka'])
       kafka_broker_cmps = kafka_service.components(SERVICE_COMPONENT_NAME_MAP['kafka_broker'])
       for x in kafka_broker_cmps.host_components:
         kafka_broker_hosts.append(x.host_name)
       if len(kafka_broker_hosts) > 0:
         CONFIG_KEY_VALUE_MAP['KAFKA_BROKER'] = ' '.join(kafka_broker_hosts)
       #print kafka_broker_hosts
    
       
   
    
        
       # Print all
       print '\nOUTPUT:\n', CONFIG_KEY_VALUE_MAP 
Exemple #6
0
parser.add_argument("-S",
                    action="store",
                    dest='service',
                    help="Service name to check",
                    required=True)
args = parser.parse_args()

client = Ambari(args.host,
                port=args.port,
                username=args.user_name,
                password=args.password)
states = {'OK': 0, 'WARNING': 1, 'CRITICAL': 2, 'UNKNOWN': 3}

#for a in client.clusters(args.cluster).services(args.service).alerts.to_dict():
#  alerts = a.alerts.to_dict()
alerts = client.clusters(args.cluster).services(args.service).alerts.to_dict()
OK = []
WARNING = []
UNKNOWN = []
CRITICAL = []
MAINTENANCE = []
for a in alerts:
    if a['state'] == 'OK':
        OK.append((a['cluster_name'], a['service_name'], a['component_name'],
                   a['definition_name'], a['text']))
    elif a['state'] == 'UNKNOWN':
        UNKNOWN.append((a['cluster_name'], a['service_name'],
                        a['component_name'], a['definition_name'], a['text']))
    elif a['state'] == 'WARNING':
        WARNING.append((a['cluster_name'], a['service_name'],
                        a['component_name'], a['definition_name'], a['text']))
Exemple #7
0
def main(args):
    image_prefix = '{}/{}/topology_hdp:hdp{}_ambari{}'.format(
        args.registry, args.namespace or DEFAULT_NAMESPACE, args.hdp_version,
        args.ambari_version)
    primary_node_image = '{}_{}'.format(image_prefix, 'primary-node')
    secondary_node_image = '{}_{}'.format(image_prefix, 'secondary-node')

    primary_node = Node(hostname=args.primary_node[0],
                        group='primary',
                        image=primary_node_image,
                        ports=[{
                            AMBARI_PORT: AMBARI_PORT
                        } if args.predictable else AMBARI_PORT])

    secondary_nodes = [
        Node(hostname=hostname, group='secondary', image=secondary_node_image)
        for hostname in args.secondary_nodes
    ]

    cluster = Cluster(primary_node, *secondary_nodes)
    cluster.primary_node = primary_node
    cluster.secondary_nodes = secondary_nodes
    cluster.start(args.network)

    logger.debug('Starting PostgreSQL for Ambari server ...')
    primary_node.execute('service postgresql start', quiet=not args.verbose)
    _update_node_names(cluster, quiet=not args.verbose)

    # The HDP topology uses two pre-built images ('primary' and 'secondary'). If a cluster
    # larger than 2 nodes is started, some modifications need to be done.
    if len(secondary_nodes) > 1:
        _remove_files(nodes=secondary_nodes[1:],
                      files=['/hadoop/hdfs/data/current/*'])

    logger.info('Starting Ambari server ...')
    primary_node.execute('ambari-server start', quiet=not args.verbose)

    # Docker for Mac exposes ports that can be accessed only with ``localhost:<port>`` so
    # use that instead of the hostname if the host name is ``moby``.
    hostname = 'localhost' if client.info().get(
        'Name') == 'moby' else socket.gethostname()
    port = cluster.primary_node.host_ports.get(AMBARI_PORT)
    server_url = 'http://{}:{}'.format(hostname, port)
    logger.info('Ambari server is now reachable at %s', server_url)

    logger.info('Starting Ambari agents ...')
    for node in cluster:
        logger.debug('Starting Ambari agent on %s ...', node.fqdn)
        node.execute('ambari-agent start', quiet=not args.verbose)

    ambari = Ambari(server_url, username='******', password='******')

    def condition(ambari, cluster):
        cluster_hosts = {node.fqdn for node in cluster}
        ambari_hosts = {host.host_name for host in ambari.hosts}
        logger.debug('Cluster hosts: %s; Ambari hosts: %s', cluster_hosts,
                     ambari_hosts)
        return cluster_hosts == ambari_hosts

    wait_for_condition(condition=condition, condition_args=[ambari, cluster])

    for node in secondary_nodes[1:]:
        logger.info('Adding %s to cluster ...', node.fqdn)
        ambari.clusters('cluster').hosts.create(node.fqdn)
        for component in ambari.clusters('cluster').hosts(
                secondary_nodes[0].fqdn).components:
            logger.debug('Adding component (%s) to cluster on host (%s) ...',
                         component.component_name, node.fqdn)
            host_components = ambari.clusters('cluster').hosts(
                node.fqdn).components
            host_components.create(component.component_name).wait()

        logger.debug('Installing all registered components on host (%s) ...',
                     node.fqdn)
        ambari.clusters('cluster').hosts(node.fqdn).components.install().wait()

    if not args.dont_start_cluster:
        logger.debug(
            'Waiting for all hosts to reach healthy state before starting cluster ...'
        )

        def condition(ambari):
            health_report = ambari.clusters('cluster').health_report
            logger.debug('Ambari cluster health report: %s ...', health_report)
            return health_report.get('Host/host_state/HEALTHY') == len(
                list(ambari.hosts))

        wait_for_condition(condition=condition, condition_args=[ambari])

        logger.info('Starting cluster services ...')
        ambari.clusters('cluster').services.start().wait()
Exemple #8
0
class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
    NAME = 'ambari'

    def verify_file(self, path):
        ''' return true/false if this is possibly a valid file for this plugin to consume '''
        valid = False
        if super(InventoryModule, self).verify_file(path):
            # base class verifies that file exists and is readable by current user
            if path.endswith(('.ambari.yaml', '.ambari.yml')):
                valid = True
        return valid

    def parse(self, inventory, loader, path, cache=False):
        # call base method to ensure properties are available for use with other helper methods
        super(InventoryModule, self).parse(inventory, loader, path)

        # this method will parse 'common format' inventory sources and
        # update any options declared in DOCUMENTATION as needed
        config_data = self._read_config_data(path)

        # initialize Apache Ambari client
        self._initialize_client()

        # get cluster name
        _cluster_name = self._get_cluster_name()

        # get services name
        _services_name = self._get_services_name(_cluster_name)

        # get hosts name
        _hosts_name = self._get_hosts_name(_cluster_name)

        # populate groups
        self._populate_groups(_cluster_name, _services_name)

        # populate hosts
        self._populate_hosts(_cluster_name, _services_name, _hosts_name)

        # populate ambari server
        self._populate_ambari(_cluster_name)

        # populate localhost
        self._populate_localhost()

    ###########################################################################
    # Engine
    ###########################################################################

    def _populate_groups(self, cluster_name, services_name):
        '''
            Populate groups
            :param cluster_name: name of the cluster
            :param services_name: name of the services
        '''
        for service_name in services_name:
            self.inventory.add_group(service_name.lower())

            for component_name in self._get_components_name(
                    cluster_name, service_name):
                self.inventory.add_group(component_name.lower())
                if service_name.lower() != component_name.lower():
                    self.inventory.add_child(service_name.lower(),
                                             component_name.lower())

    def _populate_hosts(self, cluster_name, services_name, hosts_name):
        '''
            Populate hosts
            :param cluster_name: name of the cluster
            :param service_name: name of the services
            :param hosts_name: name of the hosts
        '''
        for host_name in hosts_name:
            self.inventory.add_host(host_name)

            configurations = {}

            for service_name in services_name:
                configurations_json = {}
                for service in self._get_service_current_configuration(
                        cluster_name, service_name)['items']:
                    configuration_json = {}
                    for configuration in service['configurations']:
                        configuration_json[configuration[
                            'type']] = configuration['properties']
                    configurations_json = configuration_json
                configurations[service_name.lower()] = configurations_json

            self.inventory.set_variable(host_name, 'configurations',
                                        configurations)

            host = self._get_host(host_name)
            self.inventory.set_variable(host_name, 'ansible_host', host_name)
            for field in host.fields:
                if (field.startswith('host') is not True) and (
                        field.startswith('last')
                        is not True) and field != 'desired_configs':
                    self.inventory.set_variable(host_name, field,
                                                getattr(host, field))

            if self.get_option('ansible_user'):
                self.inventory.set_variable(host_name, 'ansible_user',
                                            self.get_option('ansible_user'))
            if self.get_option('ansible_ssh_pass'):
                self.inventory.set_variable(
                    host_name, 'ansible_ssh_pass',
                    self.get_option('ansible_ssh_pass'))

            for component in self._get_host_components(cluster_name,
                                                       host_name):
                self.inventory.add_host(host_name,
                                        group=component.component_name.lower())

    def _populate_ambari(self, _cluster_name):
        '''
            Add the Ambari Server to the inventory file
            :param cluster_name: name of the cluster
        '''
        _group = 'ambari_server'
        _hostname = self.get_option('hostname')
        ambari_config = {}

        self.inventory.add_group(_group)
        self.inventory.add_host(_hostname, group=_group)
        ambari_config['protocol'] = self.get_option('protocol')
        ambari_config['port'] = self.get_option('port')
        ambari_config['username'] = self.get_option('username')
        ambari_config['password'] = self.get_option('password')
        ambari_config['validate_ssl'] = self.get_option('validate_ssl')
        ambari_config['cluster_name'] = _cluster_name

        self.inventory.set_variable(_hostname, 'ambari_config', ambari_config)

    def _populate_localhost(self):
        '''
            Add the localhost to the inventory file
        '''
        _group = 'local'
        _hostname = 'localhost'
        self.inventory.add_group(_group)
        self.inventory.add_host(_hostname, group=_group)
        self.inventory.set_variable(_hostname, 'ansible_host', '127.0.0.1')
        self.inventory.set_variable(_hostname, 'ansible_connection', 'local')
        self.inventory.set_variable(_hostname, 'ansible_become', 'false')

    ###########################################################################
    # Apache Ambari
    ###########################################################################

    def _initialize_client(self):
        '''
            Initialize Apache Ambari client
        '''
        # check not required arguments
        protocol = 'http'
        if self.get_option('protocol'):
            if self.get_option('protocol') == 'https':
                protocol = self.get_option('protocol')

        validate_ssl = False
        if self.get_option('validate_ssl'):
            if self.get_option('validate_ssl') == True:
                validate_ssl = self.get_option('validate_ssl')

        # disable ssl warning
        if validate_ssl == False:
            urllib3.disable_warnings()

        # initiate Apache Ambari client
        self._client = Ambari(self.get_option('hostname'),
                              port=int(self.get_option('port')),
                              username=self.get_option('username'),
                              password=self.get_option('password'),
                              protocol=protocol,
                              validate_ssl=validate_ssl)

    def _get_cluster_name(self):
        '''
            :return name of the cluster
        '''
        for cluster in self._client.clusters:
            return cluster.cluster_name

    def _get_services_name(self, cluster_name):
        '''
            :param cluster_name: name of the cluster
            :return names of the services installed on the cluster
        '''
        services_name = []
        for service in self._client.clusters(cluster_name).services:
            for component in service.components:
                services_name.append(component.service_name)
        return sorted(set(services_name))

    def _get_components_name(self, cluster_name, service_name):
        '''
            :param cluster_name: name of the cluster
            :param service_name: name of the service
            :return names of the components installed on the cluster
        '''
        components_name = []
        for component in self._client.clusters(cluster_name).services(
                service_name).components:
            components_name.append(component.component_name)
        return sorted(set(components_name))

    def _get_hosts_name(self, cluster_name):
        '''
            :param cluster_name: name of the cluster
            :return name of the healthy nodes on the cluster
        '''
        hosts_name = []
        for host in self._client.clusters(cluster_name).hosts:
            hosts_name.append(host.host_name)
        return sorted(set(hosts_name))

    def _get_host(self, host_name):
        '''
            :param host_name: name of the host
            :return host
        '''
        return self._client.hosts(host_name)

    def _get_host_components(self, cluster_name, host_name):
        '''
            :param cluster_name: name of the cluster
            :param host_name: name of the host
            :return components installed on the host
        '''
        return self._client.clusters(cluster_name).hosts(host_name).components

    def _get_service_current_configuration(self, cluster_name, service_name):
        '''
            :param cluster_name: name of the cluster
            :param service_name: name of the service
        '''
        protocol = 'http'
        if self.get_option('protocol'):
            if self.get_option('protocol') == 'https':
                protocol = self.get_option('protocol')

        url = protocol + '://' + self.get_option('hostname') + ':' + str(
            self.get_option('port')
        ) + '/api/v1/clusters/' + cluster_name + '/configurations/service_config_versions?service_name.in(' + service_name + ')&is_current=true'
        headers = {'X-Requested-By': 'ambari'}
        response = requests.get(url,
                                headers=headers,
                                auth=HTTPBasicAuth(
                                    self.get_option('username'),
                                    self.get_option('password')),
                                verify=False)

        if response.ok:
            return response.json()
        else:
            response.raise_for_status()