VSTS Account Creation migration to AEX APIs (#20)

* Updating default auth_info for External Git

* VSTS Account Creation migration to AEX APIs

* Removed unused 202 server response code

* Removed dead code
This commit is contained in:
Vinod Kumar 2017-10-27 14:16:28 +05:30 коммит произвёл GitHub
Родитель 75cf1e2550
Коммит b94aba2d2b
21 изменённых файлов: 175 добавлений и 852 удалений

Просмотреть файл

@ -9,6 +9,3 @@ from .account import Account
from .version import VERSION
__all__ = ['Account']
__version__ = VERSION

73
aex_accounts/account.py Normal file
Просмотреть файл

@ -0,0 +1,73 @@
from __future__ import print_function
from sys import stderr
from msrest.service_client import ServiceClient
from msrest import Configuration, Deserializer
from msrest.exceptions import HttpOperationError
from .version import VERSION
from . import models
class AccountConfiguration(Configuration):
def __init__(self, api_version, base_url=None):
super(AccountConfiguration, self).__init__(base_url)
self.add_user_agent('azurecli/vsts/{}'.format(VERSION))
self.api_version = api_version
class Account(object):
def __init__(self, api_version, base_url=None, creds=None):
self.config = AccountConfiguration(api_version, base_url)
self._client = ServiceClient(creds, self.config)
client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)}
self._deserialize = Deserializer(client_models)
self.api_version = api_version
def create_account(self, collection_name, preferred_region):
# Construct URL
url = '/_apis/hostacquisition/collections'
# Construct parameters
query_parameters = {}
query_parameters["api-version"] = self.api_version
query_parameters["collectionName"] = collection_name
query_parameters["preferredRegion"] = preferred_region
# Construct and send request
request = self._client.post(url, query_parameters)
response = self._client.send(request)
# Handle Response
deserialized = None
if response.status_code not in [200]:
print("POST", request.url, file=stderr)
print("response:", response.status_code, file=stderr)
print(response.text, file=stderr)
raise HttpOperationError(self._deserialize, response)
else:
deserialized = self._deserialize('Collection', response)
return deserialized
def regions(self):
# Construct URL
url = '/_apis/hostacquisition/regions'
# Construct and send request
request = self._client.get(url)
response = self._client.send(request)
# Handle Response
deserialized = None
if response.status_code not in [200]:
print("GET", request.url, file=stderr)
print("response:", response.status_code, file=stderr)
print(response.text, file=stderr)
raise HttpOperationError(self._deserialize, response)
else:
deserialized = self._deserialize('Regions', response)
return deserialized

Просмотреть файл

@ -5,7 +5,14 @@
# regenerated.
# --------------------------------------------------------------------------
from msrest.authentication import (
BasicAuthentication,
BasicTokenAuthentication,
OAuthTokenAuthentication)
from .collection import Collection
from .name_availability import NameAvailability
from .region_details import RegionDetails
from .regions import Regions
__all__ = [
'Collection',
'NameAvailability',
'RegionDetails',
'Regions',
]

Просмотреть файл

@ -0,0 +1,12 @@
from msrest.serialization import Model
class Collection(Model):
_attribute_map = {
'id': {'key': 'id', 'type': 'str'},
'name': {'key': 'name', 'type': 'str'},
}
def __init__(self, id=None, name=None):
self.id = id
self.name = name

Просмотреть файл

@ -0,0 +1,14 @@
from msrest.serialization import Model
class NameAvailability(Model):
_attribute_map = {
'name': {'key': 'name', 'type': 'str'},
'is_available': {'key': 'is_available', 'type': 'str'},
'unavailability_reason': {'key': 'unavailability_reason', 'type': 'str'},
}
def __init__(self, name=None, is_available=None, unavailability_reason=None):
self.name = name
self.is_available = is_available
self.unavailability_reason = unavailability_reason

Просмотреть файл

@ -0,0 +1,14 @@
from msrest.serialization import Model
class RegionDetails(Model):
_attribute_map = {
'name': {'key': 'name', 'type': 'str'},
'display_name': {'key': 'displayName', 'type': 'str'},
'is_default': {'key': 'is_default', 'type': 'str'},
}
def __init__(self, name=None, display_name=None, is_default=None):
self.name = name
self.display_name = display_name
self.is_default = is_default

