def test_same_convert(self, mock_data):
     same = convert_location_type('usnorth2cprod', 'az', 'az')
     assert same == ['usnorth2cprod']
 def test_down_convert(self, mock_data):
     down_convert = convert_location_type('prod', 'environment', 'az')
     assert isinstance(down_convert, list)
     assert len(down_convert) > 1
     for result in down_convert:
         assert isinstance(result, str)
    def test_up_convert(self, mock_data):
        up = convert_location_type('usnorth1bprod', 'az', 'environment')
        assert up == ['prod']

        up = convert_location_type('usnorth1aprod', 'az', 'region')
        assert up == ['usnorth1-prod']
def generate_subconfiguration(service_name, advertise, extra_advertise, port,
                              ip_address, healthcheck_timeout_s, hacheck_uri, healthcheck_headers):
    config = {}

    # Register at the specified location types in the current superregion
    locations_to_register_in = set()
    for advertise_typ in advertise:
        locations_to_register_in.add((get_current_location(advertise_typ), advertise_typ))

    # Also register in any other locations specified in extra advertisements
    for (src, dst) in extra_advertise:
        src_typ, src_loc = src.split(':')
        dst_typ, dst_loc = dst.split(':')
        if get_current_location(src_typ) != src_loc:
            # We do not match the source
            continue
        # Convert the destination into the 'advertise' type(s)
        for advertise_typ in advertise:
            # Prevent upcasts, otherwise the service may be made available to
            # more hosts than intended.
            if compare_types(dst_typ, advertise_typ) > 0:
                continue
            for loc in convert_location_type(dst_loc, dst_typ, advertise_typ):
                locations_to_register_in.add((loc, advertise_typ))

    # Create a separate service entry for each location that we need to register in.
    for loc, typ in locations_to_register_in:
        superregions = convert_location_type(loc, typ, 'superregion')
        for superregion in superregions:
            try:
                zookeeper_topology = get_named_zookeeper_topology(
                    cluster_type='infrastructure',
                    cluster_location=superregion
                )
            except:
                continue

            key = '%s.%s.%s:%s.%d.new' % (
                service_name, superregion, typ, loc, port
            )
            config[key] = {
                'port': port,
                'host': ip_address,
                'weight': CPUS,
                'zk_hosts': zookeeper_topology,
                'zk_path': '/nerve/%s:%s/%s' % (typ, loc, service_name),
                'check_interval': healthcheck_timeout_s + 1.0,
                # Hit the localhost hacheck instance
                'checks': [
                    {
                        'type': 'http',
                        'host': '127.0.0.1',
                        'port': HACHECK_PORT,
                        'uri': hacheck_uri,
                        'timeout': healthcheck_timeout_s,
                        'open_timeout': healthcheck_timeout_s,
                        'rise': 1,
                        'fall': 2,
                        'headers': healthcheck_headers,
                    }
                ]
            }

    return config
