Adding --exclude-secgroup option

* There is a use case when we don't need
   to export security groups at all

Change-Id: Ib531404d3079c4aef32df367274468da53912fc4
This commit is contained in:
Nikolay Mahotkin 2016-12-22 14:43:47 +03:00 committed by Nikolay Mahotkin
parent 63fb35354e
commit ba37e5c353
5 changed files with 369 additions and 16 deletions

View File

@ -1,5 +1,5 @@
Flame: Automatic Heat template generation
============================================
=========================================
OpenStack Orchestration project Heat implements an orchestration engine to
launch multiple composite cloud applications based on templates. A Heat
@ -30,7 +30,7 @@ Then just run:
python setup.py install
Usage
----------------------
-----
usage: flame [-h] [--username USERNAME] [--password PASSWORD]
[--project PROJECT] [--region REGION] [--auth_url AUTH_URL]
@ -38,7 +38,7 @@ Usage
[--os-cert <certification>] [--os-key <key>]
[--endpoint_type ENDPOINT_TYPE] [--exclude-servers]
[--exclude-volumes] [--exclude-keypairs] [--generate-stack-data]
[--extract-ports]
[--extract-ports] [--exclude-secgroup]
Heat template and data file generator
@ -71,6 +71,7 @@ Usage
In addition to template, generate Heat stack data
file.
--extract-ports Export the tenant network ports
--exclude-secgroups Do not export in template security group resources
Usage example
-------------

View File

@ -34,12 +34,14 @@ class Client(object):
**kwargs)
def generate(self, exclude_servers, exclude_volumes, exclude_keypairs,
generate_stack_data, extract_ports=False):
generate_stack_data, extract_ports=False,
exclude_secgroups=False):
self.template_generator.extract_vm_details(exclude_servers,
exclude_volumes,
exclude_keypairs,
generate_stack_data,
extract_ports
extract_ports,
exclude_secgroups
)
self.template_generator.extract_data()
return self.template_generator.heat_template_and_data()

View File

@ -91,6 +91,10 @@ def main(args=None):
parser.add_argument('--extract-ports', action='store_true',
default=False,
help="Export the tenant network ports")
parser.add_argument('--exclude-secgroups', action='store_true',
default=False,
help="Do not export in template "
"security group resources")
args = parser.parse_args()
flame = client.Client(args.username, args.password,
@ -105,7 +109,8 @@ def main(args=None):
args.exclude_volumes,
args.exclude_keypairs,
args.generate_stack_data,
args.extract_ports)
args.extract_ports,
args.exclude_secgroups)
template.extract_data()
print("### Heat Template ###")
print(template.heat_template_and_data())

View File

