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)
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() ], )
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)
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)
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")
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")
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.")
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)
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)