--- a/components/openstack/horizon/files/local_settings.py Wed Jul 22 17:20:10 2015 -0700
+++ b/components/openstack/horizon/files/local_settings.py Wed Jul 08 14:00:24 2015 -0700
@@ -175,7 +175,7 @@
#Setting this to True, will add a new "Retrieve Password" action on instance,
#allowing Admin session password retrieval/decryption.
-#OPENSTACK_ENABLE_PASSWORD_RETRIEVE = False
+OPENSTACK_ENABLE_PASSWORD_RETRIEVE = True
# The Xen Hypervisor has the ability to set the mount point for volumes
# attached to instances (other Hypervisors currently do not). Setting
@@ -183,7 +183,7 @@
# from the UI.
OPENSTACK_HYPERVISOR_FEATURES = {
'can_set_mount_point': False,
- 'can_set_password': False,
+ 'can_set_password': True,
}
# The OPENSTACK_CINDER_FEATURES settings can be used to enable optional
--- a/components/openstack/horizon/files/overrides.py Wed Jul 22 17:20:10 2015 -0700
+++ b/components/openstack/horizon/files/overrides.py Wed Jul 08 14:00:24 2015 -0700
@@ -96,6 +96,7 @@
project_tables.AssociateIP,
project_tables.SimpleDisassociateIP,
project_tables.EditInstance,
+ project_tables.DecryptInstancePassword,
project_tables.ConsoleLink,
project_tables.LogLink,
project_tables.SoftRebootInstance,
--- a/components/openstack/nova/files/solariszones/driver.py Wed Jul 22 17:20:10 2015 -0700
+++ b/components/openstack/nova/files/solariszones/driver.py Wed Jul 08 14:00:24 2015 -0700
@@ -19,6 +19,7 @@
Driver for Solaris Zones (nee Containers):
"""
+import base64
import glob
import os
import platform
@@ -39,13 +40,16 @@
from eventlet import greenthread
from lxml import etree
from oslo_config import cfg
-
+from passlib.hash import sha256_crypt
+
+from nova.api.metadata import password
from nova.compute import power_state
from nova.compute import task_states
from nova.compute import vm_states
from nova.console import type as ctype
from nova import conductor
from nova import context as nova_context
+from nova import crypto
from nova import exception
from nova.i18n import _
from nova.image import glance
@@ -1046,7 +1050,7 @@
with ZoneConfig(zone) as zc:
zc.setprop('global', 'tenant', tenant_id)
- def _verify_sysconfig(self, sc_dir, instance):
+ def _verify_sysconfig(self, sc_dir, instance, admin_password=None):
"""verify the SC profile(s) passed in contain an entry for
system/config-user to configure the root account. If an SSH key is
specified, configure root's profile to use it.
@@ -1058,6 +1062,11 @@
hostname_needed = True
sshkey = instance.get('key_data')
name = instance.get('display_name')
+ encrypted_password = None
+
+ # encrypt admin password, using SHA-256 as default
+ if admin_password is not None:
+ encrypted_password = sha256_crypt.encrypt(admin_password)
# find all XML files in sc_dir
for root, dirs, files in os.walk(sc_dir):
@@ -1085,12 +1094,22 @@
if root_account_needed:
fp = os.path.join(sc_dir, 'config-root.xml')
- if sshkey is not None:
- # set up the root account as 'normal' with no expiration and
- # an ssh key
- tree = sysconfig.create_default_root_account(sshkey=sshkey)
+ if admin_password is not None and sshkey is not None:
+ # store password for horizon retrieval
+ ctxt = nova_context.get_admin_context()
+ enc = crypto.ssh_encrypt_text(sshkey, admin_password)
+ instance.system_metadata.update(
+ password.convert_password(ctxt, base64.b64encode(enc)))
+ instance.save()
+
+ if encrypted_password is not None or sshkey is not None:
+ # set up the root account as 'normal' with no expiration,
+ # an ssh key, and a root password
+ tree = sysconfig.create_default_root_account(
+ sshkey=sshkey, password=encrypted_password)
else:
- # set up the root account as 'normal' but to expire immediately
+ # sets up root account with expiration if sshkey is None
+ # and password is none
tree = sysconfig.create_default_root_account(expire='0')
sysconfig.create_sc_profile(fp, tree)
@@ -1104,8 +1123,8 @@
fp = os.path.join(sc_dir, 'hostname.xml')
sysconfig.create_sc_profile(fp, sysconfig.create_hostname(name))
- def _create_config(self, context, instance, network_info,
- connection_info, extra_specs, sc_dir):
+ def _create_config(self, context, instance, network_info, connection_info,
+ extra_specs, sc_dir, admin_password=None):
"""Create a new Solaris Zone configuration."""
name = instance['name']
if self._get_zone_by_name(name) is not None:
@@ -1127,7 +1146,7 @@
elif os.path.isdir(sc_profile):
shutil.copytree(sc_profile, os.path.join(sc_dir, 'sysconfig'))
- self._verify_sysconfig(sc_dir, instance)
+ self._verify_sysconfig(sc_dir, instance, admin_password)
zonemanager = self.rad_connection.get_object(zonemgr.ZoneManager())
try:
@@ -1459,8 +1478,9 @@
LOG.debug(_("creating zone configuration for '%s' (%s)") %
(name, instance['display_name']))
- self._create_config(context, instance, network_info,
- connection_info, extra_specs, sc_dir)
+
+ self._create_config(context, instance, network_info, connection_info,
+ extra_specs, sc_dir, admin_password)
try:
self._install(instance, image, extra_specs, sc_dir)
self._power_on(instance)
--- a/components/openstack/nova/files/solariszones/sysconfig.py Wed Jul 22 17:20:10 2015 -0700
+++ b/components/openstack/nova/files/solariszones/sysconfig.py Wed Jul 08 14:00:24 2015 -0700
@@ -152,7 +152,7 @@
return svcbundle
-def create_default_root_account(expire=None, sshkey=None):
+def create_default_root_account(expire=None, sshkey=None, password=None):
""" return an etree object representing the root account
"""
svcbundle = etree.Element("service_bundle", type="profile",
@@ -163,11 +163,16 @@
name="default")
root_pg = etree.SubElement(instance, "property_group", type="application",
name="root_account")
- etree.SubElement(root_pg, "propval", type="astring", name="password",
- value="NP")
etree.SubElement(root_pg, "propval", type="astring", name="type",
value="normal")
+ if password is not None:
+ etree.SubElement(root_pg, "propval", type="astring", name="password",
+ value=password)
+ else:
+ etree.SubElement(root_pg, "propval", type="astring", name="password",
+ value='NP')
+
if expire is not None:
etree.SubElement(root_pg, "propval", type="astring", name="expire",
value=expire)