def cdk_prep_team_handler(stack_class: Type["Stack"]) -> None:
    _logger.debug("sys.argv: %s", sys.argv)
    if len(sys.argv) != 5:
        raise ValueError(f"Unexpected number of values in sys.argv ({len(sys.argv)}) - {sys.argv}.")

    stack_name: str = sys.argv[1]
    # team_name: str = sys.argv[3]
    parameters: Dict[str, Any] = _deserialize_parameters(parameters=sys.argv[4])
    context: "Context" = ContextSerDe.load_context_from_ssm(env_name=sys.argv[2], type=Context)

    # Can not find /orbit/env_name/teams ssm param.
    # team_context = context.get_team_by_name(name=team_name)
    # if team_context is None:
    #     raise ValueError(f"Team {team_name} not found in the context.")

    outdir = os.path.join(
        ".orbit.out",
        context.name,
        "cdk",
        stack_name,
    )
    shutil.rmtree(outdir, ignore_errors=True)
    os.makedirs(outdir, exist_ok=True)

    # Can't be imported globally because we only have CDK installed on CodeBuild
    from aws_cdk.core import App

    app = App(outdir=outdir)
    stack_class(app, stack_name, context, parameters)  # type: ignore
    app.synth(force=True)
def deploy_credentials(filename: str, username: str, password: str, registry: str, debug: bool) -> None:
    with MessagesContext("Deploying", debug=debug) as msg_ctx:
        msg_ctx.progress(2)

        manifest: "Manifest" = ManifestSerDe.load_manifest_from_file(filename=filename, type=Manifest)
        msg_ctx.info(f"Manifest loaded: {filename}")
        msg_ctx.progress(3)

        context_parameter_name: str = f"/orbit/{manifest.name}/context"
        if not ssm.does_parameter_exist(name=context_parameter_name):
            msg_ctx.error(f"Orbit Environment {manifest.name} cannot be found in the current account and region.")
            return

        context: "Context" = ContextSerDe.load_context_from_manifest(manifest=manifest)
        msg_ctx.info("Current Context loaded")
        msg_ctx.progress(4)

        msg_ctx.info("Encrypting credentials with Toolkit KMS Key")
        ciphertext = kms.encrypt(
            context=context, plaintext=json.dumps({registry: {"username": username, "password": password}})
        )
        msg_ctx.progress(20)

        msg_ctx.info("Starting Remote CodeBuild to deploy credentials")

        deploy.deploy_credentials(env_name=context.name, ciphertext=ciphertext)

        msg_ctx.info("Registry Credentials deployed")
        msg_ctx.progress(98)

        if cfn.does_stack_exist(stack_name=context.env_stack_name):
            context = ContextSerDe.load_context_from_ssm(env_name=manifest.name, type=Context)
            msg_ctx.info(f"Context updated: {filename}")
        msg_ctx.progress(100)
def deploy_credentials(env_name: str, ciphertext: str) -> None:
    context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env_name, type=Context)
    _logger.debug("Context loaded.")

    @codeseeder.remote_function("orbit", codebuild_role=context.toolkit.admin_role)
    def deploy_credentials(env_name: str, ciphertext: str) -> None:
        new_credentials = json.loads(kms.decrypt(context=context, ciphertext=ciphertext))
        secret_id = f"orbit-{env_name}-docker-credentials"
        existing_credentials = secretsmanager.get_secret_value(secret_id=secret_id)
        for registry, creds in new_credentials.items():
            username = creds.get("username", "")
            password = creds.get("password", "")
            try:
                subprocess.check_call(
                    f"docker login --username '{username}' --password '{password}' {registry}", shell=True
                )
            except Exception as e:
                _logger.error("Invalid Registry Credentials")
                _logger.exception(e)
                return
            else:
                existing_credentials = {**existing_credentials, **new_credentials}
        secretsmanager.put_secret_value(secret_id=secret_id, secret=existing_credentials)
        _logger.debug("Registry Credentials deployed")

    deploy_credentials(env_name=env_name, ciphertext=ciphertext)
def destroy_teams(args: Tuple[str, ...]) -> None:
    _logger.debug("args %s", args)
    env_name: str = args[0]
    context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env_name,
                                                            type=Context)
    _logger.debug("context.name %s", context.name)

    plugins.PLUGINS_REGISTRIES.load_plugins(context=context,
                                            plugin_changesets=[],
                                            teams_changeset=None)
    kubectl.write_kubeconfig(context=context)
    _logger.debug("Plugins loaded")
    for team_context in context.teams:
        plugins.PLUGINS_REGISTRIES.destroy_team_plugins(
            context=context, team_context=team_context)
    _logger.debug("Plugins destroyed")
    for team_context in context.teams:
        helm.destroy_team(context=context, team_context=team_context)
    _logger.debug("Helm Charts uninstalled")
    kubectl.destroy_teams(context=context)
    _logger.debug("Kubernetes Team components destroyed")
    eksctl.destroy_teams(context=context)
    _logger.debug("EKS Team Stacks destroyed")
    teams.destroy_all(context=context)
    _logger.debug("Teams Stacks destroyed")
    ssm.cleanup_teams(env_name=context.name)
