Skip to content
Merged
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
3 changes: 2 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/psf/black
rev: 25.12.0
rev: 26.1.0
hooks:
- id: black
language_version: python3.11
Expand All @@ -9,6 +9,7 @@ repos:
hooks:
- id: mypy
args: ["quiltx", "tests"]
additional_dependencies: ["PyYAML", "types-PyYAML"]
pass_filenames: false
- repo: local
hooks:
Expand Down
21 changes: 20 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,26 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [0.6.0] - 2026-04-09

### Added

- `quiltx stack acl <config.yml>` for declarative reconciliation of Quilt buckets, managed policies, managed roles, and SSO mappings from YAML
- `quiltx stack acl` (no args) dumps the current server ACL state for inspection
- `--dry-run` flag to preview ACL changes without applying them
- `--verbose` flag for detailed diff output including SSO and default-role details
- Progress output during ACL apply (bucket, policy, role, SSO steps)
- SSO create-vs-update detection: creates new SSO config or updates existing one as needed
- Default role configuration moved into SSO config for cleaner YAML semantics
- `auto_login` decorator in `quiltx.config` for automatic session refresh on auth failure
- `normalize_catalog_url()` helper in `quiltx.config`
- Public Python API: `AclConfig`, `AclDiff`, `CurrentState`, `all_buckets`, `apply_acl`, `build_sso_config`, `compute_diff`, `fetch_current_state`, `parse_acl_config`, `print_diff` exported from `quiltx`

### Changed

- Add `pyyaml` as a runtime dependency for YAML-backed ACL configuration
- Require `quilt3>=7.3.0` so `quiltx stack acl` can use the new admin policies API
- `set_catalog_url()` now normalizes the URL (adds `https://`, strips trailing slash)

## [0.5.0] - 2026-04-09

Expand Down
119 changes: 87 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Quilt extension toolkit for working with [Quilt](https://quiltdata.com) catalogs.

## Usage
## Quick start

```bash
# See available tools
Expand All @@ -13,55 +13,110 @@ uvx quiltx
# Configure a Quilt catalog
uvx quiltx stack catalog https://open.quiltdata.com

# Register a cross-account S3 bucket
uvx quiltx bucket add s3://my-data-bucket

# Discover the Quilt CloudFormation stack
uvx quiltx stack cfn

# Open an interactive shell in a running ECS task
uvx quiltx ecs

# Tail CloudWatch logs
uvx quiltx logs --minutes 30 --filter "ERROR"

# Get help for a specific tool
# Get help for any tool
uvx quiltx <tool> --help
```

## Tools

- **bucket** — Register S3 buckets with Quilt (policy, SNS, notifications)
- **bucket** — Register cross-account S3 buckets with Quilt (policy, SNS, notifications)
- **ecs** — Interactive shell access to running ECS tasks via Session Manager
- **logs** — Display and tail CloudWatch logs for the configured catalog
- **stack** — Manage Quilt stack
- **stack** — Manage Quilt stack:
- **stack acl** — Declarative access-control-list (ACL) reconciliation from YAML
- **stack catalog** — Configure and display Quilt catalog settings
- **stack cfn** — Discover the Quilt CloudFormation stack and cache metadata

## Python API
## Stack ACL

`quiltx stack acl` declaratively manages a Quilt stack's access control lists
(ACLs) — buckets, policies, roles, and SSO mappings — from a single YAML file.
Instead of clicking through the catalog admin UI, you define the desired state
in version-controlled YAML and let the tool reconcile it against the server.

### YAML example

```yaml
# Access control lists for a Quilt stack
bucket_policies:
public:
read:
- quilt-example
internal:
read_write:
- quilt-bake
- quilt-dev
read:
- quilt-leadership

roles:
visitor:
bucket_policies: [public]
member:
bucket_policies: [public, internal]
default: true # assigned to new users

sso:
- match:
groups: Employees
roles: [member]
admin: true
- match:
groups: Everyone
roles: [visitor]
```

### CLI usage

```bash
# Show current server ACL state
uvx quiltx stack acl

# Preview changes (dry run)
uvx quiltx stack acl config.yml --dry-run

# Preview with full detail
uvx quiltx stack acl config.yml --dry-run --verbose

# Apply changes (with confirmation prompt)
uvx quiltx stack acl config.yml

# Apply without prompting
uvx quiltx stack acl config.yml --yes
```

### Python API

```python
from quiltx import (
parse_acl_config,
fetch_current_state,
compute_diff,
print_diff,
apply_acl,
)

config = parse_acl_config("config.yml")
current = fetch_current_state()
diff = compute_diff(config, current)
print_diff(diff, verbose=True, desired=config, current=current)

if diff.has_changes():
apply_acl(diff, current)
```

## Config and stack API

```python
from quiltx import get_catalog_url, get_catalog_region, get_catalog_config, set_catalog_url
from quiltx import get_catalog_url, get_catalog_region, set_catalog_url
from quiltx.stack import find_matching_stack

# Configure a catalog
set_catalog_url("https://open.quiltdata.com")
print(get_catalog_url()) # https://open.quiltdata.com
print(get_catalog_region()) # us-east-1

# Read catalog configuration
print(get_catalog_url()) # https://open.quiltdata.com
print(get_catalog_region()) # us-east-1
print(get_catalog_config()) # full config dict

# Discover stack
stack = find_matching_stack(get_catalog_url())
print(stack["StackName"])

# Register an S3 bucket (policy, SNS, notifications, catalog)
from quiltx.bucket import add_bucket

result = add_bucket("my-data-bucket", title="My Data")
print(result.sns_topic_arn)
print(result.already_registered)
```

## Persistent install (optional)
Expand Down
8 changes: 5 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "quiltx"
version = "0.5.0"
version = "0.6.0"
description = "Unified toolkit for Quilt workflows."
readme = "README.md"
requires-python = ">=3.9"
Expand All @@ -15,7 +15,8 @@ classifiers = [
"Operating System :: OS Independent"
]
dependencies = [
"quilt3",
"pyyaml",
"quilt3>=7.3.0",
"rich"
]

Expand All @@ -25,7 +26,8 @@ dev = [
"mypy",
"pre-commit",
"poethepoet",
"pytest"
"pytest",
"types-PyYAML",
]
docs = [
"mkdocs>=1.5.0",
Expand Down
24 changes: 24 additions & 0 deletions quiltx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,20 @@
from __future__ import annotations

from quiltx._version import __version__ as __version__
from quiltx.acl import (
AclConfig as AclConfig,
AclDiff as AclDiff,
CurrentState as CurrentState,
all_buckets as all_buckets,
apply_acl as apply_acl,
build_sso_config as build_sso_config,
compute_diff as compute_diff,
fetch_current_state as fetch_current_state,
parse_acl_config as parse_acl_config,
print_diff as print_diff,
)
from quiltx.config import (
auto_login as auto_login,
get_catalog_config as get_catalog_config,
get_catalog_region as get_catalog_region,
get_catalog_url as get_catalog_url,
Expand All @@ -12,8 +25,19 @@

__all__ = [
"__version__",
"AclConfig",
"AclDiff",
"CurrentState",
"all_buckets",
"apply_acl",
"auto_login",
"build_sso_config",
"compute_diff",
"fetch_current_state",
"get_catalog_config",
"get_catalog_region",
"get_catalog_url",
"parse_acl_config",
"print_diff",
"set_catalog_url",
]
2 changes: 1 addition & 1 deletion quiltx/_version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""Version information for quiltx."""

__version__ = "0.5.0"
__version__ = "0.6.0"
Loading