-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial immudb_wrapper implementation
- Loading branch information
Showing
4 changed files
with
713 additions
and
3 deletions.
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
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 |
---|---|---|
@@ -1,2 +1,300 @@ | ||
# immudb-wrapper | ||
The wrapper around Python Codetorary Immudb client. | ||
# immudb_wrapper | ||
|
||
The wrapper around the SDK client `immudb-py` from project Codenotary, which expands the functionality of the original client with additional functions. | ||
|
||
## Table of Contents | ||
|
||
- [Requirements](#requirements) | ||
- [Installation](#installation) | ||
- [Usage](#usage) | ||
- [Contribution](#contribution) | ||
|
||
## Requirements | ||
|
||
- python >= 3.7 | ||
- immudb-py >= 1.4.0 | ||
- GitPython >= 3.1.20 | ||
|
||
## Installation | ||
|
||
You can easily install `immudb_wrapper` into your environment with the following command: | ||
|
||
``` | ||
pip install git+https://git.almalinux.org/danfimov/immudb_wrapper.git@<tag|branch>#egg=immudb_wrapper | ||
``` | ||
|
||
To run the `immudb` instance locally, you can use the options from `immudb` [documentation](https://docs.immudb.io/master/running/download.html). | ||
|
||
If you want to use the `immudb` in `docker-compose.yml`, you can add the following in your compose file: | ||
|
||
``` | ||
immudb: | ||
image: codenotary/immudb:latest | ||
ports: | ||
- 3322:3322 | ||
- 9497:9497 | ||
volumes: | ||
- "../volumes/immudb/data:/var/lib/immudb" | ||
- "../volumes/immudb/config:/etc/immudb" | ||
- "../volumes/immudb/logs:/var/log/immudb" | ||
``` | ||
|
||
## Usage | ||
|
||
### Client initialization | ||
|
||
```python3 | ||
client = ImmudbWrapper( | ||
username="user", | ||
password="password", | ||
database="database", | ||
) | ||
``` | ||
|
||
### File notarization | ||
|
||
This method calculates the file hash and file size and inserts them with the user's metadata (if provided), into the database. | ||
|
||
```python3 | ||
response = client.notarize_file( | ||
"./hello_world.sh", | ||
user_metadata={ | ||
"foo": "bar", | ||
}, | ||
) | ||
print(response) | ||
{ | ||
'id': 1, | ||
'key': '4db5767d4bf4221a5656b163ef1bae833095255f80d1ad5be21dfef84caf4126', | ||
'value': { | ||
'Name': 'hello_world.sh', | ||
'Kind': 'file', | ||
'Size': '2.62 KB', | ||
'Hash': '4db5767d4bf4221a5656b163ef1bae833095255f80d1ad5be21dfef84caf4126', | ||
'Metadata': { | ||
'sbom_api_ver': '0.2', | ||
'foo': 'bar', | ||
}, | ||
}, | ||
'timestamp': 1690794033, | ||
'verified': True, | ||
'refkey': None, | ||
'revision': 1, | ||
} | ||
``` | ||
|
||
### Git repo notarization | ||
|
||
This method extracts the git metadata from a provided git directory, calculates the hash of the extracted metadata and inserts that metadata with the user's metadata (if provided), into the database. Falls with a `InvalidGitRepositoryError` when accepting non-git directories. | ||
|
||
```python3 | ||
response = client.notarize_git_repo( | ||
"./immudb_wrapper/", | ||
user_metadata={ | ||
"foo": "bar", | ||
}, | ||
) | ||
print(response) | ||
{ | ||
'id': 2, | ||
'key': 'a87f7a948900e04812c095fb457e994926fc28c2a789471521fcc076cc4d8658', | ||
'value': { | ||
'Name': '[email protected]:danfimov/immudb_wrapper.git@c093e0f', | ||
'Kind': 'git', | ||
'Size': '30.52 KB', | ||
'Hash': 'a87f7a948900e04812c095fb457e994926fc28c2a789471521fcc076cc4d8658', | ||
'Metadata': { | ||
'git': { | ||
'Author': { | ||
'Email': '[email protected]', | ||
'Name': 'Daniil Anfimov', | ||
'When': '2023-07-22T12:53:22+0200', | ||
}, | ||
'Commit': 'c093e0f468c2810f76d4c09c340c58380bd965b1', | ||
'Committer': { | ||
'Email': '[email protected]', | ||
'Name': 'Daniil Anfimov', | ||
'When': '2023-07-22T12:53:22+0200', | ||
}, | ||
'Message': 'Initial commit\n', | ||
'PGPSignature': '', | ||
'Parents': [], | ||
'Tree': '4526550b9c6b77e7e10f6e57dfecfe0504c5166f', | ||
}, | ||
'sbom_api_ver': '0.2', | ||
'foo': 'bar', | ||
}, | ||
}, | ||
'timestamp': 1690794260, | ||
'verified': True, | ||
'refkey': None, | ||
'revision': 1, | ||
} | ||
``` | ||
|
||
### Git repo authentication | ||
|
||
This method extracts the git metadata from a provided git directory, calculates the hash of the extracted metadata, and looks up the metadata of that hash in the database. Returns a dict with an error if metadata doesn't exist in the database. | ||
|
||
```python3 | ||
response = client.authenticate_git_repo("./immudb_wrapper/") | ||
print(response) | ||
{ | ||
'id': 2, | ||
'key': 'a87f7a948900e04812c095fb457e994926fc28c2a789471521fcc076cc4d8658', | ||
'value': { | ||
'Name': '[email protected]:danfimov/immudb_wrapper.git@c093e0f', | ||
'Kind': 'git', | ||
'Size': '30.52 KB', | ||
'Hash': 'a87f7a948900e04812c095fb457e994926fc28c2a789471521fcc076cc4d8658', | ||
'Metadata': { | ||
'git': { | ||
'Author': { | ||
'Email': '[email protected]', | ||
'Name': 'Daniil Anfimov', | ||
'When': '2023-07-22T12:53:22+0200', | ||
}, | ||
'Commit': 'c093e0f468c2810f76d4c09c340c58380bd965b1', | ||
'Committer': { | ||
'Email': '[email protected]', | ||
'Name': 'Daniil Anfimov', | ||
'When': '2023-07-22T12:53:22+0200', | ||
}, | ||
'Message': 'Initial commit\n', | ||
'PGPSignature': '', | ||
'Parents': [], | ||
'Tree': '4526550b9c6b77e7e10f6e57dfecfe0504c5166f', | ||
}, | ||
'sbom_api_ver': '0.2', | ||
'foo': 'bar', | ||
}, | ||
}, | ||
'timestamp': 1690794260, | ||
'verified': True, | ||
'refkey': None, | ||
'revision': 1, | ||
} | ||
|
||
response = client.authenticate_git_repo("./immudb_wrapper_foobar/") | ||
print(response) | ||
{'error': 'Traceback (most recent call last):\n' | ||
' File "/code/env/bin/immudb_wrapper.py", line 247, in ' | ||
'verified_get\n' | ||
' self.verifiedGet(\n' | ||
' File "/code/env/lib/python3.9/site-packages/immudb/client.py", ' | ||
'line 667, in verifiedGet\n' | ||
' return verifiedGet.call(self._stub, self._rs, key, ' | ||
'verifying_key=self._vk, atRevision=atRevision)\n' | ||
' File ' | ||
'"/code/env/lib/python3.9/site-packages/immudb/handler/verifiedGet.py", ' | ||
'line 30, in call\n' | ||
' ventry = service.VerifiableGet(req)\n' | ||
' File ' | ||
'"/code/env/lib64/python3.9/site-packages/grpc/_interceptor.py", ' | ||
'line 247, in __call__\n' | ||
' response, ignored_call = self._with_call(request,\n' | ||
' File ' | ||
'"/code/env/lib64/python3.9/site-packages/grpc/_interceptor.py", ' | ||
'line 290, in _with_call\n' | ||
' return call.result(), call\n' | ||
' File "/code/env/lib64/python3.9/site-packages/grpc/_channel.py", ' | ||
'line 379, in result\n' | ||
' raise self\n' | ||
' File ' | ||
'"/code/env/lib64/python3.9/site-packages/grpc/_interceptor.py", ' | ||
'line 274, in continuation\n' | ||
' response, call = self._thunk(new_method).with_call(\n' | ||
' File "/code/env/lib64/python3.9/site-packages/grpc/_channel.py", ' | ||
'line 1043, in with_call\n' | ||
' return _end_unary_response_blocking(state, call, True, None)\n' | ||
' File "/code/env/lib64/python3.9/site-packages/grpc/_channel.py", ' | ||
'line 910, in _end_unary_response_blocking\n' | ||
' raise _InactiveRpcError(state) # pytype: ' | ||
'disable=not-instantiable\n' | ||
'grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that ' | ||
'terminated with:\n' | ||
'\tstatus = StatusCode.UNKNOWN\n' | ||
'\tdetails = "tbtree: key not found"\n' | ||
'\tdebug_error_string = "UNKNOWN:Error received from peer ' | ||
'ipv4:172.18.0.2:3322 {grpc_message:"tbtree: key not found", ' | ||
'grpc_status:2, ' | ||
'created_time:"2023-07-31T09:13:55.947555151+00:00"}"\n' | ||
'>\n'} | ||
``` | ||
|
||
### File authentication | ||
|
||
This method calculates the file hash of the provided file and looks up the metadata of that hash in the database. Returns a dict with an error if metadata doesn't exist in the database. | ||
|
||
```python3 | ||
response = client.authenticate_file("./hello_world.sh") | ||
print(response) | ||
{ | ||
'id': 1, | ||
'key': '4db5767d4bf4221a5656b163ef1bae833095255f80d1ad5be21dfef84caf4126', | ||
'value': { | ||
'Name': 'hello_world.sh', | ||
'Kind': 'file', | ||
'Size': '2.62 KB', | ||
'Hash': '4db5767d4bf4221a5656b163ef1bae833095255f80d1ad5be21dfef84caf4126', | ||
'Metadata': { | ||
'sbom_api_ver': '0.2', | ||
'foo': 'bar', | ||
}, | ||
}, | ||
'timestamp': 1690794033, | ||
'verified': True, | ||
'refkey': None, | ||
'revision': 1, | ||
} | ||
|
||
response = client.authenticate_file("./hello_world1.sh") | ||
print(response) | ||
{'error': 'Traceback (most recent call last):\n' | ||
' File "/code/env/bin/immudb_wrapper.py", line 247, in ' | ||
'verified_get\n' | ||
' self.verifiedGet(\n' | ||
' File "/code/env/lib/python3.9/site-packages/immudb/client.py", ' | ||
'line 667, in verifiedGet\n' | ||
' return verifiedGet.call(self._stub, self._rs, key, ' | ||
'verifying_key=self._vk, atRevision=atRevision)\n' | ||
' File ' | ||
'"/code/env/lib/python3.9/site-packages/immudb/handler/verifiedGet.py", ' | ||
'line 30, in call\n' | ||
' ventry = service.VerifiableGet(req)\n' | ||
' File ' | ||
'"/code/env/lib64/python3.9/site-packages/grpc/_interceptor.py", ' | ||
'line 247, in __call__\n' | ||
' response, ignored_call = self._with_call(request,\n' | ||
' File ' | ||
'"/code/env/lib64/python3.9/site-packages/grpc/_interceptor.py", ' | ||
'line 290, in _with_call\n' | ||
' return call.result(), call\n' | ||
' File "/code/env/lib64/python3.9/site-packages/grpc/_channel.py", ' | ||
'line 379, in result\n' | ||
' raise self\n' | ||
' File ' | ||
'"/code/env/lib64/python3.9/site-packages/grpc/_interceptor.py", ' | ||
'line 274, in continuation\n' | ||
' response, call = self._thunk(new_method).with_call(\n' | ||
' File "/code/env/lib64/python3.9/site-packages/grpc/_channel.py", ' | ||
'line 1043, in with_call\n' | ||
' return _end_unary_response_blocking(state, call, True, None)\n' | ||
' File "/code/env/lib64/python3.9/site-packages/grpc/_channel.py", ' | ||
'line 910, in _end_unary_response_blocking\n' | ||
' raise _InactiveRpcError(state) # pytype: ' | ||
'disable=not-instantiable\n' | ||
'grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that ' | ||
'terminated with:\n' | ||
'\tstatus = StatusCode.UNKNOWN\n' | ||
'\tdetails = "tbtree: key not found"\n' | ||
'\tdebug_error_string = "UNKNOWN:Error received from peer ' | ||
'ipv4:172.18.0.2:3322 {grpc_message:"tbtree: key not found", ' | ||
'grpc_status:2, ' | ||
'created_time:"2023-07-31T09:13:55.947555151+00:00"}"\n' | ||
'>\n'} | ||
``` | ||
|
||
## Contribution | ||
|
||
If you wish to contribute to `immudb_wrapper`, just create a fork and make a PR. |
Oops, something went wrong.