def destroy_toolkit(
    env: str,
    debug: bool,
) -> None:
    with MessagesContext("Destroying Environment Toolkit",
                         debug=debug) as msg_ctx:
        msg_ctx.progress(10)

        context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env,
                                                                type=Context)
        msg_ctx.info("Context loaded")
        msg_ctx.progress(25)

        try:
            _destroy_toolkit(env_name=context.name)
        except botocore.exceptions.ClientError as ex:
            error = ex.response["Error"]
            if "does not exist" not in error["Message"]:
                raise
            _logger.debug(f"Skipping toolkit destroy: {error['Message']}")
        msg_ctx.info("Toolkit destroyed")
        ssm.cleanup_env(env_name=context.name)

        msg_ctx.info("Toolkit destroyed")
        msg_ctx.progress(100)
def destroy_env(env: str, debug: bool) -> None:
    with MessagesContext("Destroying", debug=debug) as msg_ctx:
        ssm.cleanup_changeset(env_name=env)
        ssm.cleanup_manifest(env_name=env)

        if ssm.does_parameter_exist(name=f"/orbit/{env}/context") is False:
            msg_ctx.info(f"Environment {env} not found. Destroying only possible remaining resources.")
            elb.delete_load_balancers(env_name=env)
            destroy_remaining_resources(env_name=env, top_level="orbit")
            msg_ctx.progress(100)
            return

        context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env, type=Context)
        msg_ctx.info("Context loaded")
        msg_ctx.info(f"Teams: {','.join([t.name for t in context.teams])}")
        msg_ctx.progress(2)

        if any(cfn.does_stack_exist(stack_name=t.stack_name) for t in context.teams):
            msg_ctx.error("Found Teams dependent on the Envrionment.")
            return

        if (
            cfn.does_stack_exist(stack_name=context.env_stack_name)
            or cfn.does_stack_exist(stack_name=context.toolkit.stack_name)
            or cfn.does_stack_exist(stack_name=context.cdk_toolkit.stack_name)
        ):
            bundle_path = bundle.generate_bundle(command_name="destroy", context=context)
            msg_ctx.progress(5)

            buildspec = codebuild.generate_spec(
                context=context,
                plugins=True,
                cmds_build=[f"orbit remote --command destroy_env {env}"],
                changeset=None,
            )
            remote.run(
                command_name="destroy",
                context=context,
                bundle_path=bundle_path,
                buildspec=buildspec,
                codebuild_log_callback=msg_ctx.progress_bar_callback,
                timeout=45,
            )

        msg_ctx.info("Env destroyed")
        msg_ctx.progress(95)

        try:
            destroy_toolkit(env_name=context.name)
        except botocore.exceptions.ClientError as ex:
            error = ex.response["Error"]
            if "does not exist" not in error["Message"]:
                raise
            _logger.debug(f"Skipping toolkit destroy: {error['Message']}")
        msg_ctx.info("Toolkit destroyed")
        ssm.cleanup_env(env_name=context.name)

        msg_ctx.progress(100)
def build_image(
    env: str,
    dir: Optional[str],
    name: str,
    script: Optional[str],
    build_args: Optional[List[str]],
    timeout: int = 30,
    debug: bool = False,
    source_registry: Optional[str] = None,
    source_repository: Optional[str] = None,
    source_version: Optional[str] = None,
) -> None:
    with MessagesContext("Deploying Docker Image", debug=debug) as msg_ctx:
        context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env, type=Context)
        msg_ctx.info("Manifest loaded")
        if cfn.does_stack_exist(stack_name=f"orbit-{context.name}") is False:
            msg_ctx.error("Please, deploy your environment before deploying any additional docker image")
            return
        msg_ctx.progress(3)
        if dir:
            dirs = [(dir, name)]
        else:
            dirs = []
        bundle_path = bundle.generate_bundle(command_name=f"deploy_image-{name}", context=context, dirs=dirs)
        msg_ctx.progress(5)

        script_str = "NO_SCRIPT" if script is None else script
        source_str = "NO_REPO" if source_registry is None else f"{source_registry} {source_repository} {source_version}"
        build_args = [] if build_args is None else build_args
        buildspec = codebuild.generate_spec(
            context=context,
            plugins=False,
            cmds_build=[
                f"orbit remote --command build_image " f"{env} {name} {script_str} {source_str} {' '.join(build_args)}"
            ],
            changeset=None,
        )
        msg_ctx.progress(6)

        remote.run(
            command_name=f"deploy_image-{name}",
            context=context,
            bundle_path=bundle_path,
            buildspec=buildspec,
            codebuild_log_callback=msg_ctx.progress_bar_callback,
            timeout=timeout,
        )
        msg_ctx.info("Docker Image deploy into ECR")

        address = (
            f"{context.account_id}.dkr.ecr.{context.region}.amazonaws.com/orbit-{context.name}/{name}"
            if name in [n.replace("_", "-") for n in context.images.names]
            else f"{context.account_id}.dkr.ecr.{context.region}.amazonaws.com/orbit-{context.name}/users/{name}"
        )

        msg_ctx.info(f"ECR Image Address={address}")
        msg_ctx.tip(f"ECR Image Address: {stylize(address, underline=True)}")
        msg_ctx.progress(100)
