Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 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
8 changes: 8 additions & 0 deletions src/fleet/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,11 @@ Release History
0.2.7
++++++
* Fix for `az fleet updaterun --node-image-selection` argument.

0.2.8
++++++
* Updates to Fleet identity options.

0.2.9
++++++
* Bug fixes on Fleet MSI
19 changes: 13 additions & 6 deletions src/fleet/azext_fleet/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,29 @@
type: command
short-summary: Creates or updates a Fleet.
parameters:
- name: --tags
type: string
short-summary: The tags of the managed cluster. The managed cluster instance and all resources managed by the cloud provider will be tagged.
- name: --dns-name-prefix -p
type: string
short-summary: Prefix for hostnames that are created. If not specified, generate a hostname using the
managed cluster and resource group names.
examples:
- name: Create a hubless fleet
text: az fleet create -g MyResourceGroup -l MyLocation -n MyFleetName --tags "TagKey=TagValue"
- name: Create a hubful fleet
text: az fleet create -g MyResourceGroup -l MyLocation -n MyFleetName --enable-hub --tags "TagKey=TagValue"

"""

helps['fleet update'] = """
type: command
short-summary: Patches a fleet resource.
parameters:
- name: --tags
type: string
short-summary: The tags of the managed cluster. The managed cluster instance and all resources managed by the cloud provider will be tagged.
examples:
- name: Update a Fleet's tags
text: az fleet update -g MyResourceGroup -n MyFleetName --tags Key=Value
- name: Update a Fleet to use a system assigned managed service identity.
text: az fleet update -g MyResourceGroup -n MyFleetName --enable-managed-identity --tags Key=Value
- name: Update a Fleet to use a user assigned managed service identity.
text: az fleet update -g MyResourceGroup -n MyFleetName --enable-managed-identity --assign-identity "/subscription/00000000-0000-0000-0000-000000000000/resourcegroup/MyResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/MyIdentity" --tags Key=Value
"""

helps['fleet show'] = """
Expand Down
9 changes: 5 additions & 4 deletions src/fleet/azext_fleet/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
tags_type,
file_type,
get_location_type,
get_enum_type
get_enum_type,
get_three_state_flag
)
from azure.cli.core.commands.validators import get_default_location_from_resource_group
from azext_fleet._validators import validate_member_cluster_id, validate_kubernetes_version, validate_apiserver_subnet_id, validate_agent_subnet_id, validate_assign_identity, validate_update_strategy_id
from azext_fleet._validators import validate_member_cluster_id, validate_kubernetes_version, validate_apiserver_subnet_id, validate_agent_subnet_id, validate_assign_identity, validate_update_strategy_name


def load_arguments(self, _):
Expand All @@ -34,7 +35,7 @@ def load_arguments(self, _):

with self.argument_context('fleet update') as c:
c.argument('tags', tags_type)
c.argument('enable_managed_identity', action='store_true', is_preview=True, help='Enable system assigned managed identity (MSI) on the Fleet resource.')
c.argument('enable_managed_identity', arg_type=get_three_state_flag(), is_preview=True, help='Enable system assigned managed identity (MSI) on the Fleet resource.')
c.argument('assign_identity', validator=validate_assign_identity, is_preview=True, help='With --enable-managed-identity, enable user assigned managed identity (MSI) on the Fleet resource. Specify the existing user assigned identity resource.')

with self.argument_context('fleet get-credentials') as c:
Expand All @@ -61,7 +62,7 @@ def load_arguments(self, _):
c.argument('kubernetes_version', validator=validate_kubernetes_version)
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')
c.argument('stages', type=file_type, completer=FilesCompleter(), help='Path to a json file that defines stages to upgrade a fleet. See examples for further reference.')
c.argument('update_strategy_id', validator=validate_update_strategy_id, help='The ID of the update strategy to use for this update run. If not specified, the default update strategy will be used.')
c.argument('update_strategy_name', validator=validate_update_strategy_name, help='The name of the update strategy to use for this update run. If not specified, the default update strategy will be used.')

with self.argument_context('fleet updatestrategy') as c:
c.argument('name', options_list=['--name', '-n'], help='Specify name for the fleet update strategy.')
Expand Down
23 changes: 11 additions & 12 deletions src/fleet/azext_fleet/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

import semver
import re

from azure.cli.core.azclierror import InvalidArgumentValueError
from azure.cli.core.util import CLIError
Expand All @@ -18,12 +18,12 @@ def validate_member_cluster_id(namespace):