示例#5
0
def generate_subconfiguration(
    service_name: str,
    service_info: ServiceInfo,
    ip_address: str,
    hacheck_port: int,
    weight: int,
    zk_topology_dir: str,
    zk_location_type: str,
    zk_cluster_type: str,
    labels_dir: str,
    envoy_service_info: Optional[ServiceInfo],
) -> SubConfiguration:

    port = service_info['port']
    # if this is a k8s pod the dict will have the pod IP and we have
    # an hacheck sidecar in the pod that caches checks otherwise it is
    # a marathon/puppet etc service and we use the system hacheck
    hacheck_ip = service_info.get('hacheck_ip', '127.0.0.1')
    # ditto for the IP of the service, in k8s this is the pod IP,
    # otherwise we use the hosts IP
    ip_address = service_info.get('service_ip', ip_address)

    mode = service_info.get('mode', 'http')
    healthcheck_timeout_s = service_info.get('healthcheck_timeout_s', 1.0)
    healthcheck_port = service_info.get('healthcheck_port', port)

    # hacheck will simply ignore the healthcheck_uri for TCP mode checks
    healthcheck_uri = service_info.get('healthcheck_uri', '/status')
    healthcheck_mode = service_info.get('healthcheck_mode', mode)
    custom_labels = get_labels_by_service_and_port(service_name,
                                                   port,
                                                   labels_dir=labels_dir)
    hacheck_uri = '/%s/%s/%s/%s' % (healthcheck_mode, service_name,
                                    healthcheck_port,
                                    healthcheck_uri.lstrip('/'))
    advertise = service_info.get('advertise', ['region'])
    extra_advertise = service_info.get('extra_advertise', [])
    healthcheck_headers = service_info.get('extra_healthcheck_headers', {})
    healthcheck_body_expect = service_info.get('healthcheck_body_expect')

    deploy_group = service_info.get('deploy_group')
    paasta_instance = service_info.get('paasta_instance')

    config: SubConfiguration = {}

    if not advertise or not port:
        return config

    # Register at the specified location types in the current superregion
    locations_to_register_in = set()
    for advertise_typ in advertise:
        locations_to_register_in.add(
            (get_current_location(advertise_typ), advertise_typ))

    # Also register in any other locations specified in extra advertisements
    for (src, dst) in extra_advertise:
        src_typ, src_loc = src.split(':')
        dst_typ, dst_loc = dst.split(':')
        if get_current_location(src_typ) != src_loc:
            # We do not match the source
            continue

        valid_advertise_types = [
            advertise_typ for advertise_typ in advertise
            # Prevent upcasts, otherwise the service may be made available to
            # more hosts than intended.
            if compare_types(dst_typ, advertise_typ) <= 0
        ]
        # Convert the destination into the 'advertise' type(s)
        for advertise_typ in valid_advertise_types:
            for loc in convert_location_type(dst_loc, dst_typ, advertise_typ):
                locations_to_register_in.add((loc, advertise_typ))

    # Create a separate service entry for each location that we need to register in.
    for loc, typ in locations_to_register_in:
        zk_locations = convert_location_type(loc, typ, zk_location_type)
        for zk_location in zk_locations:
            try:
                zookeeper_topology = get_named_zookeeper_topology(
                    cluster_type=zk_cluster_type,
                    cluster_location=zk_location,
                    zk_topology_dir=zk_topology_dir,
                )
            except Exception:
                continue

            key = '%s.%s.%s:%s.%s.%d.new' % (
                service_name,
                zk_location,
                typ,
                loc,
                ip_address,
                port,
            )

            checks_dict: CheckDict = {
                'type': 'http',
                'host': hacheck_ip,
                'port': hacheck_port,
                'uri': hacheck_uri,
                'timeout': healthcheck_timeout_s,
                'open_timeout': healthcheck_timeout_s,
                'rise': 1,
                'fall': 2,
                'headers': healthcheck_headers,
            }
            if healthcheck_body_expect:
                checks_dict['expect'] = healthcheck_body_expect

            config[key] = {
                'port': port,
                'host': ip_address,
                'zk_hosts': zookeeper_topology,
                'zk_path': '/nerve/%s:%s/%s' % (typ, loc, service_name),
                'check_interval': healthcheck_timeout_s + 1.0,
                # Hit the localhost hacheck instance
                'checks': [
                    checks_dict,
                ],
                'weight': weight,
            }

            v2_key = '%s.%s:%s.%d.v2.new' % (
                service_name,
                zk_location,
                ip_address,
                port,
            )

            if v2_key not in config:
                config[v2_key] = {
                    'port': port,
                    'host': ip_address,
                    'zk_hosts': zookeeper_topology,
                    'zk_path': '/smartstack/global/%s' % service_name,
                    'check_interval': healthcheck_timeout_s + 1.0,
                    # Hit the localhost hacheck instance
                    'checks': [
                        checks_dict,
                    ],
                    'labels': {},
                    'weight': weight,
                }

            config[v2_key]['labels'].update(custom_labels)
            # Set a label that maps the location to an empty string. This
            # allows synapse to find all servers being advertised to it by
            # checking discover_typ:discover_loc == ''
            config[v2_key]['labels']['%s:%s' % (typ, loc)] = ''

            # Having the deploy group and paasta instance will enable Envoy
            # routing via these values for canary instance routing
            if deploy_group:
                config[v2_key]['labels']['deploy_group'] = deploy_group
            if paasta_instance:
                config[v2_key]['labels']['paasta_instance'] = paasta_instance

            if envoy_service_info:
                envoy_key = f'{service_name}.{zk_location}:{ip_address}.{port}'
                config[envoy_key] = generate_envoy_configuration(
                    envoy_service_info,
                    healthcheck_mode,
                    service_name,
                    hacheck_port,
                    ip_address,
                    zookeeper_topology,
                    custom_labels,
                    weight,
                    deploy_group,
                    paasta_instance,
                )

    return config