Exemple #8
0
def list_env(env: str, variable: str) -> None:
    ssm = utils.boto3_client("ssm")
    res = ssm.get_parameters_by_path(Path="/orbit", Recursive=True)
    env_info: Dict[str, str] = {}
    while True:
        params = res["Parameters"]
        for p in params:
            if not p["Name"].endswith("context") or "teams" in p["Name"]:
                continue
            if len(env) > 0 and p["Name"].startswith(f"//orbit/{env}"):
                continue
            env_name = p["Name"].split("/")[2]
            context: "Context" = ContextSerDe.load_context_from_ssm(
                env_name=env_name, type=Context)
            _logger.debug(f"found env: {env_name}")
            if context.k8_dashboard_url:
                k8_dashboard_url = context.k8_dashboard_url
            else:
                k8_dashboard_url = ""
            if len(context.teams) > 0:
                teams_list: str = ",".join([x.name for x in context.teams])
            else:
                teams_list = ""

            if variable == "landing-page":
                print(context.landing_page_url)
            elif variable == "toolkitbucket":
                print(context.toolkit.s3_bucket)
            elif variable == "teams":
                print(f"[{teams_list}]")
            elif variable == "all":
                env_info[env_name] = (
                    f"LandingPage={context.landing_page_url}, "
                    f"Teams=[{teams_list}], "
                    f"ToolkitBucket={context.toolkit.s3_bucket}"
                    f"K8Dashboard={k8_dashboard_url}")
            else:
                raise Exception(f"Unknown --variable option {variable}")

        if "NextToken" in res:
            res = ssm.get_parameters_by_path(Path="/orbit",
                                             Recursive=True,
                                             NextToken=res["NextToken"])
        else:
            break

    if variable == "all":
        if len(env_info) == 0:
            click.echo("There are no Orbit environments available")
            return
        else:
            print_list(
                tittle="Available Orbit environments:",
                items=[
                    f"Name={k}{stylize(',')}{v}" for k, v in env_info.items()
                ],
            )
Exemple #9
0
def destroy_foundation(args: Tuple[str, ...]) -> None:
    _logger.debug("args %s", args)
    env_name: str = args[0]
    context: "FoundationContext" = ContextSerDe.load_context_from_ssm(env_name=env_name, type=FoundationContext)
    _logger.debug("context.name %s", context.name)

    foundation.destroy(context=context)
    _logger.debug("Demo Stack destroyed")
    cdk_toolkit.destroy(context=context)
    _logger.debug("CDK Toolkit Stack destroyed")
def list_env(env: str, variable: str) -> None:
    ssm = utils.boto3_client("ssm")
    res = ssm.get_parameters_by_path(Path="/orbit", Recursive=True)
    env_info: Dict[str, Any] = {}
    if env and len(env) > 0:
        _logger.debug(f"looking for {env}")
    while True:
        params = res["Parameters"]
        for p in params:
            if not p["Name"].endswith("context") or "teams" in p["Name"]:
                continue
            env_name = p["Name"].split("/")[2]
            if len(env) > 0 and not env_name == env:
                continue
            env_name = p["Name"].split("/")[2]
            context: "Context" = ContextSerDe.load_context_from_ssm(
                env_name=env_name, type=Context)
            _logger.debug(f"found env: {env_name}")
            if context.k8_dashboard_url:
                k8_dashboard_url = context.k8_dashboard_url
            else:
                k8_dashboard_url = ""
            if len(context.teams) > 0:
                teams_list: List[str] = [x.name for x in context.teams]
            else:
                teams_list = []

            if variable == "landing-page":
                print(context.landing_page_url)
            elif variable == "toolkitbucket":
                print(context.toolkit.s3_bucket)
            elif variable == "all":
                env_info[env_name] = {
                    "LandingPage": context.landing_page_url,
                    "Teams": teams_list,
                    "ToolkitBucket": context.toolkit.s3_bucket,
                    "K8Dashboard": k8_dashboard_url,
                }
            else:
                raise Exception(f"Unknown --variable option {variable}")

        if "NextToken" in res:
            res = ssm.get_parameters_by_path(Path="/orbit",
                                             Recursive=True,
                                             NextToken=res["NextToken"])
        else:
            break

    if variable == "all":
        if len(env_info) == 0:
            click.echo("There are no Orbit environments available")
            return
        else:
            print("Available Orbit environments:")
            print(json.dumps(env_info, indent=4, sort_keys=True))
