Skip to content

Commit 99f97da

Browse files
committed
Add integration tests for add_secret
1 parent f3057b7 commit 99f97da

3 files changed

Lines changed: 61 additions & 2 deletions

File tree

juju/errors.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ class PylibjujuProgrammingError(Exception):
9494
pass
9595

9696

97+
class JujuNotSupportedError(JujuError):
98+
pass
99+
100+
97101
class JujuNotValid(JujuError):
98102
def __init__(self, entity_type, entity_name):
99103
self.entity_type = entity_type

juju/model.py

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,14 @@
3232
from .controller import Controller, ConnectedController
3333
from .delta import get_entity_class, get_entity_delta
3434
from .errors import JujuAPIError, JujuError, JujuModelConfigError, JujuBackupError
35-
from .errors import JujuModelError, JujuAppError, JujuUnitError, JujuAgentError, JujuMachineError, PylibjujuError
35+
from .errors import JujuModelError, JujuAppError, JujuUnitError, JujuAgentError, JujuMachineError, PylibjujuError, JujuNotSupportedError
3636
from .exceptions import DeadEntityException
3737
from .names import is_valid_application
3838
from .offerendpoints import ParseError as OfferParseError
3939
from .offerendpoints import parse_local_endpoint, parse_offer_url
4040
from .origin import Channel, Source
4141
from .placement import parse as parse_placement
42+
from .secrets import create_secret_data, read_secret_data
4243
from .tag import application as application_tag
4344
from .url import URL, Schema
4445
from .version import DEFAULT_ARCHITECTURE
@@ -2613,15 +2614,51 @@ async def export_bundle(self, filename=None):
26132614
except IOError:
26142615
raise
26152616

2617+
async def add_secret(self, name, dataArgs, file="", info=""):
2618+
"""Adds a secret with a list of key values
2619+
2620+
Equivalent to the cli command:
2621+
juju add-secret [options] <name> [key[#base64|#file]=value...]
2622+
2623+
:param name str: The name of the secret to be added.
2624+
:param dataArgs []str: The key value pairs to be added into the secret.
2625+
:param file str: A path to a yaml file containing secret key values.
2626+
:param info str: The secret description.
2627+
"""
2628+
data = create_secret_data(dataArgs)
2629+
2630+
if file:
2631+
data_from_file = read_secret_data(file)
2632+
for k, v in data_from_file.items():
2633+
# Caution: key/value pairs in files overwrite the ones in the args.
2634+
data[k] = v
2635+
2636+
if client.SecretsFacade.best_facade_version(self.connection()) < 2:
2637+
raise JujuNotSupportedError("user secrets")
2638+
2639+
secretsFacade = client.SecretsFacade.from_connection(self.connection())
2640+
results = await secretsFacade.CreateSecrets([{
2641+
'content': {'data': data},
2642+
'description': info,
2643+
'label': name,
2644+
}])
2645+
if len(results.results) != 1:
2646+
raise JujuAPIError(f"expected 1 result, got {len(results.results)}")
2647+
result = results.results[0]
2648+
if result.error is not None:
2649+
raise JujuAPIError(result.error.message)
2650+
return result.result
2651+
26162652
async def list_secrets(self, filter="", show_secrets=False):
26172653
"""
26182654
Returns the list of available secrets.
26192655
"""
26202656
facade = client.SecretsFacade.from_connection(self.connection())
2621-
return await facade.ListSecrets({
2657+
results = await facade.ListSecrets({
26222658
'filter': filter,
26232659
'show-secrets': show_secrets,
26242660
})
2661+
return results.results
26252662

26262663
async def _get_source_api(self, url, controller_name=None):
26272664
controller = Controller()

tests/integration/test_secrets.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright 2023 Canonical Ltd.
2+
# Licensed under the Apache V2, see LICENCE file for details.
3+
4+
import pytest
5+
from .. import base
6+
7+
8+
@base.bootstrapped
9+
@pytest.mark.bundle
10+
async def test_add_secret(event_loop):
11+
12+
async with base.CleanModel() as model:
13+
secret = await model.add_secret(name='my-apitoken', dataArgs=['token=34ae35facd4'])
14+
assert secret.startswith('secret:')
15+
16+
secrets = await model.list_secrets()
17+
assert len(secrets) == 1
18+
assert secrets[0].label == 'my-apitoken'

0 commit comments

Comments
 (0)