Просмотреть файл

@ -0,0 +1,12 @@
from msrest.serialization import Model
class Regions(Model):
_attribute_map = {
'count': {'key': 'count', 'type': 'int'},
'value': {'key': 'value', 'type': '[RegionDetails]'},
}
def __init__(self, count=None, value=None):
self.count = count
self.value = value

Просмотреть файл

@ -5,5 +5,5 @@
# regenerated.
# --------------------------------------------------------------------------
VERSION = "3.2"
#PyPI version of package
VERSION = "1.0"

Просмотреть файл

@ -15,7 +15,7 @@ from continuous_delivery.models import ProvisioningConfigurationSource
from continuous_delivery.models import ProvisioningConfiguration
from mock import patch, Mock
from vsts_accounts.models import AccountModel
from aex_accounts.models import Collection
from vsts_info_provider.models import TeamProjectInfo, RepositoryInfo, CollectionInfo, VstsInfo
from vsts_cd_manager.continuous_delivery_manager import ContinuousDeliveryManager
@ -66,27 +66,6 @@ class TestContinousDeliveryManager(unittest.TestCase):
self.assertEqual(None, cdman._repo_info._private_repo_username)
self.assertEqual(None, cdman._repo_info._private_repo_password)
@patch("vsts_cd_manager.continuous_delivery_manager.ContinuousDelivery")
@patch("vsts_cd_manager.continuous_delivery_manager.Account")
def test_setup_continuous_delivery___account_doesnt_exist(self, mock_account, mock_cd):
# Mock the CD Client
mocked_cd = mock_cd.return_value
# Mock the Account Client
mocked_account = mock_account.return_value
mocked_account.create_account.return_value = AccountModel()
mocked_account.account_exists.return_value = False
# create CD manager
cdman = ContinuousDeliveryManager(None)
# Mock the vsts info call
cdman._get_vsts_info = self._mock_get_vsts_info
# set required values
cdman.set_azure_web_info('group1', 'web1', 'fakeCreds', 'sub1', 'subname1', 'tenant1', 'South Central US')
cdman.set_repository_info('repoUrl1', 'master1', 'token1', None, None)
# call setup
with self.assertRaises(RuntimeError) as context:
cdman.setup_continuous_delivery('staging', 'AspNet', "https://account1.visualstudio.com", False, 'token2', None, None)
self.assertTrue('does not exist' in str(context.exception))
@patch("vsts_cd_manager.continuous_delivery_manager.ContinuousDelivery")
@patch("vsts_cd_manager.continuous_delivery_manager.Account")
def test_setup_continuous_delivery___create_account(self, mock_account, mock_cd):
@ -96,7 +75,7 @@ class TestContinousDeliveryManager(unittest.TestCase):
mocked_cd.get_provisioning_configuration.return_value = self._get_provisioning_config('succeeded', '')
# Mock the Account Client
mocked_account = mock_account.return_value
mocked_account.create_account.return_value = AccountModel('111', 'collection111')
mocked_account.create_account.return_value = Collection('111', 'collection111')
mocked_account.account_exists.return_value = False
# create CD manager
cdman = ContinuousDeliveryManager(None)
@ -107,7 +86,7 @@ class TestContinousDeliveryManager(unittest.TestCase):
cdman.set_repository_info('repoUrl1', 'master1', 'token1', None, None)
cd_app_type = 'AspNet'
app_type_details = create_cd_app_type_details_map(cd_app_type, None, None, None, None)
app_type_details = self.create_cd_app_type_details_map(cd_app_type, None, None, None, None)
# call setup
result = cdman.setup_continuous_delivery('staging', app_type_details, "https://account1.visualstudio.com", True, 'token2', None, None)
@ -122,6 +101,12 @@ class TestContinousDeliveryManager(unittest.TestCase):
self.assertEqual('https://account1.visualstudio.com/333/_build?_a=simple-process&definitionId=123', result.vsts_build_def_url)
self.assertEqual('https://account1.visualstudio.com/333/_apps/hub/ms.vss-releaseManagement-web.hub-explorer?definitionId=321&_a=releases', result.vsts_release_def_url)
# call setup
mocked_account.create_account.return_value = Collection(None, 'collection111')
with self.assertRaises(RuntimeError) as context:
cdman.setup_continuous_delivery('staging', app_type_details, "https://account1.visualstudio.com", True, 'token2', None, None)
self.assertTrue('Account creation failed' in str(context.exception))
def test_get_provisioning_configuration_target(self):
cdman = ContinuousDeliveryManager(None)
cdman.set_azure_web_info('group1', 'web1', 'fakeCreds', 'sub1', 'subname1', 'tenant1', 'South Central US')
@ -161,7 +146,7 @@ class TestContinousDeliveryManager(unittest.TestCase):
test_case_count = 8
for i in range(test_case_count):
cd_app_type, nodejs_task_runner, python_framework, python_version, app_working_dir = self._set_build_configuration_variables(i)
app_type_details = create_cd_app_type_details_map(cd_app_type, nodejs_task_runner, python_framework, python_version, app_working_dir)
app_type_details = self.create_cd_app_type_details_map(cd_app_type, nodejs_task_runner, python_framework, python_version, app_working_dir)
if(i<3) :
# Verifying build configuration outputs
build_configuration = cdman._get_build_configuration(app_type_details)
@ -209,14 +194,14 @@ class TestContinousDeliveryManager(unittest.TestCase):
CiResult(status, status_message))
return ProvisioningConfiguration('abcd', None, None, ci_config)
def create_cd_app_type_details_map(cd_app_type, nodejs_task_runner, python_framework, python_version, app_working_dir):
return {
'cd_app_type' : cd_app_type,
'nodejs_task_runner' : nodejs_task_runner,
'python_framework' : python_framework,
'python_version' : python_version,
'app_working_dir' : app_working_dir
}
def create_cd_app_type_details_map(self, cd_app_type, nodejs_task_runner, python_framework, python_version, app_working_dir):
return {
'cd_app_type' : cd_app_type,
'nodejs_task_runner' : nodejs_task_runner,
'python_framework' : python_framework,
'python_version' : python_version,
'app_working_dir' : app_working_dir
}
if __name__ == '__main__':
unittest.main()

