def open_url_in_browser(url): # if we are not in cloud shell and can launch a browser, launch it with the issue draft if can_launch_browser() and not in_cloud_console(): open_page_in_browser(url) else: print("There isn't an available browser finish the setup. Please copy and paste the url" f" below in a browser to complete the configuration.\n\n{url}\n\n")
def _prompt_issue(recent_command_list): if recent_command_list: max_idx = len(recent_command_list) - 1 ans = -1 help_string = 'Please choose between 0 and {}, or enter q to quit: '.format( max_idx) while ans < 0 or ans > max_idx: try: ans = prompt(_MSG_CMD_ISSUE.format(max_idx), help_string=help_string) if ans.lower() in ["q", "quit"]: ans = ans.lower() break ans = int(ans) except ValueError: logger.warning(help_string) ans = -1 else: ans = None help_string = 'Please choose between Y and N: ' while not ans: ans = prompt(_MSG_ISSUE, help_string=help_string) if ans.lower() not in ["y", "n", "yes", "no", "q"]: ans = None continue # strip to short form ans = ans[0].lower() if ans else None if ans in ["y", "n"]: if ans == "y": browser_instruction, url, issue_body = _build_issue_info_tup() else: return False else: if ans in ["q", "quit"]: return False if ans == 0: browser_instruction, url, issue_body = _build_issue_info_tup() else: browser_instruction, url, issue_body = _build_issue_info_tup( recent_command_list[ans]) logger.info(issue_body) print(browser_instruction) # if we are not in cloud shell and can launch a browser, launch it with the issue draft if can_launch_browser() and not in_cloud_console(): open_page_in_browser(url) else: print( "There isn't an available browser to create an issue draft. You can copy and paste the url" " below in a browser to submit.\n\n{}\n\n".format(url)) return True
def test_can_launch_browser(self, webbrowser_get_mock, get_platform_mock, which_mock): import webbrowser # Windows is always fine get_platform_mock.return_value = ('windows', '10') assert can_launch_browser() # MacOS is always fine get_platform_mock.return_value = ('darwin', '10') assert can_launch_browser() # Real linux with browser get_platform_mock.return_value = ('linux', '4.15.0-1014-azure') browser_mock = mock.MagicMock() browser_mock.name = 'www-browser' webbrowser_get_mock.return_value = browser_mock assert can_launch_browser() # Real linux without browser get_platform_mock.return_value = ('linux', '4.15.0-1014-azure') webbrowser_get_mock.side_effect = webbrowser.Error assert not can_launch_browser() # WSL Linux with www-browser get_platform_mock.return_value = ('linux', '5.10.16.3-microsoft-standard-WSL2') browser_mock = mock.MagicMock() browser_mock.name = 'www-browser' webbrowser_get_mock.return_value = browser_mock assert can_launch_browser() # WSL Linux without www-browser, but with powershell.exe get_platform_mock.return_value = ('linux', '5.10.16.3-microsoft-standard-WSL2') webbrowser_get_mock.side_effect = webbrowser.Error which_mock.return_value = True assert can_launch_browser() # Docker container on WSL 2 can't launch browser get_platform_mock.return_value = ('linux', '5.10.16.3-microsoft-standard-WSL2') import webbrowser webbrowser_get_mock.side_effect = webbrowser.Error which_mock.return_value = False assert not can_launch_browser()
def datadog_link_create(): url = 'https://us3.datadoghq.com/api/v1/liftr/oauth/start' if can_launch_browser() and not in_cloud_console(): open_page_in_browser(url) else: print( "There isn't an available browser to create an issue draft. You can copy and paste the url" " below in a browser to submit.\n\n{}\n\n".format(url)) print( "After login and authorize the linking, copy the code and client_id from the broswer address bar.\n" "Use code as linking-auth-code and client_id as linking-client-id in monitor create command.\n" "example:\n" " az datadog monitor create --name \"myMonitor\" --location \"West US 2\" --identity-type" " \"SystemAssigned\" --sku-name \"Linked\" --datadog-organization-properties" " linking-auth-code=\"copyFromCode\" linking-client-id=\"00000000-0000-0000-0000-000000000000\"" " --user-info name=\"Alice\" email-address=\"[email protected]\" phone-number=\"123-456-789\"" )
def test_can_launch_browser(self, webbrowser_get_mock, get_platform_mock): # WSL is always fine get_platform_mock.return_value = ('linux', '4.4.0-17134-microsoft') result = can_launch_browser() self.assertTrue(result) # windows is always fine get_platform_mock.return_value = ('windows', '10') result = can_launch_browser() self.assertTrue(result) # osx is always fine get_platform_mock.return_value = ('darwin', '10') result = can_launch_browser() self.assertTrue(result) # now tests linux with mock.patch('os.environ', autospec=True) as env_mock: # when no GUI, return false get_platform_mock.return_value = ('linux', '4.15.0-1014-azure') env_mock.get.return_value = None result = can_launch_browser() self.assertFalse(result) # when there is gui, and browser is a good one, return True browser_mock = mock.MagicMock() browser_mock.name = 'goodone' env_mock.get.return_value = 'foo' result = can_launch_browser() self.assertTrue(result) # when there is gui, but the browser is text mode, return False browser_mock = mock.MagicMock() browser_mock.name = 'www-browser' webbrowser_get_mock.return_value = browser_mock env_mock.get.return_value = 'foo' result = can_launch_browser() self.assertFalse(result)
def find_subscriptions_on_login(self, interactive, username, password, is_service_principal, tenant, use_device_code=False, allow_no_subscriptions=False, subscription_finder=None): from azure.cli.core._debug import allow_debug_adal_connection allow_debug_adal_connection() subscriptions = [] if not subscription_finder: subscription_finder = SubscriptionFinder(self.cli_ctx, self.auth_ctx_factory, self._creds_cache.adal_token_cache) if interactive: if not use_device_code and (in_cloud_console() or not can_launch_browser()): logger.info('Detect no GUI is available, so fall back to device code') use_device_code = True if not use_device_code: try: authority_url, _ = _get_authority_url(self.cli_ctx, tenant) subscriptions = subscription_finder.find_through_authorization_code_flow( tenant, self._ad_resource_uri, authority_url) except RuntimeError: use_device_code = True logger.warning('Not able to launch a browser to log you in, falling back to device code...') if use_device_code: subscriptions = subscription_finder.find_through_interactive_flow( tenant, self._ad_resource_uri) else: if is_service_principal: if not tenant: raise CLIError('Please supply tenant using "--tenant"') sp_auth = ServicePrincipalAuth(password) subscriptions = subscription_finder.find_from_service_principal_id( username, sp_auth, tenant, self._ad_resource_uri) else: subscriptions = subscription_finder.find_from_user_account( username, password, tenant, self._ad_resource_uri) if not allow_no_subscriptions and not subscriptions: raise CLIError("No subscriptions were found for '{}'. If this is expected, use " "'--allow-no-subscriptions' to have tenant level accesses".format( username)) if is_service_principal: self._creds_cache.save_service_principal_cred(sp_auth.get_entry_to_persist(username, tenant)) if self._creds_cache.adal_token_cache.has_state_changed: self._creds_cache.persist_cached_creds() if allow_no_subscriptions: t_list = [s.tenant_id for s in subscriptions] bare_tenants = [t for t in subscription_finder.tenants if t not in t_list] profile = Profile(cli_ctx=self.cli_ctx) subscriptions = profile._build_tenant_level_accounts(bare_tenants) # pylint: disable=protected-access if not subscriptions: return [] consolidated = self._normalize_properties(subscription_finder.user_id, subscriptions, is_service_principal) self._set_subscriptions(consolidated) # use deepcopy as we don't want to persist these changes to file. return deepcopy(consolidated)
def login(self, interactive, username, password, is_service_principal, tenant, scopes=None, use_device_code=False, allow_no_subscriptions=False, use_cert_sn_issuer=None, **kwargs): """ For service principal, `password` is a dict returned by ServicePrincipalAuth.build_credential """ if not scopes: scopes = self._arm_scope identity = _create_identity_instance(self.cli_ctx, self._authority, tenant_id=tenant) user_identity = None if interactive: if not use_device_code and not can_launch_browser(): logger.info( 'No web browser is available. Fall back to device code.') use_device_code = True if use_device_code: user_identity = identity.login_with_device_code(scopes=scopes, **kwargs) else: user_identity = identity.login_with_auth_code(scopes=scopes, **kwargs) else: if not is_service_principal: user_identity = identity.login_with_username_password( username, password, scopes=scopes, **kwargs) else: identity.login_with_service_principal(username, password, scopes=scopes) # We have finished login. Let's find all subscriptions. if user_identity: username = user_identity['username'] subscription_finder = SubscriptionFinder(self.cli_ctx) # Create credentials if user_identity: credential = identity.get_user_credential(username) else: credential = identity.get_service_principal_credential(username) if tenant: subscriptions = subscription_finder.find_using_specific_tenant( tenant, credential) else: subscriptions = subscription_finder.find_using_common_tenant( username, credential) if not subscriptions and not allow_no_subscriptions: raise CLIError("No subscriptions found for {}.".format(username)) if allow_no_subscriptions: t_list = [s.tenant_id for s in subscriptions] bare_tenants = [ t for t in subscription_finder.tenants if t not in t_list ] tenant_accounts = self._build_tenant_level_accounts(bare_tenants) subscriptions.extend(tenant_accounts) if not subscriptions: return [] consolidated = self._normalize_properties(username, subscriptions, is_service_principal, bool(use_cert_sn_issuer)) self._set_subscriptions(consolidated) return deepcopy(consolidated)