def validate_kubernetes_version(namespace):
try:
if namespace.kubernetes_version:
semver.VersionInfo.parse(namespace.kubernetes_version)
except ValueError:
raise InvalidArgumentValueError(
"--kubernetes-version must be set as version x.x.x (eg. 1.2.3)")
if namespace.kubernetes_version:
k8s_release_regex = re.compile(r'^[v|V]?(\d+\.\d+(?:\.\d+)?)$')
found = k8s_release_regex.findall(namespace.kubernetes_version)
if not found:
raise InvalidArgumentValueError(
'--kubernetes-version should be the full version number or alias minor version, such as "1.7.12" or "1.7"')


def validate_apiserver_subnet_id(namespace):
Expand All @@ -34,12 +34,11 @@ def validate_agent_subnet_id(namespace):
_validate_subnet_id(namespace.agent_subnet_id, "--agent-subnet-id")


def validate_update_strategy_id(namespace):
if namespace.update_strategy_id is not None:
from msrestazure.tools import is_valid_resource_id
if not is_valid_resource_id(namespace.update_strategy_id):
def validate_update_strategy_name(namespace):
print(namespace.update_strategy_name)
Comment thread
Ealianis marked this conversation as resolved.
Outdated
if namespace.update_strategy_name is not None and not namespace.update_strategy_name.strip():
raise CLIError(
"--update-strategy-id is not a valid Azure resource ID.")
"--update-strategy-name is not a valid name")


def _validate_subnet_id(subnet_id, name):
Expand Down
8 changes: 4 additions & 4 deletions src/fleet/azext_fleet/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ def load_command_table(self, _):
g.custom_command("update", "update_fleet", supports_no_wait=True)
g.custom_show_command("show", "show_fleet")
g.custom_command("list", "list_fleet")
g.custom_command("delete", "delete_fleet", supports_no_wait=True)
g.custom_command("delete", "delete_fleet", supports_no_wait=True, confirmation=True)
Comment thread
kairu-ms marked this conversation as resolved.
g.custom_command("get-credentials", "get_credentials")
g.wait_command("wait")

# fleet members command group
with self.command_group("fleet member", fleet_members_sdk, client_factory=cf_fleet_members) as g:
g.custom_command("create", "create_fleet_member", supports_no_wait=True)
g.custom_command("update", "update_fleet_member")
g.custom_command("delete", "delete_fleet_member", supports_no_wait=True)
g.custom_command("delete", "delete_fleet_member", supports_no_wait=True, confirmation=True)
g.custom_command("list", "list_fleet_member")
g.custom_show_command("show", "show_fleet_member")
g.wait_command("wait")
Expand All @@ -58,7 +58,7 @@ def load_command_table(self, _):
g.custom_command("create", "create_update_run", supports_no_wait=True)
g.custom_show_command("show", "show_update_run")
g.custom_command("list", "list_update_run")
g.custom_command("delete", "delete_update_run", supports_no_wait=True)
g.custom_command("delete", "delete_update_run", supports_no_wait=True, confirmation=True)
g.custom_command("start", "start_update_run", supports_no_wait=True)
g.custom_command("stop", "stop_update_run", supports_no_wait=True)
g.wait_command("wait")
Expand All @@ -68,5 +68,5 @@ def load_command_table(self, _):
g.custom_command("create", "create_fleet_update_strategy", supports_no_wait=True)
g.custom_show_command("show", "show_fleet_update_strategy")
g.custom_command("list", "list_fleet_update_strategies")
g.custom_command("delete", "delete_fleet_update_strategy", supports_no_wait=True)
g.custom_command("delete", "delete_fleet_update_strategy", supports_no_wait=True, confirmation=True)
g.wait_command("wait")
58 changes: 41 additions & 17 deletions src/fleet/azext_fleet/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ def create_fleet(cmd,
operation_group="fleets"
)