Просмотреть файл

@ -1,442 +0,0 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------
from __future__ import print_function
from sys import stderr
from msrest.service_client import ServiceClient
from msrest import Configuration, Serializer, Deserializer
from .version import VERSION
from msrest.pipeline import ClientRawResponse
from msrest.exceptions import HttpOperationError
from . import models
from .models import AccountModel
class AccountConfiguration(Configuration):
"""Configuration for Account
Note that all parameters used to create this instance are saved as instance
attributes.
:param api_version: Version of the API to use. This should be set to
'3.2-preview' to use this version of the api.
:type api_version: str
:param str base_url: Service URL
"""
def __init__(
self, api_version, base_url=None):
if api_version is None:
raise ValueError("Parameter 'api_version' must not be None.")
if not isinstance(api_version, str):
raise TypeError("Parameter 'api_version' must be str.")
if not base_url:
base_url = 'https://app.vssps.visualstudio.com'
super(AccountConfiguration, self).__init__(base_url)
self.add_user_agent('account/{}'.format(VERSION))
self.api_version = api_version
class Account(object):
"""Account
:ivar config: Configuration for client.
:vartype config: AccountConfiguration
:param api_version: Version of the API to use. This should be set to
'3.2-preview' to use this version of the api.
:type api_version: str
:param str base_url: Service URL
"""
def __init__(
self, api_version, base_url=None, creds=None):
self.config = AccountConfiguration(api_version, base_url)
self._client = ServiceClient(creds, self.config)
client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)}
self.api_version = '3.2' if not api_version else api_version
self._serialize = Serializer(client_models)
self._deserialize = Deserializer(client_models)
def account_exists(
self, account_name, custom_headers=None, raw=False, **operation_config):
# Construct URL
url = 'https://{}.visualstudio.com'.format(account_name)
# Construct parameters
query_parameters = {}
# Construct headers
header_parameters = {}
header_parameters['Content-Type'] = 'application/json; charset=utf-8'
if custom_headers:
header_parameters.update(custom_headers)
# Construct and send request
request = self._client.get(url, query_parameters)
response = self._client.send(request, header_parameters, **operation_config)
if response.status_code not in [200, 404]:
print("GET", request.url, file=stderr)
print("response:", response.status_code, file=stderr)
print(response.text, file=stderr)
raise HttpOperationError(self._deserialize, response)
if response.status_code == 200:
return True
return False
def is_valid_account_name(
self, account_name, custom_headers=None, raw=False, **operation_config):
"""IsValidAccountName.
:param account_name:
:type account_name: str
:param dict custom_headers: headers that will be added to the request
:param bool raw: returns the direct response alongside the
deserialized response
:param operation_config: :ref:`Operation configuration
overrides<msrest:optionsforoperations>`.
:rtype: :class:`AccountNameAvailability
<vsts.accounts.models.AccountNameAvailability>`
:rtype: :class:`ClientRawResponse<msrest.pipeline.ClientRawResponse>`
if raw=true
:raises:
:class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
"""
# Construct URL
url = '/_apis/account/availability/{accountName}'
path_format_arguments = {
'accountName': self._serialize.url("account_name", account_name, 'str')
}
url = self._client.format_url(url, **path_format_arguments)
# Construct parameters
query_parameters = {}
if self.api_version:
query_parameters["api-version"] = self.api_version
# Construct headers
header_parameters = {}
header_parameters['Content-Type'] = 'application/json; charset=utf-8'
if custom_headers:
header_parameters.update(custom_headers)
# Construct and send request
request = self._client.get(url, query_parameters)
response = self._client.send(request, header_parameters, **operation_config)
if response.status_code not in [200]:
print("GET", request.url, file=stderr)
print("response:", response.status_code, file=stderr)
print(response.text, file=stderr)
raise HttpOperationError(self._deserialize, response)
deserialized = None
if response.status_code == 200:
deserialized = self._deserialize('AccountNameAvailability', response)
if raw:
client_raw_response = ClientRawResponse(deserialized, response)
return client_raw_response
return deserialized
def get_regions(
self, custom_headers=None, raw=False, **operation_config):
"""GetRegions.
:param dict custom_headers: headers that will be added to the request
:param bool raw: returns the direct response alongside the
deserialized response
:param operation_config: :ref:`Operation configuration
overrides<msrest:optionsforoperations>`.
:rtype: list of :class:`AccountRegion
<vsts.accounts.models.AccountRegion>`
:rtype: :class:`ClientRawResponse<msrest.pipeline.ClientRawResponse>`
if raw=true
:raises:
:class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
"""
# Construct URL
url = '/_apis/account/regions'
# Construct parameters
query_parameters = {}
# Construct headers
header_parameters = {}
header_parameters['Content-Type'] = 'application/json; charset=utf-8'
if custom_headers:
header_parameters.update(custom_headers)
# Construct and send request
request = self._client.get(url, query_parameters)
response = self._client.send(request, header_parameters, **operation_config)
if response.status_code not in [200]:
print("GET", request.url, file=stderr)
print("response:", response.status_code, file=stderr)
print(response.text, file=stderr)
raise HttpOperationError(self._deserialize, response)
deserialized = None
if response.status_code == 200:
deserialized = self._deserialize('[AccountRegion]', response)
if raw:
client_raw_response = ClientRawResponse(deserialized, response)
return client_raw_response
return deserialized
def get_account_settings(
self, custom_headers=None, raw=False, **operation_config):
"""GetAccountSettings.
:param dict custom_headers: headers that will be added to the request
:param bool raw: returns the direct response alongside the
deserialized response
:param operation_config: :ref:`Operation configuration
overrides<msrest:optionsforoperations>`.
:rtype: dict
:rtype: :class:`ClientRawResponse<msrest.pipeline.ClientRawResponse>`
if raw=true
:raises:
:class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
"""
# Construct URL
url = '/_apis/account/settings'
# Construct parameters
query_parameters = {}
# Construct headers
header_parameters = {}
header_parameters['Content-Type'] = 'application/json; charset=utf-8'
if custom_headers:
header_parameters.update(custom_headers)
# Construct and send request
request = self._client.get(url, query_parameters)
response = self._client.send(request, header_parameters, **operation_config)
if response.status_code not in [200]:
print("GET", request.url, file=stderr)
print("response:", response.status_code, file=stderr)
print(response.text, file=stderr)
raise HttpOperationError(self._deserialize, response)
deserialized = None
if response.status_code == 200:
deserialized = self._deserialize('{str}', response)
if raw:
client_raw_response = ClientRawResponse(deserialized, response)
return client_raw_response
return deserialized
def create_account(
self, body, use_precreated=None, custom_headers=None, raw=False, **operation_config):
"""CreateAccount.
:param body:
:type body: :class:`AccountCreateInfoInternal
<vsts.accounts.models.AccountCreateInfoInternal>`
:param use_precreated:
:type use_precreated: bool
:param dict custom_headers: headers that will be added to the request
:param bool raw: returns the direct response alongside the
deserialized response
:param operation_config: :ref:`Operation configuration
overrides<msrest:optionsforoperations>`.
:rtype: :class:`AccountModel <vsts.accounts.models.AccountModel>`
:rtype: :class:`ClientRawResponse<msrest.pipeline.ClientRawResponse>`
if raw=true
:raises:
:class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
"""
# Construct URL
url = '/_apis/accounts'
# Construct parameters
query_parameters = {}
if use_precreated is not None:
query_parameters['usePrecreated'] = self._serialize.query("use_precreated", use_precreated, 'bool')
if self.api_version:
query_parameters["api-version"] = self.api_version
# Construct headers
header_parameters = {}
header_parameters['Content-Type'] = 'application/json; charset=utf-8'
if custom_headers:
header_parameters.update(custom_headers)
# Construct body
body_content = self._serialize.body(body, 'AccountCreateInfoInternal')
# Construct and send request
request = self._client.post(url, query_parameters)
response = self._client.send(
request, header_parameters, body_content, **operation_config)
if response.status_code == 409:
# Return Empty AccountModel to let the caller know that an account already exists with that name
return AccountModel(status_reason='An account already exists with that name.')
if response.status_code not in [200, 201]:
print("POST", request.url, file=stderr)
print("response:", response.status_code, file=stderr)
print(response.text, file=stderr)
raise HttpOperationError(self._deserialize, response)
deserialized = None
if response.status_code == 200:
deserialized = self._deserialize('AccountModel', response)
if response.status_code == 201:
deserialized = self._deserialize('AccountModel', response)
if raw:
client_raw_response = ClientRawResponse(deserialized, response)
return client_raw_response
return deserialized
def get_accounts(
self, owner_id=None, member_id=None, properties=None, custom_headers=None, raw=False, **operation_config):
"""GetAccounts.
A new version GetAccounts API. Only supports limited set of parameters,
returns a list of account ref objects that only contains AccountUrl,
AccountName and AccountId information, will use collection host Id as
the AccountId.
:param owner_id: Owner Id to query for
:type owner_id: str
:param member_id: Member Id to query for
:type member_id: str
:param properties: Only support service URL properties
:type properties: str
:param dict custom_headers: headers that will be added to the request
:param bool raw: returns the direct response alongside the
deserialized response
:param operation_config: :ref:`Operation configuration
overrides<msrest:optionsforoperations>`.
:rtype: list of :class:`AccountModel
<vsts.accounts.models.AccountModel>`
:rtype: :class:`ClientRawResponse<msrest.pipeline.ClientRawResponse>`
if raw=true
:raises:
:class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
"""
# Construct URL
url = '/_apis/accounts'
# Construct parameters
query_parameters = {}
if owner_id is not None:
query_parameters['ownerId'] = self._serialize.query("owner_id", owner_id, 'str')
if member_id is not None:
query_parameters['memberId'] = self._serialize.query("member_id", member_id, 'str')
if properties is not None:
query_parameters['properties'] = self._serialize.query("properties", properties, 'str')
# Construct headers
header_parameters = {}
header_parameters['Content-Type'] = 'application/json; charset=utf-8'
if custom_headers:
header_parameters.update(custom_headers)
# Construct and send request
request = self._client.get(url, query_parameters)
response = self._client.send(request, header_parameters, **operation_config)
if response.status_code not in [200, 201]:
print("GET", request.url, file=stderr)
print("response:", response.status_code, file=stderr)
print(response.text, file=stderr)
raise HttpOperationError(self._deserialize, response)
deserialized = None
if response.status_code == 200:
deserialized = self._deserialize('[AccountModel]', response)
if raw:
client_raw_response = ClientRawResponse(deserialized, response)
return client_raw_response
return deserialized
def get_account(
self, account_id, properties=None, custom_headers=None, raw=False, **operation_config):
"""GetAccount.
:param account_id:
:type account_id: str
:param properties:
:type properties: str
:param dict custom_headers: headers that will be added to the request
:param bool raw: returns the direct response alongside the
deserialized response
:param operation_config: :ref:`Operation configuration
overrides<msrest:optionsforoperations>`.
:rtype: :class:`AccountModel <vsts.accounts.models.AccountModel>`
:rtype: :class:`ClientRawResponse<msrest.pipeline.ClientRawResponse>`
if raw=true
:raises:
:class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
"""
# Construct URL
url = '/_apis/accounts/{accountId}'
path_format_arguments = {
'accountId': self._serialize.url("account_id", account_id, 'str')
}
url = self._client.format_url(url, **path_format_arguments)
# Construct parameters
query_parameters = {}
if properties is not None:
query_parameters['properties'] = self._serialize.query("properties", properties, 'str')
# Construct headers
header_parameters = {}
header_parameters['Content-Type'] = 'application/json; charset=utf-8'
if custom_headers:
header_parameters.update(custom_headers)
# Construct and send request
request = self._client.get(url, query_parameters)
response = self._client.send(request, header_parameters, **operation_config)
if response.status_code not in [200]:
print("GET", request.url, file=stderr)
print("response:", response.status_code, file=stderr)
print(response.text, file=stderr)
raise HttpOperationError(self._deserialize, response)
deserialized = None
if response.status_code == 200:
deserialized = self._deserialize('AccountModel', response)
if raw:
client_raw_response = ClientRawResponse(deserialized, response)
return client_raw_response
return deserialized

