forked from Azure/azure-sdk-for-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add KeyVaultAccessControlClient for data plane RBAC (Azure#13372)
- Loading branch information
1 parent
1c80ef6
commit 0787c6c
Showing
11 changed files
with
1,107 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
114 changes: 114 additions & 0 deletions
114
...ult/azure-keyvault-administration/azure/keyvault/administration/_access_control_client.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
# ------------------------------------ | ||
# Copyright (c) Microsoft Corporation. | ||
# Licensed under the MIT License. | ||
# ------------------------------------ | ||
from typing import TYPE_CHECKING | ||
|
||
from azure.core.tracing.decorator import distributed_trace | ||
|
||
from ._models import KeyVaultRoleAssignment, KeyVaultRoleDefinition | ||
from ._internal import KeyVaultClientBase | ||
|
||
if TYPE_CHECKING: | ||
from typing import Any, Union | ||
from uuid import UUID | ||
from azure.core.paging import ItemPaged | ||
|
||
|
||
class KeyVaultAccessControlClient(KeyVaultClientBase): | ||
"""Manages role-based access to Azure Key Vault. | ||
:param str vault_url: URL of the vault the client will manage. This is also called the vault's "DNS Name". | ||
:param credential: an object which can provide an access token for the vault, such as a credential from | ||
:mod:`azure.identity` | ||
""" | ||
|
||
# pylint:disable=protected-access | ||
|
||
@distributed_trace | ||
def create_role_assignment(self, role_scope, role_assignment_name, role_definition_id, principal_id, **kwargs): | ||
# type: (str, Union[str, UUID], str, str, **Any) -> KeyVaultRoleAssignment | ||
"""Create a role assignment. | ||
:param str role_scope: scope the role assignment will apply over | ||
:param role_assignment_name: a name for the role assignment. Must be a UUID. | ||
:type role_assignment_name: str or uuid.UUID | ||
:param str role_definition_id: ID of the role's definition | ||
:param str principal_id: Azure Active Directory object ID of the principal which will be assigned the role. The | ||
principal can be a user, service principal, or security group. | ||
:rtype: KeyVaultRoleAssignment | ||
""" | ||
create_parameters = self._client.role_assignments.models.RoleAssignmentCreateParameters( | ||
properties=self._client.role_assignments.models.RoleAssignmentProperties( | ||
principal_id=principal_id, role_definition_id=str(role_definition_id) | ||
) | ||
) | ||
assignment = self._client.role_assignments.create( | ||
vault_base_url=self._vault_url, | ||
scope=role_scope, | ||
role_assignment_name=role_assignment_name, | ||
parameters=create_parameters, | ||
**kwargs | ||
) | ||
return KeyVaultRoleAssignment._from_generated(assignment) | ||
|
||
@distributed_trace | ||
def delete_role_assignment(self, role_scope, role_assignment_name, **kwargs): | ||
# type: (str, Union[str, UUID], **Any) -> KeyVaultRoleAssignment | ||
"""Delete a role assignment. | ||
:param str role_scope: the assignment's scope, for example "/", "/keys", or "/keys/<specific key identifier>" | ||
:param role_assignment_name: the assignment's name. Must be a UUID. | ||
:type role_assignment_name: str or uuid.UUID | ||
:returns: the deleted assignment | ||
:rtype: KeyVaultRoleAssignment | ||
""" | ||
assignment = self._client.role_assignments.delete( | ||
vault_base_url=self._vault_url, scope=role_scope, role_assignment_name=str(role_assignment_name), **kwargs | ||
) | ||
return KeyVaultRoleAssignment._from_generated(assignment) | ||
|
||
@distributed_trace | ||
def get_role_assignment(self, role_scope, role_assignment_name, **kwargs): | ||
# type: (str, Union[str, UUID], **Any) -> KeyVaultRoleAssignment | ||
"""Get a role assignment. | ||
:param str role_scope: the assignment's scope, for example "/", "/keys", or "/keys/<specific key identifier>" | ||
:param role_assignment_name: the assignment's name. Must be a UUID. | ||
:type role_assignment_name: str or uuid.UUID | ||
:rtype: KeyVaultRoleAssignment | ||
""" | ||
assignment = self._client.role_assignments.get( | ||
vault_base_url=self._vault_url, scope=role_scope, role_assignment_name=str(role_assignment_name), **kwargs | ||
) | ||
return KeyVaultRoleAssignment._from_generated(assignment) | ||
|
||
@distributed_trace | ||
def list_role_assignments(self, role_scope, **kwargs): | ||
# type: (str, **Any) -> ItemPaged[KeyVaultRoleAssignment] | ||
"""List all role assignments for a scope. | ||
:param str role_scope: scope of the role assignments | ||
:rtype: ~azure.core.paging.ItemPaged[KeyVaultRoleAssignment] | ||
""" | ||
return self._client.role_assignments.list_for_scope( | ||
self._vault_url, | ||
role_scope, | ||
cls=lambda result: [KeyVaultRoleAssignment._from_generated(a) for a in result], | ||
**kwargs | ||
) | ||
|
||
@distributed_trace | ||
def list_role_definitions(self, role_scope, **kwargs): | ||
# type: (str, **Any) -> ItemPaged[KeyVaultRoleDefinition] | ||
"""List all role definitions applicable at and above a scope. | ||
:param str role_scope: scope of the role definitions | ||
:rtype: ~azure.core.paging.ItemPaged[KeyVaultRoleDefinition] | ||
""" | ||
return self._client.role_definitions.list( | ||
self._vault_url, | ||
role_scope, | ||
cls=lambda result: [KeyVaultRoleDefinition._from_generated(d) for d in result], | ||
**kwargs | ||
) |
167 changes: 167 additions & 0 deletions
167
sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_models.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
# ------------------------------------ | ||
# Copyright (c) Microsoft Corporation. | ||
# Licensed under the MIT License. | ||
# ------------------------------------ | ||
from typing import TYPE_CHECKING | ||
|
||
if TYPE_CHECKING: | ||
from typing import Any | ||
|
||
|
||
# pylint:disable=protected-access | ||
|
||
|
||
class KeyVaultPermission(object): | ||
"""Role definition permissions. | ||
:ivar list[str] actions: allowed actions | ||
:ivar list[str] not_actions: denied actions | ||
:ivar list[str] data_actions: allowed data actions | ||
:ivar list[str] not_data_actions: denied data actions | ||
""" | ||
|
||
def __init__(self, **kwargs): | ||
# type: (**Any) -> None | ||
self.actions = kwargs.get("actions") | ||
self.not_actions = kwargs.get("not_actions") | ||
self.data_actions = kwargs.get("data_actions") | ||
self.not_data_actions = kwargs.get("not_data_actions") | ||
|
||
@classmethod | ||
def _from_generated(cls, permissions): | ||
return cls( | ||
actions=permissions.actions, | ||
not_actions=permissions.not_actions, | ||
data_actions=permissions.data_actions, | ||
not_data_actions=permissions.not_data_actions, | ||
) | ||
|
||
|
||
class KeyVaultRoleAssignment(object): | ||
"""Represents the assignment to a principal of a role over a scope""" | ||
|
||
def __init__(self, **kwargs): | ||
# type: (**Any) -> None | ||
self._assignment_id = kwargs.get("assignment_id") | ||
self._name = kwargs.get("name") | ||
self._properties = kwargs.get("properties") | ||
self._type = kwargs.get("assignment_type") | ||
|
||
def __repr__(self): | ||
# type: () -> str | ||
return "KeyVaultRoleAssignment<{}>".format(self._assignment_id) | ||
|
||
@property | ||
def assignment_id(self): | ||
# type: () -> str | ||
"""unique identifier for this assignment""" | ||
return self._assignment_id | ||
|
||
@property | ||
def name(self): | ||
# type: () -> str | ||
"""name of the assignment""" | ||
return self._name | ||
|
||
@property | ||
def principal_id(self): | ||
# type: () -> str | ||
"""ID of the principal this assignment applies to. | ||
This maps to the ID inside the Active Directory. It can point to a user, service principal, or security group. | ||
""" | ||
return self._properties.principal_id | ||
|
||
@property | ||
def role_definition_id(self): | ||
# type: () -> str | ||
"""ID of the role's definition""" | ||
return self._properties.role_definition_id | ||
|
||
@property | ||
def scope(self): | ||
# type: () -> str | ||
"""scope of the assignment""" | ||
return self._properties.scope | ||
|
||
@property | ||
def type(self): | ||
# type: () -> str | ||
"""the type of this assignment""" | ||
return self._type | ||
|
||
@classmethod | ||
def _from_generated(cls, role_assignment): | ||
return cls( | ||
assignment_id=role_assignment.id, | ||
name=role_assignment.name, | ||
assignment_type=role_assignment.type, | ||
properties=KeyVaultRoleAssignmentProperties._from_generated(role_assignment.properties), | ||
) | ||
|
||
|
||
class KeyVaultRoleAssignmentProperties(object): | ||
def __init__(self, **kwargs): | ||
# type: (**Any) -> None | ||
self.principal_id = kwargs.get("principal_id") | ||
self.role_definition_id = kwargs.get("role_definition_id") | ||
self.scope = kwargs.get("scope") | ||
|
||
def __repr__(self): | ||
# type: () -> str | ||
return "KeyVaultRoleAssignmentProperties(principal_id={}, role_definition_id={}, scope={})".format( | ||
self.principal_id, self.role_definition_id, self.scope | ||
)[:1024] | ||
|
||
@classmethod | ||
def _from_generated(cls, role_assignment_properties): | ||
# the generated RoleAssignmentProperties and RoleAssignmentPropertiesWithScope | ||
# models differ only in that the latter has a "scope" attribute | ||
return cls( | ||
principal_id=role_assignment_properties.principal_id, | ||
role_definition_id=role_assignment_properties.role_definition_id, | ||
scope=getattr(role_assignment_properties, "scope", None), | ||
) | ||
|
||
|
||
class KeyVaultRoleDefinition(object): | ||
"""Role definition. | ||
:ivar str id: The role definition ID. | ||
:ivar str name: The role definition name. | ||
:ivar str type: The role definition type. | ||
:ivar str role_name: The role name. | ||
:ivar str description: The role definition description. | ||
:ivar str role_type: The role type. | ||
:ivar permissions: Role definition permissions. | ||
:vartype permissions: list[KeyVaultPermission] | ||
:ivar list[str] assignable_scopes: Role definition assignable scopes. | ||
""" | ||
|
||
def __init__(self, **kwargs): | ||
# type: (**Any) -> None | ||
self.id = kwargs.get("id") | ||
self.name = kwargs.get("name") | ||
self.role_name = kwargs.get("role_name") | ||
self.description = kwargs.get("description") | ||
self.role_type = kwargs.get("role_type") | ||
self.type = kwargs.get("type") | ||
self.permissions = kwargs.get("permissions") | ||
self.assignable_scopes = kwargs.get("assignable_scopes") | ||
|
||
def __repr__(self): | ||
# type: () -> str | ||
return "<KeyVaultRoleDefinition {}>".format(self.role_name)[:1024] | ||
|
||
@classmethod | ||
def _from_generated(cls, definition): | ||
return cls( | ||
assignable_scopes=definition.assignable_scopes, | ||
description=definition.description, | ||
id=definition.id, | ||
name=definition.name, | ||
permissions=[KeyVaultPermission._from_generated(p) for p in definition.permissions], | ||
role_name=definition.role_name, | ||
role_type=definition.role_type, | ||
type=definition.type, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.