def create_certificate(client, vault_base_url, certificate_name, certificate_policy, disabled=False, expires=None, not_before=None, tags=None): cert_attrs = CertificateAttributes(not disabled, not_before, expires) logger.info( "Starting long running operation 'keyvault certificate create'") client.create_certificate(vault_base_url, certificate_name, certificate_policy, cert_attrs, tags) if certificate_policy['issuer_parameters']['name'].lower() == 'unknown': # return immediately for a pending certificate return client.get_certificate_operation(vault_base_url, certificate_name) # otherwise loop until the certificate creation is complete while True: check = client.get_certificate_operation(vault_base_url, certificate_name) if check.status != 'inProgress': logger.info("Long running operation 'keyvault certificate create' finished with result %s.", check) # pylint: disable=line-too-long return check try: time.sleep(10) except KeyboardInterrupt: logger.info("Long running operation wait cancelled.") raise except Exception as client_exception: telemetry.set_exception( exception=client_exception, fault_type='cert-create-error', summary='Unexpected client exception during cert creation') message = getattr(client_exception, 'message', client_exception) try: message = str(message) + ' ' + json.loads(client_exception.response.text) \ ['error']['details'][0]['message'] except: #pylint: disable=bare-except pass raise CLIError('{}'.format(message))
def __init__(self, test_file, test_name, run_live=False, debug=False, debug_vcr=False, skip_setup=False, skip_teardown=False): super(VCRTestBase, self).__init__(test_name) self.test_name = test_name self.recording_dir = os.path.join(os.path.dirname(test_file), 'recordings') self.cassette_path = os.path.join(self.recording_dir, '{}.yaml'.format(test_name)) self.playback = os.path.isfile(self.cassette_path) if os.environ.get(LIVE_TEST_CONTROL_ENV, None) == 'True': self.run_live = True else: self.run_live = run_live self.skip_setup = skip_setup self.skip_teardown = skip_teardown self.success = False self.exception = None self.track_commands = os.environ.get(COMMAND_COVERAGE_CONTROL_ENV, None) self._debug = debug if not self.playback and ('--buffer' in sys.argv) and not run_live: self.exception = CLIError( 'No recorded result provided for {}.'.format(self.test_name)) if debug_vcr: import logging logging.basicConfig() vcr_log = logging.getLogger('vcr') vcr_log.setLevel(logging.INFO) self.my_vcr = vcr.VCR( cassette_library_dir=self.recording_dir, before_record_request=self._before_record_request, before_record_response=self._before_record_response, decode_compressed_response=True) self.my_vcr.register_matcher('custom', _custom_request_matcher) self.my_vcr.match_on = ['custom']
def _update_ssl_binding(resource_group_name, name, certificate_thumbprint, ssl_type, slot=None): client = web_client_factory() webapp = _generic_site_operation(resource_group_name, name, 'get') webapp_certs = client.certificates.list_by_resource_group( resource_group_name) for webapp_cert in webapp_certs: if webapp_cert.thumbprint == certificate_thumbprint: return _update_host_name_ssl_state(resource_group_name, name, webapp.location, webapp_cert.host_names[0], ssl_type, certificate_thumbprint, slot) raise CLIError("Certificate for thumbprint '{}' not found.".format( certificate_thumbprint))
def _validate_vm_create_availability_set(namespace): if namespace.availability_set: as_id = parse_resource_id(namespace.availability_set) name = as_id['name'] rg = as_id.get('resource_group', namespace.resource_group_name) if not check_existence(name, rg, 'Microsoft.Compute', 'availabilitySets'): raise CLIError( "Availability set '{}' does not exist.".format(name)) namespace.availability_set = resource_id( subscription=get_subscription_id(), resource_group=rg, namespace='Microsoft.Compute', type='availabilitySets', name=name)
def set_deployment_user(user_name, password=None): ''' Update deployment credentials.(Note, all webapps in your subscription will be impacted) ''' client = web_client_factory() user = User(location='not-really-needed') user.publishing_user_name = user_name if password is None: try: password = prompt_pass(msg='Password: '******'Please specify both username and password in non-interactive mode.' ) user.publishing_password = password result = client.update_publishing_user(user) return result
def delete_policy(client, resource_group_name, vault_name, object_id=None, spn=None, upn=None): #pylint:disable=too-many-arguments """ Delete security policy settings for a Key Vault. """ from azure.mgmt.keyvault.models import VaultCreateOrUpdateParameters object_id = _object_id_args_helper(object_id, spn, upn) vault = client.get(resource_group_name=resource_group_name, vault_name=vault_name) prev_policies_len = len(vault.properties.access_policies) vault.properties.access_policies = [p for p in vault.properties.access_policies if \ vault.properties.tenant_id.lower() != p.tenant_id.lower() \ or object_id.lower() != p.object_id.lower()] if len(vault.properties.access_policies) == prev_policies_len: raise CLIError('No matching policies found') return client.create_or_update(resource_group_name=resource_group_name, vault_name=vault_name, parameters=VaultCreateOrUpdateParameters( location=vault.location, tags=vault.tags, properties=vault.properties))
def _arm_get_resource_by_name(resource_name, resource_type): '''Returns the ARM resource in the current subscription with resource_name. :param str resource_name: The name of resource :param str resource_type: The type of resource ''' result = get_resources_in_subscription(resource_type) elements = [ item for item in result if item.name.lower() == resource_name.lower() ] if len(elements) == 0: return None elif len(elements) == 1: return elements[0] else: raise CLIError( 'More than one resources with type {} are found with name: {}'. format(resource_type, resource_name))
def show_options(instance, part, path): options = instance.__dict__ if hasattr(instance, '__dict__') else instance parent = '.'.join(path[:-1]).replace('.[', '[') error_message = "Couldn't find '{}' in '{}'.".format(part, parent) if isinstance(options, dict): options = options.keys() options = sorted([make_camel_case(x) for x in options]) error_message = '{} Available options: {}'.format( error_message, options) elif isinstance(options, list): options = "index into the collection '{}' with [<index>] or [<key=value>]".format( parent) error_message = '{} Available options: {}'.format( error_message, options) else: error_message = "{} '{}' does not support further indexing.".format( error_message, parent) raise CLIError(error_message)
def handle_feedback(): try: print(MESSAGES['intro']) score = _prompt_net_promoter_score() response_do_well = None response_what_changes = None if score == 10: response_do_well = prompt(MESSAGES['prompt_do_well']) else: response_what_changes = prompt(MESSAGES['prompt_what_changes']) email_address = prompt(MESSAGES['prompt_email_addr']) _send_feedback(score, response_what_changes, response_do_well, email_address) print(MESSAGES['thanks']) except NoTTYException: raise CLIError('This command is interactive and no tty available.') except (EOFError, KeyboardInterrupt): print()
def iot_hub_create(client, hub_name, resource_group_name, location=None, sku=IotHubSku.f1.value, unit=1): name_availability = client.check_name_availability(hub_name) logger.info('name availability info: %s', name_availability) if name_availability is not None and not name_availability.name_available: raise CLIError(name_availability.message) location = _ensure_location(resource_group_name, location) iot_hub_description = IotHubDescription(location=location, sku=IotHubSkuInfo(name=sku, capacity=unit)) result = client.create_or_update(resource_group_name=resource_group_name, resource_name=hub_name, iot_hub_description=iot_hub_description) return result
def set_up(self): super(DataLakeStoreFileAccessScenarioTest, self).set_up() # create ADLS account self.cmd( 'dls account create -g {} -n {} -l {} --disable-encryption'.format( self.resource_group, self.adls_name, self.location)) result = self.cmd('dls account show -g {} -n {}'.format( self.resource_group, self.adls_name)) while result['provisioningState'] != 'Succeeded' and result[ 'provisioningState'] != 'Failed': time.sleep(5) result = self.cmd('dls account show -g {} -n {}'.format( self.resource_group, self.adls_name)) if result['provisioningState'] == 'Failed': raise CLIError( 'Failed to create the adls account, tests cannot proceed!')
def get_data_service_client(service_type, account_name, account_key, connection_string=None, sas_token=None): logger.info('Getting data service client service_type=%s', service_type.__name__) try: client = service_type(account_name=account_name, account_key=account_key, connection_string=connection_string, sas_token=sas_token) except ValueError: raise CLIError( 'Unable to obtain data client. Check your connection parameters.') # TODO: enable Fiddler client.request_callback = _add_headers return client
def _normalize_extension_version(publisher, vm_extension_name, version, location): if not version: result = load_extension_images_thru_services(publisher, vm_extension_name, None, location, show_latest=True) if not result: raise CLIError( 'Failed to find the latest version for the extension "{}"'. format(vm_extension_name)) #with 'show_latest' enabled, we will only get one result. version = result[0]['version'] version = _trim_away_build_number(version) return version
def add_certificate_contact(client, vault_base_url, contact_email, contact_name=None, contact_phone=None): """ Add a contact to the specified vault to receive notifications of certificate operations. """ from azure.cli.command_modules.keyvault.keyvaultclient.generated.models import \ (Contact, Contacts, KeyVaultErrorException) try: contacts = client.get_certificate_contacts(vault_base_url) except KeyVaultErrorException: contacts = Contacts([]) contact = Contact(contact_email, contact_name, contact_phone) if any((x for x in contacts.contact_list if x.email_address == contact_email)): raise CLIError("contact '{}' already exists".format(contact_email)) contacts.contact_list.append(contact) return client.set_certificate_contacts(vault_base_url, contacts)
def create_service_principal_for_rbac(name=None, password=None, years=1, scopes=None, role=None): '''create a service principal that can access or modify resources :param str name: an unique uri. If missing, the command will generate one. :param str password: the password used to login. If missing, command will generate one. :param str years: Years the password will be valid. :param str scopes: space separated scopes the service principal's role assignment applies to. :param str role: role the service principal has on the resources. only use with 'resource-ids'. ''' if bool(scopes) != bool(role): raise CLIError("'--scopes' and '--role' must be used together.") client = _graph_client_factory() start_date = datetime.datetime.now() app_display_name = 'azure-cli-' + start_date.strftime('%Y-%m-%d-%H-%M-%S') if name is None: name = 'http://' + app_display_name # just a valid uri, no need to exist end_date = start_date + relativedelta(years=years) password = password or str(uuid.uuid4()) aad_application = create_application(client.applications, display_name=app_display_name, #pylint: disable=too-many-function-args homepage='http://'+app_display_name, identifier_uris=[name], available_to_other_tenants=False, password=password, start_date=start_date, end_date=end_date) #pylint: disable=no-member aad_sp = _create_service_principal(aad_application.app_id, bool(scopes)) oid = aad_sp.output.object_id if scopes else aad_sp.object_id if scopes: #It is possible the SP has not been propagated to all servers, so creating assignments #might fail. The reliable workaround is to call out the server where creation occurred. #pylint: disable=protected-access session_key = aad_sp.response.headers._store['ocp-aad-session-key'][1] for scope in scopes: _create_role_assignment(role, oid, None, scope, ocp_aad_session_key=session_key) return { 'appId': aad_application.app_id, 'password': password, 'name': name, 'tenant': client.config.tenant_id }
def __call__(self, poller): from msrest.exceptions import ClientException logger.info("Starting long running operation '%s'", self.start_msg) correlation_message = '' while not poller.done(): try: # pylint: disable=protected-access correlation_id = json.loads( poller._response.__dict__['_content'])['properties']['correlationId'] correlation_message = 'Correlation ID: {}'.format(correlation_id) except: # pylint: disable=bare-except pass try: self._delay() except KeyboardInterrupt: logger.error('Long running operation wait cancelled. %s', correlation_message) raise try: result = poller.result() except ClientException as client_exception: telemetry.set_exception( client_exception, fault_type='failed-long-running-operation', summary='Unexpected client exception in {}.'.format(LongRunningOperation.__name__)) message = getattr(client_exception, 'message', client_exception) try: message = '{} {}'.format( str(message), json.loads(client_exception.response.text)['error']['details'][0]['message']) except: # pylint: disable=bare-except pass cli_error = CLIError('{} {}'.format(message, correlation_message)) # capture response for downstream commands (webapp) to dig out more details setattr(cli_error, 'response', getattr(client_exception, 'response', None)) raise cli_error logger.info("Long running operation '%s' completed with result %s", self.start_msg, result) return result
def create_adla_catalog_credential(client, account_name, database_name, credential_name, credential_user_name, uri, credential_user_password=None): if not credential_user_password: try: credential_user_password = prompt_pass('Password:'******'Please specify both --user-name and --password in non-interactive mode.') create_params = DataLakeAnalyticsCatalogCredentialCreateParameters(credential_user_password, uri, credential_user_name) client.create_credential(account_name, database_name, credential_name, create_params)
def _get_detail_error(self, ex): try: detail = json.loads(ex.response.text)['Message'] if self._creating_plan: if 'Requested features are not supported in region' in detail: detail = ( "Plan with linux worker is not supported in current region. " + "Run 'az appservice list-locations --linux-workers-enabled' " + "to cross check") elif 'Not enough available reserved instance servers to satisfy' in detail: detail = ( "Plan with Linux worker can only be created in a group " + "which has never contained a Windows worker. Please use " + "a new resource group. Original error:" + detail) return CLIError(detail) except: #pylint: disable=bare-except return ex
def _get_detail_error(self, ex): try: detail = json.loads(ex.response.text)['Message'] if self._creating_plan: if 'Requested features are not supported in region' in detail: detail = ( "Plan with linux worker is not supported in current region. For " + "supported regions, please refer to https://docs.microsoft.com/en-us/" "azure/app-service-web/app-service-linux-intro") elif 'Not enough available reserved instance servers to satisfy' in detail: detail = ( "Plan with Linux worker can only be created in a group " + "which has never contained a Windows worker. Please use " + "a new resource group. Original error:" + detail) return CLIError(detail) except: #pylint: disable=bare-except return ex
def get_data_service_client(service_type, account_name, account_key, connection_string=None, # pylint: disable=too-many-arguments sas_token=None, endpoint_suffix=None): logger.debug('Getting data service client service_type=%s', service_type.__name__) try: client_kwargs = {'account_name': account_name, 'account_key': account_key, 'connection_string': connection_string, 'sas_token': sas_token} if endpoint_suffix: client_kwargs['endpoint_suffix'] = endpoint_suffix client = service_type(**client_kwargs) except ValueError as exc: if _ERROR_STORAGE_MISSING_INFO in str(exc): raise ValueError(exc) else: raise CLIError('Unable to obtain data client. Check your connection parameters.') # TODO: enable Fiddler client.request_callback = _add_headers return client
def acr_credential_show(registry_name, resource_group_name=None): '''Get admin username and password for a container registry. :param str registry_name: The name of container registry :param str resource_group_name: The name of resource group ''' registry = get_registry_by_name(registry_name) if registry is None: registry_not_found(registry_name) if resource_group_name is None: resource_group_name = get_resource_group_name_by_resource_id(registry.id) client = get_acr_service_client().registries if registry.properties.admin_user_enabled: return client.get_credentials(resource_group_name, registry_name) else: raise CLIError( 'Admin user is not enabled for the container registry with name: {}'\ .format(registry_name))
def _install_or_update(package_list, link, private, pre, show_logs=False): options = ['--isolated', '--disable-pip-version-check', '--upgrade'] if pre: options.append('--pre') if not show_logs: options.append('--quiet') pkg_index_options = ['--find-links', link] if link else [] if private: package_index_url = az_config.get('component', 'package_index_url', fallback=None) package_index_trusted_host = az_config.get('component', 'package_index_trusted_host', fallback=None) #pylint: disable=line-too-long if package_index_url: pkg_index_options += ['--extra-index-url', package_index_url] else: raise CLIError('AZURE_COMPONENT_PACKAGE_INDEX_URL environment variable not set and not specified in config. ' #pylint: disable=line-too-long 'AZURE_COMPONENT_PACKAGE_INDEX_TRUSTED_HOST may also need to be set.') #pylint: disable=line-too-long pkg_index_options += ['--trusted-host', package_index_trusted_host] if package_index_trusted_host else [] #pylint: disable=line-too-long pip.main(['install'] + options + package_list + pkg_index_options)
def iot_hub_create(client, hub_name, resource_group_name, location=None, sku=IotHubSku.f1.value, unit=1): name_availability = client.check_name_availability(hub_name) logger.info('name availability info: %s', name_availability) if name_availability is not None and not name_availability.name_available: raise CLIError(name_availability.message) if location is None: logger.info('Location is none. Use location of resource group as default.') resource_group_client = resource_service_factory().resource_groups group_info = resource_group_client.get(resource_group_name) location = group_info.location logger.info('Location to use: %s', location) iot_hub_description = IotHubDescription(location=location, sku=IotHubSkuInfo(name=sku, capacity=unit)) result = client.create_or_update(resource_group_name=resource_group_name, resource_name=hub_name, iot_hub_description=iot_hub_description) return result
def set_active_subscription(self, subscription): #take id or name subscriptions = self.load_cached_subscriptions() subscription = subscription.lower() result = [ x for x in subscriptions if subscription in [x[_SUBSCRIPTION_ID].lower(), x[_SUBSCRIPTION_NAME].lower()] ] if len(result) != 1: raise CLIError( 'The subscription of "{}" does not exist or has more than' ' one match.'.format(subscription)) for s in subscriptions: s[_IS_DEFAULT_SUBSCRIPTION] = False result[0][_IS_DEFAULT_SUBSCRIPTION] = True self._cache_subscriptions_to_local_storage(subscriptions)
def _deploy_arm_template_core(resource_group_name, template_file=None, template_uri=None, deployment_name=None, parameters=None, mode='incremental', validate_only=False, no_wait=False): from azure.mgmt.resource.resources.models import DeploymentProperties, TemplateLink if bool(template_uri) == bool(template_file): raise CLIError( 'please provide either template file path or uri, but not both') if parameters: parameters = json.loads(parameters) if parameters: parameters = parameters.get('parameters', parameters) template = None template_link = None if template_uri: template_link = TemplateLink(uri=template_uri) else: template = get_file_json(template_file) properties = DeploymentProperties(template=template, template_link=template_link, parameters=parameters, mode=mode) smc = get_mgmt_service_client(ResourceManagementClient) if validate_only: return smc.deployments.validate(resource_group_name, deployment_name, properties, raw=no_wait) else: return smc.deployments.create_or_update(resource_group_name, deployment_name, properties, raw=no_wait)
def _get_remote_url(): """ Tries to find a remote for the repo in the current folder. If only one remote is present return that remote, if more than one remote is present it looks for origin. """ try: remotes = check_output(['git', 'remote']).strip().splitlines() remote_url = '' if len(remotes) == 1: remote_url = check_output(['git', 'remote', 'get-url', remotes[0].decode()]).strip() else: remote_url = check_output(['git', 'remote', 'get-url', 'origin']).strip() except ValueError as e: logger.debug(e) raise CLIError( "A default remote was not found for the current folder. \ Please run this command in a git repository folder with \ an 'origin' remote or specify a remote using '--remote-url'") return remote_url.decode()
def add_certificate_issuer_admin(client, vault_base_url, issuer_name, email, first_name=None, last_name=None, phone=None): """ Add admin details for a specified certificate issuer. """ from azure.keyvault.generated.models import \ (AdministratorDetails, KeyVaultErrorException) issuer = client.get_certificate_issuer(vault_base_url, issuer_name) org_details = issuer.organization_details admins = org_details.admin_details if any((x for x in admins if x.email_address == email)): raise CLIError("admin '{}' already exists".format(email)) new_admin = AdministratorDetails(first_name, last_name, email, phone) admins.append(new_admin) org_details.admin_details = admins result = client.set_certificate_issuer( vault_base_url, issuer_name, issuer.provider, issuer.credentials, org_details, issuer.attributes) created_admin = next(x for x in result.organization_details.admin_details \ if x.email_address == email) return created_admin
def acs_browse(resource_group, name, disable_browser=False): """ Opens a browser to the web interface for the cluster orchestrator :param name: Name of the target Azure container service instance. :type name: String :param resource_group_name: Name of Azure container service's resource group. :type resource_group_name: String :param disable_browser: If true, don't launch a web browser after estabilishing the proxy :type disable_browser: bool """ acs_info = _get_acs_info(name, resource_group) orchestrator_type = acs_info.orchestrator_profile.orchestrator_type # pylint: disable=no-member if orchestrator_type == 'kubernetes': return k8s_browse(disable_browser) elif orchestrator_type == 'dcos': return _dcos_browse_internal(acs_info, disable_browser) else: raise CLIError('Unsupported orchestrator type {} for browse'.format(orchestrator_type))
def _generate_lb_id_list_from_names_or_ids(namespace, prop, child_type): raw = getattr(namespace, prop) if not raw: return raw = raw if isinstance(raw, list) else [raw] result = [] for item in raw: if is_valid_resource_id(item): result.append({'id': item}) else: if not namespace.load_balancer_name: raise CLIError( 'Unable to process {}. Please supply a well-formed ID or ' '--lb-name.'.format(item)) else: result.append({ 'id': _generate_lb_subproperty_id(namespace, child_type, item) }) setattr(namespace, prop, result)
def _create_file_and_directory_from_blob(file_service, blob_service, share, container, sas, blob_name, destination_dir=None, metadata=None, timeout=None, existing_dirs=None): """ Copy a blob to file share and create the directory if needed. """ blob_url = blob_service.make_blob_url(container, blob_name, sas_token=sas) full_path = os.path.join(destination_dir, blob_name) if destination_dir else blob_name file_name = os.path.basename(full_path) dir_name = os.path.dirname(full_path) _make_directory_in_files_share(file_service, share, dir_name, existing_dirs) try: file_service.copy_file(share, dir_name, file_name, blob_url, metadata, timeout) return file_service.make_file_url(share, dir_name, file_name) except AzureException: error_template = 'Failed to copy blob {} to file share {}. Please check if you have ' + \ 'permission to read source or set a correct sas token.' raise CLIError(error_template.format(blob_name, share))