Exemple #1
0
def main(services_path: str, endpoint_path: Optional[str]):
    k8s_resources = parse_yaml(open(services_path, 'r').read())
    total_resources = len(k8s_resources)

    services = [
        obj for obj in k8s_resources if obj.get('kind', None) == 'Service'
    ]

    app.elements = {'services': services}

    if endpoint_path:
        k8s_resources = parse_yaml(open(endpoint_path, 'r').read())
        total_resources += len(k8s_resources)

        app.elements['endpoints'] = [
            obj for obj in k8s_resources
            if obj.get('kind', None) == 'Endpoints'
        ]

    print("Total resources: %d" % total_resources)
    print("Services:        %d" % len(app.elements['services']))
    print("Endpoints:       %d" % len(app.elements.get('endpoints', [])))

    app.run(host='0.0.0.0', port=9999, debug=True)
def main(k8s_yaml_paths: List[str],
         debug: bool,
         force_pod_labels: bool,
         update: bool,
         source: List[str],
         labels: List[str],
         namespace: Optional[str],
         watch: str,
         include_ir: bool,
         include_aconf: bool,
         diff_path: Optional[str] = None,
         kat_name: Optional[str] = None) -> None:
    loglevel = logging.DEBUG if debug else logging.INFO

    logging.basicConfig(
        level=loglevel,
        format="%(asctime)s mockery %(levelname)s: %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S")

    logger = logging.getLogger('mockery')

    logger.debug(f"reading from {k8s_yaml_paths}")

    if not source:
        source = [
            "Host", "service", "ingresses", "AuthService", "LogService",
            "Mapping", "Module", "RateLimitService", "TCPMapping",
            "TLSContext", "TracingService", "ConsulResolver",
            "KubernetesEndpointResolver", "KubernetesServiceResolver"
        ]

    if namespace:
        os.environ['AMBASSADOR_NAMESPACE'] = namespace

    # Make labels a list, instead of a tuple.
    labels = list(labels)
    labels_to_force = {l: True for l in labels or []}

    if kat_name:
        logger.debug(f"KAT name {kat_name}")

        # First set up some labels to force.

        labels_to_force["scope=AmbassadorTest"] = True
        labels_to_force[f"service={kat_name}"] = True

        kat_amb_id_label = f"kat-ambassador-id={kat_name}"

        if kat_amb_id_label not in labels_to_force:
            labels_to_force[kat_amb_id_label] = True
            labels.append(kat_amb_id_label)

        os.environ['AMBASSADOR_ID'] = kat_name

        # Forcibly override the cached ambassador_id.
        Config.ambassador_id = kat_name

    logger.debug(f"namespace {namespace or '*'}")
    logger.debug(f"labels to watch {', '.join(labels)}")
    logger.debug(
        f"labels to force {', '.join(sorted(labels_to_force.keys()))}")
    logger.debug(f"watch hook {watch}")
    logger.debug(f"sources {', '.join(source)}")

    for key in sorted(os.environ.keys()):
        if key.startswith('AMBASSADOR'):
            logger.debug(f"${key}={os.environ[key]}")

    if force_pod_labels:
        try:
            os.makedirs("/tmp/ambassador-pod-info")
        except OSError as e:
            if e.errno != errno.EEXIST:
                raise

        with open("/tmp/ambassador-pod-info/labels", "w",
                  encoding="utf-8") as outfile:
            for l in labels_to_force:
                outfile.write(l)
                outfile.write("\n")

    # Pull in the YAML.
    input_yaml = ''.join([open(x, "r").read() for x in k8s_yaml_paths])
    manifest = parse_yaml(input_yaml)

    w = Mockery(logger, debug, source, ",".join(labels), namespace, watch)

    iteration = 0

    while True:
        iteration += 1

        if iteration > 10:
            print(f"!!!! Not stable after 10 iterations, failing")
            logger.error("Not stable after 10 iterations, failing")
            sys.exit(1)

        logger.info(f"======== START ITERATION {iteration}")

        w.load(manifest)

        logger.info(f"WATT_K8S: {w.snapshot}")

        hook_ok, any_changes = w.run_hook()

        if not hook_ok:
            raise Exception("hook failed")

        if any_changes:
            logger.info(
                f"======== END ITERATION {iteration}: watches changed!")
        else:
            logger.info(f"======== END ITERATION {iteration}: stable!")
            break

    # Once here, we should be good to go.
    try:
        os.makedirs("/tmp/ambassador/snapshots")
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise

    scc = MockSecretHandler(logger, "mockery", "/tmp/ambassador/snapshots",
                            f"v{iteration}")

    aconf = Config()

    logger.debug(f"Config.ambassador_id {Config.ambassador_id}")
    logger.debug(f"Config.ambassador_namespace {Config.ambassador_namespace}")

    logger.info(f"STABLE WATT_K8S: {w.snapshot}")

    fetcher = ResourceFetcher(logger, aconf)
    fetcher.parse_watt(w.snapshot)
    aconf.load_all(fetcher.sorted())

    open("/tmp/ambassador/snapshots/aconf.json", "w",
         encoding="utf-8").write(aconf.as_json())

    ir = IR(aconf, secret_handler=scc)

    open("/tmp/ambassador/snapshots/ir.json", "w",
         encoding="utf-8").write(ir.as_json())

    econf = EnvoyConfig.generate(ir, "V2")
    bootstrap_config, ads_config, clustermap = econf.split_config()

    ads_config.pop('@type', None)
    with open("/tmp/ambassador/snapshots/econf.json", "w",
              encoding="utf-8") as outfile:
        outfile.write(dump_json(ads_config, pretty=True))

    with open("/tmp/ambassador/snapshots/bootstrap.json",
              "w",
              encoding="utf-8") as outfile:
        outfile.write(dump_json(bootstrap_config, pretty=True))

    diag = Diagnostics(ir, econf)

    with open("/tmp/ambassador/snapshots/diag.json", "w",
              encoding="utf-8") as outfile:
        outfile.write(dump_json(diag.as_dict(), pretty=True))

    if diff_path:
        diffs = False

        pairs_to_check = [(os.path.join(diff_path, 'snapshots', 'econf.json'),
                           '/tmp/ambassador/snapshots/econf.json'),
                          (os.path.join(diff_path, 'bootstrap-ads.json'),
                           '/tmp/ambassador/snapshots/bootstrap.json')]

        if include_ir:
            pairs_to_check.append(
                (os.path.join(diff_path, 'snapshots',
                              'ir.json'), '/tmp/ambassador/snapshots/ir.json'))

        if include_aconf:
            pairs_to_check.append((os.path.join(diff_path, 'snapshots',
                                                'aconf.json'),
                                   '/tmp/ambassador/snapshots/aconf.json'))

        for gold_path, check_path in pairs_to_check:
            if update:
                logger.info(f"mv {check_path} {gold_path}")
                shutil.move(check_path, gold_path)
            elif not filecmp.cmp(gold_path, check_path):
                diffs = True

                gold_lines = open(gold_path, "r", encoding="utf-8").readlines()
                check_lines = open(check_path, "r",
                                   encoding="utf-8").readlines()

                for line in difflib.unified_diff(gold_lines,
                                                 check_lines,
                                                 fromfile=gold_path,
                                                 tofile=check_path):
                    sys.stdout.write(line)

        if diffs:
            sys.exit(1)
Exemple #3
0
def k8s_object_from_yaml(yaml: str) -> KubernetesObject:
    return KubernetesObject(parse_yaml(yaml)[0])
Exemple #4
0
def k8s_object_from_yaml(yaml: str, **kwargs) -> KubernetesObject:
    return KubernetesObject(parse_yaml(yaml)[0], **kwargs)