Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
 def load_context_from_ssm(env_name: str, type: Type[V]) -> V:
     if type is Context:
         context_parameter_name: str = f"/orbit/{env_name}/context"
         if ssm.does_parameter_exist(context_parameter_name):
             main = ssm.get_parameter(name=context_parameter_name)
         else:
             msg = f"SSM parameter {context_parameter_name} not found for env {env_name}"
             _logger.error(msg)
             raise Exception(msg)
         teams_parameters = ssm.list_parameters(
             prefix=f"/orbit/{env_name}/teams/")
         _logger.debug("teams_parameters: %s", teams_parameters)
         teams = [
             ssm.get_parameter_if_exists(name=p) for p in teams_parameters
             if p.endswith("/context")
         ]
         main["Teams"] = [t for t in teams if t]
         return cast(
             V,
             Context.Schema().load(data=main,
                                   many=False,
                                   partial=False,
                                   unknown="RAISE"))
     elif type is FoundationContext:
         context_parameter_name = f"/orbit-foundation/{env_name}/context"
         main = ssm.get_parameter(name=context_parameter_name)
         return cast(
             V,
             FoundationContext.Schema().load(data=main,
                                             many=False,
                                             partial=False,
                                             unknown="RAISE"))
     else:
         raise ValueError("Unknown 'context' Type")
Ejemplo n.º 3
0
    def _load_context_from_manifest(manifest: "Manifest") -> Context:
        _logger.debug("Loading Context from manifest")
        context_parameter_name: str = f"/orbit/{manifest.name}/context"
        if ssm.does_parameter_exist(name=context_parameter_name):
            context: Context = ContextSerDe.load_context_from_ssm(
                env_name=manifest.name, type=Context)
            context.networking = create_networking_context_from_manifest(
                networking=manifest.networking)
            context.user_pool_id = manifest.user_pool_id
            context.shared_efs_fs_id = manifest.shared_efs_fs_id
            context.shared_efs_sg_id = manifest.shared_efs_sg_id
            context.scratch_bucket_arn = manifest.scratch_bucket_arn
            context.policies = manifest.policies
            context.role_prefix = manifest.role_prefix
            context.cognito_external_provider = manifest.cognito_external_provider
            context.cognito_external_provider_label = manifest.cognito_external_provider_label

        else:
            context = Context(
                name=manifest.name,
                account_id=utils.get_account_id(),
                region=utils.get_region(),
                env_tag=f"orbit-{manifest.name}",
                env_stack_name=f"orbit-{manifest.name}",
                env_ssm_parameter_name=f"/orbit/{manifest.name}/env",
                eks_stack_name=f"eksctl-orbit-{manifest.name}-cluster",
                ssm_parameter_name=context_parameter_name,
                ssm_dockerhub_parameter_name=
                f"/orbit/{manifest.name}/dockerhub",
                toolkit=ToolkitManifest(
                    stack_name=f"orbit-{manifest.name}-toolkit",
                    codebuild_project=f"orbit-{manifest.name}",
                ),
                cdk_toolkit=CdkToolkitManifest(
                    stack_name=f"orbit-{manifest.name}-cdk-toolkit"),
                role_prefix=manifest.role_prefix,
                scratch_bucket_arn=manifest.scratch_bucket_arn,
                networking=create_networking_context_from_manifest(
                    networking=manifest.networking),
                images=manifest.images,
                user_pool_id=manifest.user_pool_id,
                cognito_external_provider=manifest.cognito_external_provider,
                cognito_external_provider_label=manifest.
                cognito_external_provider_label,
                teams=create_teams_context_from_manifest(manifest=manifest),
                shared_efs_fs_id=manifest.shared_efs_fs_id,
                shared_efs_sg_id=manifest.shared_efs_sg_id,
                managed_nodegroups=[],
                eks_system_masters_roles=[],
                policies=manifest.policies,
                install_ssm_agent=manifest.install_ssm_agent,
                install_image_replicator=manifest.install_image_replicator,
            )
        context.install_ssm_agent = manifest.install_ssm_agent
        context.install_image_replicator = manifest.install_image_replicator

        ContextSerDe.fetch_toolkit_data(context=context)
        ContextSerDe.dump_context_to_ssm(context=context)
        return context
