in src/azure-cli/azure/cli/command_modules/appconfig/keyvalue.py [0:0]
def import_config(cmd,
source,
name=None,
connection_string=None,
label=None,
prefix="", # prefix to add
yes=False,
skip_features=False,
content_type=None,
auth_mode="key",
endpoint=None,
import_mode=ImportMode.IGNORE_MATCH,
# from-file parameters
path=None,
format_=None,
separator=None,
depth=None,
profile=ImportExportProfiles.DEFAULT,
strict=False,
# from-configstore parameters
src_name=None,
src_connection_string=None,
src_key=None,
src_label=None,
src_snapshot=None,
preserve_labels=False,
src_auth_mode="key",
src_endpoint=None,
# from-appservice parameters
appservice_account=None):
src_features = []
dest_features = []
dest_kvs = []
source = source.lower()
profile = profile.lower()
format_ = format_.lower() if format_ else None
azconfig_client = get_appconfig_data_client(cmd, name, connection_string, auth_mode, endpoint)
# generate correlation_request_id for bulk operation
correlation_request_id = str(uuid.uuid4())
# fetch key values from source
if source == 'file':
if profile == ImportExportProfiles.KVSET:
__import_kvset_from_file(client=azconfig_client, path=path, strict=strict, yes=yes, import_mode=import_mode, correlation_request_id=correlation_request_id)
return
if format_ and content_type:
# JSON content type is only supported with JSON format.
# Error out if user has provided JSON content type with any other format.
if format_ != 'json' and is_json_content_type(content_type):
raise CLIErrors.FileOperationError("Failed to import '{}' file format with '{}' content type. Please provide JSON file format to match your content type.".format(format_, content_type))
if separator:
# If separator is provided, use max depth by default unless depth is specified.
depth = sys.maxsize if depth is None else int(depth)
else:
if depth and int(depth) != 1:
logger.warning("Cannot flatten hierarchical data without a separator. --depth argument will be ignored.")
depth = 1
src_kvs = __read_kv_from_file(file_path=path,
format_=format_,
separator=separator,
prefix_to_add=prefix,
depth=depth,
content_type=content_type)
if strict or not skip_features:
# src_features is a list of KeyValue objects
src_features = __read_features_from_file(file_path=path, format_=format_)
elif source == 'appconfig':
src_azconfig_client = get_appconfig_data_client(cmd, src_name, src_connection_string, src_auth_mode, src_endpoint)
if label is not None and preserve_labels:
raise CLIErrors.MutuallyExclusiveArgumentError("Import failed! Please provide only one of these arguments: '--label' or '--preserve-labels'. See 'az appconfig kv import -h' for examples.")
if preserve_labels:
# We need label to be the same as src_label for preview later.
# This will have no effect on label while writing to config store
# as we check preserve_labels again before labelling KVs.
label = src_label
src_kvs = __read_kv_from_config_store(src_azconfig_client,
key=src_key,
snapshot=src_snapshot,
label=src_label if src_label else SearchFilterOptions.EMPTY_LABEL,
prefix_to_add=prefix,
correlation_request_id=correlation_request_id)
if not skip_features:
if src_snapshot:
all_features = [kv for kv in src_kvs if kv.key.startswith(FeatureFlagConstants.FEATURE_FLAG_PREFIX)]
else:
# Get all Feature flags with matching label
all_features = __read_kv_from_config_store(src_azconfig_client,
key=FeatureFlagConstants.FEATURE_FLAG_PREFIX + '*',
label=src_label if src_label else SearchFilterOptions.EMPTY_LABEL,
correlation_request_id=correlation_request_id)
for feature in all_features:
if feature.content_type == FeatureFlagConstants.FEATURE_FLAG_CONTENT_TYPE:
src_features.append(feature)
# We need to separate KV from feature flags
__discard_features_from_retrieved_kv(src_kvs)
elif source == 'appservice':
src_kvs = __read_kv_from_app_service(
cmd, appservice_account=appservice_account, prefix_to_add=prefix, content_type=content_type)
if strict or not yes or import_mode == ImportMode.IGNORE_MATCH:
# fetch key values from user's configstore
dest_kvs = __read_kv_from_config_store(azconfig_client,
key=prefix + SearchFilterOptions.ANY_KEY if prefix else SearchFilterOptions.ANY_KEY,
label=label if label else SearchFilterOptions.EMPTY_LABEL,
correlation_request_id=correlation_request_id)
__discard_features_from_retrieved_kv(dest_kvs)
# if customer needs preview & confirmation
# generate preview and wait for user confirmation
kv_comparer = KVComparer(
src_kvs=src_kvs,
compare_fields=CompareFieldsMap[source],
preserve_labels=source == "appconfig" and preserve_labels,
label=label,
content_type=content_type)
kv_diff = kv_comparer.compare(dest_kvs=dest_kvs, strict=strict, ignore_matching_kvs=import_mode == ImportMode.IGNORE_MATCH)
# Show indented key-value preview similar to kvset for appconfig source
indent = 2 if source == "appconfig" else None
need_kv_change = print_preview(kv_diff, source, yes=yes, strict=strict, title="Key Values", indent=indent)
need_feature_change = False
ff_diff = {}
if strict or (src_features and not skip_features):
all_features = __read_kv_from_config_store(azconfig_client,
key=FeatureFlagConstants.FEATURE_FLAG_PREFIX + SearchFilterOptions.ANY_KEY,
label=label if label else SearchFilterOptions.EMPTY_LABEL,
correlation_request_id=correlation_request_id)
# Append all features to dest_features list
for feature in all_features:
if feature.content_type == FeatureFlagConstants.FEATURE_FLAG_CONTENT_TYPE:
dest_features.append(feature)
ff_comparer = KVComparer(
src_kvs=src_features,
compare_fields=CompareFieldsMap[source],
preserve_labels=source == "appconfig" and preserve_labels,
label=label)
ff_diff = ff_comparer.compare(dest_kvs=dest_features, strict=strict, ignore_matching_kvs=import_mode == ImportMode.IGNORE_MATCH)
need_feature_change = print_preview(ff_diff, source, yes=yes, strict=strict, title="Feature Flags")
if not need_kv_change and not need_feature_change:
return
if not yes:
user_confirmation("Do you want to continue? \n")
# append all feature flags to src_kvs list
src_kvs.extend(src_features)
# In strict mode, delete kvs with specific label that are missing from the imported file
if strict:
kvs_to_delete = chain(
kv_diff.get(JsonDiff.DELETE, []),
ff_diff.get(JsonDiff.DELETE, []))
for kv in kvs_to_delete:
__delete_configuration_setting_from_config_store(azconfig_client, kv)
# import into configstore
# write only added and updated kvs
if import_mode == ImportMode.IGNORE_MATCH:
kvs_to_write = []
kvs_to_write.extend(kv_diff.get(JsonDiff.ADD, []))
kvs_to_write.extend(ff_diff.get(JsonDiff.ADD, []))
kvs_to_write.extend(update["new"] for update in kv_diff.get(JsonDiff.UPDATE, []))
kvs_to_write.extend(update["new"] for update in ff_diff.get(JsonDiff.UPDATE, []))
# write all kvs
else:
kvs_to_write = src_kvs
__write_kv_and_features_to_config_store(azconfig_client,
key_values=kvs_to_write,
label=label,
preserve_labels=preserve_labels,
content_type=content_type,
correlation_request_id=correlation_request_id)