Просмотреть файл

@ -1,17 +0,0 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------
from msrest.exceptions import (
ClientException,
SerializationError,
DeserializationError,
TokenExpiredError,
ClientRequestError,
AuthenticationError,
HttpOperationError,
ValidationError,
)

Просмотреть файл

@ -1,26 +0,0 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------
from .properties_collection import PropertiesCollection
from .account_model import AccountModel
from .account_preferences_internal import AccountPreferencesInternal
from .account_create_info_internal import AccountCreateInfoInternal
from .account_name_availability import AccountNameAvailability
from .account_region import AccountRegion
from .vss_json_collection_wrapper import VssJsonCollectionWrapper
from .vss_json_collection_wrapper_base import VssJsonCollectionWrapperBase
__all__ = [
'PropertiesCollection',
'AccountModel',
'AccountPreferencesInternal',
'AccountCreateInfoInternal',
'AccountNameAvailability',
'AccountRegion',
'VssJsonCollectionWrapper',
'VssJsonCollectionWrapperBase',
]

Просмотреть файл

@ -1,45 +0,0 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------
from msrest.serialization import Model
class AccountCreateInfoInternal(Model):
"""AccountCreateInfoInternal.
:param account_name:
:type account_name: str
:param creator:
:type creator: str
:param organization:
:type organization: str
:param preferences:
:type preferences: :class:`AccountPreferencesInternal
<vsts.accounts.models.AccountPreferencesInternal>`
:param properties:
:type properties: :class:`PropertiesCollection
<vsts.accounts.models.PropertiesCollection>`
:param service_definitions:
:type service_definitions: list of object
"""
_attribute_map = {
'account_name': {'key': 'accountName', 'type': 'str'},
'creator': {'key': 'creator', 'type': 'str'},
'organization': {'key': 'organization', 'type': 'str'},
'preferences': {'key': 'preferences', 'type': 'AccountPreferencesInternal'},
'properties': {'key': 'properties', 'type': '{object}'},
'service_definitions': {'key': 'serviceDefinitions', 'type': '[object]'},
}
def __init__(self, account_name=None, creator=None, organization=None, preferences=None, properties=None, service_definitions=None):
self.account_name = account_name
self.creator = creator
self.organization = organization
self.preferences = preferences
self.properties = properties
self.service_definitions = service_definitions

