Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

{Core} Expose public interface for SecretStore #22372

Merged
merged 3 commits into from
May 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions src/azure-cli-core/azure/cli/core/_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import os
import os.path
import sys
from copy import deepcopy
from enum import Enum

Expand Down Expand Up @@ -840,13 +839,8 @@ def _transform_subscription_for_multiapi(s, s_dict):
def _create_identity_instance(cli_ctx, *args, **kwargs):
"""Lazily import and create Identity instance to avoid unnecessary imports."""
from .auth.identity import Identity

# Only enable encryption for Windows (for now).
fallback = sys.platform.startswith('win32')

# EXPERIMENTAL: Use core.encrypt_token_cache=False to turn off token cache encryption.
# encrypt_token_cache affects both MSAL token cache and service principal entries.
encrypt = cli_ctx.config.getboolean('core', 'encrypt_token_cache', fallback=fallback)
from .util import should_encrypt_token_cache
encrypt = should_encrypt_token_cache(cli_ctx)

# EXPERIMENTAL: Use core.use_msal_http_cache=False to turn off MSAL HTTP cache.
use_msal_http_cache = cli_ctx.config.getboolean('core', 'use_msal_http_cache', fallback=True)
Expand Down
24 changes: 24 additions & 0 deletions src/azure-cli-core/azure/cli/core/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -1305,3 +1305,27 @@ def rmtree_with_retry(path):
else:
logger.warning("Failed to delete '%s': %s. You may try to delete it manually.", path, err)
break


def get_secret_store(cli_ctx, name):
"""Create a process-concurrency-safe azure.cli.core.auth.persistence.SecretStore instance that can be used to
save secret data.
"""
from azure.cli.core._environment import get_config_dir
from azure.cli.core.auth.persistence import load_secret_store
# Save to CLI's config dir, by default ~/.azure
location = os.path.join(get_config_dir(), name)
# We honor the system type (Windows, Linux, or MacOS) and global config
encrypt = should_encrypt_token_cache(cli_ctx)
return load_secret_store(location, encrypt)


def should_encrypt_token_cache(cli_ctx):
# Only enable encryption for Windows (for now).
fallback = sys.platform.startswith('win32')

# EXPERIMENTAL: Use core.encrypt_token_cache=False to turn off token cache encryption.
# encrypt_token_cache affects both MSAL token cache and service principal entries.
encrypt = cli_ctx.config.getboolean('core', 'encrypt_token_cache', fallback=fallback)

return encrypt
18 changes: 18 additions & 0 deletions src/azure-cli/azure/cli/command_modules/util/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,21 @@
type: command
short-summary: A demo showing supported text styles.
"""

helps['demo secret-store'] = """
type: group
short-summary: A demo showing how to use secret store.
"""

helps['demo secret-store save'] = """
type: command
short-summary: Save custom data to secret store.
examples:
- name: Save data to secret store.
text: az demo secret-store save "name=Johann Sebastian Bach" job=musician
"""

helps['demo secret-store load'] = """
type: command
short-summary: Load custom data from secret store.
"""
3 changes: 3 additions & 0 deletions src/azure-cli/azure/cli/command_modules/util/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@ def load_arguments(self, _):
with self.argument_context('demo style') as c:
c.argument('theme', arg_type=get_enum_type(Theme),
help='The theme to format styled text. If unspecified, the default theme is used.')

with self.argument_context('demo secret-store save') as c:
c.positional('key_value', nargs='+', help="Space-separated data: <key>=<value> [<key>=<value> ...]")
4 changes: 4 additions & 0 deletions src/azure-cli/azure/cli/command_modules/util/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ def load_command_table(self, _):

with self.command_group('demo', deprecate_info=g.deprecate(hide=True)) as g:
g.custom_command('style', 'demo_style')

with self.command_group('demo secret-store') as g:
g.custom_command('save', 'secret_store_save')
g.custom_command('load', 'secret_store_load')
16 changes: 16 additions & 0 deletions src/azure-cli/azure/cli/command_modules/util/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
logger = get_logger(__name__)

UPGRADE_MSG = 'Not able to upgrade automatically. Instructions can be found at https://aka.ms/doc/InstallAzureCli'
SECRET_STORE_DEMO = "secret_store_demo"


def rest_call(cmd, url, method=None, headers=None, uri_parameters=None,
Expand Down Expand Up @@ -321,3 +322,18 @@ def demo_style(cmd, theme=None): # pylint: disable=unused-argument
logger.warning("This is a warning log entry.")
logger.error("This is a error log entry.")
logger.critical("This is a critical log entry.")


def secret_store_save(cmd, key_value):
data = dict(kv.split('=', 1) for kv in key_value)
from azure.cli.core.util import get_secret_store
store = get_secret_store(cmd.cli_ctx, SECRET_STORE_DEMO)
store.save(data)
logger.warning("Data written to %s: %s",
store._persistence.get_location(), data) # pylint: disable=protected-access


def secret_store_load(cmd):
from azure.cli.core.util import get_secret_store
store = get_secret_store(cmd.cli_ctx, SECRET_STORE_DEMO)
return store.load()
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
# exclusions for the util module

demo secret-store save:
parameters:
key_value:
rule_exclusions:
- no_positional_parameters
...