Merge "Update ironic.driver.plug_vif implementation"

This commit is contained in:
Jenkins 2017-07-03 11:31:47 +00:00 committed by Gerrit Code Review
commit fe2710c6ff
27 changed files with 50 additions and 111 deletions

View File

@ -337,13 +337,6 @@ multi_server_name_body:
in: body in: body
required: true required: true
type: string type: string
network_port_type:
description: |
To provision the server with a specified type of NIC(like 1GE or 10 GE) for a
network, specify the type of the NIC in the ``port_type`` key in a dict in ``networks`` list.
in: body
required: false
type: string
network_uuid: network_uuid:
description: | description: |
To provision the server with a NIC for a network, specify the UUID of To provision the server with a NIC for a network, specify the UUID of

View File

@ -4,7 +4,6 @@
"network_id": "f31af5a2-f14d-4007-b2e5-abeb82429b87", "network_id": "f31af5a2-f14d-4007-b2e5-abeb82429b87",
"port_id": "99845c22-6268-46c1-b068-1dbcb8adaf68", "port_id": "99845c22-6268-46c1-b068-1dbcb8adaf68",
"floating_ip": null, "floating_ip": null,
"port_type": null,
"mac_address": "52:54:00:cc:ed:87", "mac_address": "52:54:00:cc:ed:87",
"fixed_ips": [ "fixed_ips": [
{ {

View File

@ -8,8 +8,7 @@
"net_id": "c1940655-8b8e-4370-b8f9-03ba1daeca31" "net_id": "c1940655-8b8e-4370-b8f9-03ba1daeca31"
}, },
{ {
"net_id": "8e8ceb07-4641-4188-9b22-840755e92ee2", "net_id": "8e8ceb07-4641-4188-9b22-840755e92ee2"
"port_type": "10GE"
} }
], ],
"min_count": 2, "min_count": 2,

View File