def _deploy_image(
    env: str,
    dir: str,
    name: str,
    script: Optional[str],
    build_args: Optional[List[str]],
    region: Optional[str],
    debug: bool,
) -> None:
    with MessagesContext("Deploying Docker Image", debug=debug) as msg_ctx:
        context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env,
                                                                type=Context)

        if cfn.does_stack_exist(stack_name=f"orbit-{context.name}") is False:
            msg_ctx.error(
                "Please, deploy your environment before deploy any addicional docker image"
            )
            return

        plugins.PLUGINS_REGISTRIES.load_plugins(
            context=context,
            msg_ctx=msg_ctx,
            plugin_changesets=[],
            teams_changeset=None,
        )
        msg_ctx.progress(3)

        bundle_path = bundle.generate_bundle(
            command_name=f"deploy_image-{name}",
            context=context,
            dirs=[(dir, name)])
        msg_ctx.progress(4)
        script_str = "NO_SCRIPT" if script is None else script
        build_args = [] if build_args is None else build_args
        buildspec = codebuild.generate_spec(
            context=context,
            plugins=True,
            cmds_build=[
                f"orbit remote --command _deploy_image {env} {name} {dir} {script_str} {' '.join(build_args)}"
            ],
            changeset=None,
        )
        remote.run(
            command_name=f"deploy_image-{name}",
            context=context,
            bundle_path=bundle_path,
            buildspec=buildspec,
            codebuild_log_callback=msg_ctx.progress_bar_callback,
            timeout=30,
        )
        msg_ctx.info("Docker Image deploy into ECR")
        address = f"{context.account_id}.dkr.ecr.{context.region}.amazonaws.com/orbit-{context.name}-{name}"
        msg_ctx.tip(f"ECR Image Address: {stylize(address, underline=True)}")
        msg_ctx.progress(100)
def destroy_images(env: str) -> None:
    context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env,
                                                            type=Context)
    _logger.debug("env %s", env)

    @codeseeder.remote_function("orbit",
                                codebuild_role=context.toolkit.admin_role)
    def destroy_images(env: str) -> None:
        ecr.cleanup_remaining_repos(env_name=env)

    destroy_images(env=env)
def destroy_foundation(env: str, debug: bool) -> None:
    with MessagesContext("Destroying", debug=debug) as msg_ctx:
        ssm.cleanup_changeset(env_name=env, top_level="orbit-foundation")
        ssm.cleanup_manifest(env_name=env, top_level="orbit-foundation")

        if ssm.does_parameter_exist(name=f"/orbit-foundation/{env}/context") is False:
            msg_ctx.info(f"Foundation {env} not found. Destroying only possible remaining resources.")
            destroy_remaining_resources(env_name=env, top_level="orbit-foundation")
            msg_ctx.progress(100)
            return

        context: "FoundationContext" = ContextSerDe.load_context_from_ssm(env_name=env, type=FoundationContext)
        msg_ctx.info("Context loaded")
        msg_ctx.progress(2)

        msg_ctx.progress(4)

        if (
            cfn.does_stack_exist(stack_name=cast(str, context.stack_name))
            or cfn.does_stack_exist(stack_name=context.toolkit.stack_name)
            or cfn.does_stack_exist(stack_name=context.cdk_toolkit.stack_name)
        ):
            bundle_path = bundle.generate_bundle(command_name="destroy", context=cast(Context, context))
            msg_ctx.progress(5)

            buildspec = codebuild.generate_spec(
                context=cast(Context, context),
                plugins=False,
                cmds_build=[f"orbit remote --command destroy_foundation {env}"],
                changeset=None,
            )
            remote.run(
                command_name="destroy",
                context=cast(Context, context),
                bundle_path=bundle_path,
                buildspec=buildspec,
                codebuild_log_callback=msg_ctx.progress_bar_callback,
                timeout=45,
            )
        msg_ctx.info("Foundation destroyed")
        msg_ctx.progress(95)

        try:
            destroy_toolkit(env_name=context.name, top_level="orbit-foundation")
        except botocore.exceptions.ClientError as ex:
            error = ex.response["Error"]
            if "does not exist" not in error["Message"]:
                raise
            _logger.debug(f"Skipping toolkit destroy: {error['Message']}")
        msg_ctx.info("Toolkit destroyed")
        ssm.cleanup_env(env_name=context.name, top_level="orbit-foundation")

        msg_ctx.progress(100)
