Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
bf00b70
FeatureManagement CLI Part 1 (#1)
avanigupta Sep 20, 2019
8c78d50
Merge branch 'dev' of https://github.com/avanigupta/azure-cli into dev
avanigupta Sep 20, 2019
61ef19e
Merge remote-tracking branch 'upstream/dev' into dev
avanigupta Sep 25, 2019
9fcb3fd
Merge remote-tracking branch 'upstream/dev' into dev
avanigupta Sep 27, 2019
9889cd3
Merge remote-tracking branch 'upstream/dev' into dev
avanigupta Oct 8, 2019
f2024c6
Final changes for feature management CLI (#2)
avanigupta Oct 8, 2019
f5c45a5
Fix styling issues
avanigupta Oct 8, 2019
d7cc069
String formatting for python 2.7 compatibility
avanigupta Oct 8, 2019
5026d7d
Python 2.7 compatibility for unit tests
avanigupta Oct 8, 2019
d8a5c39
fix id attribute for feature flag value
avanigupta Oct 8, 2019
c6d2881
Modify list feature default label behavior
avanigupta Oct 9, 2019
30aace3
Check content type for features
avanigupta Oct 9, 2019
7bb402b
CLI team's suggested changes
avanigupta Oct 15, 2019
c22469f
Merge remote-tracking branch 'upstream/dev' into dev
avanigupta Oct 15, 2019
abc3f20
Update test recordings
avanigupta Oct 15, 2019
e41bf4a
Merging with latest code
avanigupta Oct 16, 2019
84a58c7
Changing commands to custom_commands
avanigupta Oct 16, 2019
d5e7fcc
Stop reading dest file contents during export
avanigupta Oct 17, 2019
8fb3848
History file update
avanigupta Oct 17, 2019
d8bb37e
Merge with latest code
avanigupta Oct 17, 2019
83a8ff2
resolving conflict
avanigupta Oct 17, 2019
2902c69
changed empty label behavior for delete feature
avanigupta Oct 17, 2019
17b8f88
Change warning message
avanigupta Oct 17, 2019
f86293d
Removing label from FeatureFlagValue
avanigupta Oct 18, 2019
414e8e0
resolve conflicts
avanigupta Oct 21, 2019
f4fce0e
Use shell_safe_json_parse for deserialiization
avanigupta Oct 21, 2019
b655295
Merge branch 'dev' into dev
avanigupta Oct 22, 2019
b9a262f
Updating export for feature flags
avanigupta Oct 23, 2019
ffaa686
Merge remote-tracking branch 'upstream/dev' into dev
avanigupta Oct 23, 2019
de14a2f
Merge remote-tracking branch 'upstream/dev' into dev
avanigupta Nov 19, 2019
c3b3f75
Get latest code
avanigupta Nov 19, 2019
6441437
Feature export scenario updates
avanigupta Nov 26, 2019
261656f
Merge remote-tracking branch 'upstream/dev' into dev
avanigupta Nov 26, 2019
9d92fa2
Merge with latest code
avanigupta Nov 26, 2019
08dba5d
Import feature flags from json format
avanigupta Nov 27, 2019
738079b
Merge remote-tracking branch 'upstream/dev' into dev
avanigupta Dec 2, 2019
92cd9b6
Merge branch 'dev' into avanigupta/importexportfeatureflags
avanigupta Dec 2, 2019
3f8af31
Adding test
avanigupta Dec 3, 2019
878eb0f
Fix styling
avanigupta Dec 3, 2019
9348709
Merge remote-tracking branch 'upstream/dev' into dev
avanigupta Dec 3, 2019
fb71a76
Merge branch 'dev' into avanigupta/importexportfeatureflags
avanigupta Dec 3, 2019
5f550ae
Fix Styling
avanigupta Dec 3, 2019
79a4ccd
UPdate history file
avanigupta Dec 3, 2019
8a2e454
Add sample commands
avanigupta Dec 3, 2019
0850f42
improving help messages
avanigupta Dec 4, 2019
6302636
Split print preview of features and kv
avanigupta Dec 4, 2019
c0c50f0
Support alternate json format for ON/OFF features
avanigupta Dec 5, 2019
0fd0415
Adding more tests
avanigupta Dec 7, 2019
6b8b0e2
fix styling
avanigupta Dec 7, 2019
ddd84fa
Merge remote-tracking branch 'upstream/dev' into dev
avanigupta Dec 7, 2019
7ff2a02
Merge branch 'dev' into avanigupta/importexportfeatureflags
avanigupta Dec 7, 2019
6f6d400
Use knack logger and enum arg type
avanigupta Dec 9, 2019
bccd646
Merge branch 'dev' into avanigupta/importexportfeatureflags
avanigupta Dec 9, 2019
8f752dd
refactoring
avanigupta Dec 10, 2019
62f6b4c
Merge branch 'avanigupta/importexportfeatureflags' of https://github.…
avanigupta Dec 10, 2019
bf93ec8
disabling ensure_ascii for json dumps
avanigupta Dec 10, 2019
fc56f78
Resolving comments
avanigupta Dec 11, 2019
86fa8bd
Refactoring export command
avanigupta Dec 11, 2019
62033d0
Resolvong CLI side comments
avanigupta Dec 11, 2019
8c0e6fd
Resolving comments
avanigupta Dec 12, 2019
1135de9
Merge branch 'dev' into avanigupta/importexportfeatureflags
avanigupta Dec 12, 2019
934c227
Merge with latest code
avanigupta Dec 12, 2019
fbdc589
Update test recordings
avanigupta Dec 12, 2019
939bd41
merging history file
avanigupta Dec 12, 2019
ae05b0c
Rename default_value variable
avanigupta Dec 13, 2019
3600d16
Merge branch 'dev' into avanigupta/importexportfeatureflags
avanigupta Dec 13, 2019
bbda78f
fix history file
avanigupta Dec 13, 2019
f15f2b2
change separator for history file
avanigupta Dec 13, 2019
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
3 changes: 3 additions & 0 deletions src/azure-cli/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
Release History
===============

**AppConfig**

* Add support for importing/exporting feature flags

2.0.78

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
import json
from knack.log import get_logger
from azure.cli.core.util import shell_safe_json_parse
from ._azconfig.models import KeyValue

# pylint: disable=too-few-public-methods
# pylint: disable=too-many-instance-attributes

logger = get_logger(__name__)
FEATURE_FLAG_PREFIX = ".appconfig.featureflag/"
FEATURE_FLAG_CONTENT_TYPE = "application/vnd.microsoft.appconfig.ff+json;charset=utf-8"

# Feature Flag Models #

Expand Down Expand Up @@ -53,10 +55,12 @@ def __init__(self,
description=None,
enabled=None,
conditions=None):
default_conditions = {'client_filters': []}

self.id = id_
self.description = description
self.enabled = enabled
self.conditions = conditions
self.enabled = enabled if enabled else False
self.conditions = conditions if conditions else default_conditions

def __repr__(self):
featureflagvalue = {
Expand All @@ -66,7 +70,7 @@ def __repr__(self):
"conditions": custom_serialize_conditions(self.conditions)
}

return json.dumps(featureflagvalue, indent=2)
return json.dumps(featureflagvalue, indent=2, ensure_ascii=False)


class FeatureFlag(object):
Expand Down Expand Up @@ -118,7 +122,7 @@ def __repr__(self):
"Conditions": custom_serialize_conditions(self.conditions)
}

return json.dumps(featureflag, indent=2)
return json.dumps(featureflag, indent=2, ensure_ascii=False)


class FeatureFilter(object):
Expand All @@ -142,7 +146,7 @@ def __repr__(self):
"name": self.name,
"parameters": self.parameters
}
return json.dumps(featurefilter, indent=2)
return json.dumps(featurefilter, indent=2, ensure_ascii=False)

