def test_get_nodepool_snapshot(self): mock_snapshot = Mock() mock_snapshot_operations = Mock(get=Mock(return_value=mock_snapshot)) with patch("azext_aks_preview._helpers.get_nodepool_snapshots_client", return_value=mock_snapshot_operations): snapshot = get_nodepool_snapshot("mock_cli_ctx", "test_sub", "mock_rg", "mock_snapshot_name") self.assertEqual(snapshot, mock_snapshot) mock_snapshot_operations_2 = Mock(get=Mock( side_effect=AzureError("mock snapshot was not found"))) with patch("azext_aks_preview._helpers.get_nodepool_snapshots_client", return_value=mock_snapshot_operations_2), self.assertRaises( ResourceNotFoundError): get_nodepool_snapshot("mock_cli_ctx", "test_sub", "mock_rg", "mock_snapshot_name") http_response_error = HttpResponseError() http_response_error.status_code = 400 http_response_error.message = "test_error_msg" mock_snapshot_operations_3 = Mock(get=Mock( side_effect=http_response_error)) with patch("azext_aks_preview._helpers.get_nodepool_snapshots_client", return_value=mock_snapshot_operations_3), self.assertRaises( BadRequestError): get_nodepool_snapshot("mock_cli_ctx", "test_sub", "mock_rg", "mock_snapshot_name")
def test_get_snapshot(self): mock_snapshot = Mock() mock_snapshot_operations = Mock(get=Mock(return_value=mock_snapshot)) with patch("azure.cli.command_modules.acs._helpers.cf_snapshots", return_value=mock_snapshot_operations): snapshot = helpers.get_snapshot("mock_cli_ctx", "mock_rg", "mock_snapshot_name") self.assertEqual(snapshot, mock_snapshot) mock_snapshot_operations_2 = Mock(get=Mock( side_effect=AzureError("mock snapshot was not found"))) with patch("azure.cli.command_modules.acs._helpers.cf_snapshots", return_value=mock_snapshot_operations_2), self.assertRaises( ResourceNotFoundError): helpers.get_snapshot("mock_cli_ctx", "mock_rg", "mock_snapshot_name") http_response_error = HttpResponseError() http_response_error.status_code = 400 http_response_error.message = "test_error_msg" mock_snapshot_operations_3 = Mock(get=Mock( side_effect=http_response_error)) with patch("azure.cli.command_modules.acs._helpers.cf_snapshots", return_value=mock_snapshot_operations_3), self.assertRaises( BadRequestError): helpers.get_snapshot("mock_cli_ctx", "mock_rg", "mock_snapshot_name")
def unwrap_key(self, algorithm, encrypted_key, **kwargs): # type: (KeyWrapAlgorithm, bytes, **Any) -> UnwrapResult """Unwrap a key previously wrapped with the client's key. Requires the keys/unwrapKey permission. :param algorithm: wrapping algorithm to use :type algorithm: :class:`~azure.keyvault.keys.crypto.KeyWrapAlgorithm` :param bytes encrypted_key: the wrapped key :rtype: :class:`~azure.keyvault.keys.crypto.UnwrapResult` Example: .. code-block:: python from azure.keyvault.keys.crypto import KeyWrapAlgorithm result = client.unwrap_key(KeyWrapAlgorithm.rsa_oaep, wrapped_bytes) key = result.key """ local_key = self._get_local_key(**kwargs) if local_key and local_key.is_private_key(): if "unwrapKey" not in self._allowed_ops: raise AzureError("This client doesn't have 'keys/unwrapKey' permission") result = local_key.unwrap_key(encrypted_key, **kwargs) else: result = self._client.unwrap_key( vault_base_url=self._key_id.vault_url, key_name=self._key_id.name, key_version=self._key_id.version, algorithm=algorithm, value=encrypted_key, **kwargs ).result return UnwrapResult(key_id=self._key_id, algorithm=algorithm, key=result)
async def encrypt(self, algorithm: "EncryptionAlgorithm", plaintext: bytes, **kwargs: "Any") -> EncryptResult: """Encrypt bytes using the client's key. Requires the keys/encrypt permission. This method encrypts only a single block of data, whose size depends on the key and encryption algorithm. :param algorithm: encryption algorithm to use :type algorithm: :class:`~azure.keyvault.keys.crypto.EncryptionAlgorithm` :param bytes plaintext: bytes to encrypt :rtype: :class:`~azure.keyvault.keys.crypto.EncryptResult` Example: .. code-block:: python from azure.keyvault.keys.crypto import EncryptionAlgorithm # the result holds the ciphertext and identifies the encryption key and algorithm used result = client.encrypt(EncryptionAlgorithm.rsa_oaep, b"plaintext") ciphertext = result.ciphertext print(result.key_id) print(result.algorithm) """ local_key = await self._get_local_key(**kwargs) if local_key: if "encrypt" not in self._allowed_ops: raise AzureError("This client doesn't have 'keys/encrypt' permission") result = local_key.encrypt(plaintext, algorithm=algorithm.value) else: operation = await self._client.encrypt( self._key_id.vault_url, self._key_id.name, self._key_id.version, algorithm, plaintext, **kwargs ) result = operation.result return EncryptResult(key_id=self.key_id, algorithm=algorithm, ciphertext=result)
def send(self, request, **kwargs): # type: (PipelineRequest, Any) -> PipelineResponse if self._first: self._first = False request.body.seek(0,2) raise AzureError('fail on first') position = request.body.tell() assert position == 0 return HttpResponse(request, None)
def _raise_if_unsupported(self, operation, algorithm): # type: (KeyOperation, Algorithm) -> None if not self.supports(operation, algorithm): raise NotImplementedError( 'This key does not support the "{}" operation with algorithm "{}"' .format(operation, algorithm)) if operation not in self._allowed_ops: raise AzureError( 'This key does not allow the "{}" operation'.format(operation))
def on_response(self, request, response): if response.context.get('validate_content', False) and response.http_response.headers.get('content-md5'): computed_md5 = request.context.get('validate_content_md5') or \ encode_base64(StorageContentValidation.get_content_md5(response.http_response.body())) if response.http_response.headers['content-md5'] != computed_md5: raise AzureError( 'MD5 mismatch. Expected value is \'{0}\', computed value is \'{1}\'.'.format( response.http_response.headers['content-md5'], computed_md5), response=response.http_response )
def encrypt(self, algorithm, plaintext, **kwargs): # type: (EncryptionAlgorithm, bytes, **Any) -> EncryptResult # pylint:disable=line-too-long """ Encrypt bytes using the client's key. Requires the keys/encrypt permission. This method encrypts only a single block of data, the size of which depends on the key and encryption algorithm. :param algorithm: encryption algorithm to use :type algorithm: :class:`~azure.keyvault.keys.crypto.enums.EncryptionAlgorithm` :param bytes plaintext: bytes to encrypt :rtype: :class:`~azure.keyvault.keys.crypto.EncryptResult` Example: .. code-block:: python from azure.keyvault.keys.crypto import EncryptionAlgorithm # encrypt returns a tuple with the ciphertext and the metadata required to decrypt it key_id, algorithm, ciphertext, authentication_tag = client.encrypt(EncryptionAlgorithm.rsa_oaep, b"plaintext") """ local_key = self._get_local_key(**kwargs) if local_key: if "encrypt" not in self._allowed_ops: raise AzureError( "This client doesn't have 'keys/encrypt' permission") result = local_key.encrypt(plaintext, algorithm=algorithm.value) else: result = self._client.encrypt( vault_base_url=self._key_id.vault_endpoint, key_name=self._key_id.name, key_version=self._key_id.version, algorithm=algorithm, value=plaintext, **kwargs) if hasattr(result, 'tag'): tag = result.tag else: tag = None if hasattr(result, "iv"): iv = result.iv else: iv = None return EncryptResult(key_id=self.key_id, algorithm=algorithm, ciphertext=result.result, authentication_tag=None, iv=iv, tag=tag)
def send(self, request, **kwargs): # type: (PipelineRequest, Any) -> PipelineResponse if self._first: self._first = False request.body.seek(0, 2) raise AzureError('fail on first') position = request.body.tell() assert position == 0 response = create_http_response(http_response, request, None) response.status_code = 400 return response
def on_response(self, request, response): if response.context.get( "validate_content", False ) and response.http_response.headers.get("content-md5"): computed_md5 = request.context.get("validate_content_md5") or encode_base64( StorageContentValidation.get_content_md5(response.http_response.body()) ) if response.http_response.headers["content-md5"] != computed_md5: raise AzureError( "MD5 mismatch. Expected value is '{0}', computed value is '{1}'.".format( response.http_response.headers["content-md5"], computed_md5 ), response=response.http_response, )
def send(self, request, **kwargs): # type: (PipelineRequest, Any) -> PipelineResponse if self._first: self._first = False for value in request.files.values(): name, body = value[0], value[1] if name and body and hasattr(body, 'read'): body.seek(0,2) raise AzureError('fail on first') for value in request.files.values(): name, body = value[0], value[1] if name and body and hasattr(body, 'read'): position = body.tell() assert not position return HttpResponse(request, None)
def on_response(self, request, response): # raise exception if the echoed client request id from the service is not identical to the one we sent if self.request_id_header_name in response.http_response.headers: client_request_id = request.http_request.headers.get(self.request_id_header_name) if response.http_response.headers[self.request_id_header_name] != client_request_id: raise AzureError( "Echoed client request ID: {} does not match sent client request ID: {}. " "Service request ID: {}".format( response.http_response.headers[self.request_id_header_name], client_request_id, response.http_response.headers['x-ms-request-id']), response=response.http_response )
def encrypt(self, algorithm, plaintext, **kwargs): # type: (EncryptionAlgorithm, bytes, **Any) -> EncryptResult """Encrypt bytes using the client's key. Requires the keys/encrypt permission. This method encrypts only a single block of data, whose size depends on the key and encryption algorithm. :param algorithm: encryption algorithm to use :type algorithm: :class:`~azure.keyvault.keys.crypto.EncryptionAlgorithm` :param bytes plaintext: bytes to encrypt :rtype: :class:`~azure.keyvault.keys.crypto.EncryptResult` Example: .. code-block:: python from azure.keyvault.keys.crypto import EncryptionAlgorithm # the result holds the ciphertext and identifies the encryption key and algorithm used result = client.encrypt(EncryptionAlgorithm.rsa_oaep, b"plaintext") ciphertext = result.ciphertext print(result.key_id) print(result.algorithm) """ local_key = self._get_local_key(**kwargs) if local_key: _enforce_nbf_exp(self._key) if "encrypt" not in self._allowed_ops: raise AzureError( "This client doesn't have 'keys/encrypt' permission") result = local_key.encrypt(plaintext, algorithm=algorithm.value) else: parameters = self._models.KeyOperationsParameters( algorithm=algorithm, value=plaintext) result = self._client.encrypt( vault_base_url=self._key_id.vault_url, key_name=self._key_id.name, key_version=self._key_id.version, parameters=parameters, **kwargs).result return EncryptResult(key_id=self.key_id, algorithm=algorithm, ciphertext=result)
async def verify(self, algorithm: "SignatureAlgorithm", digest: bytes, signature: bytes, **kwargs: "Any") -> VerifyResult: """Verify a signature using the client's key. Requires the keys/verify permission. :param algorithm: verification algorithm :type algorithm: :class:`~azure.keyvault.keys.crypto.SignatureAlgorithm` :param bytes digest: Pre-hashed digest corresponding to **signature**. The hash algorithm used must be compatible with **algorithm**. :param bytes signature: signature to verify :rtype: :class:`~azure.keyvault.keys.crypto.VerifyResult` Example: .. code-block:: python from azure.keyvault.keys.crypto import SignatureAlgorithm verified = await client.verify(SignatureAlgorithm.rs256, digest, signature) assert verified.is_valid """ local_key = await self._get_local_key(**kwargs) if local_key: if "verify" not in self._allowed_ops: raise AzureError( "This client doesn't have 'keys/verify' permission") result = local_key.verify(digest, signature, algorithm=algorithm.value) else: parameters = self._models.KeyVerifyParameters(algorithm=algorithm, digest=digest, signature=signature) operation = await self._client.verify( vault_base_url=self._key_id.vault_url, key_name=self._key_id.name, key_version=self._key_id.version, parameters=parameters, **kwargs) result = operation.value return VerifyResult(key_id=self.key_id, algorithm=algorithm, is_valid=result)
def wrap_key(self, algorithm, key, **kwargs): # type: (KeyWrapAlgorithm, bytes, **Any) -> WrapResult """Wrap a key with the client's key. Requires the keys/wrapKey permission. :param algorithm: wrapping algorithm to use :type algorithm: :class:`~azure.keyvault.keys.crypto.KeyWrapAlgorithm` :param bytes key: key to wrap :rtype: :class:`~azure.keyvault.keys.crypto.WrapResult` Example: .. code-block:: python from azure.keyvault.keys.crypto import KeyWrapAlgorithm # the result holds the encrypted key and identifies the encryption key and algorithm used result = client.wrap_key(KeyWrapAlgorithm.rsa_oaep, key_bytes) encrypted_key = result.encrypted_key print(result.key_id) print(result.algorithm) """ local_key = self._get_local_key(**kwargs) if local_key: _enforce_nbf_exp(self._key) if "wrapKey" not in self._allowed_ops: raise AzureError( "This client doesn't have 'keys/wrapKey' permission") result = local_key.wrap_key(key, algorithm=algorithm.value) else: parameters = self._models.KeyOperationsParameters( algorithm=algorithm, value=key, ) result = self._client.wrap_key(self._key_id.vault_url, self._key_id.name, self._key_id.version, parameters=parameters).result return WrapResult(key_id=self.key_id, algorithm=algorithm, encrypted_key=result)
async def wrap_key(self, algorithm: "KeyWrapAlgorithm", key: bytes, **kwargs: "Any") -> WrapResult: """ Wrap a key with the client's key. Requires the keys/wrapKey permission. :param algorithm: wrapping algorithm to use :type algorithm: :class:`~azure.keyvault.keys.crypto.enums.KeyWrapAlgorithm` :param bytes key: key to wrap :rtype: :class:`~azure.keyvault.keys.crypto.WrapResult` Example: .. code-block:: python from azure.keyvault.keys.crypto import KeyWrapAlgorithm # the result holds the encrypted key and identifies the encryption key and algorithm used result = await client.wrap_key(KeyWrapAlgorithm.rsa_oaep, key_bytes) encrypted_key = result.encrypted_key print(result.key_id) print(result.algorithm) """ local_key = await self._get_local_key(**kwargs) if local_key: if "wrapKey" not in self._allowed_ops: raise AzureError( "This client doesn't have 'keys/wrapKey' permission") result = local_key.wrap_key(key, algorithm=algorithm.value) else: operation = await self._client.wrap_key( self._key_id.vault_endpoint, self._key_id.name, self._key_id.version, algorithm=algorithm, value=key, **kwargs) result = operation.result return WrapResult(key_id=self.key_id, algorithm=algorithm, encrypted_key=result)
def verify(self, algorithm, digest, signature, **kwargs): # type: (SignatureAlgorithm, bytes, bytes, **Any) -> VerifyResult """Verify a signature using the client's key. Requires the keys/verify permission. :param algorithm: verification algorithm :type algorithm: :class:`~azure.keyvault.keys.crypto.SignatureAlgorithm` :param bytes digest: :param bytes signature: :rtype: :class:`~azure.keyvault.keys.crypto.VerifyResult` Example: .. code-block:: python from azure.keyvault.keys.crypto import SignatureAlgorithm verified = client.verify(SignatureAlgorithm.rs256, digest, signature) assert verified.is_valid """ local_key = self._get_local_key(**kwargs) if local_key: if "verify" not in self._allowed_ops: raise AzureError( "This client doesn't have 'keys/verify' permission") result = local_key.verify(digest, signature, algorithm=algorithm.value) else: parameters = self._models.KeyVerifyParameters(algorithm=algorithm, digest=digest, signature=signature) result = self._client.verify(vault_base_url=self._key_id.vault_url, key_name=self._key_id.name, key_version=self._key_id.version, parameters=parameters, **kwargs).value return VerifyResult(key_id=self.key_id, algorithm=algorithm, is_valid=result)
async def encrypt(self, algorithm: "EncryptionAlgorithm", plaintext: bytes, **kwargs: "Any") -> EncryptResult: # pylint:disable=line-too-long """ Encrypt bytes using the client's key. Requires the keys/encrypt permission. This method encrypts only a single block of data, the size of which depends on the key and encryption algorithm. :param algorithm: encryption algorithm to use :type algorithm: :class:`~azure.keyvault.keys.crypto.enums.EncryptionAlgorithm` :param bytes plaintext: bytes to encrypt :rtype: :class:`~azure.keyvault.keys.crypto.EncryptResult` Example: .. code-block:: python from azure.keyvault.keys.crypto import EncryptionAlgorithm # encrypt returns a tuple with the ciphertext and the metadata required to decrypt it key_id, algorithm, ciphertext, authentication_tag = await client.encrypt(EncryptionAlgorithm.rsa_oaep, b"plaintext") """ local_key = await self._get_local_key(**kwargs) if local_key: if "encrypt" not in self._allowed_ops: raise AzureError( "This client doesn't have 'keys/encrypt' permission") result = local_key.encrypt(plaintext, algorithm=algorithm.value) else: result = await self._client.encrypt(self._key_id.vault_url, self._key_id.name, self._key_id.version, algorithm, plaintext, **kwargs).result return EncryptResult(key_id=self.key_id, algorithm=algorithm, ciphertext=result, authentication_tag=None)
async def verify(self, algorithm: "SignatureAlgorithm", digest: bytes, signature: bytes, **kwargs: "**Any") -> VerifyResult: """ Verify a signature using the client's key. Requires the keys/verify permission. :param algorithm: verification algorithm :type algorithm: :class:`~azure.keyvault.keys.crypto.enums.SignatureAlgorithm` :param bytes digest: :param bytes signature: :rtype: :class:`~azure.keyvault.keys.crypto.VerifyResult` Example: .. code-block:: python from azure.keyvault.keys.crypto import SignatureAlgorithm verified = await client.verify(SignatureAlgorithm.rs256, digest, signature) assert verified.result is True """ local_key = await self._get_local_key(**kwargs) if local_key: if "verify" not in self._allowed_ops: raise AzureError( "This client doesn't have 'keys/verify' permission") result = local_key.verify(digest, signature, algorithm=algorithm.value) else: result = await self._client.verify( vault_base_url=self._key_id.vault_endpoint, key_name=self._key_id.name, key_version=self._key_id.version, algorithm=algorithm, digest=digest, signature=signature, **kwargs).value return VerifyResult(result=result)
async def unwrap_key(self, algorithm: "KeyWrapAlgorithm", encrypted_key: bytes, **kwargs: "Any") -> UnwrapResult: """Unwrap a key previously wrapped with the client's key. Requires the keys/unwrapKey permission. :param algorithm: wrapping algorithm to use :type algorithm: :class:`~azure.keyvault.keys.crypto.KeyWrapAlgorithm` :param bytes encrypted_key: the wrapped key :rtype: :class:`~azure.keyvault.keys.crypto.UnwrapResult` Example: .. code-block:: python from azure.keyvault.keys.crypto import KeyWrapAlgorithm result = await client.unwrap_key(KeyWrapAlgorithm.rsa_oaep, wrapped_bytes) key = result.key """ local_key = await self._get_local_key(**kwargs) if local_key and local_key.is_private_key(): if "unwrapKey" not in self._allowed_ops: raise AzureError( "This client doesn't have 'keys/unwrapKey' permission") result = local_key.unwrap_key(encrypted_key, **kwargs) else: parameters = self._models.KeyOperationsParameters( algorithm=algorithm, value=encrypted_key) operation = await self._client.unwrap_key(self._key_id.vault_url, self._key_id.name, self._key_id.version, parameters=parameters, **kwargs) result = operation.result return UnwrapResult(key_id=self._key_id, algorithm=algorithm, key=result)
def wrap_key(self, algorithm, key, **kwargs): # type: (KeyWrapAlgorithm, bytes, **Any) -> WrapKeyResult """ Wrap a key with the client's key. Requires the keys/wrapKey permission. :param algorithm: wrapping algorithm to use :type algorithm: :class:`~azure.keyvault.keys.crypto.enums.KeyWrapAlgorithm` :param bytes key: key to wrap :rtype: :class:`~azure.keyvault.keys.crypto.WrapKeyResult` Example: .. code-block:: python from azure.keyvault.keys.crypto import KeyWrapAlgorithm # wrap returns a tuple with the wrapped bytes and the metadata required to unwrap the key key_id, wrap_algorithm, wrapped_bytes = client.wrap_key(KeyWrapAlgorithm.rsa_oaep, key_bytes) """ local_key = self._get_local_key(**kwargs) if local_key: if "wrapKey" not in self._allowed_ops: raise AzureError( "This client doesn't have 'keys/wrapKey' permission") result = local_key.wrap_key(key, algorithm=algorithm.value) else: result = self._client.wrap_key(self._key_id.vault_endpoint, self._key_id.name, self._key_id.version, algorithm=algorithm, value=key, **kwargs).result return WrapKeyResult(key_id=self.key_id, algorithm=algorithm, encrypted_key=result)
def send(*args): raise AzureError('boo')
def raise_if_incorrect_key_size(algorithm, key_size): if algorithm._key_size >> 3 != key_size: # pylint:disable=protected-access raise AzureError( "Invalid AES encryption algorithm for key size. The algorithm must match the size of the key." )
def test_azure_error(self): azure_error = AzureError("test_error_msg") cli_error = helpers.map_azure_error_to_cli_error(azure_error) mock_error = ServiceError("test_error_msg") self.check_error_equality(cli_error, mock_error)
def begin_create_or_update(self, resource_group_name: str, vm_name: str, parameters: Dict[str, Any] ) -> WaitableObject: tags = parameters.pop("tags") if "tags" in parameters else {} parameters = dict_keys_to_camel_case(parameters) location = parameters.pop("location") priority = parameters.get("priority") or "" if tags.get("JenkinsJobTag") == "FailSpotDB" and priority.lower() == "spot" and tags.get("NodeType") == "scylla-db": # for testing fallback on demand raise AzureError("Failing creating db spot instance because JenkinsJobTag is FailSpotDB") base = { "id": f"/subscriptions/6c268694-47ab-43ab-b306-3c5514bc4112/resourceGroups/{resource_group_name}" f"/providers/Microsoft.Compute/virtualMachines/{vm_name}", "name": vm_name, "type": "Microsoft.Compute/virtualMachines", "location": location, "properties": { "hardwareProfile": { "vmSize": "Standard_D2_v5" }, "storageProfile": { "imageReference": { "publisher": "OpenLogic", "offer": "CentOS", "sku": "7.5", "version": "latest", "exactVersion": "7.5.201808150" }, "osDisk": { "osType": "Linux", "name": "lukasz-3_OsDisk_1_7fcdd979aec64c40b5b153bfe9daed35", "caching": "ReadWrite", "createOption": "FromImage", "diskSizeGB": 30, "managedDisk": { "id": f"/subscriptions/6c268694-47ab-43ab-b306-3c5514bc4112/resourceGroups" f"/{resource_group_name}/providers/Microsoft.Compute/disks" f"/{vm_name}_OsDisk_1_7fcdd979aec64c40b5b153bfe9daed35", "storageAccountType": "Standard_LRS" }, "deleteOption": "Detach" }, "dataDisks": [] }, "osProfile": { "computerName": "lukasz-3", "adminUsername": "******", "linuxConfiguration": { "disablePasswordAuthentication": True, "ssh": { "publicKeys": [ { "path": "/home/lukasz/.ssh/authorized_keys", "keyData": "ssh-rsa fake_key_data== scylla-qa-ec2\n" } ] }, "provisionVMAgent": True, "patchSettings": { "patchMode": "ImageDefault", "assessmentMode": "ImageDefault" } }, "secrets": [], "allowExtensionOperations": True, "requireGuestProvisionSignal": True }, "networkProfile": { "networkInterfaces": [ { "id": f"/subscriptions/6c268694-47ab-43ab-b306-3c5514bc4112/resourceGroups" f"/{resource_group_name}/providers/Microsoft.Network/networkInterfaces/lukasz-3-nic", "properties": { "deleteOption": "Delete" } } ] }, "provisioningState": "Succeeded", "vmId": "ce7b8d6c-4204-4262-9504-862189431e5d" } } base["properties"].update(**parameters) base["tags"] = tags with open(self.path / resource_group_name / f"vm-{vm_name}.json", "w", encoding="utf-8") as file: json.dump(base, fp=file, indent=2) return WaitableObject()