Skip to content

Commit

Permalink
Remove more activation support code
Browse files Browse the repository at this point in the history
- `activate`, `deactivate`, and `is-activated` now all warn to stderr
  when used, and no longer have any other effects -- tests are updated
  to check this
- `--skip-activation-check` for task submission commands is now hidden
  -- and commented as a deprecated option but not otherwise changed
- remove activation helper functions
- remove the autoactivate success fixture data from tests
- remove `Activated` from `globus endpoint show` text output
  • Loading branch information
sirosen committed Aug 28, 2024
1 parent f57e613 commit 694dff4
Show file tree
Hide file tree
Showing 21 changed files with 77 additions and 503 deletions.
12 changes: 12 additions & 0 deletions changelog.d/20240828_101834_sirosen_activation2stub.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
### Other

* The CLI has removed remaining support for activation.

* Activation commands such as `globus endpoint is-activated` are already
hidden, but now act as no-ops when invoked and emit warnings to stderr
about their upcoming removal.

* The `--skip-activation-check` option for Transfer task submission has
been deprecated.

* `Activated` is no longer a field in `globus endpoint show` output.
216 changes: 17 additions & 199 deletions src/globus_cli/commands/endpoint/activate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,72 +3,22 @@
import uuid

import click
import globus_sdk

from globus_cli.login_manager import LoginManager, is_remote_session
from globus_cli.parsing import command, endpoint_id_arg, mutex_option_group
from globus_cli.termio import display


