Skip to content

Commit e1e2ff2

Browse files
Code review changes: removed functionality to set the cleanup options with linode-obj obj configure and storing the default values; added CLI cleanup options instead; some refactoring.
1 parent 127738a commit e1e2ff2

File tree

3 files changed

+123
-144
lines changed

3 files changed

+123
-144
lines changed

linodecli/configuration/config.py

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,9 @@ def plugin_set_value(self, key: str, value: Any):
221221
username = self.username or self.default_username()
222222
self.config.set(username, self._get_plugin_key(key), value)
223223

224-
def plugin_get_value(self, key: str) -> Optional[Any]:
224+
def plugin_get_value(
225+
self, key: str, default: T = None, value_type: Type[T] = str
226+
) -> Optional[T]:
225227
"""
226228
Retrieves and returns a config value previously set for a plugin. Your
227229
plugin should have set this value in the past. If this value does not
@@ -232,38 +234,36 @@ def plugin_get_value(self, key: str) -> Optional[Any]:
232234
:param key: The key of the value to return
233235
:type key: str
234236
237+
:param default: The default value to return if the key is not set
238+
:type default: T
239+
240+
:param value_type: The type to which the value should be cast
241+
:type value_type: Type[T]
242+
235243
:returns: The value for this plugin for this key, or None if not set
236244
:rtype: any
237245
"""
238246
username = self.username or self.default_username() or "DEFAULT"
239-
return self.config.get(
247+
value = self.config.get(
240248
username, self._get_plugin_key(key), fallback=None
241249
)
242-
243-
def plugin_get_config_value_or_set_default(
244-
self, key: str, default: T, value_type: Type[T] = str
245-
) -> T:
246-
"""
247-
Retrieves a plugin option value of the given type from the config. If the
248-
value is not set, sets it to the provided default value and returns that.
249-
"""
250-
value = self.plugin_get_value(key)
251-
252250
if value is None:
253-
# option not set - set to default and store it in the config file
254-
value_as_str = (
255-
("yes" if default else "no")
256-
if value_type is bool
257-
else str(default)
258-
)
259-
self.plugin_set_value(key, value_as_str)
260-
self.write_config()
261251
return default
262252

253+
if value_type is str:
254+
return value
255+
263256
if value_type is bool:
264257
return self.parse_boolean(value)
265258

266-
return cast(T, value_type(value))
259+
try:
260+
return cast(T, value_type(value))
261+
except (ValueError, TypeError):
262+
print(
263+
"" f"Could not cast config value {value} to {value_type}.",
264+
file=sys.stderr,
265+
)
266+
return default
267267

268268
def plugin_remove_option(self, key: str):
269269
"""

linodecli/plugins/obj/__init__.py

Lines changed: 70 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767

6868

6969
CLUSTER_KEY = "cluster"
70-
PERFORM_KEY_CLEANUP_KEY = "perform-key-cleanup"
70+
KEY_CLEANUP_ENABLED_KEY = "key-cleanup-enabled"
7171
KEY_LIFESPAN_KEY = "key-lifespan"
7272
KEY_ROTATION_PERIOD_KEY = "key-rotation-period"
7373
KEY_CLEANUP_BATCH_SIZE_KEY = "key-cleanup-batch-size"
@@ -326,23 +326,44 @@ def get_obj_args_parser():
326326
metavar="COMMAND",
327327
nargs="?",
328328
type=str,
329-
help="The command to execute in object storage",
329+
help="The command to execute in object storage.",
330330
)
331331
parser.add_argument(
332332
"--cluster",
333333
metavar="CLUSTER",
334334
type=str,
335-
help="The cluster to use for the operation",
335+
help="The cluster to use for the operation.",
336336
)
337337
parser.add_argument(
338-
"--skip-key-cleanup",
338+
"--force-key-cleanup",
339339
action="store_true",
340-
help="Skip cleanup of old linode-cli generated Object Storage keys",
340+
help="Performs cleanup of old linode-cli generated Object Storage keys"
341+
" before executing the Object Storage command. It overrides"
342+
" the --perform-key-cleanup option.",
341343
)
342344
parser.add_argument(
343-
"--force-key-cleanup",
344-
action="store_true",
345-
help="Force cleanup of old linode-cli generated Object Storage keys",
345+
"--key-cleanup-enabled",
346+
choices=["yes", "no"],
347+
help="If set to 'yes', performs cleanup of old linode-cli generated Object Storage"
348+
" keys before executing the Object Storage command. Cleanup occurs"
349+
" at most once every 24 hours.",
350+
)
351+
parser.add_argument(
352+
"--key-lifespan",
353+
type=str,
354+
help="Specifies the lifespan of linode-cli generated Object Storage keys"
355+
" (e.g. 30d for 30 days). Used only during key cleanup.",
356+
)
357+
parser.add_argument(
358+
"--key-rotation-period",
359+
type=str,
360+
help="Specifies the period after which the linode-cli generated Object Storage"
361+
" key must be rotated (e.g. 10d for 10 days). Used only during key cleanup.",
362+
)
363+
parser.add_argument(
364+
"--key-cleanup-batch-size",
365+
type=int,
366+
help="Number of old linode-cli generated Object Storage keys to clean up at once.",
346367
)
347368

348369
return parser
@@ -424,8 +445,7 @@ def call(
424445

425446
# make a client and clean-up keys, but only if we weren't printing help
426447
if not is_help:
427-
if not parsed.skip_key_cleanup:
428-
_cleanup_keys(context.client, parsed.force_key_cleanup)
448+
_cleanup_keys(context.client, parsed)
429449
access_key, secret_key = get_credentials(context.client)
430450

431451
cluster = parsed.cluster
@@ -606,7 +626,6 @@ def _configure_plugin(client: CLI):
606626
"""
607627
Configures Object Storage plugin.
608628
"""
609-
610629
cluster = _default_text_input( # pylint: disable=protected-access
611630
"Default cluster for operations (e.g. `us-mia-1`)",
612631
optional=False,
@@ -615,85 +634,27 @@ def _configure_plugin(client: CLI):
615634
if cluster:
616635
client.config.plugin_set_value(CLUSTER_KEY, cluster)
617636

618-
perform_key_cleanup = _default_text_input( # pylint: disable=protected-access
619-
"Perform automatic cleanup of old linode-cli generated Object Storage keys?"
620-
" The cleanup will occur before any Object Storage operation,"
621-
" at most once every 24 hours. (Y/n)",
622-
default="y",
623-
validator=lambda x: (
624-
"Please enter 'y' or 'n'"
625-
if x.lower() not in ("y", "n", "yes", "no")
626-
else None
627-
),
628-
)
629-
perform_key_cleanup = (
630-
"yes" if perform_key_cleanup.lower() in ("y", "yes") else "no"
631-
)
632-
client.config.plugin_set_value(PERFORM_KEY_CLEANUP_KEY, perform_key_cleanup)
633-
if perform_key_cleanup == "yes":
634-
key_lifespan = _default_text_input( # pylint: disable=protected-access
635-
"Linode-cli Object Storage key lifespan (e.g. `30d` for 30 days)",
636-
default="30d",
637-
validator=lambda x: (
638-
"Please enter a valid time duration"
639-
if parse_time(x) is None
640-
else None
641-
),
642-
)
643-
client.config.plugin_set_value(KEY_LIFESPAN_KEY, key_lifespan)
644-
645-
key_rotation_period = _default_text_input( # pylint: disable=protected-access
646-
"Linode-cli Object Storage key rotation period (e.g. `10d` for 10 days)",
647-
default="10d",
648-
validator=lambda x: (
649-
"Please enter a valid time duration"
650-
if parse_time(x) is None
651-
else None
652-
),
653-
)
654-
client.config.plugin_set_value(
655-
KEY_ROTATION_PERIOD_KEY, key_rotation_period
656-
)
657-
658-
cleanup_batch_size = _default_text_input( # pylint: disable=protected-access
659-
"Number of old linode-cli Object Storage keys to clean up at once",
660-
default="10",
661-
validator=lambda x: (
662-
"Please enter a valid integer" if not x.isdigit() else None
663-
),
664-
)
665-
client.config.plugin_set_value(
666-
KEY_CLEANUP_BATCH_SIZE_KEY, str(int(cleanup_batch_size))
667-
)
668-
669637
client.config.write_config()
670638

671639

672-
def _cleanup_keys(client: CLI, force_key_cleanup: bool) -> None:
640+
def _cleanup_keys(client: CLI, options) -> None:
673641
"""
674642
Cleans up stale linode-cli generated object storage keys.
675643
"""
676644
try:
677-
if not _should_perform_key_cleanup(client):
678-
return
679-
680645
current_timestamp = int(time.time())
681-
last_cleanup = client.config.plugin_get_value(
682-
LAST_KEY_CLEANUP_TIMESTAMP_KEY
683-
)
684-
if (
685-
not force_key_cleanup
686-
and last_cleanup
687-
and int(last_cleanup) > current_timestamp - 24 * 60 * 60
688-
):
689-
# if we did a cleanup in the last 24 hours, skip
646+
if not _should_perform_key_cleanup(client, options, current_timestamp):
690647
return
691648

692-
print(
693-
"Cleaning up old linode-cli Object Storage keys."
694-
" To disable this, use the --skip-key-cleanup option.",
695-
file=sys.stderr,
649+
cleanup_message = (
650+
"Cleaning up old linode-cli generated Object Storage keys."
696651
)
652+
if not options.force_key_cleanup:
653+
cleanup_message += (
654+
" To disable this, use the '--key-cleanup-enabled no' option."
655+
)
656+
print(cleanup_message, file=sys.stderr)
657+
697658
status, keys = client.call_operation("object-storage", "keys-list")
698659
if status != 200:
699660
print(
@@ -702,9 +663,9 @@ def _cleanup_keys(client: CLI, force_key_cleanup: bool) -> None:
702663
)
703664
return
704665

705-
key_lifespan = _get_key_lifespan(client)
706-
key_rotation_period = _get_key_rotation_period(client)
707-
cleanup_batch_size = _get_cleanup_batch_size(client)
666+
key_lifespan = _get_key_lifespan(client, options)
667+
key_rotation_period = _get_key_rotation_period(client, options)
668+
cleanup_batch_size = _get_cleanup_batch_size(client, options)
708669

709670
linode_cli_keys = _get_linode_cli_keys(
710671
keys["data"], key_lifespan, key_rotation_period, current_timestamp
@@ -725,26 +686,44 @@ def _cleanup_keys(client: CLI, force_key_cleanup: bool) -> None:
725686
)
726687

727688

728-
def _should_perform_key_cleanup(client: CLI) -> bool:
729-
return client.config.plugin_get_config_value_or_set_default(
730-
PERFORM_KEY_CLEANUP_KEY, True, bool
689+
def _should_perform_key_cleanup(
690+
client: CLI, options, current_timestamp
691+
) -> bool:
692+
if options.force_key_cleanup:
693+
return True
694+
if not _is_key_cleanup_enabled(client, options):
695+
return False
696+
last_cleanup = client.config.plugin_get_value(
697+
LAST_KEY_CLEANUP_TIMESTAMP_KEY
731698
)
732699

700+
# if we did a cleanup in the last 24 hours, skip it this time
701+
return (
702+
last_cleanup is None
703+
or int(last_cleanup) <= current_timestamp - 24 * 60 * 60
704+
)
705+
706+
707+
def _is_key_cleanup_enabled(client, options) -> bool:
708+
if options.key_cleanup_enabled in ["yes", "no"]:
709+
return options.key_cleanup_enabled == "yes"
710+
return client.config.plugin_get_value(KEY_CLEANUP_ENABLED_KEY, True, bool)
711+
733712

734-
def _get_key_lifespan(client) -> str:
735-
return client.config.plugin_get_config_value_or_set_default(
713+
def _get_key_lifespan(client, options) -> str:
714+
return options.key_lifespan or client.config.plugin_get_value(
736715
KEY_LIFESPAN_KEY, "30d"
737716
)
738717

739718

740-
def _get_key_rotation_period(client) -> str:
741-
return client.config.plugin_get_config_value_or_set_default(
719+
def _get_key_rotation_period(client, options) -> str:
720+
return options.key_rotation_period or client.config.plugin_get_value(
742721
KEY_ROTATION_PERIOD_KEY, "10d"
743722
)
744723

745724

746-
def _get_cleanup_batch_size(client) -> int:
747-
return client.config.plugin_get_config_value_or_set_default(
725+
def _get_cleanup_batch_size(client, options) -> int:
726+
return options.key_cleanup_batch_size or client.config.plugin_get_value(
748727
KEY_CLEANUP_BATCH_SIZE_KEY, 10, int
749728
)
750729

0 commit comments

Comments
 (0)