# Feature Flag Helper Functions #

Expand All @@ -167,6 +171,48 @@ def custom_serialize_conditions(conditions_dict):
return featurefilterdict


def map_featureflag_to_keyvalue(featureflag):
'''
Helper Function to convert FeatureFlag object to KeyValue object

Args:
featureflag - FeatureFlag object to be converted

Return:
KeyValue object
'''
try:
enabled = False
if featureflag.state in ("on", "conditional"):
enabled = True

feature_flag_value = FeatureFlagValue(id_=featureflag.key,
description=featureflag.description,
enabled=enabled,
conditions=featureflag.conditions)

set_kv = KeyValue(key=FEATURE_FLAG_PREFIX + featureflag.key,
label=featureflag.label,
value=json.dumps(feature_flag_value,
default=lambda o: o.__dict__,
ensure_ascii=False),
content_type=FEATURE_FLAG_CONTENT_TYPE,
tags={})

set_kv.locked = featureflag.locked
set_kv.last_modified = featureflag.last_modified

except ValueError as exception:
error_msg = "Exception while converting feature flag to key value: {0}\n{1}".format(featureflag.key, exception)
raise ValueError(error_msg)

except Exception as exception:
error_msg = "Exception while converting feature flag to key value: {0}\n{1}".format(featureflag.key, exception)
raise Exception(error_msg)