Ejemplo n.º 4
0
 def _load_context_from_manifest(manifest: "Manifest") -> Context:
     _logger.debug("Loading Context from manifest")
     context_parameter_name: str = f"/orbit/{manifest.name}/context"
     if ssm.does_parameter_exist(name=context_parameter_name):
         context: Context = ContextSerDe.load_context_from_ssm(
             env_name=manifest.name, type=Context)
         context.images = manifest.images
         context.networking = create_networking_context_from_manifest(
             networking=manifest.networking)
         context.user_pool_id = manifest.user_pool_id
         context.shared_efs_fs_id = manifest.shared_efs_fs_id
         context.shared_efs_sg_id = manifest.shared_efs_sg_id
         context.scratch_bucket_arn = manifest.scratch_bucket_arn
         context.policies = manifest.policies
         for team_manifest in manifest.teams:
             team_context: Optional[TeamContext] = context.get_team_by_name(
                 name=team_manifest.name)
             if team_context:
                 _logger.debug("Updating context profiles for team %s",
                               team_manifest.name)
                 team_context.profiles = team_manifest.profiles
     else:
         context = Context(
             name=manifest.name,
             account_id=utils.get_account_id(),
             region=utils.get_region(),
             env_tag=f"orbit-{manifest.name}",
             env_stack_name=f"orbit-{manifest.name}",
             env_ssm_parameter_name=f"/orbit/{manifest.name}/env",
             eks_stack_name=f"eksctl-orbit-{manifest.name}-cluster",
             ssm_parameter_name=context_parameter_name,
             ssm_dockerhub_parameter_name=
             f"/orbit/{manifest.name}/dockerhub",
             toolkit=ToolkitManifest(
                 stack_name=f"orbit-{manifest.name}-toolkit",
                 codebuild_project=f"orbit-{manifest.name}"),
             cdk_toolkit=CdkToolkitManifest(
                 stack_name=f"orbit-{manifest.name}-cdk-toolkit"),
             codeartifact_domain=manifest.codeartifact_domain,
             codeartifact_repository=manifest.codeartifact_repository,
             scratch_bucket_arn=manifest.scratch_bucket_arn,
             networking=create_networking_context_from_manifest(
                 networking=manifest.networking),
             images=manifest.images,
             user_pool_id=manifest.user_pool_id,
             cognito_external_provider=manifest.cognito_external_provider,
             cognito_external_provider_label=manifest.
             cognito_external_provider_label,
             teams=create_teams_context_from_manifest(manifest=manifest),
             shared_efs_fs_id=manifest.shared_efs_fs_id,
             shared_efs_sg_id=manifest.shared_efs_sg_id,
             managed_nodegroups=[],
             eks_system_masters_roles=[],
             policies=manifest.policies,
         )
     ContextSerDe.fetch_toolkit_data(context=context)
     ContextSerDe.dump_context_to_ssm(context=context)
     return context
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
def create_teams_context_from_manifest(
        manifest: "Manifest") -> List[TeamContext]:
    teams: List[TeamContext] = []
    for team in manifest.teams:
        ssm_parameter_name: str = f"/orbit/{manifest.name}/teams/{team.name}/context"
        if ssm.does_parameter_exist(name=ssm_parameter_name) is False:
            _logger.debug("Team %s is not deployed yet.", team.name)
            continue
        teams.append(
            create_team_context_from_manifest(manifest=manifest,
                                              team_manifest=team))
    return teams
Ejemplo n.º 7
0
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)
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
def deploy_images(debug: bool, filename: str, reqested_image: Optional[str] = None) -> 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
        env = manifest.name
        msg_ctx.info(f"Deploying images for env {env}")
        deploy.deploy_images_remotely(env=env, requested_image=reqested_image)
        msg_ctx.progress(95)
        msg_ctx.progress(100)
Ejemplo n.º 11
0
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-f")
        ssm.cleanup_manifest(env_name=env, top_level="orbit-f")

        if ssm.does_parameter_exist(name=f"/orbit-f/{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-f")
            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(25)

        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)):
            destroy.destroy_foundation(env_name=context.name)

        msg_ctx.info("Foundation destroyed")
        msg_ctx.progress(75)

        try:
            _destroy_toolkit(
                env_name=context.name,
                top_level="orbit-f",
                cdk_toolkit_bucket=context.cdk_toolkit.s3_bucket,
            )
        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-f")

        msg_ctx.progress(100)
Ejemplo n.º 12
0
 def _load_foundation_context_from_manifest(
         manifest: "FoundationManifest") -> FoundationContext:
     _logger.debug("Loading Context from manifest")
     context_parameter_name: str = f"/orbit-foundation/{manifest.name}/context"
     if ssm.does_parameter_exist(name=context_parameter_name):
         context: FoundationContext = ContextSerDe.load_context_from_ssm(
             env_name=manifest.name, type=FoundationContext)
         context.images = manifest.images
         context.policies = manifest.policies
         context.codeartifact_domain = manifest.codeartifact_domain
         context.codeartifact_repository = manifest.codeartifact_repository
     else:
         context = FoundationContext(
             name=manifest.name,
             account_id=utils.get_account_id(),
             region=utils.get_region(),
             env_tag=f"orbit-foundation-{manifest.name}",
             ssm_parameter_name=context_parameter_name,
             resources_ssm_parameter_name=
             f"/orbit-foundation/{manifest.name}/resources",
             toolkit=ToolkitManifest(
                 stack_name=f"orbit-foundation-{manifest.name}-toolkit",
                 codebuild_project=f"orbit-foundation-{manifest.name}",
             ),
             cdk_toolkit=CdkToolkitManifest(
                 stack_name=f"orbit-foundation-{manifest.name}-cdk-toolkit"
             ),
             codeartifact_domain=manifest.codeartifact_domain,
             codeartifact_repository=manifest.codeartifact_repository,
             networking=create_networking_context_from_manifest(
                 networking=manifest.networking),
             images=manifest.images,
             policies=manifest.policies,
             stack_name=f"orbit-foundation-{manifest.name}",
         )
     ContextSerDe.fetch_toolkit_data(context=context)
     ContextSerDe.dump_context_to_ssm(context=context)
     return context
Ejemplo n.º 13
0
def deploy_user_image(
    debug: bool,
    path: str,
    env: str,
    image_name: str,
    script: Optional[str],
    build_args: Optional[List[str]],
    timeout: int = 45,
) -> None:
    with MessagesContext("Deploying", debug=debug) as msg_ctx:
        context_parameter_name: str = f"/orbit/{env}/context"
        if not ssm.does_parameter_exist(name=context_parameter_name):
            msg_ctx.error(f"Orbit Environment {env} cannot be found in the current account and region.")
            return
        msg_ctx.progress(2)
        deploy.deploy_user_image(
            path=path, image_name=image_name, env=env, script=script, build_args=build_args, timeout=timeout
        )
        msg_ctx.progress(95)
        address = f"{get_account_id()}.dkr.ecr.{get_region()}.amazonaws.com/orbit-{env}/users/{image_name}"

        msg_ctx.info(f"ECR Image Address={address}")
        msg_ctx.tip(f"ECR Image Address: {stylize(address, underline=True)}")
        msg_ctx.progress(100)