feat: add list_stacks command to list existing pulumi stacks
Some checks failed
ZeroDownTime/CloudBender/pipeline/head There was a failure building this commit
ZeroDownTime/CloudBender/pipeline/tag There was a failure building this commit

This commit is contained in:
Stefan Reimer 2024-12-03 12:49:16 +00:00
parent 266604b964
commit 638876381c
6 changed files with 78 additions and 22 deletions

View File

@ -55,12 +55,13 @@ def cli(ctx, profile, region, debug, directory):
sys.exit(1) sys.exit(1)
# Only load stackgroups to get profile and region # Only load stackgroups to get profile and region
if ctx.invoked_subcommand == "wrap": if ctx.invoked_subcommand in ["wrap", "list_stacks"]:
cb.read_config(loadStacks=False) cb.read_config(loadStacks=False)
else: else:
cb.read_config() cb.read_config()
cb.dump_config() if debug:
cb.dump_config()
ctx.obj = cb ctx.obj = cb
@ -349,7 +350,16 @@ def wrap(cb, stack_group, cmd):
"""Execute custom external program""" """Execute custom external program"""
sg = cb.sg.get_stackgroup(stack_group) sg = cb.sg.get_stackgroup(stack_group)
cb.wrap(sg, " ".join(cmd)) sg.wrap(" ".join(cmd))
@click.command()
@click.argument("stack_group", nargs=1, required=True)
@click.pass_obj
def list_stacks(cb, stack_group):
"""List all Pulumi stacks"""
sg = cb.sg.get_stackgroup(stack_group)
sg.list_stacks()
@click.command() @click.command()
@ -499,6 +509,7 @@ cli.add_command(set_config)
cli.add_command(get_config) cli.add_command(get_config)
cli.add_command(_import) cli.add_command(_import)
cli.add_command(export) cli.add_command(export)
cli.add_command(list_stacks)
cli.add_command(assimilate) cli.add_command(assimilate)
cli.add_command(execute) cli.add_command(execute)
cli.add_command(wrap) cli.add_command(wrap)

View File

@ -1,9 +1,7 @@
import pathlib import pathlib
import logging import logging
import pexpect
from .stackgroup import StackGroup from .stackgroup import StackGroup
from .connection import BotoConnection
from .jinja import read_config_file from .jinja import read_config_file
from .exceptions import InvalidProjectDir from .exceptions import InvalidProjectDir
@ -133,17 +131,3 @@ class CloudBender(object):
matching_stacks.append(s) matching_stacks.append(s)
return matching_stacks return matching_stacks
def wrap(self, stack_group, cmd):
"""
Set AWS environment based on profile before executing a custom command, eg. steampipe
"""
profile = stack_group.config.get("profile", "default")
region = stack_group.config.get("region", "global")
connection_manager = BotoConnection(profile, region)
connection_manager.exportProfileEnv()
child = pexpect.spawn(cmd)
child.interact()

View File

@ -199,6 +199,8 @@ def pulumi_ws(func):
secrets_provider=secrets_provider, secrets_provider=secrets_provider,
) )
# self.pulumi_workspace = pulumi.automation.LocalWorkspace(self.pulumi_ws_opts)
response = func(self, *args, **kwargs) response = func(self, *args, **kwargs)
# Cleanup temp workspace # Cleanup temp workspace

View File

@ -987,7 +987,7 @@ class Stack(object):
def assimilate(self): def assimilate(self):
"""Import resources into Pulumi stack""" """Import resources into Pulumi stack"""
pulumi_stack = self._get_pulumi_stack(create=True) pulumi_stack = self._get_pulumi_stack()
# now lets import each defined resource # now lets import each defined resource
for r in self._pulumi_code.RESOURCES: for r in self._pulumi_code.RESOURCES:

View File

@ -1,6 +1,13 @@
import logging import logging
import pprint import pprint
import pexpect
import pulumi
import tempfile
import rich.table
import rich.console
from .connection import BotoConnection
from .utils import dict_merge from .utils import dict_merge
from .jinja import read_config_file from .jinja import read_config_file
from .stack import Stack from .stack import Stack
@ -25,7 +32,7 @@ class StackGroup(object):
for sg in self.sgs: for sg in self.sgs:
sg.dump_config() sg.dump_config()
logger.debug( logger.info(
"StackGroup {}: {}".format(self.rel_path, pprint.pformat(self.config)) "StackGroup {}: {}".format(self.rel_path, pprint.pformat(self.config))
) )
@ -135,3 +142,54 @@ class StackGroup(object):
return s return s
return None return None
def wrap(self, cmd):
"""
Set AWS environment based on profile before executing a custom command, eg. steampipe
"""
profile = self.config.get("profile", "default")
region = self.config.get("region", "global")
connection_manager = BotoConnection(profile, region)
connection_manager.exportProfileEnv()
child = pexpect.spawn(cmd)
child.interact()
def list_stacks(self):
project_name = self.config["parameters"]["Conglomerate"]
pulumi_backend = "{}/{}/{}".format(self.config["pulumi"]["backend"], project_name, self.config["region"])
project_settings = pulumi.automation.ProjectSettings(
name=project_name, runtime="python", backend=pulumi.automation.ProjectBackend(url=pulumi_backend)
)
work_dir = tempfile.mkdtemp(
dir=tempfile.gettempdir(), prefix="cloudbender-"
)
# AWS setup
profile = self.config.get("profile", "default")
region = self.config.get("region", "global")
connection_manager = BotoConnection(profile, region)
connection_manager.exportProfileEnv()
pulumi_workspace = pulumi.automation.LocalWorkspace(
work_dir=work_dir,
project_settings=project_settings
)
stacks = pulumi_workspace.list_stacks()
table = rich.table.Table(title="Pulumi stacks")
table.add_column("Name")
table.add_column("Last Update")
table.add_column("Resources")
for s in stacks:
table.add_row(s.name, str(s.last_update), str(s.resource_count))
console = rich.console.Console()
console.print(table)

View File

@ -11,7 +11,7 @@ authors = [
description = "Deploy and maintain infrastructure in automated and trackable manner" description = "Deploy and maintain infrastructure in automated and trackable manner"
readme = "README.md" readme = "README.md"
license = "AGPL-3.0-or-later" license = "AGPL-3.0-or-later"
requires-python = ">=3.9" requires-python = ">=3.12"
dependencies = [ dependencies = [
"boto3==1.35.70", "boto3==1.35.70",
"mock==5.1.0", "mock==5.1.0",
@ -21,6 +21,7 @@ dependencies = [
"python-minifier==2.11.3", "python-minifier==2.11.3",
"cfn-lint==1.20.1", "cfn-lint==1.20.1",
"ruamel.yaml==0.18.6", "ruamel.yaml==0.18.6",
"rich==13.9.4",
"pulumi==3.142.0", "pulumi==3.142.0",
"pulumi-aws==6.61.0", "pulumi-aws==6.61.0",
"pulumi-aws-native==1.11.0", "pulumi-aws-native==1.11.0",