Коммит
ac6298b930
|
@ -18,5 +18,5 @@ Use the standard PYPI packaging flow to push a new release. Make sure to increme
|
|||
*Example*
|
||||
::
|
||||
python setup.py sdist
|
||||
twine upload dist/*
|
||||
python -m twine upload dist/*
|
||||
::
|
||||
|
|
|
@ -175,73 +175,3 @@ class AzureTfs(object):
|
|||
|
||||
return deserialized
|
||||
|
||||
class VstsInfoProvider(object):
|
||||
"""VstsInfoProvider
|
||||
|
||||
:ivar config: Configuration for client.
|
||||
:vartype config: AzureTfsConfiguration
|
||||
|
||||
: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 vsts_git_url: vsts git URL
|
||||
:param Credentials creds: credentials for vsts
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, api_version, vsts_git_url, creds=None):
|
||||
self.config = AzureTfsConfiguration(api_version, vsts_git_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 get_vsts_info(
|
||||
self, custom_headers=None, raw=False, **operation_config):
|
||||
"""GetContinuousDeploymentOperation.
|
||||
|
||||
: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:`ContinuousDeploymentOperation
|
||||
<azuretfs.models.ContinuousDeploymentOperation>`
|
||||
:rtype: :class:`ClientRawResponse<msrest.pipeline.ClientRawResponse>`
|
||||
if raw=true
|
||||
:raises:
|
||||
:class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
|
||||
"""
|
||||
# Construct URL
|
||||
url = '/vsts/info'
|
||||
|
||||
# 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("response:", response.status_code)
|
||||
print(response.text)
|
||||
raise HttpOperationError(self._deserialize, response)
|
||||
|
||||
deserialized = None
|
||||
|
||||
if response.status_code == 200:
|
||||
deserialized = self._deserialize('VstsInfo', response)
|
||||
|
||||
if raw:
|
||||
client_raw_response = ClientRawResponse(deserialized, response)
|
||||
return client_raw_response
|
||||
|
||||
return deserialized
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
# 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 .continuous_delivery import ContinuousDelivery
|
||||
from .version import VERSION
|
||||
|
||||
__all__ = ['ContinuousDelivery']
|
||||
|
||||
__version__ = VERSION
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
# 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 sys import stderr
|
||||
from msrest.service_client import ServiceClient
|
||||
from msrest import Configuration, Serializer, Deserializer
|
||||
from msrest.pipeline import ClientRawResponse
|
||||
from msrest.exceptions import HttpOperationError
|
||||
from .version import VERSION
|
||||
from . import models
|
||||
|
||||
|
||||
class ContinuousDeliveryConfiguration(Configuration):
|
||||
"""Configuration for Continuous Delivery
|
||||
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://{account}.portalext.visualstudio.com/'
|
||||
|
||||
super(ContinuousDeliveryConfiguration, self).__init__(base_url)
|
||||
|
||||
self.add_user_agent('azurecli/{}/continuousdelivery/{}'.format(VERSION, VERSION))
|
||||
|
||||
self.api_version = api_version
|
||||
|
||||
|
||||
class ContinuousDelivery(object):
|
||||
"""ContinuousDelivery
|
||||
|
||||
:ivar config: Configuration for client.
|
||||
:vartype config: AzureTfsConfiguration
|
||||
|
||||
: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
|
||||
:param Credentials creds: credentials for vsts
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, api_version, base_url=None, creds=None):
|
||||
self.config = ContinuousDeliveryConfiguration(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 provisioning_configuration(
|
||||
self, body, custom_headers=None, raw=False, **operation_config):
|
||||
"""ProvisioningConfiguration.
|
||||
|
||||
:param body:
|
||||
:type body: :class:`ContinuousDeploymentConfiguration
|
||||
<azuretfs.models.ContinuousDeploymentConfiguration>`
|
||||
: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:`ContinuousDeploymentOperation
|
||||
<azuretfs.models.ContinuousDeploymentOperation>`
|
||||
:rtype: :class:`ClientRawResponse<msrest.pipeline.ClientRawResponse>`
|
||||
if raw=true
|
||||
:raises:
|
||||
:class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
|
||||
"""
|
||||
# Construct URL
|
||||
url = '/_apis/continuousdelivery/provisioningconfigurations'
|
||||
|
||||
# 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 body
|
||||
body_content = self._serialize.body(body, 'ProvisioningConfiguration')
|
||||
|
||||
# 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 not in [200, 202]:
|
||||
print("POST", request.url, file=stderr)
|
||||
print("BODY", body_content)
|
||||
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('ProvisioningConfiguration', response)
|
||||
if response.status_code == 202:
|
||||
deserialized = self._deserialize('ProvisioningConfiguration', response)
|
||||
|
||||
if raw:
|
||||
client_raw_response = ClientRawResponse(deserialized, response)
|
||||
return client_raw_response
|
||||
|
||||
return deserialized
|
||||
|
||||
def get_provisioning_configuration(
|
||||
self, provisioning_configuration_id, custom_headers=None, raw=False, **operation_config):
|
||||
"""GetContinuousDeploymentOperation.
|
||||
|
||||
:param provisioning_configuration_id:
|
||||
:type provisioning_configuration_id: 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:`ContinuousDeploymentOperation
|
||||
<azuretfs.models.ContinuousDeploymentOperation>`
|
||||
:rtype: :class:`ClientRawResponse<msrest.pipeline.ClientRawResponse>`
|
||||
if raw=true
|
||||
:raises:
|
||||
:class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
|
||||
"""
|
||||
# Construct URL
|
||||
url = '/_apis/continuousdelivery/provisioningconfigurations/{provisioningConfigurationId}'
|
||||
path_format_arguments = {
|
||||
'provisioningConfigurationId': self._serialize.url("provisioning_configuration_id", provisioning_configuration_id, 'str')
|
||||
}
|
||||
url = self._client.format_url(url, **path_format_arguments)
|
||||
|
||||
# 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('ProvisioningConfiguration', response)
|
||||
|
||||
if raw:
|
||||
client_raw_response = ClientRawResponse(deserialized, response)
|
||||
return client_raw_response
|
||||
|
||||
return deserialized
|
|
@ -0,0 +1,11 @@
|
|||
# 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.authentication import (
|
||||
BasicAuthentication,
|
||||
BasicTokenAuthentication,
|
||||
OAuthTokenAuthentication)
|
|
@ -0,0 +1,17 @@
|
|||
# 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,
|
||||
)
|
|
@ -0,0 +1,33 @@
|
|||
# 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 .authorization_info import AuthorizationInfo
|
||||
from .authorization_info_parameters import AuthorizationInfoParameters
|
||||
from .build_configuration import BuildConfiguration
|
||||
from .ci_artifact import CiArtifact
|
||||
from .ci_configuration import CiConfiguration
|
||||
from .ci_result import CiResult
|
||||
from .provisioning_configuration import ProvisioningConfiguration
|
||||
from .provisioning_configuration_source import ProvisioningConfigurationSource
|
||||
from .provisioning_configuration_target import ProvisioningConfigurationTarget
|
||||
from .slot_swap_configuration import SlotSwapConfiguration
|
||||
from .source_repository import SourceRepository
|
||||
|
||||
|
||||
__all__ = [
|
||||
'AuthorizationInfo',
|
||||
'AuthorizationInfoParameters',
|
||||
'BuildConfiguration',
|
||||
'CiArtifact',
|
||||
'CiConfiguration',
|
||||
'CiResult',
|
||||
'ProvisioningConfiguration',
|
||||
'ProvisioningConfigurationSource',
|
||||
'ProvisioningConfigurationTarget',
|
||||
'SlotSwapConfiguration',
|
||||
'SourceRepository',
|
||||
]
|
|
@ -0,0 +1,19 @@
|
|||
# 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 AuthorizationInfo(Model):
|
||||
_attribute_map = {
|
||||
'scheme': {'key': 'scheme', 'type': 'str'},
|
||||
'parameters': {'key': 'parameters', 'type': 'AuthorizationInfoParameters'},
|
||||
}
|
||||
|
||||
def __init__(self, scheme=None, parameters=None):
|
||||
self.scheme = scheme
|
||||
self.parameters = parameters
|
|
@ -0,0 +1,19 @@
|
|||
# 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 AuthorizationInfoParameters(Model):
|
||||
_attribute_map = {
|
||||
'authorization': {'key': 'Authorization', 'type': 'str'},
|
||||
'access_token': {'key': 'AccessToken', 'type': 'str'},
|
||||
}
|
||||
|
||||
def __init__(self, authorization=None, access_token=None):
|
||||
self.authorization = authorization
|
||||
self.access_token = access_token
|
|
@ -0,0 +1,19 @@
|
|||
# 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 BuildConfiguration(Model):
|
||||
_attribute_map = {
|
||||
'type': {'key': 'type', 'type': 'str'},
|
||||
'working_directory': {'key': 'workingDirectory', 'type': 'str'},
|
||||
}
|
||||
|
||||
def __init__(self, type=None, working_directory=None):
|
||||
self.type = type
|
||||
self.working_directory = working_directory
|
|
@ -0,0 +1,21 @@
|
|||
# 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 CiArtifact(Model):
|
||||
_attribute_map = {
|
||||
'id': {'key': 'id', 'type': 'str'},
|
||||
'name': {'key': 'name', 'type': 'str'},
|
||||
'url': {'key': 'url', 'type': 'str'},
|
||||
}
|
||||
|
||||
def __init__(self, id=None, name=None, url=None):
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.url = url
|
|
@ -0,0 +1,23 @@
|
|||
# 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 CiConfiguration(Model):
|
||||
_attribute_map = {
|
||||
'project': {'key': 'project', 'type': 'CiArtifact'},
|
||||
'build_definition': {'key': 'buildDefinition', 'type': 'CiArtifact'},
|
||||
'release_definition': {'key': 'releaseDefinition', 'type': 'CiArtifact'},
|
||||
'result': {'key': 'result', 'type': 'CiResult'},
|
||||
}
|
||||
|
||||
def __init__(self, project=None, build_definition=None, release_definition=None, result=None):
|
||||
self.project = project
|
||||
self.build_definition = build_definition
|
||||
self.release_definition = release_definition
|
||||
self.result = result
|
|
@ -0,0 +1,19 @@
|
|||
# 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 CiResult(Model):
|
||||
_attribute_map = {
|
||||
'status': {'key': 'status', 'type': 'str'},
|
||||
'status_message': {'key': 'statusMessage', 'type': 'str'},
|
||||
}
|
||||
|
||||
def __init__(self, status=None, status_message=None):
|
||||
self.status = status
|
||||
self.status_message = status_message
|
|
@ -0,0 +1,23 @@
|
|||
# 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 ProvisioningConfiguration(Model):
|
||||
_attribute_map = {
|
||||
'id': {'key': 'id', 'type': 'str'},
|
||||
'source': {'key': 'source', 'type': 'ProvisioningConfigurationSource'},
|
||||
'targets': {'key': 'targets', 'type': '[ProvisioningConfigurationTarget]'},
|
||||
'ci_configuration': {'key': 'ciConfiguration', 'type': 'CiConfiguration'},
|
||||
}
|
||||
|
||||
def __init__(self, id=None, source=None, targets=None, ci_configuration=None):
|
||||
self.id = id
|
||||
self.source = source
|
||||
self.targets = targets
|
||||
self.ci_configuration = ci_configuration
|
|
@ -0,0 +1,21 @@
|
|||
# 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 ProvisioningConfigurationSource(Model):
|
||||
_attribute_map = {
|
||||
'type': {'key': 'type', 'type': 'str'},
|
||||
'repository': {'key': 'repository', 'type': 'SourceRepository'},
|
||||
'build_configuration': {'key': 'buildConfiguration', 'type': 'BuildConfiguration'},
|
||||
}
|
||||
|
||||
def __init__(self, type=None, repository=None, build_configuration=None):
|
||||
self.type = type
|
||||
self.repository = repository
|
||||
self.build_configuration = build_configuration
|
|
@ -0,0 +1,41 @@
|
|||
# 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 ProvisioningConfigurationTarget(Model):
|
||||
_attribute_map = {
|
||||
'provider': {'key': 'provider', 'type': 'str'},
|
||||
'target_type': {'key': 'type', 'type': 'str'},
|
||||
'environment_type': {'key': 'environmentType', 'type': 'str'},
|
||||
'friendly_name': {'key': 'friendlyName', 'type': 'str'},
|
||||
'subscription_id': {'key': 'subscriptionId', 'type': 'str'},
|
||||
'subscription_name': {'key': 'subscriptionName', 'type': 'str'},
|
||||
'tenant_id': {'key': 'tenantId', 'type': 'str'},
|
||||
'resource_identifier': {'key': 'resourceIdentifier', 'type': 'str'},
|
||||
'resource_group_name': {'key': 'resourceGroupName', 'type': 'str'},
|
||||
'location': {'key': 'location', 'type': 'str'},
|
||||
'authorization_info': {'key': 'authorizationInfo', 'type': 'AuthorizationInfo'},
|
||||
'slot_swap_configuration': {'key': 'slotSwapConfiguration', 'type': 'SlotSwapConfiguration'},
|
||||
}
|
||||
|
||||
def __init__(self, provider=None, target_type=None, environment_type=None, friendly_name=None, subscription_id=None, subscription_name=None, tenant_id=None,
|
||||
resource_identifier=None, resource_group_name=None, location=None, authorization_info=None,
|
||||
slot_swap_configuration=None):
|
||||
self.provider = provider
|
||||
self.target_type = target_type
|
||||
self.environment_type = environment_type
|
||||
self.friendly_name = friendly_name
|
||||
self.subscription_id = subscription_id
|
||||
self.subscription_name = subscription_name
|
||||
self.tenant_id = tenant_id
|
||||
self.resource_identifier = resource_identifier
|
||||
self.resource_group_name = resource_group_name
|
||||
self.location = location
|
||||
self.authorization_info = authorization_info
|
||||
self.slot_swap_configuration = slot_swap_configuration
|
|
@ -0,0 +1,17 @@
|
|||
# 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 SlotSwapConfiguration(Model):
|
||||
_attribute_map = {
|
||||
'slot_name': {'key': 'slotName', 'type': 'str'},
|
||||
}
|
||||
|
||||
def __init__(self, slot_name=None):
|
||||
self.slot_name = slot_name
|
|
@ -0,0 +1,23 @@
|
|||
# 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 SourceRepository(Model):
|
||||
_attribute_map = {
|
||||
'type': {'key': 'type', 'type': 'str'},
|
||||
'identifier': {'key': 'id', 'type': 'str'},
|
||||
'default_branch': {'key': 'defaultBranch', 'type': 'str'},
|
||||
'authorization_info': {'key': 'authorizationInfo', 'type': 'AuthorizationInfo'},
|
||||
}
|
||||
|
||||
def __init__(self, type=None, identifier=None, default_branch=None, authorization_info = None):
|
||||
self.type = type
|
||||
self.identifier = identifier
|
||||
self.default_branch = default_branch
|
||||
self.authorization_info = authorization_info
|
|
@ -0,0 +1,9 @@
|
|||
# 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.
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
VERSION = "3.2"
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# 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 .account import Account
|
||||
from .version import VERSION
|
||||
|
||||
__all__ = ['Account']
|
||||
|
||||
__version__ = VERSION
|
||||
|
|
@ -0,0 +1,406 @@
|
|||
# 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 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
|
||||
|
||||
|
||||
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://fabrikam-fiber-inc.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 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 = {}
|
||||
|
||||
# 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')
|
||||
|
||||
# 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 none to let the caller know that an account already exists with that name
|
||||
return 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)
|
||||
|
||||
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_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]:
|
||||
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
|
|
@ -0,0 +1,11 @@
|
|||
# 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.authentication import (
|
||||
BasicAuthentication,
|
||||
BasicTokenAuthentication,
|
||||
OAuthTokenAuthentication)
|
|
@ -0,0 +1,17 @@
|
|||
# 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,
|
||||
)
|
|
@ -0,0 +1,26 @@
|
|||
# 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',
|
||||
]
|
|
@ -0,0 +1,45 @@
|
|||
# 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': 'PropertiesCollection'},
|
||||
'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
|
|
@ -0,0 +1,84 @@
|
|||
# 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': 'PropertiesCollection'},
|
||||
'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
|
|
@ -0,0 +1,27 @@
|
|||
# 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
|
|
@ -0,0 +1,31 @@
|
|||
# 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
|
|
@ -0,0 +1,31 @@
|
|||
# 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
|
|
@ -0,0 +1,35 @@
|
|||
# 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
|
|
@ -0,0 +1,27 @@
|
|||
# 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
|
|
@ -0,0 +1,23 @@
|
|||
# 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
|
|
@ -0,0 +1,9 @@
|
|||
# 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.
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
VERSION = "3.2"
|
||||
|
|
@ -11,9 +11,14 @@ try:
|
|||
except ImportError:
|
||||
from urllib import quote #pylint: disable=no-name-in-module
|
||||
from urlparse import urlparse #pylint: disable=import-error
|
||||
from azuretfs import AzureTfs, VstsInfoProvider
|
||||
from azuretfs.models import (ContinuousDeploymentConfiguration, ResourceConfiguration,
|
||||
SourceConfiguration, SourceRepository, Property, VstsInfo)
|
||||
from azuretfs import VstsInfoProvider
|
||||
from continuous_delivery import ContinuousDelivery
|
||||
from continuous_delivery.models import (AuthorizationInfo, AuthorizationInfoParameters, BuildConfiguration,
|
||||
CiArtifact, CiConfiguration, ProvisioningConfiguration,
|
||||
ProvisioningConfigurationSource, ProvisioningConfigurationTarget,
|
||||
SlotSwapConfiguration, SourceRepository)
|
||||
from vsts_accounts import Account
|
||||
from vsts_accounts.models import (AccountCreateInfoInternal)
|
||||
|
||||
# Use this class to setup or remove continuous delivery mechanisms for Azure web sites using VSTS build and release
|
||||
class ContinuousDeliveryManager(object):
|
||||
|
@ -86,64 +91,69 @@ class ContinuousDeliveryManager(object):
|
|||
:return: a message indicating final status and instructions for the user
|
||||
"""
|
||||
|
||||
app_type = self._get_app_project_type(app_type)
|
||||
branch = self._repo_info.branch or 'refs/heads/master'
|
||||
|
||||
# Verify inputs before we start generating tokens
|
||||
sourceRepository, account_name, team_project_name = self._get_source_repository(self._repo_info.url,
|
||||
self._repo_info.git_token, self._azure_info.credentials)
|
||||
self._verify_vsts_parameters(vsts_account_name, sourceRepository)
|
||||
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))
|
||||
|
||||
# Create AzureTfs client
|
||||
az_tfs = AzureTfs('3.2-preview', None, self._azure_info.credentials)
|
||||
# Try to create the account (return value of None means that the account already exists
|
||||
#accountClient = Account('3.2-preview', 'https://app.vssps.visualstudio.com', self._azure_info.credentials)
|
||||
#account_creation_parameters = AccountCreateInfoInternal(vsts_account_name)
|
||||
#creation_results = accountClient.create_account(account_creation_parameters, True)
|
||||
#account_created = not creation_results == None
|
||||
#print(creation_results)
|
||||
#return None
|
||||
|
||||
account_created = False
|
||||
|
||||
# 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
|
||||
account_configuration = ResourceConfiguration(create_account,
|
||||
[Property('region', 'CUS'),
|
||||
Property('PortalExtensionUsesNewAcquisitionFlows', 'false')],
|
||||
vsts_account_name)
|
||||
pipeline_configuration = None # This is not set because we are not the ibiza portal
|
||||
project_configuration = ResourceConfiguration(True, [Property('','')], cd_project_name)
|
||||
source_configuration = SourceConfiguration(sourceRepository, branch)
|
||||
target_configuration = [Property('resourceProperties', app_type),
|
||||
Property('resourceGroup', self._azure_info.resource_group_name),
|
||||
Property('subscriptionId', self._azure_info.subscription_id),
|
||||
Property('subscriptionName', self._azure_info.subscription_name),
|
||||
Property('tenantId', self._azure_info.tenant_id),
|
||||
Property('resourceName', self._azure_info.website_name),
|
||||
Property('deploymentSlot', azure_deployment_slot),
|
||||
Property('location', self._azure_info.webapp_location),
|
||||
Property('AuthInfo', 'Bearer ' + vsts_app_auth_token)]
|
||||
test_configuration = None # This is not set because we don't won't a test config setup
|
||||
config = ContinuousDeploymentConfiguration(account_configuration, pipeline_configuration, project_configuration,
|
||||
source_configuration, target_configuration, test_configuration)
|
||||
build_configuration = BuildConfiguration(app_type)
|
||||
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 = az_tfs.configure_continuous_deployment(config)
|
||||
if response.status == 'inProgress':
|
||||
final_status = self._wait_for_cd_completion(az_tfs, response)
|
||||
return self._get_summary(final_status, vsts_account_name, self._azure_info.subscription_id,
|
||||
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 configure_continuous_deployment: ' + response.status)
|
||||
raise RuntimeError('Unknown status returned from provisioning_configuration: ' + response.ci_configuration.result.status)
|
||||
|
||||
def _verify_vsts_parameters(self, cd_account, sourceRepository):
|
||||
def _verify_vsts_parameters(self, cd_account, source_repository):
|
||||
# if provider is vsts and repo is not vsts then we need the account name
|
||||
if sourceRepository.repository_type in [2, 4] and not cd_account:
|
||||
if source_repository.type in ['Github', 'ExternalGit'] and not cd_account:
|
||||
raise RuntimeError('You must provide a value for cd-account since your repo-url is not a VSTS repository.')
|
||||
|
||||
def _get_source_repository(self, uri, token, cred):
|
||||
# Determine the type of repository (vstsgit == 1, github == 2, tfvc == 3, externalGit == 4)
|
||||
def _get_source_repository(self, uri, token, branch, cred):
|
||||
# Determine the type of repository (TfsGit, github, tfvc, externalGit)
|
||||
# Find the identifier and set the properties; default to externalGit
|
||||
type = 4
|
||||
type = 'ExternalGit'
|
||||
identifier = uri
|
||||
properties = []
|
||||
account_name = None
|
||||
team_project_name = None
|
||||
auth_info = None
|
||||
match = re.match(r'[htps]+\:\/\/(.+)\.visualstudio\.com.*\/_git\/(.+)', uri, re.IGNORECASE)
|
||||
if match:
|
||||
type = 1
|
||||
type = 'TfsGit'
|
||||
account_name = match.group(1)
|
||||
# we have to get the repo id as the identifier
|
||||
info = self._get_vsts_info(uri, cred)
|
||||
|
@ -152,57 +162,47 @@ class ContinuousDeliveryManager(object):
|
|||
else:
|
||||
match = re.match(r'[htps]+\:\/\/github\.com\/(.+)', uri, re.IGNORECASE)
|
||||
if match:
|
||||
type = 2
|
||||
type = 'Github'
|
||||
identifier = match.group(1)
|
||||
properties = [Property('accessToken', token)]
|
||||
auth_info = AuthorizationInfo('PersonalAccessToken', AuthorizationInfoParameters(None, token))
|
||||
else:
|
||||
match = re.match(r'[htps]+\:\/\/(.+)\.visualstudio\.com\/(.+)', uri, re.IGNORECASE)
|
||||
if match:
|
||||
type = 3
|
||||
type = 'TFVC'
|
||||
identifier = match.group(2)
|
||||
account_name = match.group(1)
|
||||
sourceRepository = SourceRepository(identifier, properties, type)
|
||||
sourceRepository = SourceRepository(type, identifier, branch, auth_info)
|
||||
return sourceRepository, account_name, team_project_name
|
||||
|
||||
def _get_vsts_info(self, vsts_repo_url, cred):
|
||||
vsts_info_client = VstsInfoProvider('3.2-preview', vsts_repo_url, cred)
|
||||
return vsts_info_client.get_vsts_info()
|
||||
|
||||
def _get_app_project_type(self, cd_app_type):
|
||||
app_type = '{{\"webAppProjectType\":\"{}\"}}'.format(cd_app_type)
|
||||
return app_type
|
||||
|
||||
def _wait_for_cd_completion(self, az_tfs, response):
|
||||
def _wait_for_cd_completion(self, cd, response):
|
||||
# Wait for the configuration to finish and report on the status
|
||||
step = 5
|
||||
max = 100
|
||||
self._update_progress(step, max, 'Setting up VSTS continuous deployment')
|
||||
status = az_tfs.get_continuous_deployment_operation(response.id)
|
||||
while status.status == 'queued' or status.status == 'inProgress':
|
||||
config = cd.get_provisioning_configuration(response.id)
|
||||
while config.ci_configuration.result.status == 'queued' or config.ci_configuration.result.status == 'inProgress':
|
||||
step += 5 if step + 5 < max else 0
|
||||
self._update_progress(step, max, 'Setting up VSTS continuous deployment (' + status.status + ')')
|
||||
self._update_progress(step, max, 'Setting up VSTS continuous deployment (' + config.ci_configuration.result.status + ')')
|
||||
time.sleep(2)
|
||||
status = az_tfs.get_continuous_deployment_operation(response.id)
|
||||
if status.status == 'failed':
|
||||
config = cd.get_provisioning_configuration(response.id)
|
||||
if config.ci_configuration.result.status == 'failed':
|
||||
self._update_progress(max, max, 'Setting up VSTS continuous deployment (FAILED)')
|
||||
raise RuntimeError(status.result_message)
|
||||
raise RuntimeError(config.ci_configuration.result.status_message)
|
||||
self._update_progress(max, max, 'Setting up VSTS continuous deployment (SUCCEEDED)')
|
||||
return status
|
||||
return config
|
||||
|
||||
def _get_summary(self, final_status, account_name, subscription_id, resource_group_name, website_name):
|
||||
def _get_summary(self, provisioning_configuration, account_url, account_name, account_created, subscription_id, resource_group_name, website_name):
|
||||
summary = '\n'
|
||||
step_ids = final_status.deployment_step_ids
|
||||
if not step_ids or len(step_ids) == 0: return None
|
||||
steps = {}
|
||||
for property in step_ids:
|
||||
steps[property.name] = property.value
|
||||
if not provisioning_configuration: return None
|
||||
|
||||
# Add the vsts account info
|
||||
account_created = False
|
||||
account_url = 'https://{}.visualstudio.com'.format(quote(account_name))
|
||||
if steps['AccountCreated'] == '0':
|
||||
if not account_created:
|
||||
summary += "The VSTS account '{}' was updated to handle the continuous delivery.\n".format(account_url)
|
||||
elif steps['AccountCreated'] == '1':
|
||||
account_created = True
|
||||
else:
|
||||
summary += "The VSTS account '{}' was created to handle the continuous delivery.\n".format(account_url)
|
||||
|
||||
# Add the subscription info
|
||||
|
@ -212,20 +212,20 @@ class ContinuousDeliveryManager(object):
|
|||
summary += website_url + '\n'
|
||||
|
||||
# setup the build url and release url
|
||||
if steps['ProjectId']:
|
||||
project_id = steps['ProjectId']
|
||||
build_url = ''
|
||||
if steps['BuildDefinitionId']:
|
||||
build_url = ''
|
||||
release_url = ''
|
||||
if provisioning_configuration.ci_configuration and provisioning_configuration.ci_configuration.project:
|
||||
project_id = provisioning_configuration.ci_configuration.project.id
|
||||
if provisioning_configuration.ci_configuration.build_definition:
|
||||
build_url = '{}/{}/_build?_a=simple-process&definitionId={}'.format(
|
||||
account_url, quote(project_id), quote(steps['BuildDefinitionId']))
|
||||
release_url = ''
|
||||
if steps['ReleaseDefinitionId']:
|
||||
account_url, quote(project_id), quote(provisioning_configuration.ci_configuration.build_definition.id))
|
||||
if provisioning_configuration.ci_configuration.release_definition:
|
||||
release_url = '{}/{}/_apps/hub/ms.vss-releaseManagement-web.hub-explorer?definitionId={}&_a=releases'.format(
|
||||
account_url, quote(project_id), quote(steps['ReleaseDefinitionId']))
|
||||
account_url, quote(project_id), quote(provisioning_configuration.ci_configuration.release_definition.id))
|
||||
|
||||
return ContinuousDeliveryResult(account_created, account_url, resource_group_name,
|
||||
subscription_id, website_name, website_url, summary,
|
||||
build_url, release_url, final_status)
|
||||
build_url, release_url, provisioning_configuration)
|
||||
|
||||
def _skip_update_progress(self, count, total, message):
|
||||
return
|
||||
|
@ -258,6 +258,6 @@ class ContinuousDeliveryResult(object):
|
|||
self.azure_subscription_id = subscription_id
|
||||
self.azure_website_name = website_name
|
||||
self.azure_continuous_delivery_url = cd_url
|
||||
self.status = "SUCCESS"
|
||||
self.status = 'SUCCESS'
|
||||
self.status_message = message
|
||||
self.status_details = final_status
|
||||
|
|
Загрузка…
Ссылка в новой задаче