Skip to content

Commit eecab54

Browse files
committed
✨ feat: --set flag for update and create actions
1 parent 573078a commit eecab54

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

oks_cli/cluster.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
ctx_update, set_cluster_id, get_cluster_id, get_project_id, \
2424
get_template, get_cluster_name, format_changed_row, \
2525
is_interesting_status, profile_completer, project_completer, \
26-
kubeconfig_parse_fields, print_table, format_row
26+
kubeconfig_parse_fields, print_table, format_row, apply_set_fields
2727

2828
from .profile import add_profile
2929
from .project import project_create, project_login
@@ -371,8 +371,9 @@ def _create_cluster(project_name, cluster_config, output):
371371
@click.option('--output', '-o', type=click.Choice(["json", "yaml"]), help="Specify output format, by default is json")
372372
@click.option('--filename', '-f', type=click.File("r"), help="Path to file to use to create the cluster ")
373373
@click.option('--profile', help="Configuration profile to use", shell_complete=profile_completer)
374+
@click.option('--set', 'set_fields', multiple=True, help="Set arbitrary nested fields, e.g. auth.oidc.issuer-url=value")
374375
@click.pass_context
375-
def cluster_create_command(ctx, project_name, cluster_name, description, admin, version, cidr_pods, cidr_service, control_plane, zone, enable_admission_plugins, disable_admission_plugins, quirk, tags, disable_api_termination, cp_multi_az, dry_run, output, filename, profile):
376+
def cluster_create_command(ctx, project_name, cluster_name, description, admin, version, cidr_pods, cidr_service, control_plane, zone, enable_admission_plugins, disable_admission_plugins, quirk, tags, disable_api_termination, cp_multi_az, dry_run, output, filename, profile, set_fields):
376377
"""CLI command to create a new Kubernetes cluster with optional configuration parameters."""
377378
project_name, cluster_name, profile = ctx_update(ctx, project_name, cluster_name, profile)
378379
login_profile(profile)
@@ -443,6 +444,8 @@ def cluster_create_command(ctx, project_name, cluster_name, description, admin,
443444
if cp_multi_az is not None:
444445
cluster_config["cp_multi_az"] = cp_multi_az
445446

447+
apply_set_fields(cluster_config, set_fields)
448+
446449
if not dry_run:
447450
_create_cluster(project_name, cluster_config, output)
448451
else:
@@ -466,8 +469,9 @@ def cluster_create_command(ctx, project_name, cluster_name, description, admin,
466469
@click.option('--output', '-o', type=click.Choice(["json", "yaml"]), help="Specify output format, by default is json")
467470
@click.option('--filename', '-f', type=click.File("r"), help="Path to file to use to update the cluster ")
468471
@click.option('--profile', help="Configuration profile to use", shell_complete=profile_completer)
472+
@click.option('--set', 'set_fields', multiple=True, help="Set arbitrary nested fields, e.g. auth.oidc.issuer-url=value")
469473
@click.pass_context
470-
def cluster_update_command(ctx, project_name, cluster_name, description, admin, version, tags, enable_admission_plugins, disable_admission_plugins, quirk, disable_api_termination, control_plane, dry_run, output, filename, profile):
474+
def cluster_update_command(ctx, project_name, cluster_name, description, admin, version, tags, enable_admission_plugins, disable_admission_plugins, quirk, disable_api_termination, control_plane, dry_run, output, filename, profile, set_fields):
471475
"""CLI command to update an existing Kubernetes cluster with new configuration options."""
472476
project_name, cluster_name, profile = ctx_update(ctx, project_name, cluster_name, profile)
473477
login_profile(profile)
@@ -545,6 +549,8 @@ def cluster_update_command(ctx, project_name, cluster_name, description, admin,
545549

546550
if control_plane:
547551
cluster_config['control_planes'] = control_plane
552+
553+
apply_set_fields(cluster_config, set_fields)
548554

549555
if dry_run:
550556
print_output(cluster_config, output)

oks_cli/utils.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1070,4 +1070,41 @@ def format_changed_row(table, row):
10701070
def is_interesting_status(status):
10711071
"""Check if status is in the list of interesting statuses."""
10721072
interesting_statuses = ["pending", "deploying", "updating", "upgrading", "deleting"]
1073-
return status in interesting_statuses
1073+
return status in interesting_statuses
1074+
1075+
def parse_value(value):
1076+
value = value.strip()
1077+
if value.lower() == "true":
1078+
return True
1079+
if value.lower() == "false":
1080+
return False
1081+
try:
1082+
return int(value)
1083+
except ValueError:
1084+
pass
1085+
try:
1086+
return float(value)
1087+
except ValueError:
1088+
pass
1089+
if ',' in value:
1090+
return [v.strip() for v in value.split(',')]
1091+
return value
1092+
1093+
def apply_set_fields(target: dict, set_fields):
1094+
for field in set_fields:
1095+
if '=' not in field:
1096+
raise click.ClickException(
1097+
f"Malformed --set argument: '{field}' (expected key=value)"
1098+
)
1099+
1100+
key_path, value_str = field.split('=', 1)
1101+
key_parts = key_path.split('.')
1102+
value = parse_value(value_str)
1103+
1104+
current = target
1105+
for part in key_parts[:-1]:
1106+
if part not in current or not isinstance(current[part], dict):
1107+
current[part] = {}
1108+
current = current[part]
1109+
1110+
current[key_parts[-1]] = value

0 commit comments

Comments
 (0)