poll_interval = 5
if enable_hub:
poll_interval = 30
fleet_hub_profile_model = cmd.get_models(
"FleetHubProfile",
resource_type=CUSTOM_MGMT_FLEET,
Expand Down Expand Up @@ -94,8 +96,13 @@ def create_fleet(cmd,
if enable_managed_identity:
managed_service_identity.type = "SystemAssigned"
if assign_identity is not None:
user_assigned_identity_model = cmd.get_models(
"UserAssignedIdentity",
resource_type=CUSTOM_MGMT_FLEET,
operation_group="fleets"
)
managed_service_identity.type = "UserAssigned"
managed_service_identity.user_assigned_identities = {assign_identity: None}
managed_service_identity.user_assigned_identities = {assign_identity: user_assigned_identity_model()}
elif assign_identity is not None:
raise CLIError("Cannot assign identity without enabling managed identity.")

Expand All @@ -105,15 +112,15 @@ def create_fleet(cmd,
hub_profile=fleet_hub_profile,
identity=managed_service_identity
)

return sdk_no_wait(no_wait, client.begin_create_or_update, resource_group_name, name, fleet)
return sdk_no_wait(no_wait, client.begin_create_or_update, resource_group_name, name, fleet, polling_interval = poll_interval)


def update_fleet(cmd,
client,
resource_group_name,
name,
enable_managed_identity=False,
enable_managed_identity=None,
assign_identity=None,
tags=None,
no_wait=False):
Expand All @@ -128,20 +135,29 @@ def update_fleet(cmd,
operation_group="fleets"
)

managed_service_identity = fleet_managed_service_identity_model(type="None")
if enable_managed_identity:
managed_service_identity.type = "SystemAssigned"
if enable_managed_identity is None:
managed_service_identity = None
if assign_identity is not None:
raise CLIError("Cannot assign identity without enabling managed identity.")
elif enable_managed_identity is False:
managed_service_identity = fleet_managed_service_identity_model(type="None")
else:
managed_service_identity = fleet_managed_service_identity_model(type="SystemAssigned")
if assign_identity is not None:
user_assigned_identity_model = cmd.get_models(
"UserAssignedIdentity",
resource_type=CUSTOM_MGMT_FLEET,
operation_group="fleets"
)
managed_service_identity.type = "UserAssigned"
managed_service_identity.user_assigned_identities = {assign_identity: None}
managed_service_identity.user_assigned_identities = {assign_identity: user_assigned_identity_model()}

fleet_patch = fleet_patch_model(
tags=tags,
identity=managed_service_identity
)

fleet_patch = fleet_patch_model(tags=tags)
return sdk_no_wait(no_wait, client.begin_update, resource_group_name, name, fleet_patch)
return sdk_no_wait(no_wait, client.begin_update, resource_group_name, name, fleet_patch, polling_interval=5)


def show_fleet(cmd, # pylint: disable=unused-argument
Expand All @@ -164,7 +180,7 @@ def delete_fleet(cmd, # pylint: disable=unused-argument
resource_group_name,
name,
no_wait=False):
return sdk_no_wait(no_wait, client.begin_delete, resource_group_name, name)
return sdk_no_wait(no_wait, client.begin_delete, resource_group_name, name, polling_interval=5)


def get_credentials(cmd, # pylint: disable=unused-argument
Expand Down Expand Up @@ -251,17 +267,17 @@ def create_update_run(cmd,
fleet_name,
name,
upgrade_type,
node_image_selection,
node_image_selection=None,
kubernetes_version=None,
stages=None,
update_strategy_id=None,
update_strategy_name=None,
no_wait=False):
if upgrade_type == "Full" and kubernetes_version is None:
raise CLIError("Please set kubernetes version when upgrade type is 'Full'.")
if upgrade_type == "NodeImageOnly" and kubernetes_version is not None:
raise CLIError("Cannot set kubernetes version when upgrade type is 'NodeImageOnly'.")
if stages is not None and update_strategy_id is not None:
raise CLIError("Cannot set stages when update strategy id is set.")
if stages is not None and update_strategy_name is not None:
raise CLIError("Cannot set stages when update strategy name is set.")

update_run_strategy = get_update_run_strategy(cmd, "update_runs", stages)

Expand All @@ -288,17 +304,25 @@ def create_update_run(cmd,

managed_cluster_upgrade_spec = managed_cluster_upgrade_spec_model(
type=upgrade_type, kubernetes_version=kubernetes_version)
if node_image_selection == None:
node_image_selection = "Latest"
node_image_selection_type = node_image_selection_model(type=node_image_selection)

managed_cluster_update = managed_cluster_update_model(
upgrade=managed_cluster_upgrade_spec,
node_image_selection=node_image_selection_type)

updateStrategyId = None
if update_strategy_name is not None:
subId=get_subscription_id(cmd.cli_ctx)
updateStrategyId = f"/subscriptions/{subId}/resourceGroups/{resource_group_name}/providers/Microsoft.ContainerService/fleets/{fleet_name}/updateStrategies/{update_strategy_name}"

update_run = update_run_model(
update_strategy_id=update_strategy_id,
update_strategy_id=updateStrategyId,
strategy=update_run_strategy,
managed_cluster_update=managed_cluster_update)


print("After successfully creating the run, you need to use the following command to start the run: az fleet updaterun start --resource-group={resource_group_name} --fleet={fleet_name} --name={name}")
return sdk_no_wait(no_wait, client.begin_create_or_update, resource_group_name, fleet_name, name, update_run)


Expand Down
2 changes: 1 addition & 1 deletion src/fleet/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

# TODO: Confirm this is the right version number you want and it matches your
# HISTORY.rst entry.
VERSION = '0.2.7'
VERSION = '0.2.9'
Comment thread
kairu-ms marked this conversation as resolved.
Outdated

# The full list of classifiers is available at
# https://pypi.python.org/pypi?%3Aaction=list_classifiers
Expand Down