Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[az fleet] Hubless-Hubful PUT and reconcile commands. #7213

Merged
merged 13 commits into from
Feb 2, 2024
7 changes: 6 additions & 1 deletion src/fleet/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,9 @@ Release History

1.0.2
++++++
* Minor style & linting updates to codebase.
* Minor style & linting updates to codebase.

1.0.3
++++++
* Added `az fleet reconcile` & `az member reconcile` commands.
* Added support for converting a Fleet from hubless to hubful. See `az fleet update --help`.
11 changes: 9 additions & 2 deletions src/fleet/azext_fleet/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,15 @@ def load_arguments(self, _):

with self.argument_context('fleet update') as c:
c.argument('tags', tags_type)
c.argument('enable_managed_identity', arg_type=get_three_state_flag(), help='Enable system assigned managed identity (MSI) on the Fleet resource.')
c.argument('assign_identity', validator=validate_assign_identity, help='With --enable-managed-identity, enable user assigned managed identity (MSI) on the Fleet resource. Specify the existing user assigned identity resource.')
c.argument('dns_name_prefix', options_list=['--dns-name-prefix', '-p'], is_preview=True)
c.argument('enable_private_cluster', action='store_true', is_preview=True, help='Whether to create the Fleet hub as a private cluster or not.')
c.argument('enable_vnet_integration', action='store_true', is_preview=True, help='Whether to enable apiserver vnet integration for the Fleet hub or not.')
c.argument('apiserver_subnet_id', validator=validate_apiserver_subnet_id, is_preview=True, help='The subnet to be used when apiserver vnet integration is enabled. It is required when creating a new Fleet with BYO vnet.')
c.argument('agent_subnet_id', validator=validate_agent_subnet_id, is_preview=True, help='The ID of the subnet which the Fleet hub node will join on startup. If this is not specified, a vnet and subnet will be generated and used.')
c.argument('enable_managed_identity', action='store_true', help='Enable system assigned managed identity (MSI) on the Fleet resource.')
c.argument('assign_identity', validator=validate_assign_identity, help='With --enable-managed-identity, enable user assigned managed identity (MSI) on the Fleet resource by specifying the user assigned identity\'s resource Id.')
c.argument('enable_hub', action='store_true', is_preview=True, help='If set, the Fleet will be created with a hub cluster.')
c.argument('vm_size', is_preview=True, validator=validate_vm_size, help='The virtual machine size of the Fleet hub.')

with self.argument_context('fleet get-credentials') as c:
c.argument('context_name', options_list=['--context'], help='If specified, overwrite the default context name.')
Expand Down
2 changes: 2 additions & 0 deletions src/fleet/azext_fleet/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def load_command_table(self, _):
g.custom_command("list", "list_fleet")
g.custom_command("delete", "delete_fleet", supports_no_wait=True, confirmation=True)
g.custom_command("get-credentials", "get_credentials")
g.custom_command("reconcile", "reconcile_fleet", supports_no_wait=True)
g.wait_command("wait")

# fleet members command group
Expand All @@ -51,6 +52,7 @@ def load_command_table(self, _):
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.custom_command("reconcile", "reconcile_fleet_member", supports_no_wait=True)
g.wait_command("wait")

# fleet update runs command group
Expand Down
94 changes: 92 additions & 2 deletions src/fleet/azext_fleet/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,16 @@ def update_fleet(cmd,
client,
resource_group_name,
name,
enable_managed_identity=None,
assign_identity=None,
tags=None,
enable_hub=False,
vm_size=None,
dns_name_prefix=None,
enable_private_cluster=False,
enable_vnet_integration=False,
apiserver_subnet_id=None,
agent_subnet_id=None,
enable_managed_identity=False,
assign_identity=None,
no_wait=False):
fleet_patch_model = cmd.get_models(
"FleetPatch",
Expand Down Expand Up @@ -159,6 +166,59 @@ def update_fleet(cmd,
managed_service_identity.type = "UserAssigned"
managed_service_identity.user_assigned_identities = {assign_identity: user_assigned_identity_model()}

# Currently, patch does not support the HubProfile. Thus fleet update with --enable-hub, will do a PUT.
Ealianis marked this conversation as resolved.
Show resolved Hide resolved
if enable_hub:
print("in enabled Hub")
existingFleet = client.get(resource_group_name, name)
print("got existing fleet")

fleet_hub_profile_model = cmd.get_models(
"FleetHubProfile",
resource_type=CUSTOM_MGMT_FLEET,
operation_group="fleets"
)
api_server_access_profile_model = cmd.get_models(
"APIServerAccessProfile",
resource_type=CUSTOM_MGMT_FLEET,
operation_group="fleets"
)
agent_profile_model = cmd.get_models(
"AgentProfile",
resource_type=CUSTOM_MGMT_FLEET,
operation_group="fleets",
vm_size=vm_size
)
if dns_name_prefix is None:
subscription_id = get_subscription_id(cmd.cli_ctx)
# Use subscription id to provide uniqueness and prevent DNS name clashes
name_part = re.sub('[^A-Za-z0-9-]', '', name)[0:10]
if not name_part[0].isalpha():
name_part = (str('a') + name_part)[0:10]
resource_group_part = re.sub('[^A-Za-z0-9-]', '', resource_group_name)[0:16]
dns_name_prefix = f'{name_part}-{resource_group_part}-{subscription_id[0:6]}'

api_server_access_profile = api_server_access_profile_model(
enable_private_cluster=enable_private_cluster,
enable_vnet_integration=enable_vnet_integration,
subnet_id=apiserver_subnet_id
)
agent_profile = agent_profile_model(
subnet_id=agent_subnet_id
)
fleet_hub_profile = fleet_hub_profile_model(
dns_prefix=dns_name_prefix,
api_server_access_profile=api_server_access_profile,
agent_profile=agent_profile)

existingFleet.hub_profile = fleet_hub_profile
existingFleet.identity = managed_service_identity
if tags is not None:
existingFleet.tags = tags

print("about to execute being_create_or_update")
return sdk_no_wait(no_wait, client.begin_create_or_update, resource_group_name, name, existingFleet, polling_interval=30)


fleet_patch = fleet_patch_model(
tags=tags,
identity=managed_service_identity
Expand Down Expand Up @@ -211,6 +271,25 @@ def get_credentials(cmd, # pylint: disable=unused-argument
raise CLIError("Fail to find kubeconfig file.") from exc


def reconcile_fleet(cmd, # pylint: disable=unused-argument
client,
resource_group_name,
name,
no_wait=False):

poll_interval = 5
fleet = client.get(resource_group_name, name)
if fleet.hub_profile is not None:
poll_interval = 30

return sdk_no_wait(no_wait,
Ealianis marked this conversation as resolved.
Show resolved Hide resolved
client.begin_create_or_update,
resource_group_name,
name,
fleet,
polling_interval=poll_interval)


def create_fleet_member(cmd,
client,
resource_group_name,
Expand Down Expand Up @@ -268,6 +347,17 @@ def delete_fleet_member(cmd, # pylint: disable=unused-argument
return sdk_no_wait(no_wait, client.begin_delete, resource_group_name, fleet_name, name)


def reconcile_fleet_member(cmd, # pylint: disable=unused-argument
client,
resource_group_name,
name,
fleet_name,
no_wait=False):

member = client.get(resource_group_name, fleet_name, name)
return sdk_no_wait(no_wait, client.begin_create, resource_group_name, fleet_name, name, member)
Ealianis marked this conversation as resolved.
Show resolved Hide resolved


def create_update_run(cmd,
client,
resource_group_name,
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 = '1.0.2'
VERSION = '1.0.3'

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