Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/fleet/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,11 @@ Release History

1.5.2
++++++
* Bug fix for `az fleet create --enable-hub --enable-private-cluster` argument
* Bug fix for `az fleet create --enable-hub --enable-private-cluster` argument

1.6.0
++++++
* Upgrade SDK version to 2025-04-01-preview
* Add Fleet Gates support
* Add TargetKubernetesVersion channel support
* Add Fleet Member labels support
2 changes: 1 addition & 1 deletion src/fleet/azext_fleet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def register_fleet_resource_type():
register_resource_type(
"latest",
CUSTOM_MGMT_FLEET,
SDKProfile("2025-03-01"),
SDKProfile("2025-04-01-preview"),
)


Expand Down
4 changes: 4 additions & 0 deletions src/fleet/azext_fleet/_client_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ def cf_fleet_members(cli_ctx, *_):
return get_container_service_client(cli_ctx).fleet_members


def cf_gates(cli_ctx, *_):
return get_container_service_client(cli_ctx).gates


def cf_update_runs(cli_ctx, *_):
return get_container_service_client(cli_ctx).update_runs

Expand Down
43 changes: 41 additions & 2 deletions src/fleet/azext_fleet/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
short-summary: Update group of the member.
examples:
- name: Create a member and assign it to an update group.
text: az fleet member create -g MyFleetResourceGroup -f MyFleetName -n NameOfMember --update-group UpdateGroup1 --member-cluster-id "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyFleetResourceGroup/providers/Microsoft.ContainerService/managedClusters/MyManagedCluster"
text: az fleet member create -g MyFleetResourceGroup -f MyFleetName -n NameOfMember --update-group group1 --member-cluster-id "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyFleetResourceGroup/providers/Microsoft.ContainerService/managedClusters/MyManagedCluster"
"""

helps['fleet member update'] = """
Expand All @@ -129,7 +129,7 @@
short-summary: Update group of the member.
examples:
- name: Update an existing member's update group.
text: az fleet member update -g MyFleetResourceGroup -f MyFleetName -n NameOfMember --update-group UpdateGroup2
text: az fleet member update -g MyFleetResourceGroup -f MyFleetName -n NameOfMember --update-group group2
"""

helps['fleet member list'] = """
Expand Down Expand Up @@ -393,3 +393,42 @@
short-summary: Wait for an auto upgrade resource to reach a desired state.
long-summary: If an operation on an auto upgrade profile was interrupted or was started with `--no-wait`, use this command to wait for it to complete.
"""

helps['fleet gate'] = """
type: group
short-summary: Commands to manage gates.
"""

helps['fleet gate list'] = """
type: command
short-summary: Lists all gates under a fleet.
examples:
- name: Lists all gates under a fleet.
text: az fleet gate list -g MyFleetResourceGroup --fleet-name MyFleetName
- name: List all gates, filtering on gate state. Valid values are ('Pending', 'Skipped', 'Completed').
text: az fleet gate list -g MyFleetResourceGroup --fleet-name MyFleetName --state Pending
"""

helps['fleet gate show'] = """
type: command
short-summary: Shows a specific gate.
examples:
- name: Shows a specific gate.
text: az fleet gate show -g MyFleetResourceGroup -f MyFleetName -n 3fa85f64-5717-4562-b3fc-2c963f66afa6
"""

helps['fleet gate update'] = """
type: command
short-summary: Updates a gate. Currently only the gate state can be updated. Valid values are ('Completed').
examples:
- name: Updates a gate.
text: az fleet gate update -g MyFleetResourceGroup --fleet-name MyFleetName --gate-name 3fa85f64-5717-4562-b3fc-2c963f66afa6 --state "Completed"
"""

helps['fleet gate approve'] = """
type: command
short-summary: Approves a gate, and sets the gate state to Completed. This modifies the gate state in the same way as the general-purpose update command, however it's simpler to use.
examples:
- name: Approves a gate.
text: az fleet gate approve -g MyFleetResourceGroup --fleet-name MyFleetName --gate-name 3fa85f64-5717-4562-b3fc-2c963f66afa6
"""
65 changes: 61 additions & 4 deletions src/fleet/azext_fleet/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
file_type,
get_location_type,
get_enum_type,
get_three_state_flag
get_three_state_flag,
CLIArgumentType
)
from azure.cli.core.commands.validators import get_default_location_from_resource_group
from azext_fleet._validators import (
Expand All @@ -23,6 +24,13 @@
validate_vm_size,
validate_targets,
validate_update_strategy_id,
validate_labels
)

labels_type = CLIArgumentType(
metavar='KEY=VALUE',
type=validate_labels,
help='Space-separated labels: key[=value] [key[=value] ...]. Example: env=production region=us-west team=devops'
)


Expand Down Expand Up @@ -62,9 +70,21 @@ def load_arguments(self, _):
with self.argument_context('fleet member create') as c:
c.argument('member_cluster_id', validator=validate_member_cluster_id)
c.argument('update_group')
c.argument(
'member_labels',
labels_type,
options_list=['--member-labels', '--labels'],
help='Space-separated labels in key=value format. Example: env=production region=us-west team=devops'
)

with self.argument_context('fleet member update') as c:
c.argument('update_group')
c.argument(
'member_labels',
labels_type,
options_list=['--member-labels', '--labels'],
help='Space-separated labels in key=value format. Example: env=production region=us-west team=devops'
)

with self.argument_context('fleet updaterun') as c:
c.argument('name', options_list=['--name', '-n'], help='Specify name for the update run.')
Expand Down Expand Up @@ -100,12 +120,24 @@ def load_arguments(self, _):
with self.argument_context('fleet autoupgradeprofile create') as c:
c.argument('update_strategy_id', validator=validate_update_strategy_id,
help='The resource ID of the update strategy that the auto upgrade profile should follow.')
c.argument('channel', options_list=['--channel', '-c'], arg_type=get_enum_type(['Stable', 'Rapid', 'NodeImage']),
c.argument('channel', options_list=['--channel', '-c'], arg_type=get_enum_type(['Stable', 'Rapid', 'NodeImage', 'TargetKubernetesVersion']),
help='The auto upgrade channel type.')
c.argument('node_image_selection', arg_type=get_enum_type(['Latest', 'Consistent']),
help='Node Image Selection is an option that lets you choose how your clusters\' nodes are upgraded')
help='Node Image Selection is an option that lets you choose how your clusters\' nodes are upgraded.')
c.argument(
'target_kubernetes_version',
options_list=['--target-kubernetes-version', '--tkv'],
help=(
'This is the target Kubernetes version for auto-upgrade. The format must be "{major version}.{minor version}". '
'For example, "1.30". By default, this is empty. '
'If the upgrade channel is set to TargetKubernetesVersion, this field must not be empty. '
'If the upgrade channel is Rapid, Stable, or NodeImage, this field must be empty.'
)
)
c.argument('disabled', action='store_true',
help='The disabled flag ensures auto upgrade profile does not run by default')
help='The disabled flag ensures auto upgrade profile does not run by default.')
c.argument('long_term_support', action='store_true', options_list=['--long-term-support', '--lts'],
help='If upgrade channel is not TargetKubernetesVersion, this field must be False. If set to True: Fleet auto upgrade will generate update runs for patches of minor versions earlier than N-2 (where N is the latest supported minor version) if those minor versions support Long-Term Support (LTS). By default, this is set to False.')

with self.argument_context('fleet autoupgradeprofile wait') as c:
c.argument('auto_upgrade_profile_name', options_list=['--auto-upgrade-profile-name', '--profile-name'],
Expand All @@ -115,3 +147,28 @@ def load_arguments(self, _):
c.argument('resource_group_name', options_list=['--resource-group', '-g'], help='Name of the resource group.')
c.argument('fleet_name', options_list=['--fleet-name', '-f'], help='Name of the fleet.')
c.argument('auto_upgrade_profile_name', options_list=['--auto-upgrade-profile-name', '--profile-name', '--name', '-n'], help='Name of the auto upgrade profile.')

with self.argument_context('fleet gate list') as c:
c.argument('resource_group_name', options_list=['--resource-group', '-g'], help='Name of the resource group.')
c.argument('fleet_name', options_list=['--fleet-name', '-f'], help='Name of the fleet.')
c.argument('state_filter', options_list=['--state-filter', '--state'], help='Apply a filter on gate state. Valid values are: Pending, Skipped, Completed')

with self.argument_context('fleet gate show') as c:
c.argument('resource_group_name', options_list=['--resource-group', '-g'], help='Name of the resource group.')
c.argument('fleet_name', options_list=['--fleet-name', '-f'], help='Name of the fleet.')
c.argument('gate_name', options_list=['--gate-name', '--gate', '-n', '--name'], help='Name of the gate.')

with self.argument_context('fleet gate update') as c:
c.argument('resource_group_name', options_list=['--resource-group', '-g'], help='Name of the resource group.')
c.argument('fleet_name', options_list=['--fleet-name', '-f'], help='Name of the fleet.')
c.argument('gate_name', options_list=['--gate-name', '--gate', '-n'], help='Name of the gate.')
c.argument(
'gate_state',
options_list=['--gate-state', '--gs', '--state'],
help='The Gate State to patch. Valid values are: Completed.'
)

with self.argument_context('fleet gate approve') as c:
c.argument('resource_group_name', options_list=['--resource-group', '-g'], help='Name of the resource group.')
c.argument('fleet_name', options_list=['--fleet-name', '-f'], help='Name of the fleet.')
c.argument('gate_name', options_list=['--gate-name', '--gate', '-n'], help='Name of the gate.')
10 changes: 10 additions & 0 deletions src/fleet/azext_fleet/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,13 @@ def validate_update_strategy_id(namespace):
if not is_valid_resource_id(update_strategy_id):
raise InvalidArgumentValueError(
"--update-strategy-id is not a valid Azure resource ID.")


def validate_labels(val):
result = {}
for item in val.split():
if '=' not in item:
raise ValueError("Expected key=value format")
k, v = item.split('=', 1)
result[k] = v
return result
17 changes: 15 additions & 2 deletions src/fleet/azext_fleet/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
cf_update_runs,
cf_fleet_update_strategies,
cf_auto_upgrade_profiles,
cf_auto_upgrade_profile_operations

cf_auto_upgrade_profile_operations,
cf_gates
)


Expand Down Expand Up @@ -54,6 +54,12 @@ def load_command_table(self, _):
client_factory=cf_auto_upgrade_profile_operations
)

gates_sdk = CliCommandType(
operations_tmpl="azext_fleet.vendored_sdks.operations._gates_operations#GatesOperations.{}",
operation_group="gates",
client_factory=cf_gates
)

# fleets command group
with self.command_group("fleet", fleets_sdk, client_factory=cf_fleets) as g:
g.custom_command("create", "create_fleet", supports_no_wait=True)
Expand Down Expand Up @@ -105,3 +111,10 @@ def load_command_table(self, _):
# auto upgrade profiles operation command group
with self.command_group("fleet autoupgradeprofile", auto_upgrade_profile_operations_sdk, client_factory=cf_auto_upgrade_profile_operations) as g:
g.custom_command("generate-update-run", "generate_update_run", supports_no_wait=True)

# fleet gates command group
with self.command_group("fleet gate", gates_sdk, client_factory=cf_gates) as g:
g.custom_command("list", "list_gates_by_fleet")
g.custom_show_command("show", "show_gate")
g.custom_command("update", "update_gate")
g.custom_command("approve", "approve_gate")
3 changes: 3 additions & 0 deletions src/fleet/azext_fleet/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
UPGRADE_TYPE_NODEIMAGEONLY = "NodeImageOnly"
FLEET_1P_APP_ID = "609d2f62-527f-4451-bfd2-ac2c7850822c"

SUPPORTED_GATE_STATES_FILTERS = ["Pending", "Skipped", "Completed"]
SUPPORTED_GATE_STATES_PATCH = ["Completed"]

UPGRADE_TYPE_ERROR_MESSAGES = {
UPGRADE_TYPE_CONTROLPLANEONLY: f"Please set kubernetes version when upgrade type is '{UPGRADE_TYPE_CONTROLPLANEONLY}'.", # pylint: disable=line-too-long
UPGRADE_TYPE_FULL: f"Please set kubernetes version when upgrade type is '{UPGRADE_TYPE_FULL}'.",
Expand Down
Loading
Loading