Use tcp/udp ports from config for heat templates

Reasons:
 - Trove should use tcp/upd ports
   from config for rendering heat templates.
Changes:
 - adding another two rendering parameter:
   - tcp_rules;
   - udp_rules;
 - adding validation for empty rules sets:
   - if no tcp/udp ports were mentioned - no rules will
     be assigned AWS::EC2::SecurityGroup.

Change-Id: I066aab0e7a32136608e2a6e23999e85bc637debd
Partial-Bug: #1276228
This commit is contained in:
Denis Makogon 2014-05-30 17:40:21 +03:00
parent d4ba64dfe2
commit 10716b8f1b
6 changed files with 112 additions and 25 deletions

View File

@ -369,18 +369,34 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
LOG.debug("end _create_server_volume for id: %s" % self.id)
return volume_info
def _build_sg_rules_mapping(self, rule_ports):
final = []
cidr = CONF.trove_security_group_rule_cidr
for port_or_range in set(rule_ports):
from_, to_ = utils.gen_ports(port_or_range)
final.append({'cidr': cidr,
'from_': str(from_),
'to_': str(to_)})
return final
def _create_server_volume_heat(self, flavor, image_id,
datastore_manager,
volume_size, availability_zone, nics):
LOG.debug("begin _create_server_volume_heat for id: %s" % self.id)
try:
client = create_heat_client(self.context)
tcp_rules_mapping_list = self._build_sg_rules_mapping(CONF.get(
datastore_manager).tcp_ports)
udp_ports_mapping_list = self._build_sg_rules_mapping(CONF.get(
datastore_manager).udp_ports)
ifaces, ports = self._build_heat_nics(nics)
template_obj = template.load_heat_template(datastore_manager)
heat_template_unicode = template_obj.render(
volume_support=CONF.trove_volume_support,
ifaces=ifaces, ports=ports)
ifaces=ifaces, ports=ports,
tcp_rules=tcp_rules_mapping_list,
udp_rules=udp_ports_mapping_list)
try:
heat_template = heat_template_unicode.encode('utf-8')
except UnicodeEncodeError:

View File

@ -23,7 +23,7 @@ Resources:
Type: OS::Neutron::Port
Properties:
network_id: "{{ port.net_id }}"
security_groups: [{Ref: CassandraDbaasSG}]
security_groups: [{Ref: DatastoreSG}]
{% if port.fixed_ip %}
fixed_ips: [{"ip_address": "{{ port.fixed_ip }}"}]
{% endif %}
@ -48,7 +48,7 @@ Resources:
ImageId: {Ref: ImageId}
InstanceType: {Ref: Flavor}
AvailabilityZone: {Ref: AvailabilityZone}
SecurityGroups : [{Ref: CassandraDbaasSG}]
SecurityGroups : [{Ref: DatastoreSG}]
UserData:
Fn::Base64:
Fn::Join:
@ -71,15 +71,25 @@ Resources:
VolumeId: {Ref: DataVolume}
Device: /dev/vdb
{% endif %}
CassandraDbaasSG:
DatastoreSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Default Security group for Cassandra
{% if tcp_rules or udp_rules %}
SecurityGroupIngress:
{% for rule in tcp_rules %}
- IpProtocol: "tcp"
FromPort: "9160"
ToPort: "9160"
CidrIp: "0.0.0.0/0"
FromPort: "{{rule.from_}}"
ToPort: "{{rule.to_}}"
CidrIp: "{{rule.cidr}}"
{% endfor %}
{% for rule in udp_rules %}
- IpProtocol: "udp"
FromPort: "{{rule.from_}}"
ToPort: "{{rule.to_}}"
CidrIp: "{{rule.cidr}}"
{% endfor %}
{% endif %}
DatabaseIPAddress:
Type: AWS::EC2::EIP
DatabaseIPAssoc :

View File

@ -23,7 +23,7 @@ Resources:
Type: OS::Neutron::Port
Properties:
network_id: "{{ port.net_id }}"
security_groups: [{Ref: DBaaSSG}]
security_groups: [{Ref: DatastoreSG}]
{% if port.fixed_ip %}
fixed_ips: [{"ip_address": "{{ port.fixed_ip }}"}]
{% endif %}
@ -51,7 +51,7 @@ Resources:
{% if ifaces %}
NetworkInterfaces: [{{ ifaces|join(', ') }}]
{% else %}
SecurityGroups: [{Ref: DBaaSSG}]
SecurityGroups: [{Ref: DatastoreSG}]
{% endif %}
UserData:
Fn::Base64:
@ -75,15 +75,25 @@ Resources:
VolumeId: {Ref: DataVolume}
Device: /dev/vdb
{% endif %}
DBaaSSG:
DatastoreSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Default Security group for MongoDB
{% if tcp_rules or udp_rules %}
SecurityGroupIngress:
{% for rule in tcp_rules %}
- IpProtocol: "tcp"
FromPort: "27017"
ToPort: "27017"
CidrIp: "0.0.0.0/0"
FromPort: "{{rule.from_}}"
ToPort: "{{rule.to_}}"
CidrIp: "{{rule.cidr}}"
{% endfor %}
{% for rule in udp_rules %}
- IpProtocol: "udp"
FromPort: "{{rule.from_}}"
ToPort: "{{rule.to_}}"
CidrIp: "{{rule.cidr}}"
{% endfor %}
{% endif %}
DatabaseIPAddress:
Type: AWS::EC2::EIP
DatabaseIPAssoc :

