Skip to content

Commit

Permalink
Service Endpoint update command to set pipeline access property (#897)
Browse files Browse the repository at this point in the history
* Service Endpoint update command to set pipeline access property

* Adding tests
  • Loading branch information
atbagga committed Nov 27, 2019
1 parent bc777c5 commit d536de6
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 2 deletions.
18 changes: 18 additions & 0 deletions azure-devops/azext_devops/dev/team/_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,24 @@ def _transform_service_endpoint_row(row):
return table_row


def transform_authorized_service_endpoint_table_output(result):
table_output = []
table_output.append(_transform_authorized_service_endpoint_row(result))
return table_output


def _transform_authorized_service_endpoint_row(row):
table_row = OrderedDict()
table_row['ID'] = row['id']
table_row['Allow Pipelines'] = row['authorized']
table_row['Name'] = row['name']
table_row['Type'] = row['type']
table_row['Is Ready'] = row['isReady']
table_row['Created By'] = row['createdBy']['displayName']

return table_row


def transform_groups_table_output(result):
table_output = []
if result['continuationToken'] is not None:
Expand Down
5 changes: 5 additions & 0 deletions azure-devops/azext_devops/dev/team/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ def load_team_arguments(self, _):
help='Encoding of the input file.',
**enum_choice_list(_FILE_ENCODING_TYPE_VALUES))

with self.argument_context('devops service-endpoint update') as context:
context.argument('enable_for_all',
help='Allow all pipelines to access this service endpoint.',
arg_type=get_three_state_flag())

