Skip to content

Commit

Permalink
[Core-325] Overhaul cli, add support for mutating sharing (#12470)
Browse files Browse the repository at this point in the history
GitOrigin-RevId: 5cbff656d37e260b9157c7b24092eead888d1324
  • Loading branch information
stephencpope authored and Descartes Labs Build committed Mar 1, 2024
1 parent 1e9af75 commit 2e5c5a1
Show file tree
Hide file tree
Showing 26 changed files with 1,010 additions and 486 deletions.
3 changes: 0 additions & 3 deletions descarteslabs/auth/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -582,9 +582,6 @@ def _get_payload(token):
if isinstance(token, str):
token = token.encode("utf-8")

if isinstance(token, str):
token = token.encode("utf-8")

try:
# Anything that goes wrong here means it's a bad token
claims = token.split(b".")[1]
Expand Down
3 changes: 3 additions & 0 deletions descarteslabs/core/catalog/cli/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .cli import cli

__all__ = ["cli"]
51 changes: 51 additions & 0 deletions descarteslabs/core/catalog/cli/bands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import json

import click

from .. import BandType, Product, properties as p

from .utils import serialize


@click.group()
def bands():
"""Band management."""
pass


@bands.command()
@click.argument("product-id", type=str)
@click.option("--type", type=click.Choice([bt.value for bt in BandType]))
@click.option("--name", type=str)
@click.option("--tags", type=str, multiple=True)
@click.option("--limit", type=int)
@click.option(
"--output",
type=click.Choice(("id", "short", "json")),
default="short",
help="Output format",
)
def list(product_id, type, name, tags, limit, output):
"""List bands."""
product = Product.get(product_id)
if not product:
raise click.BadParameter(f"Product {product_id} not found")
search = product.bands()
if product_id is not None:
search = search.filter(p.product_id == product_id)
if type is not None:
search = search.filter(p.type == type)
if name is not None:
search = search.filter(p.name == name)
if tags:
search = search.filter(p.tags.any_of(tags))
if limit:
search = search.limit(limit)
if output == "json":
click.echo(json.dumps([serialize(band) for band in search]))
else:
for band in search:
if output == "id":
click.echo(band.id)
else:
click.echo(band)
168 changes: 168 additions & 0 deletions descarteslabs/core/catalog/cli/blobs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import json

import click

from .. import Blob, StorageType, properties as p

from .utils import serialize


@click.group()
def blobs():
"""Blob management."""
pass


@blobs.command()
@click.option("--ids", type=str, multiple=True)
@click.option("--storage-type", type=click.Choice([st.value for st in StorageType]))
@click.option("--namespace", type=str)
@click.option("--prefix", type=str, help="Name prefix")
@click.option("--access-id", type=str, help="Administrative users only")
@click.option("--owners", type=str, multiple=True)
@click.option("--writers", type=str, multiple=True, help="Administrative users only")
@click.option("--readers", type=str, multiple=True, help="Administrative users only")
@click.option("--tags", type=str, multiple=True)
@click.option("--limit", type=int)
@click.option(
"--output",
type=click.Choice(("id", "short", "json")),
default="short",
help="Output format",
)
def list(
ids,
storage_type,
namespace,
prefix,
access_id,
owners,
writers,
readers,
tags,
limit,
output,
):
"""List blobs."""
search = Blob.search()
if ids:
search = search.filter(p.id.any_of(ids))
if storage_type is not None:
search = search.filter(p.storage_type == storage_type)
if namespace is not None:
search = search.filter(p.namespace == namespace)
if prefix is not None:
search = search.filter(p.name.startswith(prefix))
if access_id:
search = search.filter(p.access_id == access_id)
if owners:
search = search.filter(p.owners.any_of(owners))
if writers:
search = search.filter(p.writers.any_of(writers))
if readers:
search = search.filter(p.readers.any_of(readers))
if tags:
search = search.filter(p.tags.any_of(tags))
if limit:
search = search.limit(limit)
if output == "json":
click.echo(json.dumps([serialize(blob) for blob in search]))
else:
for blob in search:
if output == "id":
click.echo(blob.id)
else:
click.echo(blob)


@blobs.command()
@click.argument("id", type=str)
@click.argument("subject", type=str)
def add_owner(id, subject):
"""Add an owner to a blob."""
blob = Blob.get(id)
if not blob:
raise click.BadParameter(f"blob {id} not found")
if subject in blob.owners:
click.echo(f"{subject} is already an owner of {id}")
else:
blob.owners.append(subject)
blob.save()
click.echo(f"Added {subject} as an owner of {id}")


@blobs.command()
@click.argument("id", type=str)
@click.argument("subject", type=str)
def remove_owner(id, subject):
"""Remove an owner from a blob."""
blob = Blob.get(id)
if not blob:
raise click.BadParameter(f"blob {id} not found")
if subject not in blob.owners:
raise click.BadParameter(f"{subject} is not an owner of {id}")
blob.owners.remove(subject)
blob.save()
click.echo(f"Removed {subject} as an owner of {id}")


@blobs.command()
@click.argument("id", type=str)
@click.argument("subject", type=str)
def add_writer(id, subject):
"""Add a writer to a blob."""
blob = Blob.get(id)
if not blob:
raise click.BadParameter(f"blob {id} not found")
if subject in blob.writers:
click.echo(f"{subject} is already a writer of {id}")
else:
blob.writers.append(subject)
blob.save()
click.echo(f"Added {subject} as a writer of {id}")


@blobs.command()
@click.argument("id", type=str)
@click.argument("subject", type=str)
def remove_writer(id, subject):
"""Remove a writer from a blob."""
blob = Blob.get(id)
if not blob:
raise click.BadParameter(f"blob {id} not found")
if subject not in blob.writers:
raise click.BadParameter(f"{subject} is not a writer of {id}")
blob.writers.remove(subject)
blob.save()
click.echo(f"Removed {subject} as a writer of {id}")


@blobs.command()
@click.argument("id", type=str)
@click.argument("subject", type=str)
def add_reader(id, subject):
"""Add a reader to a blob."""
blob = Blob.get(id)
if not blob:
raise click.BadParameter(f"blob {id} not found")
if subject in blob.reader:
click.echo(f"{subject} is already a reader of {id}")
else:
blob.readers.append(subject)
blob.save()
click.echo(f"Added {subject} as a reader of {id}")


@blobs.command()
@click.argument("id", type=str)
@click.argument("subject", type=str)
def remove_reader(id, subject):
"""Remove a reader from a blob."""
blob = Blob.get(id)
if not blob:
raise click.BadParameter(f"blob {id} not found")
if subject not in blob.readers:
raise click.BadParameter(f"{subject} is not a reader of {id}")
blob.readers.remove(subject)
blob.save()
click.echo(f"Removed {subject} as a reader of {id}")
15 changes: 15 additions & 0 deletions descarteslabs/core/catalog/cli/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import click

from .products import products
from .bands import bands
from .blobs import blobs


@click.group()
def cli():
pass


cli.add_command(products)
cli.add_command(blobs)
cli.add_command(bands)
Loading

0 comments on commit 2e5c5a1

Please sign in to comment.