示例#6
0
def generate_subconfiguration(
    service_name,
    service_info,
    ip_address,
    hacheck_port,
    weight,
    zk_topology_dir,
    zk_location_type,
    zk_cluster_type,
    labels_dir,
):

    port = service_info.get('port')

    mode = service_info.get('mode', 'http')
    healthcheck_timeout_s = service_info.get('healthcheck_timeout_s', 1.0)
    healthcheck_port = service_info.get('healthcheck_port', port)

    # hacheck will simply ignore the healthcheck_uri for TCP mode checks
    healthcheck_uri = service_info.get('healthcheck_uri', '/status')
    healthcheck_mode = service_info.get('healthcheck_mode', mode)
    custom_labels = get_labels_by_service_and_port(service_name,
                                                   port,
                                                   labels_dir=labels_dir)
    hacheck_uri = '/%s/%s/%s/%s' % (healthcheck_mode, service_name,
                                    healthcheck_port,
                                    healthcheck_uri.lstrip('/'))
    advertise = service_info.get('advertise', ['region'])
    extra_advertise = service_info.get('extra_advertise', [])
    healthcheck_headers = service_info.get('extra_healthcheck_headers', {})
    healthcheck_body_expect = service_info.get('healthcheck_body_expect')

    config = {}

    if not advertise or not port:
        return config

    # Register at the specified location types in the current superregion
    locations_to_register_in = set()
    for advertise_typ in advertise:
        locations_to_register_in.add(
            (get_current_location(advertise_typ), advertise_typ))

    # Also register in any other locations specified in extra advertisements
    for (src, dst) in extra_advertise:
        src_typ, src_loc = src.split(':')
        dst_typ, dst_loc = dst.split(':')
        if get_current_location(src_typ) != src_loc:
            # We do not match the source
            continue

        valid_advertise_types = [
            advertise_typ for advertise_typ in advertise
            # Prevent upcasts, otherwise the service may be made available to
            # more hosts than intended.
            if compare_types(dst_typ, advertise_typ) <= 0
        ]
        # Convert the destination into the 'advertise' type(s)
        for advertise_typ in valid_advertise_types:
            for loc in convert_location_type(dst_loc, dst_typ, advertise_typ):
                locations_to_register_in.add((loc, advertise_typ))

    # Create a separate service entry for each location that we need to register in.
    for loc, typ in locations_to_register_in:
        zk_locations = convert_location_type(loc, typ, zk_location_type)
        for zk_location in zk_locations:
            try:
                zookeeper_topology = get_named_zookeeper_topology(
                    cluster_type=zk_cluster_type,
                    cluster_location=zk_location,
                    zk_topology_dir=zk_topology_dir,
                )
            except:
                continue

            key = '%s.%s.%s:%s.%d.new' % (
                service_name,
                zk_location,
                typ,
                loc,
                port,
            )

            checks_dict = {
                'type': 'http',
                'host': '127.0.0.1',
                'port': hacheck_port,
                'uri': hacheck_uri,
                'timeout': healthcheck_timeout_s,
                'open_timeout': healthcheck_timeout_s,
                'rise': 1,
                'fall': 2,
                'headers': healthcheck_headers,
            }
            if healthcheck_body_expect:
                checks_dict['expect'] = healthcheck_body_expect

            config[key] = {
                'port': port,
                'host': ip_address,
                'zk_hosts': zookeeper_topology,
                'zk_path': '/nerve/%s:%s/%s' % (typ, loc, service_name),
                'check_interval': healthcheck_timeout_s + 1.0,
                # Hit the localhost hacheck instance
                'checks': [
                    checks_dict,
                ],
                'weight': weight,
            }

            v2_key = '%s.%s:%d.v2.new' % (
                service_name,
                zk_location,
                port,
            )

            if v2_key not in config:
                config[v2_key] = {
                    'port': port,
                    'host': ip_address,
                    'zk_hosts': zookeeper_topology,
                    'zk_path': '/smartstack/global/%s' % service_name,
                    'check_interval': healthcheck_timeout_s + 1.0,
                    # Hit the localhost hacheck instance
                    'checks': [
                        checks_dict,
                    ],
                    'labels': {},
                    'weight': weight,
                }

            config[v2_key]['labels'].update(custom_labels)
            # Set a label that maps the location to an empty string. This
            # allows synapse to find all servers being advertised to it by
            # checking discover_typ:discover_loc == ''
            config[v2_key]['labels']['%s:%s' % (typ, loc)] = ''

    return config