def deploy_teams(
    filename: str,
    debug: bool,
) -> None:
    with MessagesContext("Deploying", debug=debug) as msg_ctx:
        msg_ctx.progress(2)

        manifest: "Manifest" = ManifestSerDe.load_manifest_from_file(filename=filename, type=Manifest)
        msg_ctx.info(f"Manifest loaded: {filename}")
        msg_ctx.info(f"Teams: {','.join([t.name for t in manifest.teams])}")
        msg_ctx.progress(5)

        manifest_dir: str = os.path.dirname(os.path.abspath(filename))
        _logger.debug("manifest directory is set to %s", manifest_dir)

        context_parameter_name: str = f"/orbit/{manifest.name}/context"
        if not ssm.does_parameter_exist(name=context_parameter_name):
            msg_ctx.error(f"Orbit Environment {manifest.name} cannot be found in the current account and region.")
            return

        context: "Context" = ContextSerDe.load_context_from_manifest(manifest=manifest)
        msg_ctx.info("Current Context loaded")
        msg_ctx.info(f"Teams: {','.join([t.name for t in context.teams])}")
        msg_ctx.progress(10)

        _logger.debug("Inspecting possible manifest changes...")
        changeset: "Changeset" = extract_changeset(manifest=manifest, context=context, msg_ctx=msg_ctx)
        _logger.debug(f"Changeset:\n{dump_changeset_to_str(changeset=changeset)}")

        msg_ctx.progress(30)

        deploy.deploy_teams(
            env_name=context.name,
            manifest_dir=manifest_dir,
        )

        msg_ctx.info("Orbit Workbench deployed")
        msg_ctx.progress(98)

        if cfn.does_stack_exist(stack_name=context.env_stack_name):
            context = ContextSerDe.load_context_from_ssm(env_name=manifest.name, type=Context)
            msg_ctx.info(f"Context updated: {filename}")
        msg_ctx.progress(99)

        if context.user_pool_id:
            cognito_users_url = orbit_cognito.get_users_url(user_pool_id=context.user_pool_id, region=context.region)
            msg_ctx.tip(f"Add users: {stylize(cognito_users_url, underline=True)}")

        if context.landing_page_url:
            msg_ctx.tip(f"Access Orbit Workbench: {stylize(f'{context.landing_page_url}/orbit/login', underline=True)}")
        else:
            raise RuntimeError("Landing Page URL not found.")
        msg_ctx.progress(100)
Exemple #15
0
def main() -> None:
    _logger.debug("sys.argv: %s", sys.argv)
    if len(sys.argv) == 3:
        context: "Context" = ContextSerDe.load_context_from_ssm(
            env_name=sys.argv[1], type=Context)
        team_name: str = sys.argv[2]
    else:
        raise ValueError("Unexpected number of values in sys.argv.")

    changeset: Optional["Changeset"] = load_changeset_from_ssm(
        env_name=context.name)
    _logger.debug("Changeset loaded.")

    team_policies: Optional[List[str]] = None
    image: Optional[str] = None

    if changeset and changeset.teams_changeset and team_name in changeset.teams_changeset.added_teams_names:
        manifest: Optional["Manifest"] = ManifestSerDe.load_manifest_from_ssm(
            env_name=sys.argv[1], type=Manifest)
        if manifest is None:
            raise ValueError("manifest is None!")
        team_manifest: Optional["TeamManifest"] = manifest.get_team_by_name(
            name=team_name)
        if team_manifest:
            team_policies = team_manifest.policies
            image = team_manifest.image
        else:
            raise ValueError(f"{team_name} not found in manifest!")
    else:
        team_context: Optional["TeamContext"] = context.get_team_by_name(
            name=team_name)
        if team_context:
            team_policies = team_context.policies
            image = team_context.image
        else:
            raise ValueError(f"Team {team_name} not found in the context.")

    if team_policies is None:
        raise ValueError("team_policies is None!")

    stack_name: str = f"orbit-{context.name}-{team_name}"
    outdir = os.path.join(".orbit.out", context.name, "cdk", stack_name)
    os.makedirs(outdir, exist_ok=True)
    shutil.rmtree(outdir)
    app = App(outdir=outdir)
    Team(scope=app,
         id=stack_name,
         context=context,
         team_name=team_name,
         team_policies=team_policies,
         image=image)
    app.synth(force=True)