Просмотреть файл

@ -1,84 +0,0 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------
from msrest.serialization import Model
class AccountModel(Model):
"""AccountModel.
:param account_id: Identifier for an Account
:type account_id: str
:param account_name: Name for an account
:type account_name: str
:param account_owner: Owner of account
:type account_owner: str
:param account_status: Current account status
:type account_status: object
:param account_type: Type of account: Personal, Organization
:type account_type: object
:param account_uri: Uri for an account
:type account_uri: str
:param created_by: Who created the account
:type created_by: str
:param created_date: Date account was created
:type created_date: datetime
:param has_moved:
:type has_moved: bool
:param last_updated_by: Identity of last person to update the account
:type last_updated_by: str
:param last_updated_date: Date account was last updated
:type last_updated_date: datetime
:param namespace_id: Namespace for an account
:type namespace_id: str
:param new_collection_id:
:type new_collection_id: str
:param organization_name: Organization that created the account
:type organization_name: str
:param properties: Extended properties
:type properties: :class:`PropertiesCollection
<vsts.accounts.models.PropertiesCollection>`
:param status_reason: Reason for current status
:type status_reason: str
"""
_attribute_map = {
'account_id': {'key': 'accountId', 'type': 'str'},
'account_name': {'key': 'accountName', 'type': 'str'},
'account_owner': {'key': 'accountOwner', 'type': 'str'},
'account_status': {'key': 'accountStatus', 'type': 'object'},
'account_type': {'key': 'accountType', 'type': 'object'},
'account_uri': {'key': 'accountUri', 'type': 'str'},
'created_by': {'key': 'createdBy', 'type': 'str'},
'created_date': {'key': 'createdDate', 'type': 'iso-8601'},
'has_moved': {'key': 'hasMoved', 'type': 'bool'},
'last_updated_by': {'key': 'lastUpdatedBy', 'type': 'str'},
'last_updated_date': {'key': 'lastUpdatedDate', 'type': 'iso-8601'},
'namespace_id': {'key': 'namespaceId', 'type': 'str'},
'new_collection_id': {'key': 'newCollectionId', 'type': 'str'},
'organization_name': {'key': 'organizationName', 'type': 'str'},
'properties': {'key': 'properties', 'type': '{object}'},
'status_reason': {'key': 'statusReason', 'type': 'str'},
}
def __init__(self, account_id=None, account_name=None, account_owner=None, account_status=None, account_type=None, account_uri=None, created_by=None, created_date=None, has_moved=None, last_updated_by=None, last_updated_date=None, namespace_id=None, new_collection_id=None, organization_name=None, properties=None, status_reason=None):
self.account_id = account_id
self.account_name = account_name
self.account_owner = account_owner
self.account_status = account_status
self.account_type = account_type
self.account_uri = account_uri
self.created_by = created_by
self.created_date = created_date
self.has_moved = has_moved
self.last_updated_by = last_updated_by
self.last_updated_date = last_updated_date
self.namespace_id = namespace_id
self.new_collection_id = new_collection_id
self.organization_name = organization_name
self.properties = properties
self.status_reason = status_reason