示例#7
0
def generate_subconfiguration(
    service_name,
    service_info,
    ip_address,
    hacheck_port,
    weight,
    zk_topology_dir,
    zk_location_type,
    zk_cluster_type,
):

    port = service_info.get('port')

    mode = service_info.get('mode', 'http')
    healthcheck_timeout_s = service_info.get('healthcheck_timeout_s', 1.0)
    healthcheck_port = service_info.get('healthcheck_port', port)

    # hacheck will simply ignore the healthcheck_uri for TCP mode checks
    healthcheck_uri = service_info.get('healthcheck_uri', '/status')
    healthcheck_mode = service_info.get('healthcheck_mode', mode)
    hacheck_uri = '/%s/%s/%s/%s' % (
        healthcheck_mode, service_name, healthcheck_port, healthcheck_uri.lstrip('/'))
    advertise = service_info.get('advertise', ['region'])
    extra_advertise = service_info.get('extra_advertise', [])
    healthcheck_headers = service_info.get('extra_healthcheck_headers', {})

    config = {}

    if not advertise or not port:
        return config

    # Register at the specified location types in the current superregion
    locations_to_register_in = set()
    for advertise_typ in advertise:
        locations_to_register_in.add((get_current_location(advertise_typ), advertise_typ))

    # Also register in any other locations specified in extra advertisements
    for (src, dst) in extra_advertise:
        src_typ, src_loc = src.split(':')
        dst_typ, dst_loc = dst.split(':')
        if get_current_location(src_typ) != src_loc:
            # We do not match the source
            continue

        valid_advertise_types = [
            advertise_typ
            for advertise_typ in advertise
            # Prevent upcasts, otherwise the service may be made available to
            # more hosts than intended.
            if compare_types(dst_typ, advertise_typ) <= 0
        ]
        # Convert the destination into the 'advertise' type(s)
        for advertise_typ in valid_advertise_types:
            for loc in convert_location_type(dst_loc, dst_typ, advertise_typ):
                locations_to_register_in.add((loc, advertise_typ))

    # Create a separate service entry for each location that we need to register in.
    for loc, typ in locations_to_register_in:
        zk_locations = convert_location_type(loc, typ, zk_location_type)
        for zk_location in zk_locations:
            try:
                zookeeper_topology = get_named_zookeeper_topology(
                    cluster_type=zk_cluster_type,
                    cluster_location=zk_location,
                    zk_topology_dir=zk_topology_dir,
                )
            except:
                continue

            key = '%s.%s.%s:%s.%d.new' % (
                service_name, zk_location, typ, loc, port,
            )

            config[key] = {
                'port': port,
                'host': ip_address,
                'zk_hosts': zookeeper_topology,
                'zk_path': '/nerve/%s:%s/%s' % (typ, loc, service_name),
                'check_interval': healthcheck_timeout_s + 1.0,
                # Hit the localhost hacheck instance
                'checks': [
                    {
                        'type': 'http',
                        'host': '127.0.0.1',
                        'port': hacheck_port,
                        'uri': hacheck_uri,
                        'timeout': healthcheck_timeout_s,
                        'open_timeout': healthcheck_timeout_s,
                        'rise': 1,
                        'fall': 2,
                        'headers': healthcheck_headers,
                    },
                ],
                'weight': weight,
            }

            v2_key = '%s.%s:%d.v2.new' % (
                service_name, zk_location, port,
            )

            if v2_key not in config:
                config[v2_key] = {
                    'port': port,
                    'host': ip_address,
                    'zk_hosts': zookeeper_topology,
                    'zk_path': '/smartstack/global/%s' % service_name,
                    'check_interval': healthcheck_timeout_s + 1.0,
                    # Hit the localhost hacheck instance
                    'checks': [
                        {
                            'type': 'http',
                            'host': '127.0.0.1',
                            'port': hacheck_port,
                            'uri': hacheck_uri,
                            'timeout': healthcheck_timeout_s,
                            'open_timeout': healthcheck_timeout_s,
                            'rise': 1,
                            'fall': 2,
                            'headers': healthcheck_headers,
                        },
                    ],
                    'labels': {},
                    'weight': weight,
                }

            # Set a label that maps the location to an empty string. This
            # allows synapse to find all servers being advertised to it by
            # checking discover_typ:discover_loc == ''
            config[v2_key]['labels']['%s:%s' % (typ, loc)] = ''

    return config