def deploy_foundation(args: Tuple[str, ...]) -> None:
    _logger.debug("args: %s", args)
    if len(args) != 1:
        raise ValueError("Unexpected number of values in args")
    env_name: str = args[0]
    context: "FoundationContext" = ContextSerDe.load_context_from_ssm(env_name=env_name, type=FoundationContext)
    _logger.debug("Context loaded.")
    docker.login(context=context)
    _logger.debug("DockerHub and ECR Logged in")
    cdk_toolkit.deploy(context=context)
    _logger.debug("CDK Toolkit Stack deployed")
    foundation.deploy(context=context)
    _logger.debug("Demo Stack deployed")
def _deploy_remote_image(
    path: str,
    image_name: str,
    env: str,
    script: Optional[str],
    build_args: Optional[List[str]] = [],
    timeout: int = 120,
) -> None:
    _logger.debug(f"_deploy_remote_image_v2 args: {path} {image_name} {script} {env}")
    context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env, type=Context)
    _logger.debug(f"context loaded: {env}")
    pre_build_commands = []
    extra_dirs = {image_name: path}
    # the script is relative to the bundle on codeseeder
    if script:
        pre_build_commands = [f"bash {image_name}/{script}"]
    if os.path.exists(os.path.join(path, "toolkit_helper.json")):
        f = os.path.join(path, "toolkit_helper.json")
        helper = json.loads(_load_toolkit_helper(file_path=f, image_name=image_name, env=env))
        _logger.debug(helper)
        if helper.get("extra_dirs"):
            extra_dirs = {**extra_dirs, **helper["extra_dirs"]}
        if helper.get("build_args"):
            build_args = [*build_args, *helper["build_args"]]  # type: ignore
        if helper.get("pre_build_commands"):
            pre_build_commands = [*build_args, *helper["pre_build_commands"]]  # type: ignore

    else:
        _logger.debug("No Toolkit Helper")

    team_env = os.environ.get("AWS_ORBIT_TEAM_SPACE", None)
    team_role = context.get_team_by_name(team_env).eks_pod_role_arn if team_env else None  # type: ignore
    service_role = team_role if team_role else context.toolkit.admin_role
    _logger.debug(f"service_role: {service_role}")
    _logger.debug(f"extra_dirs: {extra_dirs}")
    _logger.debug(f"build_arg: {build_args}")

    @codeseeder.remote_function(
        "orbit",
        codebuild_role=service_role,
        extra_dirs=extra_dirs,
        bundle_id=image_name,
        extra_pre_build_commands=pre_build_commands,
        timeout=timeout,
    )
    def _deploy_remote_image(path: str, image_name: str, env: str, build_args: List[str]) -> None:
        _logger.info(f"running ...{image_name} at {path}")
        _deploy_user_image(path=path, image_name=image_name, env=env, build_args=build_args)

    _deploy_remote_image(path, image_name, env, build_args)
Exemple #18
0
def delete_image(args: Tuple[str, ...]) -> None:
    _logger.debug("args %s", args)
    env_name: str = args[0]
    context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env_name, type=Context)

    if len(args) == 2:
        image_name: str = args[1]
    else:
        raise ValueError("Unexpected number of values in args.")

    env.deploy(context=context, add_images=[], remove_images=[image_name], eks_system_masters_roles_changes=None)
    _logger.debug("Env changes deployed")
    ecr.delete_repo(repo=f"orbit-{context.name}-{image_name}")
    _logger.debug("Docker Image Destroyed from ECR")
Exemple #19
0
def destroy_env(args: Tuple[str, ...]) -> None:
    _logger.debug("args %s", args)
    env_name: str = args[0]
    context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env_name, type=Context)
    _logger.debug("context.name %s", context.name)

    kubectl.destroy_env(context=context)
    _logger.debug("Kubernetes Environment components destroyed")
    eksctl.destroy_env(context=context)
    _logger.debug("EKS Environment Stacks destroyed")
    env.destroy(context=context)
    _logger.debug("Env Stack destroyed")
    cdk_toolkit.destroy(context=context)
    _logger.debug("CDK Toolkit Stack destroyed")
Exemple #20
0
def list_images(env: str, region: Optional[str]) -> None:
    context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env,
                                                            type=Context)
    names = utils.extract_images_names(env_name=env)
    if names:
        print_list(
            tittle=
            f"Available docker images into the {stylize(context.name)} env:",
            items=[k for k in names],
        )
    else:
        click.echo(
            f"There is no docker image(s) into the {stylize(context.name)} env."
        )
def destroy_foundation(env_name: str) -> None:
    context: "FoundationContext" = ContextSerDe.load_context_from_ssm(
        env_name=env_name, type=FoundationContext)
    _logger.debug("context.name %s", context.name)

    @codeseeder.remote_function("orbit",
                                codebuild_role=context.toolkit.admin_role)
    def destroy_foundation(env_name: str) -> None:
        foundation.destroy(context=context)
        _logger.debug("Demo Stack destroyed")
        cdk_toolkit.destroy(context=context)
        _logger.debug("CDK Toolkit Stack destroyed")

    destroy_foundation(env_name)