@command("activate", deprecated=True, hidden=True)
@endpoint_id_arg
@click.option(
"--web",
is_flag=True,
default=False,
help="Use web activation. Mutually exclusive with --myproxy.",
)
@click.option(
"--no-browser",
is_flag=True,
default=False,
help=(
"If using --web, Give a url to manually follow instead of "
"opening your default web browser. Implied if the CLI "
"detects this is a remote session."
),
)
@click.option(
"--myproxy",
is_flag=True,
default=False,
help="Use myproxy activation. Mutually exclusive with --web.",
)
@click.option(
"--myproxy-username",
"-U",
help="Give a username to use with --myproxy",
)
@click.option("--web", is_flag=True, default=False)
@click.option("--no-browser", is_flag=True, default=False)
@click.option("--myproxy", is_flag=True, default=False)
@click.option("--myproxy-username", "-U")
@click.option("--myproxy-password", "-P", hidden=True)
@click.option(
"--myproxy-lifetime",
type=int,
help=(
"The lifetime for the credential to request from the "
"server under --myproxy activation, in hours. "
"The myproxy server may be configured with a maximum "
"lifetime which it will use if this value is too high"
),
)
@click.option(
"--no-autoactivate",
is_flag=True,
default=False,
help=(
"Don't attempt to autoactivate endpoint before using "
"another activation method."
),
)
@click.option(
"--force",
is_flag=True,
default=False,
help="Force activation even if endpoint is already activated.",
)
@click.option("--myproxy-lifetime", type=int)
@click.option("--no-autoactivate", is_flag=True, default=False)
@click.option("--force", is_flag=True, default=False)
@mutex_option_group("--web", "--myproxy")
@LoginManager.requires_login("transfer")
def endpoint_activate(
login_manager: LoginManager,
*,
endpoint_id: uuid.UUID,
myproxy: bool,
Expand All @@ -83,146 +33,14 @@ def endpoint_activate(
"""
Activate an endpoint.
Note that --web and --myproxy activation are mutually
exclusive options.
\b
Autoactivation will always be attempted unless the --no-autoactivate
option is given. If autoactivation succeeds any other activation options
will be ignored as the endpoint has already been successfully activated.
\b
To use Web activation use the --web option.
The CLI will try to open your default browser to the endpoint's activation
page, but if a remote CLI session is detected, or the --no-browser option
is given, a url will be printed for you to manually follow and activate
the endpoint.
\b
To use Myproxy activation give the --myproxy option.
Myproxy activation requires your username and password for the myproxy
server the endpoint is using for authentication. e.g. for default
Globus Connect Server endpoints this will be your login credentials for the
server the endpoint is hosted on.
You can enter your username when prompted or give your username with the
--myproxy-username option.
For security it is recommended that you only enter your password when
prompted to hide your inputs and keep your password out of your
command history, but you may pass your password with the hidden
--myproxy-password or -P options.
Endpoint Activation has been removed from the Globus ecosystem. This command
no longer does anything.
"""
from globus_cli.services.transfer import activation_requirements_help_text

transfer_client = login_manager.get_transfer_client()

# validate options
if no_autoactivate and not (myproxy or web):
raise click.UsageError(
"--no-autoactivate requires another activation method be given."
)
if myproxy_username and not myproxy:
raise click.UsageError("--myproxy-username requires --myproxy.")
if myproxy_password and not myproxy:
raise click.UsageError("--myproxy-password requires --myproxy.")
# NOTE: "0" is a legitimate, though weird, value
# In the case where someone is setting this value programmatically,
# respecting it behaves more consistently/predictably
if myproxy_lifetime is not None and not myproxy:
raise click.UsageError("--myproxy-lifetime requires --myproxy.")
if no_browser and not web:
raise click.UsageError("--no-browser requires --web.")

# check if endpoint is already activated unless --force
if not force:
res: dict[str, str] | globus_sdk.GlobusHTTPResponse = (
transfer_client.endpoint_autoactivate(endpoint_id, if_expires_in=60)
)

if "AlreadyActivated" == res["code"]:
display(
res,
simple_text=(
"Endpoint is already activated. Activation "
"expires at {}".format(res["expire_time"])
),
)
return

# attempt autoactivation unless --no-autoactivate
if not no_autoactivate:
res = transfer_client.endpoint_autoactivate(endpoint_id)

if "AutoActivated" in res["code"]:
display(
res,
simple_text=(
"Autoactivation succeeded with message: {}".format(res["message"])
),
)
return

# override potentially confusing autoactivation failure response
else:
message = (
"The endpoint could not be auto-activated.\n\n"
+ activation_requirements_help_text(res, endpoint_id)
)
res = {"message": message}

# myproxy activation
if myproxy:
# fetch activation requirements
requirements_data = transfer_client.endpoint_get_activation_requirements(
endpoint_id
).data
# filter to the myproxy requirements; ensure that there are values
myproxy_requirements_data = [
x for x in requirements_data["DATA"] if x["type"] == "myproxy"
]
if not len(myproxy_requirements_data):
raise click.ClickException(
"This endpoint does not support myproxy activation"
)

# get username and password
if not myproxy_username:
myproxy_username = click.prompt("Myproxy username")
if not myproxy_password:
myproxy_password = click.prompt("Myproxy password", hide_input=True)

# fill out the requirements data -- note that because everything has been done
# by reference, `requirements_data` still refers to the document containing
# these values
for data in myproxy_requirements_data:
if data["name"] == "passphrase":
data["value"] = myproxy_password
if data["name"] == "username":
data["value"] = myproxy_username
if data["name"] == "hostname" and data["value"] is None:
raise click.ClickException(
"This endpoint has no myproxy server "
"and so cannot be activated through myproxy"
)
# NOTE: remember that "0" is a possible value
if data["name"] == "lifetime_in_hours" and myproxy_lifetime is not None:
data["value"] = str(myproxy_lifetime)

res = transfer_client.endpoint_activate(
endpoint_id, requirements_data=requirements_data
)

# web activation
elif web:
import webbrowser

from globus_sdk.config import get_webapp_url

url = f"{get_webapp_url()}file-manager?origin_id={endpoint_id}"
if no_browser or is_remote_session():
res = {"message": f"Web activation url: {url}", "url": url}
else:
webbrowser.open(url, new=1)
res = {"message": "Browser opened to web activation page", "url": url}

# output
display(res, text_mode=display.RAW, response_key="message")
click.echo(
click.style(
"`globus endpoint activate` has been deprecated and "
"will be removed in a future release.",
fg="yellow",
),
err=True,
)
25 changes: 16 additions & 9 deletions src/globus_cli/commands/endpoint/deactivate.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
import uuid

from globus_cli.login_manager import LoginManager
import click

from globus_cli.parsing import command, endpoint_id_arg
from globus_cli.termio import display


@command("deactivate", deprecated=True, hidden=True)
@endpoint_id_arg
@LoginManager.requires_login("transfer")
def endpoint_deactivate(login_manager: LoginManager, *, endpoint_id: uuid.UUID) -> None:
def endpoint_deactivate(*, endpoint_id: uuid.UUID) -> None:
"""
Remove the credential previously assigned to an endpoint via
'globus endpoint activate' or any other form of endpoint activation
Deactivate an endpoint.
Endpoint Activation has been removed from the Globus ecosystem. This command
no longer does anything.
"""
transfer_client = login_manager.get_transfer_client()
res = transfer_client.endpoint_deactivate(endpoint_id)
display(res, text_mode=display.RAW, response_key="message")
click.echo(
click.style(
"`globus endpoint deactivate` has been deprecated and "
"will be removed in a future release.",
fg="yellow",
),
err=True,
)
78 changes: 12 additions & 66 deletions src/globus_cli/commands/endpoint/is_activated.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,17 @@
from __future__ import annotations

import typing as t
import uuid

import click

from globus_cli.login_manager import LoginManager
from globus_cli.parsing import command, endpoint_id_arg
from globus_cli.termio import display


@command("is-activated", deprecated=True, hidden=True)
@endpoint_id_arg
@click.option(
"--until",
type=int,
help=(
"An integer number of seconds in the future. If the "
"endpoint is activated, but will expire by then, exits "
"with status 1"
),
)
@click.option(
"--absolute-time",
is_flag=True,
show_default=True,
default=False,
help=(
"Treat the value of --until as a POSIX timestamp (seconds "
"since Epoch), not a number of seconds into the future."
),
)
@LoginManager.requires_login("transfer")
@click.option("--until", type=int)
@click.option("--absolute-time", is_flag=True, show_default=True, default=False)
def endpoint_is_activated(
login_manager: LoginManager,
*,
endpoint_id: uuid.UUID,
until: int | None,
Expand All @@ -42,46 +20,14 @@ def endpoint_is_activated(
"""
Check if an endpoint is activated or requires activation.
If it requires activation, exits with status 1, otherwise exits with status 0.
If the endpoint is not activated, this command will output a link for web
activation, or you can use 'globus endpoint activate' to activate the endpoint.
Endpoint Activation has been removed from the Globus ecosystem. This command
no longer does anything.
"""
from globus_cli.services.transfer import activation_requirements_help_text

transfer_client = login_manager.get_transfer_client()
res = transfer_client.endpoint_get_activation_requirements(endpoint_id)

def fail(deadline: int | None = None) -> t.NoReturn:
exp_string = ""
if deadline is not None:
exp_string = f" or will expire within {deadline} seconds"
requirements_help = activation_requirements_help_text(res, endpoint_id)

message = (
f"'{endpoint_id}' is not activated{exp_string}.\n\n{requirements_help}"
)
display(res, simple_text=message)
click.get_current_context().exit(1)

def success(msg: str) -> t.NoReturn:
display(res, simple_text=msg)
click.get_current_context().exit(0)

# eternally active endpoints have a special expires_in value
if res["expires_in"] == -1:
success(f"'{endpoint_id}' does not require activation")

# autoactivation is not supported and --until was not passed
if until is None:
# and we are active right now (0s in the future)...
if res.active_until(0):
success(f"'{endpoint_id}' is activated")
# or we are not active
fail()

# autoactivation is not supported and --until was passed
if res.active_until(until, relative_time=not absolute_time):
success(f"'{endpoint_id}' will be active for at least {until} seconds")
else:
fail(deadline=until)
click.echo(
click.style(
"`globus endpoint is-activated` has been deprecated and "
"will be removed in a future release.",
fg="yellow",
),
err=True,
)
1 change: 0 additions & 1 deletion src/globus_cli/commands/endpoint/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
Field("ID", "id"),
Field("Owner", "owner_string"),
Field("Description", "description", wrap_enabled=True),
Field("Activated", "activated"),
Field("Shareable", "shareable"),
Field("Department", "department"),
Field("Keywords", "keywords"),
Expand Down
Loading

0 comments on commit 694dff4

Please sign in to comment.