Skip to content

Commit 93b0718

Browse files
authored
Merge pull request #986 from cderici/add-secrets
#986 #### Description This is the first PR in exposing user secrets for python-libjuju. I decided to split this work into multiple PRs (rest is/are coming right after this) because this PR was getting really big with the updated schema and the clients etc. The main changes are as follows: - Adds a new `secrets.py` module that contains the client logic for producing the data bag for secrets to be added (and updated), including reading values from yaml/json files etc. - Updates the schema with the latest 3.3 schema from juju and re-generates the clients to get the `Secrets` v2 facade. - Adds the `model.add_secret()` function that corresponds to `juju add-secret` cli command. #### QA Steps Some unit tests are added for the functions in the new `secrets.py` module. ``` tox -e py3 -- tests/unit/test_secrets.py::TestCreateSecretData ``` ``` tox -e py3 -- tests/unit/test_secrets.py::TestReadSecretData ``` Also added an integration test for `add_secret`: ``` tox -e integration -- tests/integration/test_secrets.py::test_add_secret ``` This can also be tested manually by using Python repl: ```python $ python -m asyncio >>> from juju import model >>> m=model.Model();await m.connect() >>> await model.add_secret(name='my-apitoken', dataArgs=['token=34ae35facd4']) secret:........ ``` After this, check the `juju secrets`, you should see the newly added secret. #### Notes & Discussion JUJU-4926
2 parents f91507a + fcd42b9 commit 93b0718

19 files changed

Lines changed: 7230 additions & 138 deletions

.github/workflows/test.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565
uses: charmed-kubernetes/actions-operator@main
6666
with:
6767
provider: lxd
68-
juju-channel: 3.2/stable
68+
juju-channel: 3.3/stable
6969
# 2023-01-11 Commented until we discover a
7070
# clear approach for this.
7171
# - name: Set proxy in controller

.github/workflows/test_candidate.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
uses: charmed-kubernetes/actions-operator@main
5555
with:
5656
provider: lxd
57-
juju-channel: 3.2/candidate
57+
juju-channel: 3.3/candidate
5858
- name: Setup Python
5959
if: ${{ env.next-test != 'NA' }}
6060
uses: actions/setup-python@v4

.github/workflows/test_edge.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
uses: charmed-kubernetes/actions-operator@main
5555
with:
5656
provider: lxd
57-
juju-channel: 3.2/edge
57+
juju-channel: 3.3/edge
5858
- name: Setup Python
5959
if: ${{ env.next-test != 'NA' }}
6060
uses: actions/setup-python@v4

juju/client/_client.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,14 @@ class UserManagerFacade(TypeFactory):
554554
pass
555555

556556

557+
class UserSecretsDrainFacade(TypeFactory):
558+
pass
559+
560+
561+
class UserSecretsManagerFacade(TypeFactory):
562+
pass
563+
564+
557565
class VolumeAttachmentPlansWatcherFacade(TypeFactory):
558566
pass
559567

juju/client/_client1.py

Lines changed: 535 additions & 3 deletions
Large diffs are not rendered by default.

juju/client/_client19.py

Lines changed: 4491 additions & 0 deletions
Large diffs are not rendered by default.

