This commit updates the mailmap file and changes my alias in a few places within old comments. Change-Id: Ica0e184109d794b8e129d567b5606d7fe84ff384tags/15.0.0
@@ -2,3 +2,4 @@ | |||
# <preferred e-mail> <other e-mail 1> | |||
# <preferred e-mail> <other e-mail 2> | |||
Joe Gordon <joe.gordon0@gmail.com> <jogo@cloudscaling.com> | |||
Aeva Black <aeva.online@gmail.com> <devananda.vdv@gmail.com> |
@@ -1639,7 +1639,7 @@ function create_ironic_accounts { | |||
"$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT" | |||
# Create ironic service user | |||
# TODO(deva): make this work with the 'service' role | |||
# TODO(tenbrae): make this work with the 'service' role | |||
# https://bugs.launchpad.net/ironic/+bug/1605398 | |||
create_service_user "ironic" "admin" | |||
@@ -367,7 +367,7 @@ class DriversController(rest.RestController): | |||
@expose.expose(DriverList, str, types.boolean) | |||
def get_all(self, type=None, detail=None): | |||
"""Retrieve a list of drivers.""" | |||
# FIXME(deva): formatting of the auto-generated REST API docs | |||
# FIXME(tenbrae): formatting of the auto-generated REST API docs | |||
# will break from a single-line doc string. | |||
# This is a result of a bug in sphinxcontrib-pecanwsme | |||
# https://github.com/dreamhost/sphinxcontrib-pecanwsme/issues/8 | |||
@@ -1265,8 +1265,8 @@ class Node(base.APIBase): | |||
retired_reason = wsme.wsattr(str) | |||
"""Indicates the reason for a node's retirement.""" | |||
# NOTE(deva): "conductor_affinity" shouldn't be presented on the | |||
# API because it's an internal value. Don't add it here. | |||
# NOTE(tenbrae): "conductor_affinity" shouldn't be presented on the | |||
# API because it's an internal value. Don't add it here. | |||
def __init__(self, **kwargs): | |||
self.fields = [] | |||
@@ -1399,10 +1399,10 @@ class Node(base.APIBase): | |||
:type fields: list of str | |||
""" | |||
cdict = api.request.context.to_policy_values() | |||
# NOTE(deva): the 'show_password' policy setting name exists for legacy | |||
# purposes and can not be changed. Changing it will cause | |||
# upgrade problems for any operators who have customized | |||
# the value of this field | |||
# NOTE(tenbrae): the 'show_password' policy setting name exists for | |||
# legacy purposes and can not be changed. Changing it will | |||
# cause upgrade problems for any operators who have | |||
# customized the value of this field | |||
show_driver_secrets = policy.check("show_password", cdict, cdict) | |||
show_instance_secrets = policy.check("show_instance_secrets", | |||
cdict, cdict) | |||
@@ -1421,7 +1421,7 @@ class Node(base.APIBase): | |||
if not show_instance_secrets and self.instance_info != wtypes.Unset: | |||
self.instance_info = strutils.mask_dict_password( | |||
self.instance_info, "******") | |||
# NOTE(deva): agent driver may store a swift temp_url on the | |||
# NOTE(tenbrae): agent driver may store a swift temp_url on the | |||
# instance_info, which shouldn't be exposed to non-admin users. | |||
# Now that ironic supports additional policies, we need to hide | |||
# it here, based on this policy. | |||
@@ -2231,8 +2231,8 @@ class NodesController(rest.RestController): | |||
msg = _("Allocation UUID cannot be specified, use allocations API") | |||
raise exception.Invalid(msg) | |||
# NOTE(deva): get_topic_for checks if node.driver is in the hash ring | |||
# and raises NoValidHost if it is not. | |||
# NOTE(tenbrae): get_topic_for checks if node.driver is in the hash | |||
# ring and raises NoValidHost if it is not. | |||
# We need to ensure that node has a UUID before it can | |||
# be mapped onto the hash ring. | |||
if not node.uuid: | |||
@@ -2241,7 +2241,7 @@ class NodesController(rest.RestController): | |||
try: | |||
topic = api.request.rpcapi.get_topic_for(node) | |||
except exception.NoValidHost as e: | |||
# NOTE(deva): convert from 404 to 400 because client can see | |||
# NOTE(tenbrae): convert from 404 to 400 because client can see | |||
# list of available drivers and shouldn't request | |||
# one that doesn't exist. | |||
e.code = http_client.BAD_REQUEST | |||
@@ -2400,14 +2400,14 @@ class NodesController(rest.RestController): | |||
node_dict['chassis_uuid'] = node_dict.pop('chassis_id', None) | |||
node = Node(**api_utils.apply_jsonpatch(node_dict, patch)) | |||
self._update_changed_fields(node, rpc_node) | |||
# NOTE(deva): we calculate the rpc topic here in case node.driver | |||
# NOTE(tenbrae): we calculate the rpc topic here in case node.driver | |||
# has changed, so that update is sent to the | |||
# new conductor, not the old one which may fail to | |||
# load the new driver. | |||
try: | |||
topic = api.request.rpcapi.get_topic_for(rpc_node) | |||
except exception.NoValidHost as e: | |||
# NOTE(deva): convert from 404 to 400 because client can see | |||
# NOTE(tenbrae): convert from 404 to 400 because client can see | |||
# list of available drivers and shouldn't request | |||
# one that doesn't exist. | |||
e.code = http_client.BAD_REQUEST | |||
@@ -294,9 +294,9 @@ class BaseDriverFactory(object): | |||
This is subclassed to load both main drivers and extra interfaces. | |||
""" | |||
# NOTE(deva): loading the _extension_manager as a class member will break | |||
# stevedore when it loads a driver, because the driver will | |||
# import this file (and thus instantiate another factory). | |||
# NOTE(tenbrae): loading the _extension_manager as a class member will | |||
# break stevedore when it loads a driver, because the driver | |||
# will import this file (and thus instantiate another factory). | |||
# Instead, we instantiate a NameDispatchExtensionManager only | |||
# once, the first time DriverFactory.__init__ is called. | |||
_extension_manager = None | |||
@@ -322,12 +322,12 @@ class BaseDriverFactory(object): | |||
def get_driver(self, name): | |||
return self[name].obj | |||
# NOTE(deva): Use lockutils to avoid a potential race in eventlet | |||
# NOTE(tenbrae): Use lockutils to avoid a potential race in eventlet | |||
# that might try to create two driver factories. | |||
@classmethod | |||
@lockutils.synchronized(EM_SEMAPHORE) | |||
def _init_extension_manager(cls): | |||
# NOTE(deva): In case multiple greenthreads queue up on this lock | |||
# NOTE(tenbrae): In case multiple greenthreads queue up on this lock | |||
# before _extension_manager is initialized, prevent | |||
# creation of multiple NameDispatchExtensionManagers. | |||
if cls._extension_manager: | |||
@@ -356,8 +356,8 @@ class BaseDriverFactory(object): | |||
'configuration file.', | |||
', '.join(duplicated_drivers)) | |||
# NOTE(deva): Drivers raise "DriverLoadError" if they are unable to be | |||
# loaded, eg. due to missing external dependencies. | |||
# NOTE(tenbrae): Drivers raise "DriverLoadError" if they are unable to | |||
# be loaded, eg. due to missing external dependencies. | |||
# We capture that exception, and, only if it is for an | |||
# enabled driver, raise it from here. If enabled driver | |||
# raises other exception type, it is wrapped in | |||
@@ -365,7 +365,7 @@ class BaseDriverFactory(object): | |||
# caused it, and raised. If the exception is for a | |||
# non-enabled driver, we suppress it. | |||
def _catch_driver_not_found(mgr, ep, exc): | |||
# NOTE(deva): stevedore loads plugins *before* evaluating | |||
# NOTE(tenbrae): stevedore loads plugins *before* evaluating | |||
# _check_func, so we need to check here, too. | |||
if ep.name in cls._enabled_driver_list: | |||
if not isinstance(exc, exception.DriverLoadError): | |||
@@ -52,7 +52,8 @@ class TemporaryFailure(IronicException): | |||
class NotAcceptable(IronicException): | |||
# TODO(deva): We need to set response headers in the API for this exception | |||
# TODO(tenbrae): We need to set response headers in the API | |||
# for this exception | |||
_msg_fmt = _("Request not acceptable.") | |||
code = http_client.NOT_ACCEPTABLE | |||
@@ -41,7 +41,7 @@ default_policies = [ | |||
'is_public_api:True', | |||
description='Internal flag for public API routes'), | |||
# Generic default to hide passwords in node driver_info | |||
# NOTE(deva): the 'show_password' policy setting hides secrets in | |||
# NOTE(tenbrae): the 'show_password' policy setting hides secrets in | |||
# driver_info. However, the name exists for legacy | |||
# purposes and can not be changed. Changing it will cause | |||
# upgrade problems for any operators who have customized | |||
@@ -74,7 +74,7 @@ default_policies = [ | |||
description='Owner of allocation'), | |||
] | |||
# NOTE(deva): to follow policy-in-code spec, we define defaults for | |||
# NOTE(tenbrae): to follow policy-in-code spec, we define defaults for | |||
# the granular policies in code, rather than in policy.json. | |||
# All of these may be overridden by configuration, but we can | |||
# depend on their existence throughout the code. | |||
@@ -581,7 +581,7 @@ def init_enforcer(policy_file=None, rules=None, | |||
if _ENFORCER: | |||
return | |||
# NOTE(deva): Register defaults for policy-in-code here so that they are | |||
# NOTE(tenbrae): Register defaults for policy-in-code here so that they are | |||
# loaded exactly once - when this module-global is initialized. | |||
# Defining these in the relevant API modules won't work | |||
# because API classes lack singletons and don't use globals. | |||
@@ -622,7 +622,7 @@ def get_oslo_policy_enforcer(): | |||
return get_enforcer() | |||
# NOTE(deva): We can't call these methods from within decorators because the | |||
# NOTE(tenbrae): We can't call these methods from within decorators because the | |||
# 'target' and 'creds' parameter must be fetched from the call time | |||
# context-local pecan.request magic variable, but decorators are compiled | |||
# at module-load time. | |||
@@ -38,7 +38,7 @@ LOG = logging.getLogger(__name__) | |||
# Provisioning states | |||
##################### | |||
# TODO(deva): add add'l state mappings here | |||
# TODO(tenbrae): add add'l state mappings here | |||
VERBS = { | |||
'active': 'deploy', | |||
'deleted': 'delete', | |||
@@ -315,7 +315,7 @@ for state in STABLE_STATES: | |||
machine.add_state(VERIFYING, target=MANAGEABLE, **watchers) | |||
# Add deploy* states | |||
# NOTE(deva): Juno shows a target_provision_state of DEPLOYDONE | |||
# NOTE(tenbrae): Juno shows a target_provision_state of DEPLOYDONE | |||
# this is changed in Kilo to ACTIVE | |||
machine.add_state(DEPLOYING, target=ACTIVE, **watchers) | |||
machine.add_state(DEPLOYWAIT, target=ACTIVE, **watchers) | |||
@@ -354,7 +354,7 @@ machine.add_transition(DEPLOYING, DEPLOYFAIL, 'fail') | |||
# A failed deployment may be retried | |||
# ironic/conductor/manager.py:do_node_deploy() | |||
machine.add_transition(DEPLOYFAIL, DEPLOYING, 'rebuild') | |||
# NOTE(deva): Juno allows a client to send "active" to initiate a rebuild | |||
# NOTE(tenbrae): Juno allows a client to send "active" to initiate a rebuild | |||
machine.add_transition(DEPLOYFAIL, DEPLOYING, 'deploy') | |||
# A deployment may also wait on external callbacks | |||
@@ -118,7 +118,8 @@ class BaseConductorManager(object): | |||
_check_enabled_interfaces() | |||
# NOTE(deva): these calls may raise DriverLoadError or DriverNotFound | |||
# NOTE(tenbrae): these calls may raise DriverLoadError or | |||
# DriverNotFound | |||
# NOTE(vdrok): Instantiate network and storage interface factory on | |||
# startup so that all the interfaces are loaded at the very | |||
# beginning, and failures prevent the conductor from starting. | |||
@@ -281,8 +281,8 @@ def do_next_deploy_step(task, step_index, conductor_id): | |||
# Check if the step is done or not. The step should return | |||
# states.DEPLOYWAIT if the step is still being executed, or | |||
# None if the step is done. | |||
# NOTE(deva): Some drivers may return states.DEPLOYWAIT | |||
# eg. if they are waiting for a callback | |||
# NOTE(tenbrae): Some drivers may return states.DEPLOYWAIT | |||
# eg. if they are waiting for a callback | |||
if result == states.DEPLOYWAIT: | |||
# Kill this worker, the async step will make an RPC call to | |||
# continue_node_deploy() to continue deploying | |||
@@ -1004,13 +1004,13 @@ class ConductorManager(base_manager.BaseConductorManager): | |||
node.last_error = _("Failed to tear down. Error: %s") % e | |||
task.process_event('error') | |||
else: | |||
# NOTE(deva): When tear_down finishes, the deletion is done, | |||
# NOTE(tenbrae): When tear_down finishes, the deletion is done, | |||
# cleaning will start next | |||
LOG.info('Successfully unprovisioned node %(node)s with ' | |||
'instance %(instance)s.', | |||
{'node': node.uuid, 'instance': node.instance_uuid}) | |||
finally: | |||
# NOTE(deva): there is no need to unset conductor_affinity | |||
# NOTE(tenbrae): there is no need to unset conductor_affinity | |||
# because it is a reference to the most recent conductor which | |||
# deployed a node, and does not limit any future actions. | |||
# But we do need to clear the instance-related fields. | |||
@@ -1463,7 +1463,7 @@ class ConductorManager(base_manager.BaseConductorManager): | |||
with task_manager.acquire(context, node_uuid, | |||
purpose='power state sync', | |||
shared=True) as task: | |||
# NOTE(deva): we should not acquire a lock on a node in | |||
# NOTE(tenbrae): we should not acquire a lock on a node in | |||
# DEPLOYWAIT/CLEANWAIT, as this could cause | |||
# an error within a deploy ramdisk POSTing back | |||
# at the same time. | |||
@@ -1883,7 +1883,7 @@ class ConductorManager(base_manager.BaseConductorManager): | |||
try: | |||
with task_manager.acquire(context, node_uuid, | |||
purpose='node take over') as task: | |||
# NOTE(deva): now that we have the lock, check again to | |||
# NOTE(tenbrae): now that we have the lock, check again to | |||
# avoid racing with deletes and other state changes | |||
node = task.node | |||
if (node.maintenance | |||
@@ -2235,7 +2235,7 @@ class ConductorManager(base_manager.BaseConductorManager): | |||
try: | |||
if enabled: | |||
task.driver.console.start_console(task) | |||
# TODO(deva): We should be updating conductor_affinity here | |||
# TODO(tenbrae): We should be updating conductor_affinity here | |||
# but there is no support for console sessions in | |||
# take_over() right now. | |||
else: | |||
@@ -132,7 +132,7 @@ class ConductorAPI(object): | |||
serializer=serializer) | |||
use_groups = self.client.can_send_version('1.47') | |||
# NOTE(deva): this is going to be buggy | |||
# NOTE(tenbrae): this is going to be buggy | |||
self.ring_manager = hash_ring.HashRingManager(use_groups=use_groups) | |||
def get_conductor_for(self, node): | |||
@@ -369,7 +369,7 @@ def provisioning_error_handler(e, node, provision_state, | |||
""" | |||
if isinstance(e, exception.NoFreeConductorWorker): | |||
# NOTE(deva): there is no need to clear conductor_affinity | |||
# NOTE(tenbrae): there is no need to clear conductor_affinity | |||
# because it isn't updated on a failed deploy | |||
node.provision_state = provision_state | |||
node.target_provision_state = target_provision_state | |||
@@ -499,7 +499,7 @@ def deploying_error_handler(task, logmsg, errmsg=None, traceback=False, | |||
node.last_error = cleanup_err | |||
node.save() | |||
# NOTE(deva): there is no need to clear conductor_affinity | |||
# NOTE(tenbrae): there is no need to clear conductor_affinity | |||
task.process_event('fail') | |||
@@ -31,10 +31,10 @@ node = table('nodes', | |||
column('provision_state', String(15))) | |||
# NOTE(deva): We must represent the states as static strings in this migration | |||
# file, rather than import ironic.common.states, because that file may change | |||
# in the future. This migration script must still be able to be run with | |||
# future versions of the code and still produce the same results. | |||
# NOTE(tenbrae): We must represent the states as static strings in this | |||
# migration file, rather than import ironic.common.states, because that file | |||
# may change in the future. This migration script must still be able to be | |||
# run with future versions of the code and still produce the same results. | |||
AVAILABLE = 'available' | |||
@@ -128,7 +128,7 @@ class Node(Base): | |||
table_args()) | |||
id = Column(Integer, primary_key=True) | |||
uuid = Column(String(36)) | |||
# NOTE(deva): we store instance_uuid directly on the node so that we can | |||
# NOTE(tenbrae): we store instance_uuid directly on the node so that we can | |||
# filter on it more efficiently, even though it is | |||
# user-settable, and would otherwise be in node.properties. | |||
instance_uuid = Column(String(36), nullable=True) | |||
@@ -152,12 +152,12 @@ class Node(Base): | |||
raid_config = Column(db_types.JsonEncodedDict) | |||
target_raid_config = Column(db_types.JsonEncodedDict) | |||
# NOTE(deva): this is the host name of the conductor which has | |||
# NOTE(tenbrae): this is the host name of the conductor which has | |||
# acquired a TaskManager lock on the node. | |||
# We should use an INT FK (conductors.id) in the future. | |||
reservation = Column(String(255), nullable=True) | |||
# NOTE(deva): this is the id of the last conductor which prepared local | |||
# NOTE(tenbrae): this is the id of the last conductor which prepared local | |||
# state for the node (eg, a PXE config file). | |||
# When affinity and the hash ring's mapping do not match, | |||
# this indicates that a conductor should rebuild local state. | |||
@@ -276,7 +276,7 @@ def set_failed_state(task, msg, collect_logs=True): | |||
'should be removed from Ironic or put in maintenance ' | |||
'mode until the problem is resolved.' % node.uuid) | |||
LOG.exception(msg2) | |||
# NOTE(deva): node_power_action() erases node.last_error | |||
# NOTE(tenbrae): node_power_action() erases node.last_error | |||
# so we need to set it here. | |||
node.last_error = msg | |||
node.save() | |||
@@ -504,7 +504,7 @@ def _exec_ipmitool(driver_info, command, check_exit_code=None, | |||
while True: | |||
num_tries = num_tries - 1 | |||
# NOTE(deva): ensure that no communications are sent to a BMC more | |||
# NOTE(tenbrae): ensure that no communications are sent to a BMC more | |||
# often than once every min_command_interval seconds. | |||
time_till_next_poll = CONF.ipmi.min_command_interval - ( | |||
time.time() - LAST_CMD_TIME.get(driver_info['address'], 0)) | |||
@@ -870,7 +870,7 @@ class IPMIPower(base.PowerInterface): | |||
""" | |||
_parse_driver_info(task.node) | |||
# NOTE(deva): don't actually touch the BMC in validate because it is | |||
# NOTE(tenbrae): don't actually touch the BMC in validate because it is | |||
# called too often, and BMCs are too fragile. | |||
# This is a temporary measure to mitigate problems while | |||
# 1314954 and 1314961 are resolved. | |||
@@ -22,7 +22,7 @@ | |||
:platform: Unix | |||
""" | |||
# TODO(deva): move eventlet imports to ironic.__init__ once we move to PBR | |||
# TODO(tenbrae): move eventlet imports to ironic.__init__ once we move to PBR | |||
import eventlet | |||
from oslo_config import cfg | |||
@@ -5062,10 +5062,10 @@ class TestPut(test_api_base.BaseApiTest): | |||
self.assertEqual(urlparse.urlparse(ret.location).path, | |||
expected_location) | |||
# NOTE(deva): this test asserts API functionality which is not part of | |||
# NOTE(tenbrae): this test asserts API functionality which is not part of | |||
# the new-ironic-state-machine in Kilo. It is retained for backwards | |||
# compatibility with Juno. | |||
# TODO(deva): add a deprecation-warning to the REST result | |||
# TODO(tenbrae): add a deprecation-warning to the REST result | |||
# and check for it here. | |||
def test_provision_with_deploy_after_deployfail(self): | |||
node = self.node | |||
@@ -53,7 +53,7 @@ class DoNodeDeployTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase): | |||
self.service.conductor.id) | |||
node.refresh() | |||
self.assertEqual(states.DEPLOYFAIL, node.provision_state) | |||
# NOTE(deva): failing a deploy does not clear the target state | |||
# NOTE(tenbrae): failing a deploy does not clear the target state | |||
# any longer. Instead, it is cleared when the instance | |||
# is deleted. | |||
self.assertEqual(states.ACTIVE, node.target_provision_state) | |||
@@ -78,7 +78,7 @@ class DoNodeDeployTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase): | |||
self.service.conductor.id) | |||
node.refresh() | |||
self.assertEqual(states.DEPLOYFAIL, node.provision_state) | |||
# NOTE(deva): failing a deploy does not clear the target state | |||
# NOTE(tenbrae): failing a deploy does not clear the target state | |||
# any longer. Instead, it is cleared when the instance | |||
# is deleted. | |||
self.assertEqual(states.ACTIVE, node.target_provision_state) | |||
@@ -101,7 +101,7 @@ class DoNodeDeployTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase): | |||
deployments.do_node_deploy(task, self.service.conductor.id) | |||
node.refresh() | |||
self.assertEqual(states.DEPLOYFAIL, node.provision_state) | |||
# NOTE(deva): failing a deploy does not clear the target state | |||
# NOTE(tenbrae): failing a deploy does not clear the target state | |||
# any longer. Instead, it is cleared when the instance | |||
# is deleted. | |||
self.assertEqual(states.ACTIVE, node.target_provision_state) | |||
@@ -2097,12 +2097,12 @@ class DoNodeTearDownTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase): | |||
for state in valid_rescue_states: | |||
self._test_do_node_tear_down_from_state(state, True) | |||
# NOTE(deva): partial tear-down was broken. A node left in a state of | |||
# DELETING could not have tear_down called on it a second time | |||
# Thus, I have removed the unit test, which faultily asserted | |||
# only that a node could be left in a state of incomplete | |||
# deletion -- not that such a node's deletion could later be | |||
# completed. | |||
# NOTE(tenbrae): partial tear-down was broken. A node left in a state of | |||
# DELETING could not have tear_down called on it a second | |||
# time Thus, I have removed the unit test, which faultily | |||
# asserted only that a node could be left in a state of | |||
# incomplete deletion -- not that such a node's deletion | |||
# could later be completed. | |||
@mock.patch('ironic.conductor.manager.ConductorManager._spawn_worker', | |||
autospec=True) | |||
@@ -163,9 +163,10 @@ def get_test_node(**kw): | |||
"local_gb": "10", | |||
"memory_mb": "4096", | |||
} | |||
# NOTE(deva): API unit tests confirm that sensitive fields in instance_info | |||
# and driver_info will get scrubbed from the API response | |||
# but other fields (eg, 'foo') do not. | |||
# NOTE(tenbrae): API unit tests confirm that sensitive fields in | |||
# instance_info and driver_info will get scrubbed | |||
# from the API response but other fields | |||
# (eg, 'foo') do not. | |||
fake_instance_info = { | |||
"configdrive": "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ=", | |||
"image_url": "http://example.com/test_image_url", | |||
@@ -13,9 +13,9 @@ | |||
# License for the specific language governing permissions and limitations | |||
# under the License. | |||
# NOTE(deva): since __init__ is loaded before the files in the same directory, | |||
# and some third-party driver tests may need to have their | |||
# external libraries mocked, we load the file which does that | |||
# mocking here -- in the __init__. | |||
# NOTE(tenbrae): since __init__ is loaded before the files in the same | |||
# directory, and some third-party driver tests may need to have | |||
# their external libraries mocked, we load the file which does | |||
# that mocking here -- in the __init__. | |||
from ironic.tests.unit.drivers import third_party_driver_mocks # noqa |
@@ -22,7 +22,7 @@ from ironic.common import policy as ironic_policy | |||
CONF = cfg.CONF | |||
# NOTE(deva): We ship a default that always masks passwords, but for testing | |||
# NOTE(tenbrae): We ship a default that always masks passwords, but for testing | |||
# we need to override that default to ensure passwords can be | |||
# made visible by operators that choose to do so. | |||
policy_data = """ | |||