infisicalsdk 1.0.3__tar.gz → 1.0.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of infisicalsdk might be problematic. Click here for more details.
- {infisicalsdk-1.0.3 → infisicalsdk-1.0.5}/PKG-INFO +1 -1
- {infisicalsdk-1.0.3 → infisicalsdk-1.0.5}/README.md +175 -21
- {infisicalsdk-1.0.3 → infisicalsdk-1.0.5}/infisical_sdk/api_types.py +70 -1
- {infisicalsdk-1.0.3 → infisicalsdk-1.0.5}/infisical_sdk/client.py +184 -4
- {infisicalsdk-1.0.3 → infisicalsdk-1.0.5}/infisical_sdk/infisical_requests.py +5 -5
- {infisicalsdk-1.0.3 → infisicalsdk-1.0.5}/infisicalsdk.egg-info/PKG-INFO +1 -1
- {infisicalsdk-1.0.3 → infisicalsdk-1.0.5}/setup.py +2 -2
- {infisicalsdk-1.0.3 → infisicalsdk-1.0.5}/infisical_sdk/__init__.py +0 -0
- {infisicalsdk-1.0.3 → infisicalsdk-1.0.5}/infisicalsdk.egg-info/SOURCES.txt +0 -0
- {infisicalsdk-1.0.3 → infisicalsdk-1.0.5}/infisicalsdk.egg-info/dependency_links.txt +0 -0
- {infisicalsdk-1.0.3 → infisicalsdk-1.0.5}/infisicalsdk.egg-info/requires.txt +0 -0
- {infisicalsdk-1.0.3 → infisicalsdk-1.0.5}/infisicalsdk.egg-info/top_level.txt +0 -0
- {infisicalsdk-1.0.3 → infisicalsdk-1.0.5}/pyproject.toml +0 -0
- {infisicalsdk-1.0.3 → infisicalsdk-1.0.5}/setup.cfg +0 -0
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
The Infisical SDK provides a convenient way to interact with the Infisical API.
|
|
4
4
|
|
|
5
|
-
### Migrating to version 1.0.
|
|
5
|
+
### Migrating to version 1.0.3 or above
|
|
6
6
|
|
|
7
|
-
We have recently rolled out our first stable version of the SDK, version `1.0.
|
|
7
|
+
We have recently rolled out our first stable version of the SDK, version `1.0.3` and above.
|
|
8
8
|
|
|
9
|
-
The 1.0.
|
|
9
|
+
The 1.0.3 version comes with a few key changes that may change how you're using the SDK.
|
|
10
10
|
1. **Removal of `rest`**: The SDK no longer exposes the entire Infisical API. This was nessecary as we have moved away from using an OpenAPI generator approach. We aim to add support for more API resources in the near future. If you have any specific requests, please [open an issue](https://github.com/Infisical/python-sdk-official/issues).
|
|
11
11
|
|
|
12
|
-
2. **New response types**: The 1.0.
|
|
12
|
+
2. **New response types**: The 1.0.3 release uses return types that differ from the older versions. The new return types such as `BaseSecret`, are all exported from the Infisical SDK.
|
|
13
13
|
|
|
14
14
|
3. **Property renaming**: Some properties on the responses have been slightly renamed. An example of this would be that the `secret_key` property on the `get_secret_by_name()` method, that has been renamed to `secretKey`.
|
|
15
15
|
|
|
16
|
-
With this in mind, you're ready to upgrade your SDK version to `1.0.
|
|
16
|
+
With this in mind, you're ready to upgrade your SDK version to `1.0.3` or above.
|
|
17
17
|
|
|
18
18
|
You can refer to our [legacy documentation](https://github.com/Infisical/python-sdk-official/tree/9b0403938ee5ae599d42c5f1fdf9158671a15606?tab=readme-ov-file#infisical-python-sdk) if need be.
|
|
19
19
|
|
|
@@ -36,10 +36,13 @@ from infisical_sdk import InfisicalSDKClient
|
|
|
36
36
|
client = InfisicalSDKClient(host="https://app.infisical.com")
|
|
37
37
|
|
|
38
38
|
# Authenticate (example using Universal Auth)
|
|
39
|
-
client.auth.universal_auth.login(
|
|
39
|
+
client.auth.universal_auth.login(
|
|
40
|
+
client_id="<machine-identity-client-id>",
|
|
41
|
+
client_secret="<machine-identity-client-secret>"
|
|
42
|
+
)
|
|
40
43
|
|
|
41
44
|
# Use the SDK to interact with Infisical
|
|
42
|
-
secrets = client.secrets.list_secrets(project_id="
|
|
45
|
+
secrets = client.secrets.list_secrets(project_id="<project-id>", environment_slug="dev", secret_path="/")
|
|
43
46
|
```
|
|
44
47
|
|
|
45
48
|
## Core Methods
|
|
@@ -56,13 +59,16 @@ The `Auth` component provides methods for authentication:
|
|
|
56
59
|
#### Universal Auth
|
|
57
60
|
|
|
58
61
|
```python
|
|
59
|
-
response = client.auth.universal_auth.login(
|
|
62
|
+
response = client.auth.universal_auth.login(
|
|
63
|
+
client_id="<machine-identity-client-id>",
|
|
64
|
+
client_secret="<machine-identity-client-secret>"
|
|
65
|
+
)
|
|
60
66
|
```
|
|
61
67
|
|
|
62
68
|
#### AWS Auth
|
|
63
69
|
|
|
64
70
|
```python
|
|
65
|
-
response = client.auth.aws_auth.login(identity_id="
|
|
71
|
+
response = client.auth.aws_auth.login(identity_id="<machine-identity-id>")
|
|
66
72
|
```
|
|
67
73
|
|
|
68
74
|
### `secrets`
|
|
@@ -73,13 +79,14 @@ This sub-class handles operations related to secrets:
|
|
|
73
79
|
|
|
74
80
|
```python
|
|
75
81
|
secrets = client.secrets.list_secrets(
|
|
76
|
-
project_id="
|
|
82
|
+
project_id="<project-id>",
|
|
77
83
|
environment_slug="dev",
|
|
78
84
|
secret_path="/",
|
|
79
|
-
expand_secret_references=True,
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
expand_secret_references=True, # Optional
|
|
86
|
+
view_secret_value=True, # Optional
|
|
87
|
+
recursive=False, # Optional
|
|
88
|
+
include_imports=True, # Optional
|
|
89
|
+
tag_filters=[] # Optional
|
|
83
90
|
)
|
|
84
91
|
```
|
|
85
92
|
|
|
@@ -88,6 +95,7 @@ secrets = client.secrets.list_secrets(
|
|
|
88
95
|
- `environment_slug` (str): The environment in which to list secrets (e.g., "dev").
|
|
89
96
|
- `secret_path` (str): The path to the secrets.
|
|
90
97
|
- `expand_secret_references` (bool): Whether to expand secret references.
|
|
98
|
+
- `view_secret_value` (bool): Whether or not to include the secret value in the response. If set to false, the `secretValue` will be masked with `<hidden-by-infisical>`. Defaults to true.
|
|
91
99
|
- `recursive` (bool): Whether to list secrets recursively.
|
|
92
100
|
- `include_imports` (bool): Whether to include imported secrets.
|
|
93
101
|
- `tag_filters` (List[str]): Tags to filter secrets.
|
|
@@ -100,7 +108,7 @@ secrets = client.secrets.list_secrets(
|
|
|
100
108
|
```python
|
|
101
109
|
new_secret = client.secrets.create_secret_by_name(
|
|
102
110
|
secret_name="NEW_SECRET",
|
|
103
|
-
project_id="
|
|
111
|
+
project_id="<project-id>",
|
|
104
112
|
secret_path="/",
|
|
105
113
|
environment_slug="dev",
|
|
106
114
|
secret_value="secret_value",
|
|
@@ -130,7 +138,7 @@ new_secret = client.secrets.create_secret_by_name(
|
|
|
130
138
|
```python
|
|
131
139
|
updated_secret = client.secrets.update_secret_by_name(
|
|
132
140
|
current_secret_name="EXISTING_SECRET",
|
|
133
|
-
project_id="
|
|
141
|
+
project_id="<project-id>",
|
|
134
142
|
secret_path="/",
|
|
135
143
|
environment_slug="dev",
|
|
136
144
|
secret_value="new_secret_value",
|
|
@@ -162,12 +170,13 @@ updated_secret = client.secrets.update_secret_by_name(
|
|
|
162
170
|
```python
|
|
163
171
|
secret = client.secrets.get_secret_by_name(
|
|
164
172
|
secret_name="EXISTING_SECRET",
|
|
165
|
-
project_id="
|
|
173
|
+
project_id="<project-id>",
|
|
166
174
|
environment_slug="dev",
|
|
167
175
|
secret_path="/",
|
|
168
|
-
expand_secret_references=True,
|
|
169
|
-
|
|
170
|
-
|
|
176
|
+
expand_secret_references=True, # Optional
|
|
177
|
+
view_secret_value=True, # Optional
|
|
178
|
+
include_imports=True, # Optional
|
|
179
|
+
version=None # Optional
|
|
171
180
|
)
|
|
172
181
|
```
|
|
173
182
|
|
|
@@ -177,6 +186,7 @@ secret = client.secrets.get_secret_by_name(
|
|
|
177
186
|
- `environment_slug` (str): The environment in which to retrieve the secret.
|
|
178
187
|
- `secret_path` (str): The path to the secret.
|
|
179
188
|
- `expand_secret_references` (bool): Whether to expand secret references.
|
|
189
|
+
- `view_secret_value` (bool): Whether or not to include the secret value in the response. If set to false, the `secretValue` will be masked with `<hidden-by-infisical>`. Defaults to true.
|
|
180
190
|
- `include_imports` (bool): Whether to include imported secrets.
|
|
181
191
|
- `version` (str, optional): The version of the secret to retrieve. Fetches the latest by default.
|
|
182
192
|
|
|
@@ -188,7 +198,7 @@ secret = client.secrets.get_secret_by_name(
|
|
|
188
198
|
```python
|
|
189
199
|
deleted_secret = client.secrets.delete_secret_by_name(
|
|
190
200
|
secret_name="EXISTING_SECRET",
|
|
191
|
-
project_id="
|
|
201
|
+
project_id="<project-id>",
|
|
192
202
|
environment_slug="dev",
|
|
193
203
|
secret_path="/"
|
|
194
204
|
)
|
|
@@ -202,3 +212,147 @@ deleted_secret = client.secrets.delete_secret_by_name(
|
|
|
202
212
|
|
|
203
213
|
**Returns:**
|
|
204
214
|
- `BaseSecret`: The response after deleting the secret.
|
|
215
|
+
|
|
216
|
+
### `kms`
|
|
217
|
+
|
|
218
|
+
This sub-class handles KMS related operations:
|
|
219
|
+
|
|
220
|
+
#### List KMS Keys
|
|
221
|
+
|
|
222
|
+
```python
|
|
223
|
+
kms_keys = client.kms.list_keys(
|
|
224
|
+
project_id="<project-id>",
|
|
225
|
+
offset=0, # Optional
|
|
226
|
+
limit=100, # Optional
|
|
227
|
+
order_by=KmsKeysOrderBy.NAME, # Optional
|
|
228
|
+
order_direction=OrderDirection.ASC, # Optional
|
|
229
|
+
search=None # Optional
|
|
230
|
+
)
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**Parameters:**
|
|
234
|
+
- `project_id` (str): The ID of your project.
|
|
235
|
+
- `offset` (int, optional): The offset to paginate from.
|
|
236
|
+
- `limit` (int, optional): The page size for paginating.
|
|
237
|
+
- `order_by` (KmsKeysOrderBy, optional): The key property to order the list response by.
|
|
238
|
+
- `order_direction` (OrderDirection, optional): The direction to order the list response in.
|
|
239
|
+
- `search` (str, optional): The text value to filter key names by.
|
|
240
|
+
|
|
241
|
+
**Returns:**
|
|
242
|
+
- `ListKmsKeysResponse`: The response containing the list of KMS keys.
|
|
243
|
+
|
|
244
|
+
#### Get KMS Key by ID
|
|
245
|
+
|
|
246
|
+
```python
|
|
247
|
+
kms_key = client.kms.get_key_by_id(
|
|
248
|
+
key_id="<key-id>"
|
|
249
|
+
)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**Parameters:**
|
|
253
|
+
- `key_id` (str): The ID of the key to retrieve.
|
|
254
|
+
|
|
255
|
+
**Returns:**
|
|
256
|
+
- `KmsKey`: The specified key.
|
|
257
|
+
|
|
258
|
+
#### Get KMS Key by Name
|
|
259
|
+
|
|
260
|
+
```python
|
|
261
|
+
kms_key = client.kms.get_key_by_name(
|
|
262
|
+
key_name="my-key",
|
|
263
|
+
project_id="<project-id>"
|
|
264
|
+
)
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Parameters:**
|
|
268
|
+
- `key_name` (str): The name of the key to retrieve.
|
|
269
|
+
- `project_id` (str): The ID of your project.
|
|
270
|
+
|
|
271
|
+
**Returns:**
|
|
272
|
+
- `KmsKey`: The specified key.
|
|
273
|
+
|
|
274
|
+
#### Create KMS Key
|
|
275
|
+
|
|
276
|
+
```python
|
|
277
|
+
kms_key = client.kms.create_key(
|
|
278
|
+
name="my-key",
|
|
279
|
+
project_id="<project-id>",
|
|
280
|
+
encryption_algorithm=SymmetricEncryption.AES_GCM_256,
|
|
281
|
+
description=None # Optional
|
|
282
|
+
)
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**Parameters:**
|
|
286
|
+
- `name` (str): The name of the key (must be slug-friendly).
|
|
287
|
+
- `project_id` (str): The ID of your project.
|
|
288
|
+
- `encryption_algorithm` (SymmetricEncryption): The encryption alogrithm this key should use.
|
|
289
|
+
- `description` (str, optional): A description of your key.
|
|
290
|
+
|
|
291
|
+
**Returns:**
|
|
292
|
+
- `KmsKey`: The newly created key.
|
|
293
|
+
|
|
294
|
+
#### Update KMS Key
|
|
295
|
+
|
|
296
|
+
```python
|
|
297
|
+
updated_key = client.kms.update_key(
|
|
298
|
+
key_id="<key-id>",
|
|
299
|
+
name="my-updated-key", # Optional
|
|
300
|
+
description="Updated description", # Optional
|
|
301
|
+
is_disabled=True # Optional
|
|
302
|
+
)
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**Parameters:**
|
|
306
|
+
- `key_id` (str): The ID of the key to be updated.
|
|
307
|
+
- `name` (str, optional): The updated name of the key (must be slug-friendly).
|
|
308
|
+
- `description` (str): The updated description of the key.
|
|
309
|
+
- `is_disabled` (str): The flag to disable operations with this key.
|
|
310
|
+
|
|
311
|
+
**Returns:**
|
|
312
|
+
- `KmsKey`: The updated key.
|
|
313
|
+
|
|
314
|
+
#### Delete KMS Key
|
|
315
|
+
|
|
316
|
+
```python
|
|
317
|
+
deleted_key = client.kms.delete_key(
|
|
318
|
+
key_id="<key-id>"
|
|
319
|
+
)
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**Parameters:**
|
|
323
|
+
- `key_id` (str): The ID of the key to be deleted.
|
|
324
|
+
|
|
325
|
+
**Returns:**
|
|
326
|
+
- `KmsKey`: The deleted key.
|
|
327
|
+
|
|
328
|
+
#### Encrypt Data with KMS Key
|
|
329
|
+
|
|
330
|
+
```python
|
|
331
|
+
encrypted_data = client.kms.encrypt_data(
|
|
332
|
+
key_id="<key-id>",
|
|
333
|
+
base64EncodedPlaintext="TXkgc2VjcmV0IG1lc3NhZ2U=" # must be base64 encoded
|
|
334
|
+
)
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
**Parameters:**
|
|
338
|
+
- `key_id` (str): The ID of the key to encrypt the data with.
|
|
339
|
+
- `base64EncodedPlaintext` (str): The plaintext data to encrypt (must be base64 encoded).
|
|
340
|
+
|
|
341
|
+
**Returns:**
|
|
342
|
+
- `str`: The encrypted ciphertext.
|
|
343
|
+
|
|
344
|
+
#### Decrypte Data with KMS Key
|
|
345
|
+
|
|
346
|
+
```python
|
|
347
|
+
decrypted_data = client.kms.decrypt_data(
|
|
348
|
+
key_id="<key-id>",
|
|
349
|
+
ciphertext="Aq96Ry7sMH3k/ogaIB5MiSfH+LblQRBu69lcJe0GfIvI48ZvbWY+9JulyoQYdjAx"
|
|
350
|
+
)
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
**Parameters:**
|
|
354
|
+
- `key_id` (str): The ID of the key to decrypt the data with.
|
|
355
|
+
- `ciphertext` (str): The ciphertext returned from the encrypt operation.
|
|
356
|
+
|
|
357
|
+
**Returns:**
|
|
358
|
+
- `str`: The base64 encoded plaintext.
|
|
@@ -74,6 +74,7 @@ class BaseSecret(BaseModel):
|
|
|
74
74
|
createdAt: str
|
|
75
75
|
updatedAt: str
|
|
76
76
|
secretMetadata: Optional[Dict[str, Any]] = None
|
|
77
|
+
secretValueHidden: Optional[bool] = False
|
|
77
78
|
secretReminderNote: Optional[str] = None
|
|
78
79
|
secretReminderRepeatDays: Optional[int] = None
|
|
79
80
|
skipMultilineEncoding: Optional[bool] = False
|
|
@@ -112,7 +113,7 @@ class SingleSecretResponse(BaseModel):
|
|
|
112
113
|
secret: BaseSecret
|
|
113
114
|
|
|
114
115
|
@classmethod
|
|
115
|
-
def from_dict(cls, data: Dict) -> '
|
|
116
|
+
def from_dict(cls, data: Dict) -> 'SingleSecretResponse':
|
|
116
117
|
return cls(
|
|
117
118
|
secret=BaseSecret.from_dict(data['secret']),
|
|
118
119
|
)
|
|
@@ -125,3 +126,71 @@ class MachineIdentityLoginResponse(BaseModel):
|
|
|
125
126
|
expiresIn: int
|
|
126
127
|
accessTokenMaxTTL: int
|
|
127
128
|
tokenType: str
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class SymmetricEncryption(str, Enum):
|
|
132
|
+
AES_GCM_256 = "aes-256-gcm"
|
|
133
|
+
AES_GCM_128 = "aes-128-gcm"
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class OrderDirection(str, Enum):
|
|
137
|
+
ASC = "asc"
|
|
138
|
+
DESC = "desc"
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class KmsKeysOrderBy(str, Enum):
|
|
142
|
+
NAME = "name"
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@dataclass
|
|
146
|
+
class KmsKey(BaseModel):
|
|
147
|
+
"""Infisical KMS Key"""
|
|
148
|
+
id: str
|
|
149
|
+
description: str
|
|
150
|
+
isDisabled: bool
|
|
151
|
+
orgId: str
|
|
152
|
+
name: str
|
|
153
|
+
createdAt: str
|
|
154
|
+
updatedAt: str
|
|
155
|
+
projectId: str
|
|
156
|
+
version: int
|
|
157
|
+
encryptionAlgorithm: SymmetricEncryption
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
@dataclass
|
|
161
|
+
class ListKmsKeysResponse(BaseModel):
|
|
162
|
+
"""Complete response model for Kms Keys API"""
|
|
163
|
+
keys: List[KmsKey]
|
|
164
|
+
totalCount: int
|
|
165
|
+
|
|
166
|
+
@classmethod
|
|
167
|
+
def from_dict(cls, data: Dict) -> 'ListKmsKeysResponse':
|
|
168
|
+
"""Create model from dictionary with camelCase keys, handling nested objects"""
|
|
169
|
+
return cls(
|
|
170
|
+
keys=[KmsKey.from_dict(key) for key in data['keys']],
|
|
171
|
+
totalCount=data['totalCount']
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
@dataclass
|
|
176
|
+
class SingleKmsKeyResponse(BaseModel):
|
|
177
|
+
"""Response model for get/create/update/delete API"""
|
|
178
|
+
key: KmsKey
|
|
179
|
+
|
|
180
|
+
@classmethod
|
|
181
|
+
def from_dict(cls, data: Dict) -> 'SingleKmsKeyResponse':
|
|
182
|
+
return cls(
|
|
183
|
+
key=KmsKey.from_dict(data['key']),
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
@dataclass
|
|
188
|
+
class KmsKeyEncryptDataResponse(BaseModel):
|
|
189
|
+
"""Response model for encrypt data API"""
|
|
190
|
+
ciphertext: str
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@dataclass
|
|
194
|
+
class KmsKeyDecryptDataResponse(BaseModel):
|
|
195
|
+
"""Response model for decrypt data API"""
|
|
196
|
+
plaintext: str
|
|
@@ -12,8 +12,11 @@ from botocore.awsrequest import AWSRequest
|
|
|
12
12
|
from botocore.exceptions import NoCredentialsError
|
|
13
13
|
|
|
14
14
|
from .infisical_requests import InfisicalRequests
|
|
15
|
-
|
|
16
|
-
from .api_types import SingleSecretResponse, BaseSecret
|
|
15
|
+
|
|
16
|
+
from .api_types import ListSecretsResponse, SingleSecretResponse, BaseSecret
|
|
17
|
+
from .api_types import SymmetricEncryption, KmsKeysOrderBy, OrderDirection
|
|
18
|
+
from .api_types import ListKmsKeysResponse, SingleKmsKeyResponse, MachineIdentityLoginResponse
|
|
19
|
+
from .api_types import KmsKey, KmsKeyEncryptDataResponse, KmsKeyDecryptDataResponse
|
|
17
20
|
|
|
18
21
|
|
|
19
22
|
class InfisicalSDKClient:
|
|
@@ -25,6 +28,7 @@ class InfisicalSDKClient:
|
|
|
25
28
|
|
|
26
29
|
self.auth = Auth(self)
|
|
27
30
|
self.secrets = V3RawSecrets(self)
|
|
31
|
+
self.kms = KMS(self)
|
|
28
32
|
|
|
29
33
|
def set_token(self, token: str):
|
|
30
34
|
"""
|
|
@@ -205,6 +209,7 @@ class V3RawSecrets:
|
|
|
205
209
|
environment_slug: str,
|
|
206
210
|
secret_path: str,
|
|
207
211
|
expand_secret_references: bool = True,
|
|
212
|
+
view_secret_value: bool = True,
|
|
208
213
|
recursive: bool = False,
|
|
209
214
|
include_imports: bool = True,
|
|
210
215
|
tag_filters: List[str] = []) -> ListSecretsResponse:
|
|
@@ -213,13 +218,14 @@ class V3RawSecrets:
|
|
|
213
218
|
"workspaceId": project_id,
|
|
214
219
|
"environment": environment_slug,
|
|
215
220
|
"secretPath": secret_path,
|
|
221
|
+
"viewSecretValue": str(view_secret_value).lower(),
|
|
216
222
|
"expandSecretReferences": str(expand_secret_references).lower(),
|
|
217
223
|
"recursive": str(recursive).lower(),
|
|
218
224
|
"include_imports": str(include_imports).lower(),
|
|
219
225
|
}
|
|
220
226
|
|
|
221
227
|
if tag_filters:
|
|
222
|
-
params["
|
|
228
|
+
params["tagSlugs"] = ",".join(tag_filters)
|
|
223
229
|
|
|
224
230
|
result = self.client.api.get(
|
|
225
231
|
path="/api/v3/secrets/raw",
|
|
@@ -237,10 +243,12 @@ class V3RawSecrets:
|
|
|
237
243
|
secret_path: str,
|
|
238
244
|
expand_secret_references: bool = True,
|
|
239
245
|
include_imports: bool = True,
|
|
246
|
+
view_secret_value: bool = True,
|
|
240
247
|
version: str = None) -> BaseSecret:
|
|
241
248
|
|
|
242
249
|
params = {
|
|
243
250
|
"workspaceId": project_id,
|
|
251
|
+
"viewSecretValue": str(view_secret_value).lower(),
|
|
244
252
|
"environment": environment_slug,
|
|
245
253
|
"secretPath": secret_path,
|
|
246
254
|
"expandSecretReferences": str(expand_secret_references).lower(),
|
|
@@ -307,7 +315,7 @@ class V3RawSecrets:
|
|
|
307
315
|
"secretPath": secret_path,
|
|
308
316
|
"secretValue": secret_value,
|
|
309
317
|
"secretComment": secret_comment,
|
|
310
|
-
"
|
|
318
|
+
"newSecretName": new_secret_name,
|
|
311
319
|
"tagIds": None,
|
|
312
320
|
"skipMultilineEncoding": skip_multiline_encoding,
|
|
313
321
|
"type": "shared",
|
|
@@ -343,3 +351,175 @@ class V3RawSecrets:
|
|
|
343
351
|
)
|
|
344
352
|
|
|
345
353
|
return result.data.secret
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
class KMS:
|
|
357
|
+
def __init__(self, client: InfisicalSDKClient) -> None:
|
|
358
|
+
self.client = client
|
|
359
|
+
|
|
360
|
+
def list_keys(
|
|
361
|
+
self,
|
|
362
|
+
project_id: str,
|
|
363
|
+
offset: int = 0,
|
|
364
|
+
limit: int = 100,
|
|
365
|
+
order_by: KmsKeysOrderBy = KmsKeysOrderBy.NAME,
|
|
366
|
+
order_direction: OrderDirection = OrderDirection.ASC,
|
|
367
|
+
search: str = None) -> ListKmsKeysResponse:
|
|
368
|
+
|
|
369
|
+
params = {
|
|
370
|
+
"projectId": project_id,
|
|
371
|
+
"search": search,
|
|
372
|
+
"offset": offset,
|
|
373
|
+
"limit": limit,
|
|
374
|
+
"orderBy": order_by,
|
|
375
|
+
"orderDirection": order_direction,
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
result = self.client.api.get(
|
|
379
|
+
path="/api/v1/kms/keys",
|
|
380
|
+
params=params,
|
|
381
|
+
model=ListKmsKeysResponse
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
return result.data
|
|
385
|
+
|
|
386
|
+
def get_key_by_id(
|
|
387
|
+
self,
|
|
388
|
+
key_id: str) -> KmsKey:
|
|
389
|
+
|
|
390
|
+
result = self.client.api.get(
|
|
391
|
+
path=f"/api/v1/kms/keys/{key_id}",
|
|
392
|
+
model=SingleKmsKeyResponse
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
return result.data.key
|
|
396
|
+
|
|
397
|
+
def get_key_by_name(
|
|
398
|
+
self,
|
|
399
|
+
key_name: str,
|
|
400
|
+
project_id: str) -> KmsKey:
|
|
401
|
+
|
|
402
|
+
params = {
|
|
403
|
+
"projectId": project_id,
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
result = self.client.api.get(
|
|
407
|
+
path=f"/api/v1/kms/keys/key-name/{key_name}",
|
|
408
|
+
params=params,
|
|
409
|
+
model=SingleKmsKeyResponse
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
return result.data.key
|
|
413
|
+
|
|
414
|
+
def create_key(
|
|
415
|
+
self,
|
|
416
|
+
name: str,
|
|
417
|
+
project_id: str,
|
|
418
|
+
encryption_algorithm: SymmetricEncryption,
|
|
419
|
+
description: str = None) -> KmsKey:
|
|
420
|
+
|
|
421
|
+
request_body = {
|
|
422
|
+
"name": name,
|
|
423
|
+
"projectId": project_id,
|
|
424
|
+
"encryptionAlgorithm": encryption_algorithm,
|
|
425
|
+
"description": description,
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
result = self.client.api.post(
|
|
429
|
+
path="/api/v1/kms/keys",
|
|
430
|
+
json=request_body,
|
|
431
|
+
model=SingleKmsKeyResponse
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
return result.data.key
|
|
435
|
+
|
|
436
|
+
def update_key(
|
|
437
|
+
self,
|
|
438
|
+
key_id: str,
|
|
439
|
+
name: str = None,
|
|
440
|
+
is_disabled: bool = None,
|
|
441
|
+
description: str = None) -> KmsKey:
|
|
442
|
+
|
|
443
|
+
request_body = {
|
|
444
|
+
"name": name,
|
|
445
|
+
"isDisabled": is_disabled,
|
|
446
|
+
"description": description,
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
result = self.client.api.patch(
|
|
450
|
+
path=f"/api/v1/kms/keys/{key_id}",
|
|
451
|
+
json=request_body,
|
|
452
|
+
model=SingleKmsKeyResponse
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
return result.data.key
|
|
456
|
+
|
|
457
|
+
def delete_key(
|
|
458
|
+
self,
|
|
459
|
+
key_id: str) -> KmsKey:
|
|
460
|
+
|
|
461
|
+
result = self.client.api.delete(
|
|
462
|
+
path=f"/api/v1/kms/keys/{key_id}",
|
|
463
|
+
json={},
|
|
464
|
+
model=SingleKmsKeyResponse
|
|
465
|
+
)
|
|
466
|
+
|
|
467
|
+
return result.data.key
|
|
468
|
+
|
|
469
|
+
def encrypt_data(
|
|
470
|
+
self,
|
|
471
|
+
key_id: str,
|
|
472
|
+
base64EncodedPlaintext: str) -> str:
|
|
473
|
+
"""
|
|
474
|
+
Encrypt data with the specified KMS key.
|
|
475
|
+
|
|
476
|
+
:param key_id: The ID of the key to decrypt the ciphertext with
|
|
477
|
+
:type key_id: str
|
|
478
|
+
:param base64EncodedPlaintext: The base64 encoded plaintext to encrypt
|
|
479
|
+
:type plaintext: str
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
:return: The encrypted base64 encoded plaintext (ciphertext)
|
|
483
|
+
:rtype: str
|
|
484
|
+
"""
|
|
485
|
+
|
|
486
|
+
request_body = {
|
|
487
|
+
"plaintext": base64EncodedPlaintext
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
result = self.client.api.post(
|
|
491
|
+
path=f"/api/v1/kms/keys/{key_id}/encrypt",
|
|
492
|
+
json=request_body,
|
|
493
|
+
model=KmsKeyEncryptDataResponse
|
|
494
|
+
)
|
|
495
|
+
|
|
496
|
+
return result.data.ciphertext
|
|
497
|
+
|
|
498
|
+
def decrypt_data(
|
|
499
|
+
self,
|
|
500
|
+
key_id: str,
|
|
501
|
+
ciphertext: str) -> str:
|
|
502
|
+
"""
|
|
503
|
+
Decrypt data with the specified KMS key.
|
|
504
|
+
|
|
505
|
+
:param key_id: The ID of the key to decrypt the ciphertext with
|
|
506
|
+
:type key_id: str
|
|
507
|
+
:param ciphertext: The encrypted base64 plaintext to decrypt
|
|
508
|
+
:type ciphertext: str
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
:return: The base64 encoded plaintext
|
|
512
|
+
:rtype: str
|
|
513
|
+
"""
|
|
514
|
+
|
|
515
|
+
request_body = {
|
|
516
|
+
"ciphertext": ciphertext
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
result = self.client.api.post(
|
|
520
|
+
path=f"/api/v1/kms/keys/{key_id}/decrypt",
|
|
521
|
+
json=request_body,
|
|
522
|
+
model=KmsKeyDecryptDataResponse
|
|
523
|
+
)
|
|
524
|
+
|
|
525
|
+
return result.data.plaintext
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any, Dict, Generic, Optional, TypeVar
|
|
1
|
+
from typing import Any, Dict, Generic, Optional, TypeVar, Type
|
|
2
2
|
from urllib.parse import urljoin
|
|
3
3
|
import requests
|
|
4
4
|
from dataclasses import dataclass
|
|
@@ -90,7 +90,7 @@ class InfisicalRequests:
|
|
|
90
90
|
def get(
|
|
91
91
|
self,
|
|
92
92
|
path: str,
|
|
93
|
-
model:
|
|
93
|
+
model: Type[T],
|
|
94
94
|
params: Optional[Dict[str, Any]] = None
|
|
95
95
|
) -> APIResponse[T]:
|
|
96
96
|
|
|
@@ -116,7 +116,7 @@ class InfisicalRequests:
|
|
|
116
116
|
def post(
|
|
117
117
|
self,
|
|
118
118
|
path: str,
|
|
119
|
-
model:
|
|
119
|
+
model: Type[T],
|
|
120
120
|
json: Optional[Dict[str, Any]] = None
|
|
121
121
|
) -> APIResponse[T]:
|
|
122
122
|
|
|
@@ -140,7 +140,7 @@ class InfisicalRequests:
|
|
|
140
140
|
def patch(
|
|
141
141
|
self,
|
|
142
142
|
path: str,
|
|
143
|
-
model:
|
|
143
|
+
model: Type[T],
|
|
144
144
|
json: Optional[Dict[str, Any]] = None
|
|
145
145
|
) -> APIResponse[T]:
|
|
146
146
|
|
|
@@ -164,7 +164,7 @@ class InfisicalRequests:
|
|
|
164
164
|
def delete(
|
|
165
165
|
self,
|
|
166
166
|
path: str,
|
|
167
|
-
model:
|
|
167
|
+
model: Type[T],
|
|
168
168
|
json: Optional[Dict[str, Any]] = None
|
|
169
169
|
) -> APIResponse[T]:
|
|
170
170
|
|
|
@@ -15,8 +15,8 @@ from setuptools import setup, find_packages # noqa: H301
|
|
|
15
15
|
# prerequisite: setuptools
|
|
16
16
|
# http://pypi.python.org/pypi/setuptools
|
|
17
17
|
NAME = "infisicalsdk"
|
|
18
|
-
VERSION = "1.0.
|
|
19
|
-
PYTHON_REQUIRES = ">=3.
|
|
18
|
+
VERSION = "1.0.5"
|
|
19
|
+
PYTHON_REQUIRES = ">=3.8"
|
|
20
20
|
REQUIRES = [
|
|
21
21
|
"urllib3 >= 1.25.3, < 2.1.0",
|
|
22
22
|
"python-dateutil",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|