def deploy_env(env_name: str, manifest_dir: str) -> None:
    _logger.debug("env_name: %s", env_name)
    manifest: Optional[Manifest] = ManifestSerDe.load_manifest_from_ssm(env_name=env_name, type=Manifest)
    _logger.debug("Manifest loaded.")
    context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env_name, type=Context)
    _logger.debug("Context loaded.")
    changeset: Optional["Changeset"] = load_changeset_from_ssm(env_name=env_name)
    _logger.debug("Changeset loaded.")

    if manifest is None:
        raise Exception("Unable to load Manifest")

    @codeseeder.remote_function(
        "orbit",
        codebuild_role=context.toolkit.admin_role,
        extra_dirs={
            "manifests": manifest_dir,
        },
    )
    def deploy_env(env_name: str, manifest_dir: str) -> None:
        docker.login(context=context)
        _logger.debug("DockerHub and ECR Logged in")
        cdk_toolkit.deploy(context=context)
        _logger.debug("CDK Toolkit Stack deployed")
        env.deploy(
            context=context,
            eks_system_masters_roles_changes=changeset.eks_system_masters_roles_changeset if changeset else None,
        )

        _logger.debug("Env Stack deployed")
        eksctl.deploy_env(
            context=context,
            changeset=changeset,
        )
        _logger.debug("EKS Environment Stack deployed")
        kubectl.deploy_env(context=context)
        _logger.debug("Kubernetes Environment components deployed")

        helm.deploy_env(context=context)
        _logger.debug("Helm Charts installed")

        k8s_context = utils.get_k8s_context(context=context)
        kubectl.fetch_kubectl_data(context=context, k8s_context=k8s_context)
        ContextSerDe.dump_context_to_ssm(context=context)
        _logger.debug("Updating userpool redirect")
        _update_userpool_client(context=context)
        _update_userpool(context=context)

    deploy_env(env_name=env_name, manifest_dir=manifest_dir)
def destroy_env(env: str, preserve_credentials: bool, debug: bool) -> None:
    with MessagesContext("Destroying", debug=debug) as msg_ctx:
        ssm.cleanup_changeset(env_name=env)
        ssm.cleanup_manifest(env_name=env)

        if ssm.does_parameter_exist(name=f"/orbit/{env}/context") is False:
            msg_ctx.info(
                f"Environment {env} not found. Destroying only possible remaining resources."
            )
            elb.delete_load_balancers(env_name=env)
            destroy_remaining_resources(env_name=env, top_level="orbit")
            msg_ctx.progress(100)
            return

        msg_ctx.progress(15)
        context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env,
                                                                type=Context)
        msg_ctx.info("Context loaded")
        msg_ctx.info(f"Teams: {','.join([t.name for t in context.teams])}")

        if any(
                cfn.does_stack_exist(stack_name=t.stack_name)
                for t in context.teams):
            raise click.ClickException(
                "Found Teams dependent on the Envrionment.")

        if (cfn.does_stack_exist(stack_name=context.env_stack_name)
                or cfn.does_stack_exist(stack_name=context.toolkit.stack_name)
                or cfn.does_stack_exist(
                    stack_name=context.cdk_toolkit.stack_name)):
            msg_ctx.progress(50)
            destroy.destroy_env(env_name=context.name)

        if not preserve_credentials:
            secretsmanager.delete_docker_credentials(
                secret_id=f"orbit-{context.name}-docker-credentials")
            _logger.info("Removed docker credentials from SecretsManager")

        try:
            if context.cdk_toolkit.s3_bucket:
                s3.delete_bucket(bucket=context.cdk_toolkit.s3_bucket)
        except Exception as ex:
            _logger.debug(
                "Skipping Environment CDK Toolkit bucket deletion. Cause: %s",
                ex)

        msg_ctx.info("Env destroyed leaving the Env toolkit")

        msg_ctx.progress(100)
def deploy_foundation(env_name: str) -> None:
    _logger.debug("env_name: %s", env_name)
    context: "FoundationContext" = ContextSerDe.load_context_from_ssm(env_name=env_name, type=FoundationContext)
    _logger.debug("Context loaded.")

    @codeseeder.remote_function("orbit", codebuild_role=context.toolkit.admin_role)
    def deploy_foundation(env_name: str) -> None:
        docker.login(context=context)
        _logger.debug("DockerHub and ECR Logged in")
        cdk_toolkit.deploy(context=context)
        _logger.debug("CDK Toolkit Stack deployed")
        foundation.deploy(context=context)
        _logger.debug("Demo Stack deployed")

    deploy_foundation(env_name=env_name)
