feat: add list_stacks command to list existing pulumi stacks
This commit is contained in:
parent
266604b964
commit
638876381c
@ -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)
|
||||||
|
@ -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()
|
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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)
|
||||||
|
@ -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",
|
||||||
|
Loading…
Reference in New Issue
Block a user