@ -172,23 +172,28 @@ class TemplateGenerator(object):
def extract_vm_details(self, exclude_servers, exclude_volumes,
exclude_keypairs, generate_data,
extract_ports=False):
extract_ports=False, exclude_secgroups=False):
self.exclude_servers = exclude_servers
self.exclude_volumes = exclude_volumes
self.exclude_keypairs = exclude_keypairs
self.generate_data = generate_data
self.extract_ports = extract_ports
self.exclude_secgroups = exclude_secgroups
self.external_networks = []
fetch_map = {
'subnets': (self.neutron.subnet_list, self.build_data),
'networks': (self.neutron.network_list, self.build_data),
'routers': (self.neutron.router_list, lambda x: x),
'secgroups': (self.neutron.secgroup_list, self.build_data),
'servergroups': (self.nova.servergroup_list, self.build_data),
'floatingips': (self.neutron.floatingip_list, lambda x: x),
'ports': (self.neutron.port_list, self.build_data),
}
if not exclude_secgroups:
fetch_map['secgroups'] = (
self.neutron.secgroup_list, self.build_data
)
if not exclude_keypairs:
fetch_map['keys'] = (self.nova.keypair_list,
lambda l: {key.name: (index, key) for
@ -378,8 +383,9 @@ class TemplateGenerator(object):
properties['name'] = port['name']
resource = Resource("port_%d" % n, 'OS::Neutron::Port',
port['id'], properties)
security_groups = self.build_port_secgroups(resource, port)
properties['security_groups'] = security_groups
if not self.exclude_secgroups:
security_groups = self.build_port_secgroups(resource, port)
properties['security_groups'] = security_groups
resources.append(resource)
resources_dict[port['id']] = resource
@ -568,9 +574,10 @@ class TemplateGenerator(object):
if ports:
properties['networks'] = ports
else:
security_groups = self.build_secgroups(resource, server)
if security_groups:
properties['security_groups'] = security_groups
if not self.exclude_secgroups:
security_groups = self.build_secgroups(resource, server)
if security_groups:
properties['security_groups'] = security_groups
networks = self.build_networks(server.addresses)
if networks:
@ -724,10 +731,12 @@ class TemplateGenerator(object):
resources += self._extract_ports()
resources += self._extract_subnets()
resources += self._extract_secgroups()
resources += self._extract_floating()
resources += self._extract_servergroups()
if not self.exclude_secgroups:
resources += self._extract_secgroups()
if not self.exclude_keypairs:
resources += self._extract_keys()
if not self.exclude_servers:

View File

@ -275,12 +275,13 @@ class BaseTestCase(base.TestCase):
super(BaseTestCase, self).tearDown()
def get_generator(self, exclude_servers, exclude_volumes,
exclude_keypairs, generate_data, extract_ports):
exclude_keypairs, generate_data,
extract_ports, exclude_secgroups=False):
generator = flame.TemplateGenerator('x', 'x', 'x', 'x', True,
'publicURL')
generator.extract_vm_details(exclude_servers, exclude_volumes,
exclude_keypairs, generate_data,
extract_ports)
extract_ports, exclude_secgroups)
return generator
def check_stackdata(self, resources, expected_resources):
@ -2102,6 +2103,341 @@ class GenerationTests(BaseTestCase):
self.assertEqual(generator.template['parameters'], expected_parameters)
self.assertEqual(generator.stack_data['resources'], expected_data)
def test_generation_secgroups(self):
self.mock_neutron().groups = [{
'id': '4321',
'name': 'my_sec_group',
'security_group_rules': [{
'protocol': 'TCP',
'port_range_min': '22',
'port_range_max': '22',
'tenant_id': 'tenant',
'id': '1212',
'security_group_id': '4444',
'remote_group_id': None
}],
'description': 'group description'
}]
generator = self.get_generator(False, False, False, True, False, False)
expected_resources = {
"volume_0": {
"properties": {
"name": "vol1",
"volume_type": {
"get_param": "volume_0_volume_type"
},
"description": "Description",
"size": 1
},
"type": "OS::Cinder::Volume"
},
"key_0": {
"type": "OS::Nova::KeyPair",
"properties": {
"name": "testkey",
"public_key": "ssh-rsa XXXX"
}
},
"network_0": {
"properties": {
"admin_state_up": True,
"shared": False,
"name": "mynetwork"
},
"type": "OS::Neutron::Net"
},
"router_0": {
"properties": {
"admin_state_up": "true",
"name": "myrouter"
},
"type": "OS::Neutron::Router"
},
"server_0": {
"properties": {
"image": {
"get_param": "server_0_image"
},
"flavor": {
"get_param": "server_0_flavor"
},
"name": "server1",
"diskConfig": "MANUAL",
"key_name": {
"get_resource": "key_0"
}
},
"type": "OS::Nova::Server"
},
"security_group_0": {
"type": "OS::Neutron::SecurityGroup",
"properties": {
"rules": [
{
"port_range_min": "22",
"port_range_max": "22",
"protocol": "TCP"
}
],
"name": "my_sec_group",
"description": "group description"
}
},
"servergroup_0": {
"type": "OS::Nova::ServerGroup",
"properties": {
"policies": "affinity",
"name": "policy_group"
}
}
}
expected_parameters = {
"server_0_image": {
"description": "Image to use to boot server server_0",
"type": "string",
"default": "3333"
},
"server_0_flavor": {
"description": "Flavor to use for server server_0",
"type": "string",
"default": "m1.small"
},
"volume_0_volume_type": {
"default": "fast",
"description": "Volume type for volume volume_0",
"type": "string"
}
}
expected_data = {
'key_0': {
'action': 'CREATE',
'metadata': {},
'name': 'key_0',
'resource_data': {},
'resource_id': 'key',
'status': 'COMPLETE',
'type': 'OS::Nova::KeyPair'
},
'network_0': {
'action': 'CREATE',
'metadata': {},
'name': 'network_0',
'resource_data': {},
'resource_id': '2222',
'status': 'COMPLETE',
'type': 'OS::Neutron::Net'
},
'router_0': {
'action': 'CREATE',
'metadata': {},
'name': 'router_0',
'resource_data': {},
'resource_id': '1234',
'status': 'COMPLETE',
'type': 'OS::Neutron::Router'
},
'security_group_0': {
'action': 'CREATE',
'metadata': {},
'name': 'security_group_0',
'resource_data': {},
'resource_id': '4321',
'status': 'COMPLETE',
'type': 'OS::Neutron::SecurityGroup'
},
'server_0': {
'action': 'CREATE',
'metadata': {},
'name': 'server_0',
'resource_data': {},
'resource_id': '1234',
'status': 'COMPLETE',
'type': 'OS::Nova::Server'
},
'servergroup_0': {
'action': 'CREATE',
'metadata': {},
'name': 'servergroup_0',
'resource_data': {},
'resource_id': '1234',
'status': 'COMPLETE',
'type': 'OS::Nova::ServerGroup'
},
'volume_0': {
'action': 'CREATE',
'metadata': {},
'name': 'volume_0',
'resource_data': {},
'resource_id': 1234,
'status': 'COMPLETE',
'type': 'OS::Cinder::Volume'
}
}
generator.extract_data()
self.assertEqual(expected_resources, generator.template['resources'])
self.assertEqual(expected_parameters, generator.template['parameters'])
self.assertEqual(expected_data, generator.stack_data['resources'])
def test_generation_exclude_secgroups(self):
self.mock_neutron().groups = [{
'id': '4321',
'name': 'my_sec_group',
'security_group_rules': [{
'protocol': 'TCP',
'port_range_min': '22',
'port_range_max': '22',
'tenant_id': 'tenant',
'id': '1212',
'security_group_id': '4444',
'remote_group_id': None
}],
'description': 'group description'
}]
generator = self.get_generator(False, False, False, True, False, True)
expected_resources = {
"volume_0": {
"properties": {
"name": "vol1",
"volume_type": {
"get_param": "volume_0_volume_type"
},
"description": "Description",
"size": 1
},
"type": "OS::Cinder::Volume"
},
"key_0": {
"type": "OS::Nova::KeyPair",
"properties": {
"name": "testkey",
"public_key": "ssh-rsa XXXX"
}
},
"network_0": {
"properties": {
"admin_state_up": True,
"shared": False,
"name": "mynetwork"
},
"type": "OS::Neutron::Net"
},
"router_0": {
"properties": {
"admin_state_up": "true",
"name": "myrouter"
},
"type": "OS::Neutron::Router"
},
"server_0": {
"properties": {
"image": {
"get_param": "server_0_image"
},
"flavor": {
"get_param": "server_0_flavor"
},
"name": "server1",
"diskConfig": "MANUAL",
"key_name": {
"get_resource": "key_0"
}
},
"type": "OS::Nova::Server"
},
"servergroup_0": {
"type": "OS::Nova::ServerGroup",
"properties": {
"policies": "affinity",
"name": "policy_group"
}
}
}
expected_parameters = {
"server_0_image": {
"description": "Image to use to boot server server_0",
"type": "string",
"default": "3333"
},
"server_0_flavor": {
"description": "Flavor to use for server server_0",
"type": "string",
"default": "m1.small"
},
"volume_0_volume_type": {
"default": "fast",
"description": "Volume type for volume volume_0",
"type": "string"
}
}
expected_data = {
'key_0': {
'action': 'CREATE',
'metadata': {},
'name': 'key_0',
'resource_data': {},
'resource_id': 'key',
'status': 'COMPLETE',
'type': 'OS::Nova::KeyPair'
},
'network_0': {
'action': 'CREATE',
'metadata': {},
'name': 'network_0',
'resource_data': {},
'resource_id': '2222',
'status': 'COMPLETE',
'type': 'OS::Neutron::Net'
},
'router_0': {
'action': 'CREATE',
'metadata': {},
'name': 'router_0',
'resource_data': {},
'resource_id': '1234',
'status': 'COMPLETE',
'type': 'OS::Neutron::Router'
},
'server_0': {
'action': 'CREATE',
'metadata': {},
'name': 'server_0',
'resource_data': {},
'resource_id': '1234',
'status': 'COMPLETE',
'type': 'OS::Nova::Server'
},
'servergroup_0': {
'action': 'CREATE',
'metadata': {},
'name': 'servergroup_0',
'resource_data': {},
'resource_id': '1234',
'status': 'COMPLETE',
'type': 'OS::Nova::ServerGroup'
},
'volume_0': {
'action': 'CREATE',
'metadata': {},
'name': 'volume_0',
'resource_data': {},
'resource_id': 1234,
'status': 'COMPLETE',
'type': 'OS::Cinder::Volume'
}
}
generator.extract_data()
self.assertEqual(expected_resources, generator.template['resources'])
self.assertEqual(expected_parameters, generator.template['parameters'])
self.assertEqual(expected_data, generator.stack_data['resources'])
def test_generation_exclude_servers(self):
generator = self.get_generator(True, False, False, True, False)