def _get_source_repository(self, uri, token, branch, cred, username, password): # Determine the type of repository (TfsGit, github, tfvc, externalGit) # Find the identifier and set the properties. # Default is externalGit type = 'Git' identifier = uri account_name = None team_project_name = None auth_info = AuthorizationInfo('UsernamePassword', AuthorizationInfoParameters(None, None, username, password)) match = re.match(r'[htps]+\:\/\/(.+)\.visualstudio\.com.*\/_git\/(.+)', uri, re.IGNORECASE) if match: type = 'TfsGit' account_name = match.group(1) # we have to get the repo id as the identifier info = self._get_vsts_info(uri, cred) identifier = info.repository_info.id team_project_name = info.repository_info.project_info.name auth_info = None else: match = re.match(r'[htps]+\:\/\/github\.com\/(.+)', uri, re.IGNORECASE) if match: if token is not None: type = 'Github' identifier = match.group(1).replace(".git", "") auth_info = AuthorizationInfo('PersonalAccessToken', AuthorizationInfoParameters(None, token)) else: match = re.match(r'[htps]+\:\/\/(.+)\.visualstudio\.com\/(.+)', uri, re.IGNORECASE) if match: type = 'TFVC' identifier = match.group(2) account_name = match.group(1) auth_info = None sourceRepository = SourceRepository(type, identifier, branch, auth_info) return sourceRepository, account_name, team_project_name
def setup_continuous_delivery(self, swap_with_slot, app_type_details, cd_project_url, create_account, vsts_app_auth_token, test, webapp_list): """ Use this method to setup Continuous Delivery of an Azure web site from a source control repository. :param swap_with_slot: the slot to use for deployment :param app_type_details: the details of app that will be deployed. i.e. app_type = Python, python_framework = Django etc. :param cd_project_url: CD Project url in the format of https://<accountname>.visualstudio.com/<projectname> :param create_account: Boolean value to decide if account need to be created or not :param vsts_app_auth_token: Authentication token for vsts app :param test: Load test webapp name :param webapp_list: Existing webapp list :return: a message indicating final status and instructions for the user """ branch = self._repo_info.branch or 'refs/heads/master' self._validate_cd_project_url(cd_project_url) vsts_account_name = self._get_vsts_account_name(cd_project_url) # Verify inputs before we start generating tokens source_repository, account_name, team_project_name = self._get_source_repository(self._repo_info.url, self._repo_info.git_token, branch, self._azure_info.credentials, self._repo_info._private_repo_username, self._repo_info._private_repo_password) self._verify_vsts_parameters(vsts_account_name, source_repository) vsts_account_name = vsts_account_name or account_name cd_project_name = team_project_name or self._azure_info.website_name account_url = 'https://{}.visualstudio.com'.format(quote(vsts_account_name)) portalext_account_url = 'https://{}.portalext.visualstudio.com'.format(quote(vsts_account_name)) # VSTS Account using AEX APIs account_created = False if create_account: self.create_vsts_account(self._azure_info.credentials, vsts_account_name) account_created = True # Create ContinuousDelivery client cd = ContinuousDelivery('3.2-preview.1', portalext_account_url, self._azure_info.credentials) # Construct the config body of the continuous delivery call build_configuration = self._get_build_configuration(app_type_details) source = ProvisioningConfigurationSource('codeRepository', source_repository, build_configuration) auth_info = AuthorizationInfo('Headers', AuthorizationInfoParameters('Bearer ' + vsts_app_auth_token)) target = self.get_provisioning_configuration_target(auth_info, swap_with_slot, test, webapp_list) ci_config = CiConfiguration(CiArtifact(name=cd_project_name)) config = ProvisioningConfiguration(None, source, target, ci_config) # Configure the continuous deliver using VSTS as a backend response = cd.provisioning_configuration(config) if response.ci_configuration.result.status == 'queued': final_status = self._wait_for_cd_completion(cd, response) return self._get_summary(final_status, account_url, vsts_account_name, account_created, self._azure_info.subscription_id, self._azure_info.resource_group_name, self._azure_info.website_name) else: raise RuntimeError('Unknown status returned from provisioning_configuration: ' + response.ci_configuration.result.status)
def setup_continuous_delivery(self, azure_deployment_slot, app_type, vsts_account_name, create_account, vsts_app_auth_token): """ Use this method to setup Continuous Delivery of an Azure web site from a source control repository. :param azure_deployment_slot: the slot to use for deployment :param app_type: the type of app that will be deployed. i.e. AspNetWap, AspNetCore, etc. :param vsts_account_name: :param create_account: :param vsts_app_auth_token: :return: a message indicating final status and instructions for the user """ branch = self._repo_info.branch or 'refs/heads/master' # Verify inputs before we start generating tokens source_repository, account_name, team_project_name = self._get_source_repository(self._repo_info.url, self._repo_info.git_token, branch, self._azure_info.credentials) self._verify_vsts_parameters(vsts_account_name, source_repository) vsts_account_name = vsts_account_name or account_name cd_project_name = team_project_name or self._azure_info.website_name account_url = 'https://{}.visualstudio.com'.format(quote(vsts_account_name)) portalext_account_url = 'https://{}.portalext.visualstudio.com'.format(quote(vsts_account_name)) account_created = False accountClient = Account('3.2-preview', None, self._azure_info.credentials) if create_account: # Try to create the account (already existing accounts are fine too) self._update_progress(0, 100, 'Creating or getting Team Services account information') properties = {} #TODO right now it is hard to match a random Azure region to a VSTS region #properties['Microsoft.VisualStudio.Services.Account.TfsAccountRegion'] = self._azure_info.webapp_location properties['Microsoft.VisualStudio.Services.Account.SignupEntryPoint'] = 'AzureCli' account_creation_parameters = AccountCreateInfoInternal( vsts_account_name, None, vsts_account_name, None, properties) creation_results = accountClient.create_account(account_creation_parameters, True) account_created = not creation_results.account_id == None if account_created: self._update_progress(5, 100, 'Team Services account created') else: # Verify that the account exists if not accountClient.account_exists(vsts_account_name): raise RuntimeError( "'The Team Services url '{}' does not exist. Check the spelling and try again.".format(account_url)) # Create ContinuousDelivery client cd = ContinuousDelivery('3.2-preview.1', portalext_account_url, self._azure_info.credentials) # Construct the config body of the continuous delivery call build_configuration = self._get_build_configuration(app_type, None) source = ProvisioningConfigurationSource('codeRepository', source_repository, build_configuration) auth_info = AuthorizationInfo('Headers', AuthorizationInfoParameters('Bearer ' + vsts_app_auth_token)) slot_name = azure_deployment_slot or 'staging' slot_swap = None # TODO SlotSwapConfiguration(slot_name) target = ProvisioningConfigurationTarget('azure', 'windowsAppService', 'production', 'Production', self._azure_info.subscription_id, self._azure_info.subscription_name, self._azure_info.tenant_id, self._azure_info.website_name, self._azure_info.resource_group_name, self._azure_info.webapp_location, auth_info, slot_swap) ci_config = CiConfiguration(CiArtifact(name=cd_project_name)) config = ProvisioningConfiguration(None, source, [target], ci_config) # Configure the continuous deliver using VSTS as a backend response = cd.provisioning_configuration(config) if response.ci_configuration.result.status == 'queued': final_status = self._wait_for_cd_completion(cd, response) return self._get_summary(final_status, account_url, vsts_account_name, account_created, self._azure_info.subscription_id, self._azure_info.resource_group_name, self._azure_info.website_name) else: raise RuntimeError('Unknown status returned from provisioning_configuration: ' + response.ci_configuration.result.status)