示例#8
0
def generate_subconfiguration(service_name, advertise, extra_advertise, port,
                              ip_address, healthcheck_timeout_s, hacheck_uri,
                              healthcheck_headers, hacheck_port, weight,
                              zk_topology_dir, zk_location_type,
                              zk_cluster_type):
    config = {}

    # Register at the specified location types in the current superregion
    locations_to_register_in = set()
    for advertise_typ in advertise:
        locations_to_register_in.add(
            (get_current_location(advertise_typ), advertise_typ))

    # Also register in any other locations specified in extra advertisements
    for (src, dst) in extra_advertise:
        src_typ, src_loc = src.split(':')
        dst_typ, dst_loc = dst.split(':')
        if get_current_location(src_typ) != src_loc:
            # We do not match the source
            continue
        # Convert the destination into the 'advertise' type(s)
        for advertise_typ in advertise:
            # Prevent upcasts, otherwise the service may be made available to
            # more hosts than intended.
            if compare_types(dst_typ, advertise_typ) > 0:
                continue
            for loc in convert_location_type(dst_loc, dst_typ, advertise_typ):
                locations_to_register_in.add((loc, advertise_typ))

    # Create a separate service entry for each location that we need to register in.
    for loc, typ in locations_to_register_in:
        zk_locations = convert_location_type(loc, typ, zk_location_type)
        for zk_location in zk_locations:
            try:
                zookeeper_topology = get_named_zookeeper_topology(
                    cluster_type=zk_cluster_type,
                    cluster_location=zk_location,
                    zk_topology_dir=zk_topology_dir,
                )
            except:
                continue

            key = '%s.%s.%s:%s.%d.new' % (service_name, zk_location, typ, loc,
                                          port)
            config[key] = {
                'port':
                port,
                'host':
                ip_address,
                'weight':
                weight,
                'zk_hosts':
                zookeeper_topology,
                'zk_path':
                '/nerve/%s:%s/%s' % (typ, loc, service_name),
                'check_interval':
                healthcheck_timeout_s + 1.0,
                # Hit the localhost hacheck instance
                'checks': [{
                    'type': 'http',
                    'host': '127.0.0.1',
                    'port': hacheck_port,
                    'uri': hacheck_uri,
                    'timeout': healthcheck_timeout_s,
                    'open_timeout': healthcheck_timeout_s,
                    'rise': 1,
                    'fall': 2,
                    'headers': healthcheck_headers,
                }]
            }

    return config