Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,14 @@ hyp create --region <region>

**Note**: The region flag is optional. If not provided, the command will use the default region from your AWS credentials configuration.

#### List Cluster Stacks
#### List CloudFormation Stacks

```bash
hyp list cluster-stack
```

**Note**: This command lists all CloudFormation stacks in the current AWS account and Region. It does not currently filter the results to HyperPod-created stacks.

| Option | Type | Description |
|--------|------|-------------|
| `--region <region>` | Optional | The AWS region to list stacks from. |
Expand Down Expand Up @@ -1002,14 +1004,16 @@ cluster_stack = HpClusterStack(
response = cluster_stack.create(region="us-east-2")
```

#### Listing Cluster Stacks
#### Listing CloudFormation Stacks

```python
# List all cluster stacks
# List all CloudFormation stacks in the Region
stacks = HpClusterStack.list(region="us-east-2")
print(f"Found {len(stacks['StackSummaries'])} stacks")
```

**Note**: `HpClusterStack.list()` returns all CloudFormation stacks in the current account and Region; it does not filter to HyperPod cluster stacks.

#### Describing a Cluster Stack

```python
Expand Down
8 changes: 6 additions & 2 deletions doc/cli/cluster_management/cli_cluster_management.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,11 @@ hyp update cluster [OPTIONS]

## hyp list cluster-stack

List all HyperPod cluster stacks (CloudFormation stacks).
List all CloudFormation stacks in the current AWS account and Region.

```{note}
This command does not currently filter the results to HyperPod-created stacks.
```

#### Syntax

Expand Down Expand Up @@ -426,7 +430,7 @@ hyp update cluster \
### List and Describe

```bash
# List all cluster stacks
# List all CloudFormation stacks in the Region
hyp list cluster-stack --region us-west-2

# Describe specific cluster stack
Expand Down
7 changes: 6 additions & 1 deletion doc/getting_started/cluster_management.rst
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,12 @@ Check the status of your cluster:
**Region-Specific Stack Names**: Cluster stack names are unique within each AWS region. When describing a stack, ensure you specify the correct region where the stack was created, or the command will fail to find the stack.


List all clusters:
List CloudFormation stacks:

.. note::
``hyp list cluster-stack`` lists all CloudFormation stacks in the current
account and Region. It does not currently filter the results to HyperPod
cluster stacks.

.. tab-set::

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,12 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 8: List All Cluster Stacks\n",
"## Step 8: List CloudFormation Stacks\n",
"\n",
"The `hyp list cluster-stack` command shows all HyperPod cluster stacks in your account. This is useful for managing multiple clusters and getting an overview of your infrastructure.\n",
"The `hyp list cluster-stack` command lists all CloudFormation stacks in your account and Region. This is useful for getting an overview of your infrastructure; it does not currently filter the results to HyperPod cluster stacks.\n",
"\n",
"**Displays:**\n",
"- All cluster stacks in the current region\n",
"- All CloudFormation stacks in the current Region\n",
"- Stack names and creation timestamps\n",
"- Current status of each stack\n",
"- Resource counts and types\n"
Expand All @@ -246,7 +246,7 @@
"cell_type": "code",
"metadata": {},
"source": [
"# List all cluster stacks in your account\n",
"# List all CloudFormation stacks in your account and Region\n",
"!hyp list cluster-stack"
],
"outputs": [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,12 +355,12 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 6: List All Cluster Stacks\n",
"## Step 6: List CloudFormation Stacks\n",
"\n",
"List all HyperPod cluster stacks in your account using SDK methods. This is equivalent to `hyp list cluster-stack` in the CLI.\n",
"List CloudFormation stacks in your account using SDK methods. This is equivalent to `hyp list cluster-stack` in the CLI. The SDK returns all stacks in the Region; the name-based filter below is only an illustration and is not a reliable way to identify HyperPod stacks.\n",
"\n",
"**Displays:**\n",
"- All cluster stacks in the current region\n",
"- All CloudFormation stacks in the current Region\n",
"- Stack names and creation timestamps\n",
"- Current status of each stack\n",
"- Resource counts and types"
Expand All @@ -372,11 +372,11 @@
"metadata": {},
"outputs": [],
"source": [
"# List all cluster stacks (equivalent to hyp list cluster-stack)\n",
"# List all CloudFormation stacks (equivalent to hyp list cluster-stack)\n",
"def list_cluster_stacks(region=\"us-east-2\"):\n",
" \"\"\"List all cluster stacks in the account\"\"\"\n",
" \"\"\"List CloudFormation stacks in the account and Region\"\"\"\n",
" try:\n",
" print(f\"Listing cluster stacks in region: {region}\")\n",
" print(f\"Listing CloudFormation stacks in region: {region}\")\n",
" \n",
" # Get list of stacks\n",
" response = HpClusterStack.list(region=region)\n",
Expand All @@ -396,18 +396,18 @@
" created = str(stack.get('CreationTime', 'N/A'))[:19]\n",
" print(f\"{name:<40} {status:<25} {created:<20}\")\n",
" else:\n",
" print(\"No cluster stacks found.\")\n",
" print(\"No CloudFormation stacks found.\")\n",
" \n",
" return response\n",
" \n",
" except Exception as e:\n",
" print(f\"Error listing stacks: {str(e)}\")\n",
" return None\n",
"\n",
"# List all cluster stacks\n",
"# List all CloudFormation stacks\n",
"list_response = list_cluster_stacks()\n",
"\n",
"# Filter for HyperPod-related stacks\n",
"# Optional name-based heuristic; not a reliable HyperPod identifier\n",
"if list_response and 'StackSummaries' in list_response:\n",
" hyperpod_stacks = [\n",
" stack for stack in list_response['StackSummaries']\n",
Expand Down
17 changes: 9 additions & 8 deletions src/sagemaker/hyperpod/cli/commands/cluster_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,21 +210,22 @@ def describe_cluster_stack(stack_name: str, debug: bool, region: str) -> None:
help="Filter by stack status. Format: \"['CREATE_COMPLETE', 'UPDATE_COMPLETE']\"")
@_hyperpod_telemetry_emitter(Feature.HYPERPOD_CLI, "list_cluster_stack_cli")
def list_cluster_stacks(region, debug, status):
"""List all HyperPod cluster stacks.
"""List CloudFormation stacks in the current AWS account and Region.

Displays a summary of all CloudFormation stacks related to HyperPod clusters
in the specified region or default region.
Returns all CloudFormation stacks in the current account and Region. This
command does not currently filter results to stacks created for HyperPod
clusters. Use --status to filter by stack status.

.. dropdown:: Usage Examples
:open:

.. code-block:: bash

# List all cluster stacks
hyp list hyp-cluster
# List CloudFormation stacks
hyp list cluster-stack

# List stacks in specific region
hyp list hyp-cluster --region us-east-1
# List stacks in a specific region
hyp list cluster-stack --region us-east-1
"""
logger = setup_logging(logging.getLogger(__name__), debug)

Expand All @@ -242,7 +243,7 @@ def list_cluster_stacks(region, debug, status):

logger.debug(f"Listing stacks in region: {region or 'default'}")

click.echo(f"📋 HyperPod Cluster Stacks ({len(stack_summaries)} found)")
click.echo(f"📋 CloudFormation Stacks ({len(stack_summaries)} found)")

if stack_summaries:
for i, stack in enumerate(stack_summaries, 1):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,11 @@ def list(region: Optional[str] = None, stack_status_filter: Optional[List[str]]
.. note::
Stack listings are region-specific. If no region is provided, uses the default region from your AWS configuration.

.. note::
This method does not filter results to HyperPod-related stacks. The
CloudFormation ListStacks API does not return stack tags, so callers
that need a specific subset must make additional API calls.

**Parameters:**

.. list-table::
Expand Down
41 changes: 40 additions & 1 deletion test/unit_tests/cli/test_cluster_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,50 @@ def test_list_cluster_stacks_success(self, mock_setup_logging, mock_hp_cluster_l

# Assert
assert result.exit_code == 0
assert 'HyperPod Cluster Stacks (1 found)' in result.output
assert 'CloudFormation Stacks (1 found)' in result.output
assert 'test-stack' in result.output
assert 'CREATE_COMPLETE' in result.output
mock_hp_cluster_list.assert_called_once_with(region=None, stack_status_filter=None)

@patch('sagemaker.hyperpod.cli.commands.cluster_stack.HpClusterStack.list')
@patch('sagemaker.hyperpod.cli.commands.cluster_stack.setup_logging')
def test_list_cluster_stacks_includes_unrelated_cloudformation_stacks(self, mock_setup_logging, mock_hp_cluster_list):
"""The command returns all CloudFormation stacks, not only HyperPod stacks."""
mock_setup_logging.return_value = Mock()
mock_hp_cluster_list.return_value = {
'StackSummaries': [
{
'StackName': 'hyperpod-cluster-stack',
'StackStatus': 'CREATE_COMPLETE',
'CreationTime': datetime(2024, 1, 1, 12, 0, 0),
},
{
'StackName': 'unrelated-application-stack',
'StackStatus': 'UPDATE_COMPLETE',
'CreationTime': datetime(2024, 1, 2, 12, 0, 0),
},
]
}

result = CliRunner().invoke(list_cluster_stacks, [])

assert result.exit_code == 0
assert 'CloudFormation Stacks (2 found)' in result.output
assert 'HyperPod Cluster Stacks' not in result.output
assert 'hyperpod-cluster-stack' in result.output
assert 'unrelated-application-stack' in result.output

def test_list_cluster_stacks_help_describes_all_stacks(self):
"""The help output does not claim that results are limited to HyperPod stacks."""
result = CliRunner().invoke(list_cluster_stacks, ['--help'])

assert result.exit_code == 0
help_text = ' '.join(result.output.split())
assert 'List CloudFormation stacks in the current AWS account and Region.' in help_text
assert 'Returns all CloudFormation stacks in the current account and Region.' in help_text
assert 'does not currently filter results to stacks created for HyperPod clusters.' in help_text
assert 'HyperPod Cluster Stacks' not in help_text

@patch('sagemaker.hyperpod.cli.commands.cluster_stack.HpClusterStack.list')
@patch('sagemaker.hyperpod.cli.commands.cluster_stack.setup_logging')
def test_list_cluster_stacks_with_region(self, mock_setup_logging, mock_hp_cluster_list):
Expand Down
Loading