with self.argument_context('devops invoke') as context:
context.argument('route_parameters', nargs='*',
help='Specifies the list of route parameters')
Expand Down
3 changes: 3 additions & 0 deletions azure-devops/azext_devops/dev/team/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from ._format import (transform_project_table_output,
transform_projects_table_output,
transform_service_endpoints_table_output,
transform_authorized_service_endpoint_table_output,
transform_groups_table_output,
transform_group_table_output,
transform_memberships_table_output,
Expand Down Expand Up @@ -111,6 +112,8 @@ def load_team_commands(self, _):
g.command('list', 'list_service_endpoints', table_transformer=transform_service_endpoints_table_output)
g.command('show', 'show_service_endpoint') # no table transform because type is not well defined
g.command('create', 'create_service_endpoint', is_preview=True)
g.command('update', 'update_service_endpoint', is_preview=True,
table_transformer=transform_authorized_service_endpoint_table_output)
g.command('azurerm create', 'create_azurerm_service_endpoint')
g.command('github create', 'create_github_service_endpoint')
g.command('delete', 'delete_service_endpoint',
Expand Down
51 changes: 51 additions & 0 deletions azure-devops/azext_devops/dev/team/service_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import os
from knack.log import get_logger
from knack.prompting import prompt_pass
from knack.util import CLIError
from azext_devops.devops_sdk.v5_0.service_endpoint.models import ServiceEndpoint, EndpointAuthorization
from azext_devops.dev.common.services import get_service_endpoint_client, resolve_instance_and_project
from azext_devops.dev.common.const import CLI_ENV_VARIABLE_PREFIX, AZ_DEVOPS_GITHUB_PAT_ENVKEY
Expand All @@ -21,6 +22,32 @@
logger = get_logger(__name__)


# pylint: disable=too-few-public-methods, too-many-instance-attributes
class ServiceEndpointAuthorized():
_attribute_map = {
'service_endpoint_parameters': {'key': 'service_endpoint_parameters', 'type': 'ServiceEndpoint'},
'authorized': {'key': 'authorized', 'type': 'bool'}
}

def __init__(self, service_endpoint_parameters, authorized):
self.authorized = authorized if authorized is not None else False
self.administratorsGroup = service_endpoint_parameters.administrators_group
self.authorization = service_endpoint_parameters.authorization
self.createdBy = service_endpoint_parameters.created_by
self.data = service_endpoint_parameters.data
self.description = service_endpoint_parameters.description
self.groupScopeId = service_endpoint_parameters.group_scope_id
self.id = service_endpoint_parameters.id
self.isReady = service_endpoint_parameters.is_ready
self.isShared = service_endpoint_parameters.is_shared
self.name = service_endpoint_parameters.name
self.operationStatus = service_endpoint_parameters.operation_status
self.owner = service_endpoint_parameters.owner
self.readersGroup = service_endpoint_parameters.readers_group
self.type = service_endpoint_parameters.type
self.url = service_endpoint_parameters.url


def list_service_endpoints(organization=None, project=None, detect=None):
"""List service endpoints in a project.
:rtype: list of :class:`VssJsonCollectionWrapper <service_endpoint.v4_1.models.ServiceEndpoint>`
Expand Down Expand Up @@ -172,3 +199,27 @@ def create_service_endpoint(service_endpoint_configuration,
import json
service_endpoint_to_create = json.loads(in_file_content)
return client.create_service_endpoint(service_endpoint_to_create, project)


def update_service_endpoint(id, enable_for_all=None, organization=None, # pylint: disable=redefined-builtin
project=None, detect=None):
"""Update a service endpoint
:param id: ID of the service endpoint.
:type id: str
"""
if enable_for_all is None:
raise CLIError('Atleast one property to be updated must be specified.')
organization, project = resolve_instance_and_project(detect=detect,
organization=organization,
project=project)
client = get_service_endpoint_client(organization)
se = client.get_service_endpoint_details(project, id)

# set authorization if get service endpoint succeeded
from azext_devops.dev.pipelines.pipeline_utils import set_authorize_resource, get_authorize_resource
set_authorize_resource(
authorized=enable_for_all, res_id=se.id, name=se.name, res_type='endpoint',
organization=organization, project=project)

authorized = get_authorize_resource(res_id=se.id, res_type='endpoint', organization=organization, project=project)
return ServiceEndpointAuthorized(service_endpoint_parameters=se, authorized=authorized)
31 changes: 29 additions & 2 deletions azure-devops/azext_devops/test/team/test_service_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
create_service_endpoint,
create_github_service_endpoint,
create_azurerm_service_endpoint,
delete_service_endpoint)
delete_service_endpoint,
update_service_endpoint)

from azext_devops.dev.common.services import clear_connection_cache
from azext_devops.test.utils.authentication import AuthenticatedTests
Expand All @@ -39,12 +40,16 @@ def setUp(self):
self.get_SE_details_patcher = patch('azext_devops.devops_sdk.v5_0.service_endpoint.service_endpoint_client.ServiceEndpointClient.get_service_endpoint_details')
self.create_SE_patcher = patch('azext_devops.devops_sdk.v5_0.service_endpoint.service_endpoint_client.ServiceEndpointClient.create_service_endpoint')
self.delete_SE_patcher = patch('azext_devops.devops_sdk.v5_0.service_endpoint.service_endpoint_client.ServiceEndpointClient.delete_service_endpoint')
self.set_authorize_endpoint = patch('azext_devops.dev.pipelines.pipeline_utils.set_authorize_resource')
self.get_authorize_endpoint = patch('azext_devops.dev.pipelines.pipeline_utils.get_authorize_resource')

self.mock_get_client = self.get_client.start()
self.mock_get_SEs = self.get_SEs_patcher.start()
self.mock_get_SE_detail = self.get_SE_details_patcher.start()
self.mock_create_SE = self.create_SE_patcher.start()
self.mock_delete_SE = self.delete_SE_patcher.start()
self.mock_set_authorize = self.set_authorize_endpoint.start()
self.mock_get_authorize = self.get_authorize_endpoint.start()

#clear connection cache before running each test
clear_connection_cache()
Expand All @@ -70,7 +75,29 @@ def test_delete_service_endpoint(self):
delete_service_endpoint(randomId, 'false', self._TEST_DEVOPS_ORGANIZATION, self._TEST_PROJECT_NAME)

#assert
self.mock_delete_SE(self._TEST_PROJECT_NAME, randomId, 'false')
self.mock_delete_SE.assert_called_once_with(self._TEST_PROJECT_NAME, randomId, 'false')

def test_update_service_endpoint(self):
randomId = 'abcdfe34343'
update_service_endpoint(id=randomId, enable_for_all=True, organization=self._TEST_DEVOPS_ORGANIZATION,
project=self._TEST_PROJECT_NAME)

#assert
self.mock_get_SE_detail.assert_called_once_with(self._TEST_PROJECT_NAME, randomId)
self.mock_set_authorize.assert_called_once()
self.mock_get_authorize.assert_called_once()


def test_update_without_params_service_endpoint(self):
randomId = 'abcdfe34343'
try:
update_service_endpoint(id=randomId, enable_for_all=None, organization=self._TEST_DEVOPS_ORGANIZATION,
project=self._TEST_PROJECT_NAME)
except CLIError as ex:
self.assertEqual(str(ex), 'Atleast one property to be updated must be specified.')
self.mock_get_SE_detail.assert_not_called()
self.mock_set_authorize.assert_not_called()
self.mock_get_authorize.assert_not_called()

def test_create_service_endpoint_github(self):
import os
Expand Down

0 comments on commit d536de6

Please sign in to comment.