Просмотреть файл

@ -1,27 +0,0 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------
from msrest.serialization import Model
class AccountNameAvailability(Model):
"""AccountNameAvailability.
:param is_valid_name:
:type is_valid_name: bool
:param status_reason: Reason for current status
:type status_reason: str
"""
_attribute_map = {
'is_valid_name': {'key': 'isValidName', 'type': 'bool'},
'status_reason': {'key': 'statusReason', 'type': 'str'},
}
def __init__(self, is_valid_name=None, status_reason=None):
self.is_valid_name = is_valid_name
self.status_reason = status_reason

Просмотреть файл

@ -1,31 +0,0 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------
from msrest.serialization import Model
class AccountPreferencesInternal(Model):
"""AccountPreferencesInternal.
:param culture:
:type culture: str
:param language:
:type language: str
:param time_zone:
:type time_zone: str
"""
_attribute_map = {
'culture': {'key': 'culture', 'type': 'str'},
'language': {'key': 'language', 'type': 'str'},
'time_zone': {'key': 'timeZone', 'type': 'str'},
}
def __init__(self, culture=None, language=None, time_zone=None):
self.culture = culture
self.language = language
self.time_zone = time_zone

Просмотреть файл

@ -1,31 +0,0 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------
from msrest.serialization import Model
class AccountRegion(Model):
"""AccountRegion.
:param display_name: Display name of the account region
:type display_name: str
:param is_default: Whether the region is default or not
:type is_default: bool
:param location_name: Azure location name
:type location_name: str
"""
_attribute_map = {
'display_name': {'key': 'displayName', 'type': 'str'},
'is_default': {'key': 'isDefault', 'type': 'bool'},
'location_name': {'key': 'locationName', 'type': 'str'},
}
def __init__(self, display_name=None, is_default=None, location_name=None):
self.display_name = display_name
self.is_default = is_default
self.location_name = location_name