return set_kv


def map_keyvalue_to_featureflag(keyvalue, show_conditions=True):
'''
Helper Function to convert KeyValue object to FeatureFlag object for display
Expand Down Expand Up @@ -223,8 +269,6 @@ def map_keyvalue_to_featureflagvalue(keyvalue):
Valid FeatureFlagValue object
'''

default_conditions = {'client_filters': []}

try:
# Make sure value string is a valid json
feature_flag_dict = shell_safe_json_parse(keyvalue.value)
Expand All @@ -240,22 +284,23 @@ def map_keyvalue_to_featureflagvalue(keyvalue):
logger.debug("'%s' feature flag is missing required values or it contains ", feature_name +
"unsupported values. Setting missing value to defaults and ignoring unsupported values\n")

conditions = feature_flag_dict.get('conditions', default_conditions)
client_filters = conditions.get('client_filters', [])

# Convert all filters to FeatureFilter objects
client_filters_list = []
for client_filter in client_filters:
# If there is a filter, it should always have a name
# In case it doesn't, ignore this filter
name = client_filter.get('name')
if name:
params = client_filter.get('parameters', {})
client_filters_list.append(FeatureFilter(name, params))
else:
logger.warning("Ignoring this filter without the 'name' attribute:\n%s",
json.dumps(client_filter, indent=2))
conditions['client_filters'] = client_filters_list
conditions = feature_flag_dict.get('conditions', None)
if conditions:
client_filters = conditions.get('client_filters', [])

# Convert all filters to FeatureFilter objects
client_filters_list = []
for client_filter in client_filters:
# If there is a filter, it should always have a name
# In case it doesn't, ignore this filter
name = client_filter.get('name')
if name:
params = client_filter.get('parameters', {})
client_filters_list.append(FeatureFilter(name, params))
else:
logger.warning("Ignoring this filter without the 'name' attribute:\n%s",
json.dumps(client_filter, indent=2, ensure_ascii=False))
conditions['client_filters'] = client_filters_list

feature_flag_value = FeatureFlagValue(id_=feature_name,
description=feature_flag_dict.get(
Expand Down
16 changes: 10 additions & 6 deletions src/azure-cli/azure/cli/command_modules/appconfig/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,24 +68,28 @@
type: command
short-summary: Export configurations to another place from your App Configuration.
examples:
- name: Export all keys with label test to a json file.
- name: Export all keys and feature flags with label test to a json file.
text: az appconfig kv export -n MyAppConfiguration --label test -d file --path D:/abc.json --format json
- name: Export all keys with null label to another App Configuration.
- name: Export all keys and feature flags with null label to another App Configuration.
text: az appconfig kv export -n MyAppConfiguration -d appconfig --dest-name AnotherAppConfiguration
- name: Export all keys with null label to an App Service appliaction.
- name: Export all keys with null label to an App Service application.
text: az appconfig kv export -n MyAppConfiguration -d appservice --appservice-account MyAppService
- name: Export all keys with label test excluding feature flags to a json file.
text: az appconfig kv export -n MyAppConfiguration --label test -d file --path D:/abc.json --format json --skip-features
"""

helps['appconfig kv import'] = """
type: command
short-summary: Import configurations into your App Configuration from another place.
examples:
- name: Import all keys with label test from a file.
- name: Import all keys and feature flags from a file and apply test label.
text: az appconfig kv import -n MyAppConfiguration --label test -s file --path D:/abc.json --format json
- name: Import all keys with null label from an App Configuration.
- name: Import all keys and feature flags and apply null label from an App Configuration.
text: az appconfig kv import -n MyAppConfiguration -s appconfig --src-name AnotherAppConfiguration
- name: Import all keys with null label from an App Service appliaction.
- name: Import all keys and apply null label from an App Service appliaction.
text: az appconfig kv import -n MyAppConfiguration -s appservice --appservice-account MyAppService
- name: Import all keys with label test and apply test2 label excluding feature flags from an App Configuration.
text: az appconfig kv import -n MyAppConfiguration -s appconfig --src-label test --label test2 --src-name AnotherAppConfiguration --skip-features
"""

helps['appconfig kv list'] = """
Expand Down
Loading