diff --git a/riocli/deployment/__init__.py b/riocli/deployment/__init__.py index f7d35fd9..ffa1f7c2 100644 --- a/riocli/deployment/__init__.py +++ b/riocli/deployment/__init__.py @@ -22,6 +22,7 @@ from riocli.deployment.status import status from riocli.deployment.wait import wait_for_deployment from riocli.deployment.execute import execute_command +from riocli.deployment.update import update_deployment @click.group( @@ -46,3 +47,4 @@ def deployment(): deployment.add_command(ssh_deployment) deployment.add_command(ssh_init) deployment.add_command(execute_command) +deployment.add_command(update_deployment) diff --git a/riocli/deployment/update.py b/riocli/deployment/update.py new file mode 100644 index 00000000..0c1e2788 --- /dev/null +++ b/riocli/deployment/update.py @@ -0,0 +1,88 @@ +# Copyright 2023 Rapyuta Robotics +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import functools +import re +import sys + +import click +from click_help_colors import HelpColorsCommand + +from rapyuta_io import Client, DeploymentPhaseConstants + +from riocli.config import new_client +from riocli.constants import Symbols, Colors +from riocli.utils import tabulate_data +from riocli.utils.spinner import with_spinner + +@click.command( + 'update', + cls=HelpColorsCommand, + help_headers_color=Colors.YELLOW, + help_options_color=Colors.GREEN, +) +@click.option('--force', '-f', '--silent', is_flag=True, default=False, + help='Skip confirmation') +@click.option('--update-all', '-a', is_flag=True, default=False, + help='Updates all deployments') +@click.argument('deployment-name-or-regex', type=str, default="") +@with_spinner(text="Update deployment...") +def update_deployment(force: bool, deployment_name_or_regex: str, update_all: bool, spinner=None) -> None: + """ + Delete the deployment from the Platform + """ + client = new_client() + if not(deployment_name_or_regex or update_all): + return + + deployments = fetch_deployments(client, deployment_name_or_regex, update_all) + if not deployments: + return + + headers = ["deployment name", "deployment id"] + data = [] + for deployment in deployments: + data.append([deployment.name, deployment.deploymentId]) + sys.stdout.write("\n") + tabulate_data(data, headers) + + if not force: + with spinner.hidden(): + click.confirm("Do you want to update above deployment(s)?", default=True, abort=True) + + try: + for deployment in deployments: + client.update_deployment(deployment.deploymentId) + + spinner.text = click.style( + 'Deployment(s) updated successfully!', fg=Colors.GREEN) + spinner.green.ok(Symbols.SUCCESS) + except Exception as e: + spinner.text = click.style( + 'Failed to update deployment(s): {}'.format(e), Colors.RED) + spinner.red.fail(Symbols.ERROR) + raise SystemExit(1) from e + +def fetch_deployments(client: Client, deployment_name_or_regex: str, update_all: bool): + find_func = functools.partial(client.get_all_deployments, + phases=[DeploymentPhaseConstants.SUCCEEDED, + DeploymentPhaseConstants.PROVISIONING]) + deployments = find_func() + result = [] + for deployment in deployments: + if update_all or deployment.name == deployment_name_or_regex or \ + (deployment_name_or_regex not in deployment.name and \ + re.search(deployment_name_or_regex, deployment.name)): + result.append(deployment) + return result \ No newline at end of file