Просмотреть файл

@ -1,35 +0,0 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------
from msrest.serialization import Model
class PropertiesCollection(Model):
"""PropertiesCollection.
:param count: Implements ICollection<KeyValuePair<String,Object>>.Count/>
:type count: int
:param item:
:type item: object
:param keys:
:type keys: list of str
:param values:
:type values: list of str
"""
_attribute_map = {
'count': {'key': 'count', 'type': 'int'},
'item': {'key': 'item', 'type': 'object'},
'keys': {'key': 'keys', 'type': '[str]'},
'values': {'key': 'values', 'type': '[str]'},
}
def __init__(self, count=None, item=None, keys=None, values=None):
self.count = count
self.item = item
self.keys = keys
self.values = values

Просмотреть файл

@ -1,27 +0,0 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------
from .vss_json_collection_wrapper_base import VssJsonCollectionWrapperBase
class VssJsonCollectionWrapper(VssJsonCollectionWrapperBase):
"""VssJsonCollectionWrapper.
:param count:
:type count: int
:param value:
:type value: str
"""
_attribute_map = {
'count': {'key': 'count', 'type': 'int'},
'value': {'key': 'value', 'type': 'str'},
}
def __init__(self, count=None, value=None):
super(VssJsonCollectionWrapper, self).__init__(count=count)
self.value = value