@ -9,8 +9,7 @@
"net_id": "c1940655-8b8e-4370-b8f9-03ba1daeca31" "net_id": "c1940655-8b8e-4370-b8f9-03ba1daeca31"
}, },
{ {
"net_id": "8e8ceb07-4641-4188-9b22-840755e92ee2", "net_id": "8e8ceb07-4641-4188-9b22-840755e92ee2"
"port_type": "10GE"
} }
], ],
"metadata" : { "metadata" : {

View File

@ -20,7 +20,6 @@
"network_id": "f31af5a2-f14d-4007-b2e5-abeb82429b87", "network_id": "f31af5a2-f14d-4007-b2e5-abeb82429b87",
"port_id": "43cb1111-63c5-45d2-8bcf-3443d94b34f3", "port_id": "43cb1111-63c5-45d2-8bcf-3443d94b34f3",
"floating_ip": null, "floating_ip": null,
"port_type": null,
"mac_address": "52:54:00:d0:f9:2c", "mac_address": "52:54:00:d0:f9:2c",
"fixed_ips": [ "fixed_ips": [
{ {

View File

@ -22,7 +22,6 @@
"network_id": "f31af5a2-f14d-4007-b2e5-abeb82429b87", "network_id": "f31af5a2-f14d-4007-b2e5-abeb82429b87",
"port_id": "43cb1111-63c5-45d2-8bcf-3443d94b34f3", "port_id": "43cb1111-63c5-45d2-8bcf-3443d94b34f3",
"floating_ip": null, "floating_ip": null,
"port_type": null,
"mac_address": "52:54:00:d0:f9:2c", "mac_address": "52:54:00:d0:f9:2c",
"fixed_ips": [ "fixed_ips": [
{ {

View File

@ -27,7 +27,6 @@
"network_id": "f31af5a2-f14d-4007-b2e5-abeb82429b87", "network_id": "f31af5a2-f14d-4007-b2e5-abeb82429b87",
"port_id": "99845c22-6268-46c1-b068-1dbcb8adaf68", "port_id": "99845c22-6268-46c1-b068-1dbcb8adaf68",
"floating_ip": null, "floating_ip": null,
"port_type": null,
"mac_address": "52:54:00:cc:ed:87", "mac_address": "52:54:00:cc:ed:87",
"fixed_ips": [ "fixed_ips": [
{ {

View File

@ -37,7 +37,6 @@ Request
- availability_zone: availability_zone - availability_zone: availability_zone
- networks: networks - networks: networks
- networks.net_id: network_uuid - networks.net_id: network_uuid
- networks.port_type: network_port_type
- networks.port_id: port_uuid - networks.port_id: port_uuid
- metadata: metadata - metadata: metadata
- user_data: user_data - user_data: user_data

View File

@ -31,7 +31,6 @@ create_server = {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
'net_id': parameter_types.network_id, 'net_id': parameter_types.network_id,
'port_type': parameter_types.port_type,
'port_id': parameter_types.network_port_id, 'port_id': parameter_types.network_port_id,
}, },
'oneOf': [ 'oneOf': [

View File

@ -57,7 +57,7 @@ def apply_jsonpatch(doc, patch):
def show_nics(nics): def show_nics(nics):
show_keys = ['port_id', 'port_type', 'network_id', 'mac_address', show_keys = ['port_id', 'network_id', 'mac_address',
'fixed_ips', 'floating_ip', 'extra'] 'fixed_ips', 'floating_ip', 'extra']
ret_nics = [] ret_nics = []
for nic in nics: for nic in nics:

View File

@ -54,11 +54,6 @@ network_port_id = {
} }
port_type = {
'type': 'string', 'minLength': 1, 'maxLength': 255,
}
flavor_id = { flavor_id = {
'type': 'string', 'format': 'uuid' 'type': 'string', 'format': 'uuid'
} }

View File

@ -105,7 +105,6 @@ def upgrade():
sa.Column('updated_at', sa.DateTime(), nullable=True), sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False), sa.Column('id', sa.Integer(), nullable=False),
sa.Column('address', sa.String(length=18), nullable=False), sa.Column('address', sa.String(length=18), nullable=False),
sa.Column('port_type', sa.String(length=255), nullable=False),
sa.Column('port_uuid', sa.String(length=36), nullable=False), sa.Column('port_uuid', sa.String(length=36), nullable=False),
sa.Column('node_uuid', sa.String(length=36), nullable=False), sa.Column('node_uuid', sa.String(length=36), nullable=False),
sa.Column('extra_specs', sa.Text(), nullable=True), sa.Column('extra_specs', sa.Text(), nullable=True),
@ -123,7 +122,6 @@ def upgrade():
sa.Column('port_id', sa.String(length=36), nullable=False), sa.Column('port_id', sa.String(length=36), nullable=False),
sa.Column('mac_address', sa.String(length=36), nullable=True), sa.Column('mac_address', sa.String(length=36), nullable=True),
sa.Column('network_id', sa.String(length=36), nullable=True), sa.Column('network_id', sa.String(length=36), nullable=True),
sa.Column('port_type', sa.String(length=64), nullable=True),
sa.Column('floating_ip', sa.String(length=64), nullable=True), sa.Column('floating_ip', sa.String(length=64), nullable=True),
sa.Column('fixed_ips', sa.Text(), nullable=True), sa.Column('fixed_ips', sa.Text(), nullable=True),
sa.ForeignKeyConstraint(['server_uuid'], ['servers.uuid'], ), sa.ForeignKeyConstraint(['server_uuid'], ['servers.uuid'], ),

View File

@ -120,7 +120,6 @@ class ComputePort(Base):
) )
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
address = Column(String(18), nullable=False) address = Column(String(18), nullable=False)
port_type = Column(String(255), nullable=False)
port_uuid = Column(String(36), nullable=False) port_uuid = Column(String(36), nullable=False)
node_uuid = Column(String(36), nullable=False) node_uuid = Column(String(36), nullable=False)
extra_specs = Column(db_types.JsonEncodedDict) extra_specs = Column(db_types.JsonEncodedDict)
@ -140,7 +139,6 @@ class ServerNic(Base):
mac_address = Column(String(32), nullable=False) mac_address = Column(String(32), nullable=False)
network_id = Column(String(36), nullable=True) network_id = Column(String(36), nullable=True)
fixed_ips = Column(db_types.JsonEncodedList) fixed_ips = Column(db_types.JsonEncodedList)
port_type = Column(String(64), nullable=True)
floating_ip = Column(String(64), nullable=True) floating_ip = Column(String(64), nullable=True)
_server = orm.relationship( _server = orm.relationship(
Server, Server,

View File

@ -159,11 +159,8 @@ class IronicDriver(base_driver.BaseEngineDriver):
def _port_resource(self, port): def _port_resource(self, port):
"""Helper method to create resource dict from port stats.""" """Helper method to create resource dict from port stats."""
port_type = port.extra.get('port_type')
dic = { dic = {
'address': str(port.address), 'address': str(port.address),
'port_type': str(port_type),
'node_uuid': str(port.node_uuid), 'node_uuid': str(port.node_uuid),
'port_uuid': str(port.uuid), 'port_uuid': str(port.uuid),
} }
@ -261,11 +258,8 @@ class IronicDriver(base_driver.BaseEngineDriver):
detail=detail) detail=detail)
return ports + portgroups return ports + portgroups
def plug_vif(self, ironic_port_id, port_id): def plug_vif(self, node_uuid, port_id):
patch = [{'op': 'add', self.ironicclient.call("node.vif_attach", node_uuid, port_id)
'path': '/extra/vif_port_id',
'value': port_id}]
self.ironicclient.call("port.update", ironic_port_id, patch)
def unplug_vifs(self, context, server): def unplug_vifs(self, context, server):
LOG.debug("unplug: server_uuid=%(uuid)s vif=%(server_nics)s", LOG.debug("unplug: server_uuid=%(uuid)s vif=%(server_nics)s",

View File

@ -156,38 +156,38 @@ class BuildNetworkTask(flow_utils.MoganTask):
'pif_count': len(ports)}) 'pif_count': len(ports)})
nics_obj = objects.ServerNics(context) nics_obj = objects.ServerNics(context)
for vif, pif in zip(requested_networks, ports): for vif in requested_networks:
# Match the specified port type with physical interface type try:
if vif.get('port_type', 'None') == pif.port_type: if vif.get('net_id'):
try: port = self.manager.network_api.create_port(
if vif.get('net_id'): context, vif['net_id'], server.uuid)
port = self.manager.network_api.create_port( port_dict = port['port']
context, vif['net_id'], pif.address, server.uuid) elif vif.get('port_id'):
port_dict = port['port'] port_dict = self.manager.network_api.show_port(
elif vif.get('port_id'): context, vif.get('port_id'))
port_dict = self.manager.network_api.show_port(
context, vif.get('port_id'))
self.manager.driver.plug_vif(pif.port_uuid, self.manager.driver.plug_vif(server.node_uuid,
port_dict['id']) port_dict['id'])
nic_dict = {'port_id': port_dict['id'], # Get updated VIF info
'network_id': port_dict['network_id'], port_dict = self.manager.network_api.show_port(
'mac_address': port_dict['mac_address'], context, port_dict.get('id'))
'fixed_ips': port_dict['fixed_ips'],
'port_type': vif.get('port_type'),
'server_uuid': server.uuid}
nics_obj.objects.append(objects.ServerNic(
context, **nic_dict))
except Exception as e: nic_dict = {'port_id': port_dict['id'],
# Set nics here, so we can clean up the 'network_id': port_dict['network_id'],
# created networks during reverting. 'mac_address': port_dict['mac_address'],
server.nics = nics_obj 'fixed_ips': port_dict['fixed_ips'],
LOG.error("Server %(server)s: create or get network " 'server_uuid': server.uuid}
"failed. The reason is %(reason)s", nics_obj.objects.append(objects.ServerNic(context, **nic_dict))
{"server": server.uuid, "reason": e})
raise exception.NetworkError(_( except Exception as e:
"Build network for server failed.")) # Set nics here, so we can clean up the
# created networks during reverting.
server.nics = nics_obj
LOG.error("Server %(server)s: create or get network "
"failed. The reason is %(reason)s",
{"server": server.uuid, "reason": e})
raise exception.NetworkError(_(
"Build network for server failed."))
return nics_obj return nics_obj
def execute(self, context, server, requested_networks, ports): def execute(self, context, server, requested_networks, ports):

View File

@ -599,19 +599,15 @@ class EngineManager(base_manager.BaseEngineManager):
raise exception.ComputePortNotAvailable(message=message) raise exception.ComputePortNotAvailable(message=message)
def attach_interface(self, context, server, net_id=None): def attach_interface(self, context, server, net_id=None):
pif = self._choose_pif_from_node(context, server.node_uuid) vif = self.network_api.create_port(context, net_id, server.uuid)
vif = self.network_api.create_port(
context, net_id, pif.address, server.uuid)
vif_port = vif['port'] vif_port = vif['port']
try: try:
self.driver.plug_vif(pif.uuid, vif_port['id']) self.driver.plug_vif(server.node_uuid, vif_port['id'])
nics_obj = objects.ServerNics(context) nics_obj = objects.ServerNics(context)
nic_dict = {'port_id': vif_port['id'], nic_dict = {'port_id': vif_port['id'],
'network_id': vif_port['network_id'], 'network_id': vif_port['network_id'],
'mac_address': vif_port['mac_address'], 'mac_address': vif_port['mac_address'],
'fixed_ips': vif_port['fixed_ips'], 'fixed_ips': vif_port['fixed_ips'],
'port_type': vif_port.get('port_type'),
'server_uuid': server.uuid} 'server_uuid': server.uuid}
nics_obj.objects.append(objects.ServerNic( nics_obj.objects.append(objects.ServerNic(
context, **nic_dict)) context, **nic_dict))

View File

@ -62,14 +62,13 @@ def get_client(token=None):
class API(object): class API(object):
"""API for interacting with the neutron 2.x API.""" """API for interacting with the neutron 2.x API."""
def create_port(self, context, network_uuid, mac, server_uuid): def create_port(self, context, network_uuid, server_uuid):
"""Create neutron port.""" """Create neutron port."""
client = get_client(context.auth_token) client = get_client(context.auth_token)
body = { body = {
'port': { 'port': {
'network_id': network_uuid, 'network_id': network_uuid,
'mac_address': mac,
'device_id': server_uuid, 'device_id': server_uuid,
} }
} }

View File

@ -31,7 +31,6 @@ class ComputePort(base.MoganObject, object_base.VersionedObjectDictCompat):
fields = { fields = {
'id': object_fields.IntegerField(read_only=True), 'id': object_fields.IntegerField(read_only=True),
'address': object_fields.MACAddressField(nullable=False), 'address': object_fields.MACAddressField(nullable=False),
'port_type': object_fields.StringField(),
'port_uuid': object_fields.UUIDField(read_only=True), 'port_uuid': object_fields.UUIDField(read_only=True),
'node_uuid': object_fields.UUIDField(read_only=True), 'node_uuid': object_fields.UUIDField(read_only=True),
'extra_specs': object_fields.FlexibleDictField(nullable=True), 'extra_specs': object_fields.FlexibleDictField(nullable=True),
@ -74,7 +73,7 @@ class ComputePort(base.MoganObject, object_base.VersionedObjectDictCompat):
self.obj_refresh(current) self.obj_refresh(current)
def update_from_driver(self, port): def update_from_driver(self, port):
keys = ["address", "port_type", "port_uuid", "node_uuid", keys = ["address", "port_uuid", "node_uuid",
"extra_specs"] "extra_specs"]
for key in keys: for key in keys:
if key in port: if key in port:

View File

@ -36,7 +36,6 @@ class ServerNic(base.MoganObject, object_base.VersionedObjectDictCompat):
'network_id': object_fields.UUIDField(nullable=True), 'network_id': object_fields.UUIDField(nullable=True),
'fixed_ips': object_fields.ListOfDictOfNullableStringsField( 'fixed_ips': object_fields.ListOfDictOfNullableStringsField(
nullable=True), nullable=True),
'port_type': object_fields.StringField(nullable=True),
'floating_ip': object_fields.StringField(nullable=True), 'floating_ip': object_fields.StringField(nullable=True),
} }

View File

@ -23,15 +23,6 @@ LOG = logging.getLogger(__name__)
class PortsFilter(filters.BaseNodeFilter): class PortsFilter(filters.BaseNodeFilter):
"""NodeFilter to work with resource server type records.""" """NodeFilter to work with resource server type records."""
def _find_port_type(self, ports, port_type):
"""Check if ports has the specified port type."""
for port in ports:
if port_type == port.port_type:
return True
return False
def _satisfies_networks(self, ports, networks): def _satisfies_networks(self, ports, networks):
"""Check if ports satisfy networks requirements. """Check if ports satisfy networks requirements.
@ -45,11 +36,6 @@ class PortsFilter(filters.BaseNodeFilter):
if len(ports) < len(networks): if len(ports) < len(networks):
return False return False
for net in networks:
if 'port_type' in net:
if not self._find_port_type(ports, net.get('port_type')):
return False
return True return True
def node_passes(self, node_state, filter_properties): def node_passes(self, node_state, filter_properties):

View File

@ -134,8 +134,8 @@ class TestServers(v1_test.APITestV1):
'flavor_uuid': 'ff28b5a2-73e5-431c-b4b7-1b96b74bca7b', 'flavor_uuid': 'ff28b5a2-73e5-431c-b4b7-1b96b74bca7b',
'image_uuid': 'b8f82429-3a13-4ffe-9398-4d1abdc256a8', 'image_uuid': 'b8f82429-3a13-4ffe-9398-4d1abdc256a8',
'networks': [ 'networks': [
{'net_id': 'c1940655-8b8e-4370-b8f9-03ba1daeca31', {'net_id': 'c1940655-8b8e-4370-b8f9-03ba1daeca31'}
'port_type': 'Ethernet'}], ],
'metadata': {'fake_key': 'fake_value'} 'metadata': {'fake_key': 'fake_value'}
} }
responses.append( responses.append(

View File

@ -161,7 +161,6 @@ class BaremetalComputeAPIServersTest(base.BaseBaremetalComputeTest):
self.assertIn('network_id', nic) self.assertIn('network_id', nic)
self.assertIn('port_id', nic) self.assertIn('port_id', nic)
self.assertIn('floating_ip', nic) self.assertIn('floating_ip', nic)
self.assertIn('port_type', nic)
self.assertIn('mac_address', nic) self.assertIn('mac_address', nic)
self.assertIsInstance(nic['fixed_ips'], list) self.assertIsInstance(nic['fixed_ips'], list)
fixed_ip = nic['fixed_ips'][0] fixed_ip = nic['fixed_ips'][0]
@ -181,7 +180,6 @@ class BaremetalComputeAPIServersTest(base.BaseBaremetalComputeTest):
self.assertIn('network_id', nic) self.assertIn('network_id', nic)
self.assertIn('port_id', nic) self.assertIn('port_id', nic)
self.assertIn('floating_ip', nic) self.assertIn('floating_ip', nic)
self.assertIn('port_type', nic)
self.assertIn('mac_address', nic) self.assertIn('mac_address', nic)
self.assertIsInstance(nic['fixed_ips'], list) self.assertIsInstance(nic['fixed_ips'], list)
fixed_ip = nic['fixed_ips'][0] fixed_ip = nic['fixed_ips'][0]

View File

@ -29,8 +29,7 @@ def gen_post_body(**kw):
"net_id": "c1940655-8b8e-4370-b8f9-03ba1daeca31" "net_id": "c1940655-8b8e-4370-b8f9-03ba1daeca31"
}, },
{ {
"net_id": "8e8ceb07-4641-4188-9b22-840755e92ee2", "net_id": "8e8ceb07-4641-4188-9b22-840755e92ee2"
"port_type": "10GE"
} }
] ]
return { return {
@ -81,12 +80,10 @@ class TestServerAuthorization(v1_test.APITestV1):
mock_engine_create.return_value = [self.server1] mock_engine_create.return_value = [self.server1]
fake_networks = [ fake_networks = [
{ {
"port_id": "c1940655-8b8e-4370-b8f9-03ba1daeca31", "port_id": "c1940655-8b8e-4370-b8f9-03ba1daeca31"
"port_type": "Ethernet"
}, },
{ {
"port_id": "8e8ceb07-4641-4188-9b22-840755e92ee2", "port_id": "8e8ceb07-4641-4188-9b22-840755e92ee2"
"port_type": "Ethernet"
} }
] ]
body = gen_post_body(**{'networks': fake_networks}) body = gen_post_body(**{'networks': fake_networks})
@ -110,13 +107,11 @@ class TestServerAuthorization(v1_test.APITestV1):
fake_networks = [ fake_networks = [
{ {
"port_id": "c1940655-8b8e-4370-b8f9-03ba1daeca31", "port_id": "c1940655-8b8e-4370-b8f9-03ba1daeca31",
"net_id": "c1940655-8b8e-4370-b8f9-03ba1daeca32", "net_id": "c1940655-8b8e-4370-b8f9-03ba1daeca32"
"port_type": "Ethernet"
}, },
{ {
"port_id": "8e8ceb07-4641-4188-9b22-840755e92ee2", "port_id": "8e8ceb07-4641-4188-9b22-840755e92ee2",
"net_id": "8e8ceb07-4641-4188-9b22-840755e92ee3", "net_id": "8e8ceb07-4641-4188-9b22-840755e92ee3"
"port_type": "Ethernet"
} }
] ]
body = gen_post_body(**{'networks': fake_networks}) body = gen_post_body(**{'networks': fake_networks})

View File

@ -74,5 +74,5 @@ class DbComputePortTestCase(base.DbTestCase):
port = utils.create_test_compute_port() port = utils.create_test_compute_port()
res = self.dbapi.compute_port_update(self.context, res = self.dbapi.compute_port_update(self.context,
port.port_uuid, port.port_uuid,
{'port_type': 'foo'}) {'address': 'aa:bb:cc:dd:ee:ff'})
self.assertEqual('foo', res.port_type) self.assertEqual('aa:bb:cc:dd:ee:ff', res.address)

View File

@ -35,7 +35,6 @@ def get_test_server(**kw):
"ip_address": "2001:db8:8000:0:5054:ff:fe6a:b7cc" "ip_address": "2001:db8:8000:0:5054:ff:fe6a:b7cc"
} }
], ],
'port_type': 'test_type',
'floating_ip': '', 'floating_ip': '',
}, ] }, ]
@ -130,7 +129,6 @@ def get_test_compute_port(**kw):
return { return {
'id': kw.get('id', 123), 'id': kw.get('id', 123),
'address': kw.get('address', '52:54:00:cf:2d:31'), 'address': kw.get('address', '52:54:00:cf:2d:31'),
'port_type': kw.get('port_type', '1GE'),
'port_uuid': kw.get('port_uuid', 'port_uuid': kw.get('port_uuid',
'f978ef48-d4af-4dad-beec-e6174309bc72'), 'f978ef48-d4af-4dad-beec-e6174309bc72'),
'node_uuid': kw.get('node_uuid', 'node_uuid': kw.get('node_uuid',

View File

@ -90,5 +90,4 @@ class TestComputePortObject(base.DbTestCase):
db_port = utils.create_test_compute_port(context=self.ctxt) db_port = utils.create_test_compute_port(context=self.ctxt)
port = objects.ComputePort.get(self.context, db_port.port_uuid) port = objects.ComputePort.get(self.context, db_port.port_uuid)
port.refresh(self.context) port.refresh(self.context)
port.port_type = 'refresh'
port.save(self.context) port.save(self.context)

View File

@ -385,13 +385,13 @@ expected_object_fingerprints = {
'Server': '1.0-dc54162c0cc91fac43fed5304cd2c968', 'Server': '1.0-dc54162c0cc91fac43fed5304cd2c968',
'ComputeNode': '1.0-586e7eaadd4ec88a0506c4238ebdd7a5', 'ComputeNode': '1.0-586e7eaadd4ec88a0506c4238ebdd7a5',
'ComputeNodeList': '1.0-33a2e1bb91ad4082f9f63429b77c1244', 'ComputeNodeList': '1.0-33a2e1bb91ad4082f9f63429b77c1244',
'ComputePort': '1.0-ca4c1817ad7324286813f2cfcdcf802e', 'ComputePort': '1.0-996a1dc296ac109730e7976735488eb2',
'ComputePortList': '1.0-33a2e1bb91ad4082f9f63429b77c1244', 'ComputePortList': '1.0-33a2e1bb91ad4082f9f63429b77c1244',
'ServerFault': '1.0-74349ff701259e4834b4e9dc2dac1b12', 'ServerFault': '1.0-74349ff701259e4834b4e9dc2dac1b12',
'ServerFaultList': '1.0-43e8aad0258652921f929934e9e048fd', 'ServerFaultList': '1.0-43e8aad0258652921f929934e9e048fd',
'Flavor': '1.0-f53b71bd4aaaadea0d9284b811a82bb5', 'Flavor': '1.0-f53b71bd4aaaadea0d9284b811a82bb5',
'MyObj': '1.1-aad62eedc5a5cc8bcaf2982c285e753f', 'MyObj': '1.1-aad62eedc5a5cc8bcaf2982c285e753f',
'ServerNic': '1.0-ebbd767c2f6a7f14bd524c6067f2b382', 'ServerNic': '1.0-0494306157ef437802260ff8b51cf5cf',
'ServerNics': '1.0-33a2e1bb91ad4082f9f63429b77c1244', 'ServerNics': '1.0-33a2e1bb91ad4082f9f63429b77c1244',
'Quota': '1.0-c8caa082f4d726cb63fdc5943f7cd186', 'Quota': '1.0-c8caa082f4d726cb63fdc5943f7cd186',
'KeyPair': '1.0-c6820166e307676c5900f7801831b84c', 'KeyPair': '1.0-c6820166e307676c5900f7801831b84c',