juju/client/_client2.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5130,10 +5130,11 @@ class SecretsFacade(Type):
51305130
'required': ['args'],
51315131
'type': 'object'},
51325132
'DeleteSecretArg': {'additionalProperties': False,
5133-
'properties': {'revisions': {'items': {'type': 'integer'},
5133+
'properties': {'label': {'type': 'string'},
5134+
'revisions': {'items': {'type': 'integer'},
51345135
'type': 'array'},
51355136
'uri': {'type': 'string'}},
5136-
'required': ['uri'],
5137+
'required': ['uri', 'label'],
51375138
'type': 'object'},
51385139
'DeleteSecretArgs': {'additionalProperties': False,
51395140
'properties': {'args': {'items': {'$ref': '#/definitions/DeleteSecretArg'},
@@ -5159,8 +5160,10 @@ class SecretsFacade(Type):
51595160
'GrantRevokeUserSecretArg': {'additionalProperties': False,
51605161
'properties': {'applications': {'items': {'type': 'string'},
51615162
'type': 'array'},
5163+
'label': {'type': 'string'},
51625164
'uri': {'type': 'string'}},
51635165
'required': ['uri',
5166+
'label',
51645167
'applications'],
51655168
'type': 'object'},
51665169
'ListSecretResult': {'additionalProperties': False,
@@ -5228,7 +5231,8 @@ class SecretsFacade(Type):
52285231
'error': {'$ref': '#/definitions/Error'}},
52295232
'type': 'object'},
52305233
'SecretsFilter': {'additionalProperties': False,
5231-
'properties': {'owner-tag': {'type': 'string'},
5234+
'properties': {'label': {'type': 'string'},
5235+
'owner-tag': {'type': 'string'},
52325236
'revision': {'type': 'integer'},
52335237
'uri': {'type': 'string'}},
52345238
'type': 'object'},
@@ -5247,6 +5251,7 @@ class SecretsFacade(Type):
52475251
'auto-prune': {'type': 'boolean'},
52485252
'content': {'$ref': '#/definitions/SecretContentParams'},
52495253
'description': {'type': 'string'},
5254+
'existing-label': {'type': 'string'},
52505255
'expire-time': {'format': 'date-time',
52515256
'type': 'string'},
52525257
'label': {'type': 'string'},
@@ -5255,7 +5260,9 @@ class SecretsFacade(Type):
52555260
'type': 'object'},
52565261
'rotate-policy': {'type': 'string'},
52575262
'uri': {'type': 'string'}},
5258-
'required': ['UpsertSecretArg', 'uri'],
5263+
'required': ['UpsertSecretArg',
5264+
'uri',
5265+
'existing-label'],
52595266
'type': 'object'},
52605267
'UpdateUserSecretArgs': {'additionalProperties': False,
52615268
'properties': {'args': {'items': {'$ref': '#/definitions/UpdateUserSecretArg'},
@@ -5330,17 +5337,21 @@ async def CreateSecrets(self, args=None):
53305337

53315338

53325339
@ReturnMapping(ErrorResults)
5333-
async def GrantSecret(self, applications=None, uri=None):
5340+
async def GrantSecret(self, applications=None, label=None, uri=None):
53345341
'''
53355342
GrantSecret grants access to a user secret.
53365343
53375344
applications : typing.Sequence[str]
5345+
label : str
53385346
uri : str
53395347
Returns -> ErrorResults
53405348
'''
53415349
if applications is not None and not isinstance(applications, (bytes, str, list)):
53425350
raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications)))
53435351

5352+
if label is not None and not isinstance(label, (bytes, str)):
5353+
raise Exception("Expected label to be a str, received: {}".format(type(label)))
5354+
53445355
if uri is not None and not isinstance(uri, (bytes, str)):
53455356
raise Exception("Expected uri to be a str, received: {}".format(type(uri)))
53465357

@@ -5351,6 +5362,7 @@ async def GrantSecret(self, applications=None, uri=None):
53515362
version=2,
53525363
params=_params)
53535364
_params['applications'] = applications
5365+
_params['label'] = label
53545366
_params['uri'] = uri
53555367
reply = await self.rpc(msg)
53565368
return reply
@@ -5409,17 +5421,21 @@ async def RemoveSecrets(self, args=None):
54095421

54105422

54115423
@ReturnMapping(ErrorResults)
5412-
async def RevokeSecret(self, applications=None, uri=None):
5424+
async def RevokeSecret(self, applications=None, label=None, uri=None):
54135425
'''
54145426
RevokeSecret revokes access to a user secret.
54155427
54165428
applications : typing.Sequence[str]
5429+
label : str
54175430
uri : str
54185431
Returns -> ErrorResults
54195432
'''
54205433
if applications is not None and not isinstance(applications, (bytes, str, list)):
54215434
raise Exception("Expected applications to be a Sequence, received: {}".format(type(applications)))
54225435

5436+
if label is not None and not isinstance(label, (bytes, str)):
5437+
raise Exception("Expected label to be a str, received: {}".format(type(label)))
5438+
54235439
if uri is not None and not isinstance(uri, (bytes, str)):
54245440
raise Exception("Expected uri to be a str, received: {}".format(type(uri)))
54255441

@@ -5430,6 +5446,7 @@ async def RevokeSecret(self, applications=None, uri=None):
54305446
version=2,
54315447
params=_params)
54325448
_params['applications'] = applications
5449+
_params['label'] = label
54335450
_params['uri'] = uri
54345451
reply = await self.rpc(msg)
54355452
return reply
@@ -5488,10 +5505,11 @@ class SecretsManagerFacade(Type):
54885505
'required': ['count'],
54895506
'type': 'object'},
54905507
'DeleteSecretArg': {'additionalProperties': False,
5491-
'properties': {'revisions': {'items': {'type': 'integer'},
5508+
'properties': {'label': {'type': 'string'},
5509+
'revisions': {'items': {'type': 'integer'},
54925510
'type': 'array'},
54935511
'uri': {'type': 'string'}},
5494-
'required': ['uri'],
5512+
'required': ['uri', 'label'],
54955513
'type': 'object'},
54965514
'DeleteSecretArgs': {'additionalProperties': False,
54975515
'properties': {'args': {'items': {'$ref': '#/definitions/DeleteSecretArg'},

0 commit comments

Comments
 (0)