Просмотреть файл

@ -1,23 +0,0 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------
from msrest.serialization import Model
class VssJsonCollectionWrapperBase(Model):
"""VssJsonCollectionWrapperBase.
:param count:
:type count: int
"""
_attribute_map = {
'count': {'key': 'count', 'type': 'int'},
}
def __init__(self, count=None):
self.count = count

Просмотреть файл

@ -19,8 +19,7 @@ from continuous_delivery.models import (AuthorizationInfo, AuthorizationInfoPara
CiArtifact, CiConfiguration, ProvisioningConfiguration,
ProvisioningConfigurationSource, ProvisioningConfigurationTarget,
SlotSwapConfiguration, SourceRepository, CreateOptions)
from vsts_accounts import Account
from vsts_accounts.models import (AccountCreateInfoInternal)
from aex_accounts import Account
# Use this class to setup or remove continuous delivery mechanisms for Azure web sites using VSTS build and release
class ContinuousDeliveryManager(object):
@ -113,27 +112,12 @@ class ContinuousDeliveryManager(object):
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
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))
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)
@ -154,6 +138,20 @@ class ContinuousDeliveryManager(object):
else:
raise RuntimeError('Unknown status returned from provisioning_configuration: ' + response.ci_configuration.result.status)
def create_vsts_account(self, creds, vsts_account_name):
aex_url = 'https://app.vsaex.visualstudio.com'
accountClient = Account('4.0-preview.1', aex_url, creds)
self._update_progress(0, 100, 'Creating or getting Team Services account information')
regions = accountClient.regions()
if regions.count == 0:
raise RuntimeError('Region details not found.')
region_name = regions.value[0].name
create_account_reponse = accountClient.create_account(vsts_account_name, region_name)
if create_account_reponse.id:
self._update_progress(5, 100, 'Team Services account created')
else:
raise RuntimeError('Account creation failed.')
def _validate_cd_project_url(self, cd_project_url):
if -1 == cd_project_url.find('visualstudio.com') or -1 == cd_project_url.find('https://'):
raise RuntimeError('Project URL should be in format https://<accountname>.visualstudio.com/<projectname>')
@ -349,4 +347,3 @@ class ContinuousDeliveryResult(object):
self.status = 'SUCCESS'
self.status_message = message
self.status_details = final_status