1# -------------------------------------------------------------------------------------------- 2# Copyright (c) Microsoft Corporation. All rights reserved. 3# Licensed under the MIT License. See License.txt in the project root for license information. 4# -------------------------------------------------------------------------------------------- 5 6# pylint: disable=line-too-long,too-many-lines 7 8from azure.cli.core.commands import LongRunningOperation 9from azure.core.exceptions import HttpResponseError 10from azure.mgmt.servicefabricmanagedclusters.models import ( 11 NodeType, 12 EndpointRangeDescription, 13 VMSSExtension, 14 VaultSecretGroup, 15 VaultCertificate, 16 SubResource, 17 NodeTypeActionParameters 18) 19 20from knack.log import get_logger 21 22logger = get_logger(__name__) 23 24 25# pylint:disable=too-many-locals, 26def create_node_type(cmd, 27 client, 28 resource_group_name, 29 cluster_name, 30 node_type_name, 31 instance_count, 32 primary=False, 33 disk_size=None, 34 disk_type=None, 35 application_start_port=None, 36 application_end_port=None, 37 ephemeral_start_port=None, 38 ephemeral_end_port=None, 39 vm_size=None, 40 vm_image_publisher=None, 41 vm_image_offer=None, 42 vm_image_sku=None, 43 vm_image_version=None, 44 capacity=None, 45 placement_property=None, 46 is_stateless=False, 47 multiple_placement_groups=False): 48 49 # set defult parameters 50 if disk_size is None: 51 disk_size = 100 52 53 if vm_size is None: 54 vm_size = "Standard_D2" 55 56 if vm_image_publisher is None: 57 vm_image_publisher = "MicrosoftWindowsServer" 58 59 if vm_image_offer is None: 60 vm_image_offer = "WindowsServer" 61 62 if vm_image_sku is None: 63 vm_image_sku = "2019-Datacenter" 64 65 if vm_image_version is None: 66 vm_image_version = "latest" 67 68 try: 69 new_node_type = NodeType(is_primary=primary, 70 vm_instance_count=int(instance_count), 71 data_disk_size_gb=disk_size, 72 data_disk_type=disk_type, 73 vm_size=vm_size, 74 vm_image_publisher=vm_image_publisher, 75 vm_image_offer=vm_image_offer, 76 vm_image_sku=vm_image_sku, 77 vm_image_version=vm_image_version, 78 capacities=capacity, 79 placement_properties=placement_property, 80 is_stateless=is_stateless, 81 multiple_placement_groups=multiple_placement_groups) 82 83 if application_start_port and application_end_port: 84 new_node_type.application_ports = EndpointRangeDescription(start_port=application_start_port, 85 end_port=application_end_port) 86 87 if ephemeral_start_port and ephemeral_end_port: 88 new_node_type.ephemeral_ports = EndpointRangeDescription(start_port=ephemeral_start_port, 89 end_port=ephemeral_end_port) 90 91 logger.info("Creating node type '%s'", node_type_name) 92 poller = client.node_types.begin_create_or_update(resource_group_name, cluster_name, node_type_name, new_node_type) 93 node_type = LongRunningOperation(cmd.cli_ctx)(poller) 94 return node_type 95 except HttpResponseError as ex: 96 logger.error("HttpResponseError: %s", ex) 97 raise 98 99 100def update_node_type(cmd, 101 client, 102 resource_group_name, 103 cluster_name, 104 node_type_name, 105 instance_count=None, 106 application_start_port=None, 107 application_end_port=None, 108 ephemeral_start_port=None, 109 ephemeral_end_port=None, 110 capacity=None, 111 placement_property=None): 112 try: 113 node_type = client.node_types.get(resource_group_name, cluster_name, node_type_name) 114 115 if instance_count is not None: 116 node_type.vm_instance_count = instance_count 117 118 if application_start_port and application_end_port: 119 node_type.application_ports = EndpointRangeDescription(start_port=application_start_port, 120 end_port=application_end_port) 121 122 if ephemeral_start_port and ephemeral_end_port: 123 node_type.ephemeral_ports = EndpointRangeDescription(start_port=ephemeral_start_port, 124 end_port=ephemeral_end_port) 125 126 if capacity is not None: 127 node_type.capacities = capacity 128 129 if placement_property is not None: 130 node_type.placement_properties = placement_property 131 132 poller = client.node_types.begin_create_or_update(resource_group_name, cluster_name, node_type_name, node_type) 133 return LongRunningOperation(cmd.cli_ctx)(poller) 134 except HttpResponseError as ex: 135 logger.error("HttpResponseError: %s", ex) 136 raise 137 138 139def reimage_node(cmd, 140 client, 141 resource_group_name, 142 cluster_name, 143 node_type_name, 144 node_name, 145 force=False): 146 try: 147 nodes = [node_name] if isinstance(node_name, str) else node_name 148 action_parameters = NodeTypeActionParameters(nodes=nodes, force=force) 149 poller = client.node_types.begin_reimage(resource_group_name, cluster_name, node_type_name, parameters=action_parameters) 150 LongRunningOperation(cmd.cli_ctx, start_msg='Reimaging nodes', finish_msg='Nodes reimaged')(poller) 151 except HttpResponseError as ex: 152 logger.error("HttpResponseError: %s", ex) 153 raise 154 155 156def restart_node(cmd, 157 client, 158 resource_group_name, 159 cluster_name, 160 node_type_name, 161 node_name, 162 force=False): 163 try: 164 nodes = [node_name] if isinstance(node_name, str) else node_name 165 action_parameters = NodeTypeActionParameters(nodes=nodes, force=force) 166 poller = client.node_types.begin_restart(resource_group_name, cluster_name, node_type_name, parameters=action_parameters) 167 LongRunningOperation(cmd.cli_ctx, start_msg='Restarting nodes', finish_msg='Nodes restarted')(poller) 168 except HttpResponseError as ex: 169 logger.error("HttpResponseError: %s", ex) 170 raise 171 172 173def delete_node(cmd, 174 client, 175 resource_group_name, 176 cluster_name, 177 node_type_name, 178 node_name, 179 force=False): 180 try: 181 nodes = [node_name] if isinstance(node_name, str) else node_name 182 action_parameters = NodeTypeActionParameters(nodes=nodes, force=force) 183 poller = client.node_types.begin_delete_node(resource_group_name, cluster_name, node_type_name, parameters=action_parameters) 184 LongRunningOperation(cmd.cli_ctx, start_msg='Deleting nodes', finish_msg='Nodes deleted')(poller) 185 except HttpResponseError as ex: 186 logger.error("HttpResponseError: %s", ex) 187 raise 188 189 190def add_vm_extension(cmd, 191 client, 192 resource_group_name, 193 cluster_name, 194 node_type_name, 195 extension_name, 196 publisher, 197 extension_type, 198 type_handler_version, 199 force_update_tag=None, 200 auto_upgrade_minor_version=True, 201 setting=None, 202 protected_setting=None, 203 provision_after_extension=None): 204 try: 205 node_type: NodeType = client.node_types.get(resource_group_name, cluster_name, node_type_name) 206 207 if node_type.vm_extensions is None: 208 node_type.vm_extensions = [] 209 210 newExtension = VMSSExtension(name=extension_name, 211 publisher=publisher, 212 type=extension_type, 213 type_handler_version=type_handler_version, 214 force_update_tag=force_update_tag, 215 auto_upgrade_minor_version=auto_upgrade_minor_version, 216 settings=setting, 217 protected_settings=protected_setting, 218 provision_after_extensions=provision_after_extension) 219 220 node_type.vm_extensions.append(newExtension) 221 222 poller = client.node_types.begin_create_or_update(resource_group_name, cluster_name, node_type_name, node_type) 223 return LongRunningOperation(cmd.cli_ctx)(poller) 224 except HttpResponseError as ex: 225 logger.error("HttpResponseError: %s", ex) 226 raise 227 228 229def delete_vm_extension(cmd, 230 client, 231 resource_group_name, 232 cluster_name, 233 node_type_name, 234 extension_name): 235 try: 236 node_type: NodeType = client.node_types.get(resource_group_name, cluster_name, node_type_name) 237 238 if node_type.vm_extensions is not None: 239 original_len = len(node_type.vm_extensions) 240 node_type.vm_extensions = list(filter(lambda x: x.name.lower() != extension_name.lower(), node_type.vm_extensions)) 241 if original_len == len(node_type.vm_extensions): 242 raise 'Extension with name {} not found'.format(extension_name) 243 244 poller = client.node_types.begin_create_or_update(resource_group_name, cluster_name, node_type_name, node_type) 245 return LongRunningOperation(cmd.cli_ctx)(poller) 246 except HttpResponseError as ex: 247 logger.error("HttpResponseError: %s", ex) 248 raise 249 250 251def add_vm_secret(cmd, 252 client, 253 resource_group_name, 254 cluster_name, 255 node_type_name, 256 source_vault_id, 257 certificate_url, 258 certificate_store): 259 try: 260 node_type: NodeType = client.node_types.get(resource_group_name, cluster_name, node_type_name) 261 262 if node_type.vm_secrets is None: 263 node_type.vm_secrets = [] 264 265 vault = next((x for x in node_type.vm_secrets if x.source_vault.id.lower() == source_vault_id.lower()), None) 266 267 vault_certificate = VaultCertificate(certificate_store=certificate_store, certificate_url=certificate_url) 268 new_vault_secret_group = False 269 if vault is None: 270 new_vault_secret_group = True 271 source_vault = SubResource(id=source_vault_id) 272 vault = VaultSecretGroup(source_vault=source_vault, vault_certificates=[]) 273 274 if vault.vault_certificates is None: 275 vault.vault_certificates = [] 276 277 vault.vault_certificates.append(vault_certificate) 278 279 if new_vault_secret_group: 280 node_type.vm_secrets.append(vault) 281 282 poller = client.node_types.begin_create_or_update(resource_group_name, cluster_name, node_type_name, node_type) 283 return LongRunningOperation(cmd.cli_ctx)(poller) 284 except HttpResponseError as ex: 285 logger.error("HttpResponseError: %s", ex) 286 raise 287