Allow overriding the instance_user per server

I have called the property 'admin_user' as the bug suggests.

Closes-bug: #1229825
Change-Id: I578ba9c0419383b34ac137e714f9cc00fe696ea3
This commit is contained in:
Angus Salkeld 2013-10-11 16:54:57 +11:00
parent 57dac72b55
commit cb2801cc7b
4 changed files with 42 additions and 6 deletions

View File

@ -122,7 +122,7 @@ def get_keypair(nova_client, key_name):
raise exception.UserKeyPairMissing(key_name=key_name)
def build_userdata(resource, userdata=None):
def build_userdata(resource, userdata=None, instance_user=None):
'''
Build multipart data blob for CloudInit which includes user-supplied
Metadata, user data, and the required Heat in-instance configuration.
@ -131,6 +131,8 @@ def build_userdata(resource, userdata=None):
:type resource: heat.engine.Resource
:param userdata: user data string
:type userdata: str or None
:param instance_user: the user to create on the server
:type instance_user: string
:returns: multipart mime as a string
'''
@ -145,7 +147,7 @@ def build_userdata(resource, userdata=None):
def read_cloudinit_file(fn):
data = pkgutil.get_data('heat', 'cloudinit/%s' % fn)
data = data.replace('@INSTANCE_USER@',
cfg.CONF.instance_user)
instance_user or cfg.CONF.instance_user)
return data
attachments = [(read_cloudinit_file('config'), 'cloud-config'),

View File

@ -13,6 +13,10 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo.config import cfg
cfg.CONF.import_opt('instance_user', 'heat.common.config')
from heat.common import exception
from heat.engine import clients
from heat.engine import scheduler
@ -95,6 +99,12 @@ class Server(resource.Resource):
'key_name': {
'Type': 'String',
'Description': _('Name of keypair to inject into the server')},
'admin_user': {
'Type': 'String',
'Default': cfg.CONF.instance_user,
'Description': _('Name of the administrative user to use '
' on the server')},
'availability_zone': {
'Type': 'String',
'Description': _('Name of the availability zone for server '
@ -171,7 +181,8 @@ class Server(resource.Resource):
def get_mime_string(self, userdata):
if not self.mime_string:
self.mime_string = nova_utils.build_userdata(self, userdata)
self.mime_string = nova_utils.build_userdata(
self, userdata, instance_user=self.properties['admin_user'])
return self.mime_string
def physical_resource_name(self):

View File

@ -14,12 +14,15 @@
# under the License.
"""Tests for :module:'heat.engine.resources.nova_utls'."""
import testscenarios
import uuid
from heat.common import exception
from heat.engine.resources import nova_utils
from heat.tests.common import HeatTestCase
load_tests = testscenarios.load_tests_apply_scenarios
class NovaUtilsTests(HeatTestCase):
"""
@ -84,19 +87,38 @@ class NovaUtilsTests(HeatTestCase):
self.nova_client, 'notakey')
self.m.VerifyAll()
class NovaUtilsUserdataTests(HeatTestCase):
scenarios = [
('no_conf_no_prop', dict(
conf_user='ec2-user', instance_user=None, expect='ec2-user')),
('no_conf_prop', dict(
conf_user='ec2-user', instance_user='fruity', expect='fruity')),
('conf_no_prop', dict(
conf_user='nutty', instance_user=None, expect='nutty')),
('conf_prop', dict(
conf_user='nutty', instance_user='fruity', expect='fruity')),
]
def setUp(self):
super(NovaUtilsUserdataTests, self).setUp()
self.nova_client = self.m.CreateMockAnything()
def test_build_userdata(self):
"""Tests the build_userdata function."""
resource = self.m.CreateMockAnything()
resource.t = {}
self.m.StubOutWithMock(nova_utils.cfg, 'CONF')
cnf = nova_utils.cfg.CONF
cnf.instance_user = 'testuser'
cnf.instance_user = self.conf_user
cnf.heat_metadata_server_url = 'http://server.test:123'
cnf.heat_watch_server_url = 'http://server.test:345'
cnf.instance_connection_is_secure = False
cnf.instance_connection_https_validate_certificates = False
self.m.ReplayAll()
data = nova_utils.build_userdata(resource)
data = nova_utils.build_userdata(resource,
instance_user=self.instance_user)
self.assertTrue("Content-Type: text/cloud-config;" in data)
self.assertTrue("Content-Type: text/cloud-boothook;" in data)
self.assertTrue("Content-Type: text/part-handler;" in data)
@ -105,5 +127,5 @@ class NovaUtilsTests(HeatTestCase):
self.assertTrue("http://server.test:345" in data)
self.assertTrue("http://server.test:123" in data)
self.assertTrue("[Boto]" in data)
self.assertTrue('testuser' in data)
self.assertTrue(self.expect in data)
self.m.VerifyAll()

View File

@ -10,6 +10,7 @@ mock>=1.0
mox>=0.5.3
testtools>=0.9.32
testrepository>=0.0.17
testscenarios>=0.4
python-glanceclient>=0.9.0
sphinx>=1.1.2
oslo.sphinx