View File

@ -23,7 +23,7 @@ Resources:
Type: OS::Neutron::Port
Properties:
network_id: "{{ port.net_id }}"
security_groups: [{Ref: MySqlDbaasSG}]
security_groups: [{Ref: DatastoreSG}]
{% if port.fixed_ip %}
fixed_ips: [{"ip_address": "{{ port.fixed_ip }}"}]
{% endif %}
@ -51,7 +51,7 @@ Resources:
{% if ifaces %}
NetworkInterfaces: [{{ ifaces|join(', ') }}]
{% else %}
SecurityGroups: [{Ref: MySqlDbaasSG}]
SecurityGroups: [{Ref: DatastoreSG}]
{% endif %}
UserData:
Fn::Base64:
@ -75,15 +75,25 @@ Resources:
VolumeId: {Ref: DataVolume}
Device: /dev/vdb
{% endif %}
MySqlDbaasSG:
DatastoreSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Default Security group for MySQL
{% if tcp_rules or udp_rules %}
SecurityGroupIngress:
{% for rule in tcp_rules %}
- IpProtocol: "tcp"
FromPort: "3306"
ToPort: "3306"
CidrIp: "0.0.0.0/0"
FromPort: "{{rule.from_}}"
ToPort: "{{rule.to_}}"
CidrIp: "{{rule.cidr}}"
{% endfor %}
{% for rule in udp_rules %}
- IpProtocol: "udp"
FromPort: "{{rule.from_}}"
ToPort: "{{rule.to_}}"
CidrIp: "{{rule.cidr}}"
{% endfor %}
{% endif %}
DatabaseIPAddress:
Type: AWS::EC2::EIP
DatabaseIPAssoc :

View File

@ -23,7 +23,7 @@ Resources:
Type: OS::Neutron::Port
Properties:
network_id: "{{ port.net_id }}"
security_groups: [{Ref: DBaaSSG}]
security_groups: [{Ref: DatastoreSG}]
{% if port.fixed_ip %}
fixed_ips: [{"ip_address": "{{ port.fixed_ip }}"}]
{% endif %}
@ -51,7 +51,7 @@ Resources:
{% if ifaces %}
NetworkInterfaces: [{{ ifaces|join(', ') }}]
{% else %}
SecurityGroups: [{Ref: DBaaSSG}]
SecurityGroups: [{Ref: DatastoreSG}]
{% endif %}
UserData:
Fn::Base64:
@ -75,15 +75,25 @@ Resources:
VolumeId: {Ref: DataVolume}
Device: /dev/vdb
{% endif %}
DBaaSSG:
DatastoreSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Default Security group for Redis
{% if tcp_rules or udp_rules %}
SecurityGroupIngress:
{% for rule in tcp_rules %}
- IpProtocol: "tcp"
FromPort: "6379"
ToPort: "6379"
CidrIp: "0.0.0.0/0"
FromPort: "{{rule.from_}}"
ToPort: "{{rule.to_}}"
CidrIp: "{{rule.cidr}}"
{% endfor %}
{% for rule in udp_rules %}
- IpProtocol: "udp"
FromPort: "{{rule.from_}}"
ToPort: "{{rule.to_}}"
CidrIp: "{{rule.cidr}}"
{% endfor %}
{% endif %}
DatabaseIPAddress:
Type: AWS::EC2::EIP
DatabaseIPAssoc :

View File

@ -103,3 +103,34 @@ class HeatTemplateLoadTest(testtools.TestCase):
self.assertIsNotNone(redis_tmplt)
self.assertIsNotNone(cassandra_tmpl)
self.assertIsNotNone(mongo_tmpl)
def test_render_templates_with_ports_from_config(self):
mysql_tmpl = template.load_heat_template('mysql')
tcp_rules = [{'cidr': "0.0.0.0/0",
'from_': 3306,
'to_': 3309},
{'cidr': "0.0.0.0/0",
'from_': 3320,
'to_': 33022}]
output = mysql_tmpl.render(
volume_support=True,
ifaces=[], ports=[],
tcp_rules=tcp_rules,
udp_rules=[])
self.assertIsNotNone(output)
self.assertIn('FromPort: "3306"', output)
self.assertIn('ToPort: "3309"', output)
self.assertIn('CidrIp: "0.0.0.0/0"', output)
self.assertIn('FromPort: "3320"', output)
self.assertIn('ToPort: "33022"', output)
def test_no_rules_if_no_ports(self):
mysql_tmpl = template.load_heat_template('mysql')
output = mysql_tmpl.render(
volume_support=True,
ifaces=[], ports=[],
tcp_rules=[],
udp_rules=[])
self.assertIsNotNone(output)
self.assertNotIn('- IpProtocol: "tcp"', output)
self.assertNotIn('- IpProtocol: "udp"', output)