Skip to content

Commit

Permalink
Allow overriding the instance_user per server
Browse files Browse the repository at this point in the history
I have called the property 'admin_user' as the bug suggests.

Closes-bug: #1229825
Change-Id: I578ba9c0419383b34ac137e714f9cc00fe696ea3
  • Loading branch information
asalkeld committed Oct 11, 2013
1 parent 57dac72 commit cb2801c
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 6 deletions.
6 changes: 4 additions & 2 deletions heat/engine/resources/nova_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
'''

Expand All @@ -145,7 +147,7 @@ def make_subpart(content, filename, subtype=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'),
Expand Down
13 changes: 12 additions & 1 deletion heat/engine/resources/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 '
Expand Down Expand Up @@ -171,7 +181,8 @@ def __init__(self, name, json_snippet, stack):

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):
Expand Down
28 changes: 25 additions & 3 deletions heat/tests/test_nova_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
"""
Expand Down Expand Up @@ -84,19 +87,38 @@ def test_get_keypair(self):
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)
Expand All @@ -105,5 +127,5 @@ def test_build_userdata(self):
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()
1 change: 1 addition & 0 deletions test-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit cb2801c

Please sign in to comment.