def setUp(self): super(AppConfigurationClientTest, self).setUp() self.test_config_setting = self._add_for_test( ConfigurationSetting( key=KEY, label=LABEL, value=TEST_VALUE, content_type=TEST_CONTENT_TYPE, tags={ "tag1": "tag1", "tag2": "tag2" }, )) self.test_config_setting_no_label = self._add_for_test( ConfigurationSetting( key=KEY, label=None, value=TEST_VALUE, content_type=TEST_CONTENT_TYPE, tags={ "tag1": "tag1", "tag2": "tag2" }, )) self.to_delete = [ self.test_config_setting, self.test_config_setting_no_label ]
def test_sync_tokens(self, client): sync_tokens = copy.deepcopy(client.obj._sync_token_policy._sync_tokens) sync_token_header = self._order_dict(sync_tokens) sync_token_header = ",".join(str(x) for x in sync_token_header.values()) new = ConfigurationSetting( key="KEY1", label=None, value="TEST_VALUE1", content_type=TEST_CONTENT_TYPE, tags={"tag1": "tag1", "tag2": "tag2"}, ) sent = client.set_configuration_setting(new) sync_tokens2 = copy.deepcopy(client.obj._sync_token_policy._sync_tokens) sync_token_header2 = self._order_dict(sync_tokens2) sync_token_header2 = ",".join(str(x) for x in sync_token_header2.values()) assert sync_token_header != sync_token_header2 new = ConfigurationSetting( key="KEY2", label=None, value="TEST_VALUE2", content_type=TEST_CONTENT_TYPE, tags={"tag1": "tag1", "tag2": "tag2"}, ) sent = client.set_configuration_setting(new) sync_tokens3 = copy.deepcopy(client.obj._sync_token_policy._sync_tokens) sync_token_header3 = self._order_dict(sync_tokens3) sync_token_header3 = ",".join(str(x) for x in sync_token_header3.values()) assert sync_token_header2 != sync_token_header3
def test_set_configuration_setting_etag(self, client, appconfiguration_connection_string, test_config_setting, test_config_setting_no_label): kv = ConfigurationSetting( key=KEY + "_SET", label=LABEL, value=TEST_VALUE, content_type=TEST_CONTENT_TYPE, tags={"tag1": "tag1", "tag2": "tag2"}, ) kv.etag = "random etag" with pytest.raises(ResourceModifiedError): client.set_configuration_setting(kv, match_condition=MatchConditions.IfNotModified)
def wrapper(*args, **kwargs): appconfiguration_connection_string = kwargs.pop( "appconfiguration_connection_string") client = AzureAppConfigurationClient.from_connection_string( appconfiguration_connection_string) kwargs['client'] = client kwargs[ 'appconfiguration_connection_string'] = appconfiguration_connection_string # Do setUp on client test_config_setting = _add_for_test( client, ConfigurationSetting( key=KEY, label=LABEL, value=TEST_VALUE, content_type=TEST_CONTENT_TYPE, tags={ "tag1": "tag1", "tag2": "tag2" }, )) test_config_setting_no_label = _add_for_test( client, ConfigurationSetting( key=KEY, label=None, value=TEST_VALUE, content_type=TEST_CONTENT_TYPE, tags={ "tag1": "tag1", "tag2": "tag2" }, )) to_delete = [test_config_setting, test_config_setting_no_label] kwargs['test_config_setting'] = test_config_setting kwargs['test_config_setting_no_label'] = test_config_setting_no_label trimmed_kwargs = {k: v for k, v in kwargs.items()} trim_kwargs_from_test_function(func, trimmed_kwargs) func(*args, **trimmed_kwargs) for item in to_delete: try: client.delete_configuration_setting(key=item.key, label=item.label) except: print("Issue deleting config with key {} and label {}".format( item.key, item.label))
def test_list_configuration_settings_multi_pages(self): # create PAGE_SIZE+1 configuration settings to have at least two pages try: delete_me = [ self.app_config_client.add_configuration_setting( ConfigurationSetting( key="multi_" + str(i) + KEY_UUID, label="multi_label_" + str(i), value="multi value", ) ) for i in range(PAGE_SIZE + 1) ] except ResourceExistsError: pass items = self.app_config_client.list_configuration_settings(keys=["multi_*"]) assert len(list(items)) > PAGE_SIZE # Remove the configuration settings try: [ self.app_config_client.delete_configuration_setting( key="multi_" + str(i) + KEY_UUID, label="multi_label_" + str(i) ) for i in range(PAGE_SIZE + 1) ] except AzureError: pass
def main(): CONNECTION_STRING = get_connection_string() # Create app config client client = AzureAppConfigurationClient.from_connection_string( CONNECTION_STRING) print("Add new configuration setting") config_setting = ConfigurationSetting(key="MyKey", label="MyLabel", value="my value", content_type="my content type", tags={"my tag": "my tag value"}) added_config_setting = client.add_configuration_setting(config_setting) print("New configuration setting:") print_configuration_setting(added_config_setting) print("") print("Set configuration setting") added_config_setting.value = "new value" added_config_setting.content_type = "new content type" updated_config_setting = client.set_configuration_setting(config_setting) print_configuration_setting(updated_config_setting) print("") print("List configuration settings") config_settings = client.list_configuration_settings(labels=["MyLabel"]) for item in config_settings: print_configuration_setting(item) print("Delete configuration setting") client.delete_configuration_setting( key="MyKey", label="MyLabel", )
def test_add_existing_configuration_setting(self): with pytest.raises(ResourceExistsError): self.app_config_client.add_configuration_setting( ConfigurationSetting( key=self.test_config_setting.key, lable=self.test_config_setting.label, ))
async def main(): CONNECTION_STRING = get_connection_string() # Create app config client client = AzureAppConfigurationClient.from_connection_string( CONNECTION_STRING) print("Set new configuration setting") config_setting = ConfigurationSetting(key="MyKey", value="my value", content_type="my content type", tags={"my tag": "my tag value"}) returned_config_setting = await client.set_configuration_setting( config_setting) print("New configuration setting:") print_configuration_setting(returned_config_setting) print("") print("Get configuration setting") fetched_config_setting = await client.get_configuration_setting(key="MyKey" ) print("Fetched configuration setting:") print_configuration_setting(fetched_config_setting) print("") print("Delete configuration setting") await client.delete_configuration_setting(key="MyKey")
def test_list_configuration_settings_multi_pages(self, appconfiguration_endpoint_string, test_config_setting, test_config_setting_no_label): client = self.create_aad_client(appconfiguration_endpoint_string) # create PAGE_SIZE+1 configuration settings to have at least two pages try: delete_me = [ client.add_configuration_setting( ConfigurationSetting( key="multi_" + str(i) + KEY_UUID, label="multi_label_" + str(i), value="multi value", ) ) for i in range(PAGE_SIZE + 1) ] except ResourceExistsError: pass items = client.list_configuration_settings(key_filter="multi_*") assert len(list(items)) > PAGE_SIZE # Remove the configuration settings try: [ client.delete_configuration_setting( key="multi_" + str(i) + KEY_UUID, label="multi_label_" + str(i) ) for i in range(PAGE_SIZE + 1) ] except AzureError: pass
def __update_existing_key_value(azconfig_client, retrieved_kv, updated_value): ''' To update the value of a pre-existing KeyValue Args: azconfig_client - AppConfig client making calls to the service retrieved_kv - Pre-existing ConfigurationSetting object updated_value - Value string to be updated Return: KeyValue object ''' set_kv = ConfigurationSetting(key=retrieved_kv.key, value=updated_value, label=retrieved_kv.label, tags=retrieved_kv.tags, content_type=FeatureFlagConstants.FEATURE_FLAG_CONTENT_TYPE, read_only=retrieved_kv.read_only, etag=retrieved_kv.etag, last_modified=retrieved_kv.last_modified) try: new_kv = azconfig_client.set_configuration_setting(set_kv, match_condition=MatchConditions.IfNotModified) return convert_configurationsetting_to_keyvalue(new_kv) except ResourceReadOnlyError: raise CLIError("Failed to update read only feature flag. Unlock the feature flag before updating it.")
async def main(): CONNECTION_STRING = get_connection_string() # Create app config client client = AzureAppConfigurationClient.from_connection_string(CONNECTION_STRING) config_setting = ConfigurationSetting( key="MyKey", value="my value", content_type="my content type", tags={"my tag": "my tag value"} ) returned_config_setting = await client.set_configuration_setting(config_setting) returned_config_setting.value = "new value" returned_config_setting.content_type = "new content type" await client.set_configuration_setting(config_setting) items = client.list_revisions(key_filter="MyKey") async for item in items: print_configuration_setting(item) print("") await client.delete_configuration_setting( key="MyKey", )
async def global_setup(self): await super().global_setup() kv = ConfigurationSetting( key=self.key, value="VALUE", ) await self.async_service_client.set_configuration_setting(kv)
def main(): CONNECTION_STRING = get_connection_string() # Create app config client client = AzureAppConfigurationClient.from_connection_string( CONNECTION_STRING) print("Set new configuration setting") config_setting = ConfigurationSetting(key="MyKey", value="my value", content_type="my content type", tags={"my tag": "my tag value"}) returned_config_setting = client.set_configuration_setting(config_setting) print("New configuration setting:") print_configuration_setting(returned_config_setting) print("") print("Read only configuration setting:") read_only_config_setting = client.set_read_only(returned_config_setting) print_configuration_setting(read_only_config_setting) print("") print("Clear read only configuration setting:") read_write_config_setting = client.clear_read_only(returned_config_setting) print_configuration_setting(read_write_config_setting) print("") print("Delete configuration setting") client.delete_configuration_setting(key="MyKey", )
def test_add_configuration_setting(self, client, appconfiguration_connection_string, test_config_setting, test_config_setting_no_label): kv = ConfigurationSetting( key=KEY + "_ADD", label=LABEL, value=TEST_VALUE, content_type=TEST_CONTENT_TYPE, tags={"tag1": "tag1", "tag2": "tag2"}, ) created_kv = client.add_configuration_setting(kv) assert ( created_kv.label == kv.label and kv.value == kv.value and created_kv.content_type == kv.content_type and created_kv.tags == kv.tags ) assert ( created_kv.etag is not None and created_kv.last_modified is not None and created_kv.read_only is False ) created_kv.value = None created_kv.value = "" client.delete_configuration_setting( created_kv.key, created_kv.label )
def test_add_existing_configuration_setting(self, client, appconfiguration_connection_string, test_config_setting, test_config_setting_no_label): with pytest.raises(ResourceExistsError): client.add_configuration_setting( ConfigurationSetting( key=test_config_setting.key, lable=test_config_setting.label, ) )
def test_add_existing_configuration_setting(self, appconfiguration_endpoint_string, test_config_setting, test_config_setting_no_label): client = self.create_aad_client(appconfiguration_endpoint_string) with pytest.raises(ResourceExistsError): client.add_configuration_setting( ConfigurationSetting( key=test_config_setting.key, lable=test_config_setting.label, ) )
def convert_keyvalue_to_configurationsetting(keyvalue=None): if keyvalue is None: return None return ConfigurationSetting(key=keyvalue.key, label=keyvalue.label, content_type=keyvalue.content_type, value=keyvalue.value, last_modified=keyvalue.last_modified, tags=keyvalue.tags, read_only=keyvalue.locked, etag=keyvalue.etag)
def test_list_configuration_settings_reserved_chars( self, client, appconfiguration_connection_string, test_config_setting, test_config_setting_no_label): resered_char_kv = ConfigurationSetting(key=KEY, label=LABEL_RESERVED_CHARS, value=TEST_VALUE) resered_char_kv = client.add_configuration_setting(resered_char_kv) escaped_label = re.sub(r"((?!^)\*(?!$)|\\|,)", r"\\\1", LABEL_RESERVED_CHARS) items = client.list_configuration_settings(label_filter=escaped_label) assert len(items) == 1 assert all(x.label == LABEL_RESERVED_CHARS for x in items)
def test_list_configuration_settings_reserved_chars(self): resered_char_kv = ConfigurationSetting(key=KEY, label=LABEL_RESERVED_CHARS, value=TEST_VALUE) resered_char_kv = self.app_config_client.add_configuration_setting( resered_char_kv) self.to_delete.append(resered_char_kv) escaped_label = re.sub(r"((?!^)\*(?!$)|\\|,)", r"\\\1", LABEL_RESERVED_CHARS) items = self.app_config_client.list_configuration_settings( label_filter=escaped_label) assert len(items) == 1 assert all(x.label == LABEL_RESERVED_CHARS for x in items)
def test_list_configuration_settings_reserved_chars(self): resered_char_kv = ConfigurationSetting(key=KEY, label=LABEL_RESERVED_CHARS, value=TEST_VALUE) resered_char_kv = self.get_config_client().add_configuration_setting( resered_char_kv) self.to_delete.append(resered_char_kv) items = self.get_config_client().list_configuration_settings( labels=[LABEL_RESERVED_CHARS]) cnt = 0 for kv in items: assert kv.label == LABEL_RESERVED_CHARS cnt += 1 assert cnt == 1
def _add_for_test(self, key, label): exist = bool( list( self.client.list_configuration_settings(keys=[key], labels=[label]))) if not exist: sc = ConfigurationSetting( key=key, label=label, value="my value", content_type="my content type", tags={"my tag": "my tag value"}, ) self.client.add_configuration_setting(sc)
def test_list_configuration_settings_reserved_chars( self, appconfiguration_endpoint_string, test_config_setting, test_config_setting_no_label): client = self.create_aad_client(appconfiguration_endpoint_string) resered_char_kv = ConfigurationSetting(key=KEY, label=LABEL_RESERVED_CHARS, value=TEST_VALUE) resered_char_kv = client.add_configuration_setting(resered_char_kv) escaped_label = re.sub(r"((?!^)\*(?!$)|\\|,)", r"\\\1", LABEL_RESERVED_CHARS) items = list( client.list_configuration_settings(label_filter=escaped_label)) assert len(items) == 1 assert all(x.label == LABEL_RESERVED_CHARS for x in items) client.delete_configuration_setting(resered_char_kv.key)
def create_kv(self, connection_str): from azure.appconfiguration import (AzureAppConfigurationClient, ConfigurationSetting) app_config_client = AzureAppConfigurationClient.from_connection_string( connection_str) kv = ConfigurationSetting(key=KEY, label=LABEL, value=TEST_VALUE, content_type=TEST_CONTENT_TYPE, tags={ "tag1": "tag1", "tag2": "tag2" }) created_kv = app_config_client.add_configuration_setting(kv) return created_kv
def test_set_configuration_setting_no_etag(self): to_set_kv = ConfigurationSetting( key=KEY + "_SET", label=LABEL, value=TEST_VALUE, content_type=TEST_CONTENT_TYPE, tags={ "tag1": "tag1", "tag2": "tag2" }, ) set_kv = self.app_config_client.set_configuration_setting(to_set_kv) self.to_delete.append(to_set_kv) assert (to_set_kv.key == set_kv.key and to_set_kv.label == set_kv.label and to_set_kv.value == set_kv.value and to_set_kv.content_type == set_kv.content_type and to_set_kv.tags == set_kv.tags and to_set_kv.etag != set_kv.etag)
def test_set_configuration_setting_no_etag(self, client, appconfiguration_connection_string, test_config_setting, test_config_setting_no_label): to_set_kv = ConfigurationSetting( key=KEY + "_SET", label=LABEL, value=TEST_VALUE, content_type=TEST_CONTENT_TYPE, tags={"tag1": "tag1", "tag2": "tag2"}, ) set_kv = client.set_configuration_setting(to_set_kv) self._delete_setting(client, to_set_kv) assert ( to_set_kv.key == set_kv.key and to_set_kv.label == set_kv.label and to_set_kv.value == set_kv.value and to_set_kv.content_type == set_kv.content_type and to_set_kv.tags == set_kv.tags and to_set_kv.etag != set_kv.etag )
def test_add_configuration_setting(self): kv = ConfigurationSetting( key=KEY + "_ADD", label=LABEL, value=TEST_VALUE, content_type=TEST_CONTENT_TYPE, tags={ "tag1": "tag1", "tag2": "tag2" }, ) created_kv = self.app_config_client.add_configuration_setting(kv) self.to_delete.append(created_kv) assert (created_kv.label == kv.label and kv.value == kv.value and created_kv.content_type == kv.content_type and created_kv.tags == kv.tags) assert (created_kv.etag is not None and created_kv.last_modified is not None and created_kv.read_only is False)
def main(): CONNECTION_STRING = get_connection_string() # Create app config client client = AzureAppConfigurationClient.from_connection_string( CONNECTION_STRING) # Unconditional set config_setting = ConfigurationSetting(key="MyKey", value="my value", content_type="my content type", tags={"my tag": "my tag value"}) client.set_configuration_setting(config_setting) # Unconditional get first_get = client.get_configuration_setting(key="MyKey") print_configuration_setting(first_get) # Conditional get, expect to return None because it is not modified second_get = client.get_configuration_setting( key="MyKey", etag=first_get.etag, match_condition=MatchConditions.IfModified) print_configuration_setting(second_get) # Conditional set first_get.value = "new value" client.set_configuration_setting( configuration_setting=first_get, match_condition=MatchConditions.IfNotModified) # Conditional set, expect to see error because it is modified try: client.set_configuration_setting( configuration_setting=first_get, match_condition=MatchConditions.IfNotModified) except ResourceModifiedError: pass client.delete_configuration_setting(key="MyKey")
def test_appconfig_client_sample(self): # This is not unit test code. Just to verify if these sample code snippets work. client = self.client # [START add_configuration_setting] config_setting = ConfigurationSetting( key="MyKey", label="MyLabel", value="my value", content_type="my content type", tags={"my tag": "my tag value"}, ) added_config_setting = client.add_configuration_setting(config_setting) # [END add_configuration_setting] # [START update_configuration_setting] updated_kv = client.update_configuration_setting( key="MyKey", label="MyLabel", value="my updated value", content_type=None, # None means not to update it tags={"my updated tag": "my updated tag value"} # TODO: etag handling ) # [END update_configuration_setting] # [START set_configuration_setting] config_setting = ConfigurationSetting( key="MyKey", label="MyLabel", value="my set value", content_type="my set content type", tags={"my set tag": "my set tag value"} # TODO: etag handling ) returned_config_setting = client.set_configuration_setting( config_setting) # [END set_configuration_setting] # [START get_configuration_setting] fetched_config_setting = client.get_configuration_setting( key="MyKey", label="MyLabel") # [END get_configuration_setting] # [START list_configuration_setting] from datetime import datetime, timedelta accept_date_time = datetime.today() + timedelta(days=-1) all_listed = client.list_configuration_settings() for item in all_listed: pass # do something filtered_listed = client.list_configuration_settings( labels=["*Labe*"], keys=["*Ke*"], accept_date_time=accept_date_time) for item in filtered_listed: pass # do something # [END list_configuration_setting] # [START list_revisions] from datetime import datetime, timedelta accept_date_time = datetime.today() + timedelta(days=-1) all_revisions = client.list_configuration_settings() for item in all_revisions: pass # do something filtered_revisions = client.list_revisions( labels=["*Labe*"], keys=["*Ke*"], accept_date_time=accept_date_time) for item in filtered_revisions: pass # do something # [END list_revisions] # [START delete_configuration_setting] deleted_config_setting = client.delete_configuration_setting( key="MyKey", label="MyLabel")
def set_keyvault(cmd, key, secret_identifier, name=None, label=None, tags=None, yes=False, connection_string=None, auth_mode="key", endpoint=None): azconfig_client = get_appconfig_data_client(cmd, name, connection_string, auth_mode, endpoint) keyvault_ref_value = json.dumps({"uri": secret_identifier}, ensure_ascii=False, separators=(',', ':')) retry_times = 3 retry_interval = 1 label = label if label and label != SearchFilterOptions.EMPTY_LABEL else None for i in range(0, retry_times): retrieved_kv = None set_kv = None new_kv = None try: retrieved_kv = azconfig_client.get_configuration_setting( key=key, label=label) except ResourceNotFoundError: logger.debug( "Key '%s' with label '%s' not found. A new key-vault reference will be created.", key, label) except HttpResponseError as exception: raise CLIError( "Failed to retrieve key-values from config store. " + str(exception)) if retrieved_kv is None: set_kv = ConfigurationSetting( key=key, label=label, value=keyvault_ref_value, content_type=KeyVaultConstants.KEYVAULT_CONTENT_TYPE, tags=tags) else: set_kv = ConfigurationSetting( key=key, label=label, value=keyvault_ref_value, content_type=KeyVaultConstants.KEYVAULT_CONTENT_TYPE, tags=retrieved_kv.tags if tags is None else tags, read_only=retrieved_kv.read_only, etag=retrieved_kv.etag) verification_kv = { "key": set_kv.key, "label": set_kv.label, "content_type": set_kv.content_type, "value": set_kv.value, "tags": set_kv.tags } entry = json.dumps(verification_kv, indent=2, sort_keys=True, ensure_ascii=False) confirmation_message = "Are you sure you want to set the keyvault reference: \n" + entry + "\n" user_confirmation(confirmation_message, yes) try: if set_kv.etag is None: new_kv = azconfig_client.add_configuration_setting(set_kv) else: new_kv = azconfig_client.set_configuration_setting( set_kv, match_condition=MatchConditions.IfNotModified) return convert_configurationsetting_to_keyvalue(new_kv) except ResourceReadOnlyError: raise CLIError( "Failed to update read only key vault reference. Unlock the key vault reference before updating it." ) except HttpResponseError as exception: if exception.status_code == StatusCodes.PRECONDITION_FAILED: logger.debug( 'Retrying setting %s times with exception: concurrent setting operations', i + 1) time.sleep(retry_interval) else: raise CLIError( "Failed to set the keyvault reference due to an exception: " + str(exception)) except Exception as exception: raise CLIError( "Failed to set the keyvault reference due to an exception: " + str(exception)) raise CLIError( "Failed to set the keyvault reference '{}' due to a conflicting operation." .format(key))
def set_key(cmd, key, name=None, label=None, content_type=None, tags=None, value=None, yes=False, connection_string=None, auth_mode="key", endpoint=None): azconfig_client = get_appconfig_data_client(cmd, name, connection_string, auth_mode, endpoint) if content_type: if content_type.lower() == KeyVaultConstants.KEYVAULT_CONTENT_TYPE: logger.warning( "There is a dedicated command to set key vault reference. 'appconfig kv set-keyvault -h'" ) elif content_type.lower( ) == FeatureFlagConstants.FEATURE_FLAG_CONTENT_TYPE: logger.warning( "There is a dedicated command to set feature flag. 'appconfig feature set -h'" ) retry_times = 3 retry_interval = 1 label = label if label and label != SearchFilterOptions.EMPTY_LABEL else None for i in range(0, retry_times): retrieved_kv = None set_kv = None new_kv = None try: retrieved_kv = azconfig_client.get_configuration_setting( key=key, label=label) except ResourceNotFoundError: logger.debug( "Key '%s' with label '%s' not found. A new key-value will be created.", key, label) except HttpResponseError as exception: raise CLIError( "Failed to retrieve key-values from config store. " + str(exception)) if retrieved_kv is None: if content_type and __is_json_content_type(content_type): try: # Ensure that provided value is valid JSON. Error out if value is invalid JSON. value = 'null' if value is None else value json.loads(value) except ValueError: raise CLIError( 'Value "{}" is not a valid JSON object, which conflicts with the content type "{}".' .format(value, content_type)) set_kv = ConfigurationSetting(key=key, label=label, value=value, content_type=content_type, tags=tags) else: value = retrieved_kv.value if value is None else value content_type = retrieved_kv.content_type if content_type is None else content_type if content_type and __is_json_content_type(content_type): try: # Ensure that provided/existing value is valid JSON. Error out if value is invalid JSON. json.loads(value) except (TypeError, ValueError): raise CLIError( 'Value "{}" is not a valid JSON object, which conflicts with the content type "{}". Set the value again in valid JSON format.' .format(value, content_type)) set_kv = ConfigurationSetting( key=key, label=label, value=value, content_type=content_type, tags=retrieved_kv.tags if tags is None else tags, read_only=retrieved_kv.read_only, etag=retrieved_kv.etag) verification_kv = { "key": set_kv.key, "label": set_kv.label, "content_type": set_kv.content_type, "value": set_kv.value, "tags": set_kv.tags } entry = json.dumps(verification_kv, indent=2, sort_keys=True, ensure_ascii=False) confirmation_message = "Are you sure you want to set the key: \n" + entry + "\n" user_confirmation(confirmation_message, yes) try: if set_kv.etag is None: new_kv = azconfig_client.add_configuration_setting(set_kv) else: new_kv = azconfig_client.set_configuration_setting( set_kv, match_condition=MatchConditions.IfNotModified) return convert_configurationsetting_to_keyvalue(new_kv) except ResourceReadOnlyError: raise CLIError( "Failed to update read only key-value. Unlock the key-value before updating it." ) except HttpResponseError as exception: if exception.status_code == StatusCodes.PRECONDITION_FAILED: logger.debug( 'Retrying setting %s times with exception: concurrent setting operations', i + 1) time.sleep(retry_interval) else: raise CLIError( "Failed to set the key-value due to an exception: " + str(exception)) except Exception as exception: raise CLIError( "Failed to set the key-value due to an exception: " + str(exception)) raise CLIError( "Failed to set the key '{}' due to a conflicting operation.".format( key))