def destroy_credentials(env: str, registry: str, debug: bool) -> None:
    with MessagesContext("Destroying", debug=debug) as msg_ctx:
        context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env,
                                                                type=Context)
        msg_ctx.info("Context loaded")
        msg_ctx.progress(2)

        if any(
                cfn.does_stack_exist(stack_name=t.stack_name)
                for t in context.teams):
            destroy.destroy_credentials(env_name=env, registry=registry)
        msg_ctx.progress(95)

        msg_ctx.info("Registry Credentials Destroyed")
        msg_ctx.progress(100)
def delete_image(env_name: str, image_name: str) -> None:
    _logger.debug("env_name: %s, image_name: %s", env_name, image_name)
    context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env_name,
                                                            type=Context)
    _logger.debug("context.name %s", context.name)

    @codeseeder.remote_function("orbit",
                                codebuild_role=context.toolkit.admin_role)
    def delete_image(env_name: str, image_name: str) -> None:
        env.deploy(context=context, eks_system_masters_roles_changes=None)
        _logger.debug("Env changes deployed")
        ecr.delete_repo(repo=f"orbit-{context.name}/users/{image_name}")
        _logger.debug("Docker Image Destroyed from ECR")

    delete_image(env_name=env_name, image_name=image_name)
def list_images(env: str, region: Optional[str]) -> None:
    context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env,
                                                            type=Context)
    names = utils.extract_images_names(env_name=env)
    _logger.debug("names: %s", names)
    if names:
        uris = _fetch_repo_uri(names=names, context=context)
        print_list(
            tittle=
            f"Available docker images into the {stylize(context.name)} env:",
            items=[f"{k} {stylize(':')} {v}" for k, v in uris.items()],
        )
    else:
        click.echo(
            f"Thre is no docker images into the {stylize(context.name)} env.")
Exemple #28
0
def destroy_teams(env: str, debug: bool) -> None:
    with MessagesContext("Destroying", debug=debug) as msg_ctx:
        ssm.cleanup_changeset(env_name=env)

        if not ssm.list_parameters(prefix=f"/orbit/{env}/teams/"):
            msg_ctx.info(f"No {env} Teams found.")
            msg_ctx.progress(100)
            return

        context: "Context" = ContextSerDe.load_context_from_ssm(env_name=env,
                                                                type=Context)
        msg_ctx.info("Context loaded")
        msg_ctx.info(f"Teams: {','.join([t.name for t in context.teams])}")
        msg_ctx.progress(2)

        plugins.PLUGINS_REGISTRIES.load_plugins(
            context=context,
            msg_ctx=msg_ctx,
            plugin_changesets=[],
            teams_changeset=None,
        )
        msg_ctx.progress(4)

        if any(
                cfn.does_stack_exist(stack_name=t.stack_name)
                for t in context.teams):
            bundle_path = bundle.generate_bundle(command_name="destroy",
                                                 context=context)
            msg_ctx.progress(5)

            buildspec = codebuild.generate_spec(
                context=context,
                plugins=True,
                cmds_build=[f"orbit remote --command destroy_teams {env}"],
                changeset=None,
            )
            remote.run(
                command_name="destroy",
                context=context,
                bundle_path=bundle_path,
                buildspec=buildspec,
                codebuild_log_callback=msg_ctx.progress_bar_callback,
                timeout=45,
            )
        msg_ctx.progress(95)

        msg_ctx.info("Teams Destroyed")
        msg_ctx.progress(100)
def main() -> None:
    _logger.debug("sys.argv: %s", sys.argv)
    if len(sys.argv) == 2:
        context: "FoundationContext" = ContextSerDe.load_context_from_ssm(
            env_name=sys.argv[1], type=FoundationContext)
    else:
        raise ValueError("Unexpected number of values in sys.argv.")

    outdir = os.path.join(".orbit.out", context.name, "cdk",
                          cast(str, context.stack_name))
    os.makedirs(outdir, exist_ok=True)
    shutil.rmtree(outdir)

    app = App(outdir=outdir)
    FoundationStack(scope=app,
                    id=cast(str, context.stack_name),
                    context=context)
    app.synth(force=True)
Exemple #30
0
def main() -> None:
    _logger.debug("sys.argv: %s", sys.argv)
    if len(sys.argv) == 2:
        context: "Context" = ContextSerDe.load_context_from_ssm(env_name=sys.argv[1], type=Context)
    else:
        raise ValueError(f"Unexpected number of values in sys.argv ({len(sys.argv)}), {sys.argv}")

    outdir = os.path.join(".orbit.out", context.name, "cdk", context.env_stack_name)
    os.makedirs(outdir, exist_ok=True)
    shutil.rmtree(outdir)

    app = App(outdir=outdir)
    Env(
        scope=app,
        id=context.env_stack_name,
        context=context,
    )
    app.synth(force=True)