Merge lp:~cisco-openstack/neutron/l2network-plugin-persistence into lp:neutron/diablo

Proposed by Rohit Agarwalla
Status: Merged
Approved by: Salvatore Orlando
Approved revision: 76
Merged at revision: 48
Proposed branch: lp:~cisco-openstack/neutron/l2network-plugin-persistence
Merge into: lp:neutron/diablo
Diff against target: 5302 lines (+2779/-936)
37 files modified
quantum/plugins/cisco/README (+57/-14)
quantum/plugins/cisco/__init__.py (+2/-0)
quantum/plugins/cisco/common/__init__.py (+2/-0)
quantum/plugins/cisco/common/cisco_configparser.py (+4/-5)
quantum/plugins/cisco/common/cisco_constants.py (+20/-1)
quantum/plugins/cisco/common/cisco_credentials.py (+11/-1)
quantum/plugins/cisco/common/cisco_exceptions.py (+53/-6)
quantum/plugins/cisco/common/cisco_nova_configuration.py (+10/-8)
quantum/plugins/cisco/common/cisco_utils.py (+16/-4)
quantum/plugins/cisco/conf/db_conn.ini (+5/-0)
quantum/plugins/cisco/conf/nexus.ini (+2/-0)
quantum/plugins/cisco/db/api.py (+254/-0)
quantum/plugins/cisco/db/l2network_db.py (+346/-0)
quantum/plugins/cisco/db/l2network_models.py (+147/-0)
quantum/plugins/cisco/db/models.py (+102/-0)
quantum/plugins/cisco/l2device_plugin_base.py (+9/-1)
quantum/plugins/cisco/l2network_model.py (+47/-24)
quantum/plugins/cisco/l2network_model_base.py (+10/-1)
quantum/plugins/cisco/l2network_plugin.py (+208/-195)
quantum/plugins/cisco/l2network_plugin_configuration.py (+40/-23)
quantum/plugins/cisco/nexus/__init__.py (+4/-1)
quantum/plugins/cisco/nexus/cisco_nexus_configuration.py (+12/-7)
quantum/plugins/cisco/nexus/cisco_nexus_network_driver.py (+73/-167)
quantum/plugins/cisco/nexus/cisco_nexus_plugin.py (+20/-6)
quantum/plugins/cisco/nexus/cisco_nexus_snippets.py (+156/-0)
quantum/plugins/cisco/run_tests.py (+40/-252)
quantum/plugins/cisco/tests/unit/test_database.py (+840/-0)
quantum/plugins/cisco/tests/unit/test_l2networkApi.py (+180/-110)
quantum/plugins/cisco/tests/unit/test_nexus_plugin.py (+3/-4)
quantum/plugins/cisco/tests/unit/test_ucs_driver.py (+29/-26)
quantum/plugins/cisco/tests/unit/test_ucs_plugin.py (+16/-18)
quantum/plugins/cisco/ucs/__init__.py (+2/-0)
quantum/plugins/cisco/ucs/cisco_getvif.py (+4/-1)
quantum/plugins/cisco/ucs/cisco_ucs_configuration.py (+11/-9)
quantum/plugins/cisco/ucs/cisco_ucs_network_driver.py (+26/-10)
quantum/plugins/cisco/ucs/cisco_ucs_plugin.py (+17/-5)
tests/unit/test_api.py (+1/-37)
To merge this branch: bzr merge lp:~cisco-openstack/neutron/l2network-plugin-persistence
Reviewer Review Type Date Requested Status
Salvatore Orlando Approve
Brad Hall (community) Approve
Review via email: mp+71779@code.launchpad.net

Description of the change

This branch has two main changes over the earlier approved branch (lp:~cisco-openstack/quantum/l2network-plugin):

• Addition of persistence support and framework
• Enhancements/fixes to increase the pylint score. (The pylint score for the modules checked under quantum/plugins/cisco now stands as 8.29, above the target of 7.5 set for us by Salvatore. :-))

The changes proposed in this branch are again contained within the quantum/plugins/cisco directory (with the exception of some test related artifacts to comply with Dan's framework), and as such do not affect any other Quantum functionality. Branch has been tested, and all tests pass successfully.

We have also made changes to address the review comments provided for the earlier branch, most notably,
• We address the ID generation issue, as suggested by Salvatore
• We have cleaned up the XML snippets in the nexus driver, as recommended by Dan (we still use them in the ucs driver since it's more convenient to that right now, but we will move them in the future)
• We have moved ssh port-specific details to the conf files
• We have added more descriptive comments so that the network model and device plugin base classes can be better understood. We have also enhanced the README file.
• We still have a single logging component, and we will change that in an upcoming merge.

More specifically on the persistence support in this branch - We would hope that some of the practices we have followed can be promoted to the core Quantum framework. For instance, we found it useful to use the "InnoDB" engine to enforce foreign key constraints. This and other such details related to the persistence framework are highlighted below:
- persistence framework for quantum/plugins/cisco/l2network_plugin
                - implementation - mysql as the database and sqlalchmey as the ORM
                - quantum/plugins/cisco/db/ consists the persistent framework code
                - l2network_plugin specific new models and db methods have been defined
                - vlan_id management implementation using the db has been implemented
                - quantum core models and api (for network & port) have been reused within the plugin with the following changes -
                    - specify mysql engine for models (InnoDB) - this engine imposes foreign key constraints
                    - early loading of tables using joinedload in queries - this allows to exercise the relation attribute defined between network & port tables
                - README contains instructions on how to perform the database configurations
- plugin specific changes -
                - refactored plugins/cisco/l2network_plugin methods
                     - to perform necessary actions against the db for various methods
                     - to return dictionary items from method as per api expectations
- tests specific changes -
                - refactored plugins/cisco/tests/unit/test_l2networkapi test cases to check results with the db for various methods
                - independent database tests added in plugins/cisco/tests/unit/test_database.py to test core and l2network_plugin models

Thanks
Sumit, Shweta, Rohit

To post a comment you must log in.
Revision history for this message
Salvatore Orlando (salvatore-orlando) wrote :

Hi Sumit/Rohit,

I apologise for the "needs fixing" without a proper review, but it seems your branch has several conflict with trunk!

review: Needs Fixing
70. By Sumit Naiksatam

Pulling in changes from lp:quantum.

Revision history for this message
Sumit Naiksatam (snaiksat) wrote :

> Hi Sumit/Rohit,
>
> I apologise for the "needs fixing" without a proper review, but it seems your
> branch has several conflict with trunk!

Our apologies as well, the conflicts have been fixed.

Revision history for this message
Brad Hall (bgh) wrote :

1171 + return vlanid
1172 + except exc.NoResultFound:
1173 + pass

Indentation is off there

1244 + except exc.NoResultFound:
1245 + pass

Same here

1315 + return pp
1316 + except exc.NoResultFound:
1317 + pass

And here

1320 +def update_portprofile(tenantid, ppid, newppname=None, newvlanid=None, \
1321 + newqos=None):

You don't need the "\" there

2454 + res[const.NET_PORTS] = ports

I think you want const.NETWORKPORTS there?

1975 + const.NET_PORTS: []}

(and here)

4911 + def _make_net_dict(self, net_id, net_name, ports):
4912 + res = {const.NET_ID: net_id, const.NET_NAME: net_name}
4913 + res[const.NET_PORTS] = ports
4914 + return res

(and here)

2460 + res[const.NET_ID] = net_id

There is const.NET_ID used in a lot of places when I think it should be
const.NETWORKID .. but I could be missing something here. Maybe const.NET_ID
is still defined somewher else.

3182 +"""Unittest runner for quantum OVS plugin

Might want to change that to Cisco plugin ;)

3438 +#from quantum.plugins.openvswitch.tests.test_vlan_map import VlanMapTest

Might as well nuke that line.. don't think its ever going to be used in this
file.

3740 +class QuantumDB(object):
3741 + """Class conisting of methods to call Quantum db methods"""
3742 + def get_all_networks(self, tenant_id):

We should probably move this type of stuff into a library since other plugins
will want to use it. Not an issue for this merge though.

review: Needs Fixing
71. By Rohit Agarwalla

Fixed indentation and changed file comments

Revision history for this message
Rohit Agarwalla (rohitagarwalla) wrote :

Thanks for the review and comments Brad.

> 1171 + return vlanid
> 1172 + except exc.NoResultFound:
> 1173 + pass
>
> Indentation is off there
>
> 1244 + except exc.NoResultFound:
> 1245 + pass
>
> Same here
>
> 1315 + return pp
> 1316 + except exc.NoResultFound:
> 1317 + pass
>
> And here
>
> 1320 +def update_portprofile(tenantid, ppid, newppname=None,
> newvlanid=None, \
> 1321 + newqos=None):
>
> You don't need the "\" there
>

Fixed.

> 2454 + res[const.NET_PORTS] = ports
>
> I think you want const.NETWORKPORTS there?
>
> 1975 + const.NET_PORTS: []}
>
> (and here)
>
> 4911 + def _make_net_dict(self, net_id, net_name, ports):
> 4912 + res = {const.NET_ID: net_id, const.NET_NAME: net_name}
> 4913 + res[const.NET_PORTS] = ports
> 4914 + return res
>
> (and here)
>
> 2460 + res[const.NET_ID] = net_id
>
> There is const.NET_ID used in a lot of places when I think it should be
> const.NETWORKID .. but I could be missing something here. Maybe const.NET_ID
> is still defined somewher else.
>

NETWORKPORTS = 'ports'
NET_PORTS = 'net-ports'

NETWORKID = 'network_id'
NET_ID = 'net-id'

There are two different constants defined in cisco/common/cisco_constants.py.
As you would have seen, the make_dict methods create a dictionary with keys as excepted by the api (net-id in this case)
We couldn't define net-id (and others containing '-' ) as variables for the database models and therefore had to use different variables.

> 3182 +"""Unittest runner for quantum OVS plugin
>
> Might want to change that to Cisco plugin ;)
>
> 3438 +#from quantum.plugins.openvswitch.tests.test_vlan_map import
> VlanMapTest
>
> Might as well nuke that line.. don't think its ever going to be used in this
> file.
>
> 3740 +class QuantumDB(object):
> 3741 + """Class conisting of methods to call Quantum db methods"""
> 3742 + def get_all_networks(self, tenant_id):
>
> We should probably move this type of stuff into a library since other plugins
> will want to use it. Not an issue for this merge though.

Sure, we'll take this an action item.

Revision history for this message
Brad Hall (bgh) wrote :

> Thanks for the review and comments Brad.
>
> > 1171 + return vlanid
> > 1172 + except exc.NoResultFound:
> > 1173 + pass
> >
> > Indentation is off there
> >
> > 1244 + except exc.NoResultFound:
> > 1245 + pass
> >
> > Same here
> >
> > 1315 + return pp
> > 1316 + except exc.NoResultFound:
> > 1317 + pass
> >
> > And here
> >
> > 1320 +def update_portprofile(tenantid, ppid, newppname=None,
> > newvlanid=None, \
> > 1321 + newqos=None):
> >
> > You don't need the "\" there
> >
>
> Fixed.

Great, thanks!

>
> > 2454 + res[const.NET_PORTS] = ports
> >
> > I think you want const.NETWORKPORTS there?
> >
> > 1975 + const.NET_PORTS: []}
> >
> > (and here)
> >
> > 4911 + def _make_net_dict(self, net_id, net_name, ports):
> > 4912 + res = {const.NET_ID: net_id, const.NET_NAME: net_name}
> > 4913 + res[const.NET_PORTS] = ports
> > 4914 + return res
> >
> > (and here)
> >
> > 2460 + res[const.NET_ID] = net_id
> >
> > There is const.NET_ID used in a lot of places when I think it should be
> > const.NETWORKID .. but I could be missing something here. Maybe
> const.NET_ID
> > is still defined somewher else.
> >
>
> NETWORKPORTS = 'ports'
> NET_PORTS = 'net-ports'
>
> NETWORKID = 'network_id'
> NET_ID = 'net-id'
>
> There are two different constants defined in cisco/common/cisco_constants.py.
> As you would have seen, the make_dict methods create a dictionary with keys as
> excepted by the api (net-id in this case)
> We couldn't define net-id (and others containing '-' ) as variables for the
> database models and therefore had to use different variables.

OK, I understand now.. I just didn't see NET_ID in the diff.

> > 3182 +"""Unittest runner for quantum OVS plugin
> >
> > Might want to change that to Cisco plugin ;)
> >
> > 3438 +#from quantum.plugins.openvswitch.tests.test_vlan_map import
> > VlanMapTest
> >
> > Might as well nuke that line.. don't think its ever going to be used in this
> > file.
> >
> > 3740 +class QuantumDB(object):
> > 3741 + """Class conisting of methods to call Quantum db methods"""
> > 3742 + def get_all_networks(self, tenant_id):
> >
> > We should probably move this type of stuff into a library since other
> plugins
> > will want to use it. Not an issue for this merge though.
>
> Sure, we'll take this an action item.

Awesome, thanks.

review: Approve
72. By Rohit Agarwalla

pep8 error fixed for l2network_db.py

Revision history for this message
Salvatore Orlando (salvatore-orlando) wrote :
Download full text (4.3 KiB)

Hi Rohit,

thanks a lot for proposing this significant improvement on the Cisco plugin.
The code looks good, and, as usual, it is very well written and easy to understand.

I have a few comments below aimed at improving it or understanding whether some bits of it can be "promoted" to quantum core. Please let me know if you have any question.

(Relatively) Major comments:

1 === added file 'quantum/common/test_lib.py'
2 --- quantum/common/test_lib.py 1970-01-01 00:00:00 +0000
3 +++ quantum/common/test_lib.py 2011-08-18 18:13:27 +0000

This is strange. quantum/common/test_lib.py is already in trunk, and it seems it is identical to the one in this branch.

1104 +def create_vlanids():
1105 + """Prepopulates the vlan_bindings table"""
1106 + session = db.get_session()
1107 + try:
1108 + vlanid = session.query(l2network_models.VlanID).\
1109 + one()
1110 + except exc.MultipleResultsFound:
1111 + pass
1112 + except exc.NoResultFound:
1113 + start = int(conf.VLAN_START)
1114 + end = int(conf.VLAN_END)
1115 + while start <= end:
1116 + vlanid = l2network_models.VlanID(start)
1117 + session.add(vlanid)
1118 + start += 1
1119 + session.flush()
1120 + return

IMHO this routine could be improved. Pre-population is skipped if a single record is found in the DB. This means that if I change VLAN_START or VLAN_END and I do not destroy the DB, the DB will not be updated.

4168 -4323: These are unit tests specific for quantum.db. I'd propose to have them in a separate file in /tests/unit. Thank you very much for implementing these much-needed unit tests!!!

Minor comments:

335 + 5b. Enter the quantum_l2netowrk database configuration info in the
336 + quantum/plugins/cisco/conf/db_conn.ini file.

There's a typo in the first line (should be quantum_l2network)

348 your configuration of each of the above files hasn't gone a little kaka

'kaka'? Are you referring to the Real Madrid's Brazilian player :) ? I guess it means something like "screwed". No need to change it, it is just that this term is totally new to me.

1093 +import l2network_models

Please avoid relative imports

1180 + vlanids = session.query(l2network_models.VlanID).\
1181 + filter_by(vlan_used=False).\
1182 + all()
1183 + rvlan = vlanids[0]

IMHO using first() instead of all() will improve the efficiency of this routine.

1747 + LOG.debug("Loaded device plugin %s\n" % \

Python logging already adds newline at the end of line. This newline is therefore redundant, unless we need it for other reasons.

2788 -2789 : Indentation can be improved here

2798 + confstr = snipp.CMD_VLAN_CONF_SNIPPET % (vlanid, vlanname)
2799 + confstr = snipp.EXEC_CONF_PREFIX + confstr + snipp.EXEC_CONF_POSTFIX

Consider merging EXEC_CONF_PREFIX and POSTIFIX into a EXEC_CONF_SNIPPET.
Also, since line 2799 is repeated several times, consider moving it into a subroutine.

3144 +FILTER_SHOW_VLAN_BRIEF_SNIPPET = """
3145 + <show xmlns="http://www.cisco.com/nxos:1.0:vlan_mgr_cli">
3146 + <vlan>
3147 + <brief/>
3148 + </vlan>
3149 + </show> """

End delimiter for a docstring is usually in a new line, as you did for other docstrings in the same module.

3517 - 3905: L2NetworkDB and QuantumDB are wrappers around database apis...

Read more...

review: Needs Fixing
73. By Rohit Agarwalla

Fixes based on review comments

Revision history for this message
Rohit Agarwalla (rohitagarwalla) wrote :
Download full text (7.1 KiB)

Hi Salvatore,

Thank you very much for the meticulous review. Appreciate all of your comments. Please find responses in line.

> Hi Rohit,
>
> thanks a lot for proposing this significant improvement on the Cisco plugin.
> The code looks good, and, as usual, it is very well written and easy to
> understand.
>
Thank you !

> I have a few comments below aimed at improving it or understanding whether
> some bits of it can be "promoted" to quantum core. Please let me know if you
> have any question.
>
> (Relatively) Major comments:
>
> 1 === added file 'quantum/common/test_lib.py'
> 2 --- quantum/common/test_lib.py 1970-01-01 00:00:00 +0000
> 3 +++ quantum/common/test_lib.py 2011-08-18 18:13:27 +0000
>
> This is strange. quantum/common/test_lib.py is already in trunk, and it seems
> it is identical to the one in this branch.
>
This file wasn't touched at all in this branch. I have made a checkin based on some of the changes proposed below. I'll try to sync this branch with top of quantum and see if this diff file goes away.

> 1104 +def create_vlanids():
> 1105 + """Prepopulates the vlan_bindings table"""
> 1106 + session = db.get_session()
> 1107 + try:
> 1108 + vlanid = session.query(l2network_models.VlanID).\
> 1109 + one()
> 1110 + except exc.MultipleResultsFound:
> 1111 + pass
> 1112 + except exc.NoResultFound:
> 1113 + start = int(conf.VLAN_START)
> 1114 + end = int(conf.VLAN_END)
> 1115 + while start <= end:
> 1116 + vlanid = l2network_models.VlanID(start)
> 1117 + session.add(vlanid)
> 1118 + start += 1
> 1119 + session.flush()
> 1120 + return
>
> IMHO this routine could be improved. Pre-population is skipped if a single
> record is found in the DB. This means that if I change VLAN_START or VLAN_END
> and I do not destroy the DB, the DB will not be updated.
>

Fine observation. Currently, a changed config would require to start on a clean slate as the cleanup of the old config needs to happen at other levels as well. We realize this limitation and have made a note in the cisco plugins README file.

> 4168 -4323: These are unit tests specific for quantum.db. I'd propose to have
> them in a separate file in /tests/unit. Thank you very much for implementing
> these much-needed unit tests!!!
>

Thank you. I'd be very motivated to place them in the quantum framework structure. To begin with, we didn't want to propose directly and wanted to get comments if such tests could be useful (which seems like they are). Also, currently, at the quantum layer we dont have a mysql database that these tests need. I'm thinking of using in-memory database for these tests to run at the quantum level. I also have some extra tests within this class that needs changes at the db/api module (mentioned below). If you think the way it is currently is ok, then I already have this as an action item to followup/work on this as a separate activity.

>
> Minor comments:
>
> 335 + 5b. Enter the quantum_l2netowrk database configuration info in the
> 336 + quantum/plugins/cisco/conf/db_conn.ini file.
>
> There's a typo in the first line (should be quantum_l2network)
>
> 348 your conf...

Read more...

74. By Rohit Agarwalla

merging from lp:quantum

75. By Rohit Agarwalla

merging with lp:quantum

76. By Edgar Magana

Code changed base on Reviews
pep8 passed
pylint 9.10

Revision history for this message
Edgar Magana (emagana) wrote :

Salvatore and Brad,

Thank you so much for your review. Regarding the reviews on the Nexus these are my changes:

> 2788 -2789 : Indentation can be improved here
>
> 2798 + confstr = snipp.CMD_VLAN_CONF_SNIPPET % (vlanid, vlanname)
> 2799 + confstr = snipp.EXEC_CONF_PREFIX + confstr + snipp.EXEC_CONF_POSTFIX
>
> Consider merging EXEC_CONF_PREFIX and POSTIFIX into a EXEC_CONF_SNIPPET.
> Also, since line 2799 is repeated several times, consider moving it into a
> subroutine.

<Edgar> I did both, merged post and pre-fixs and also moved it to a subroutine.

>
> 3144 +FILTER_SHOW_VLAN_BRIEF_SNIPPET = """
> 3145 + <show xmlns="http://www.cisco.com/nxos:1.0:vlan_mgr_cli">
> 3146 + <vlan>
> 3147 + <brief/>
> 3148 + </vlan>
> 3149 + </show> """
> End delimiter for a docstring is usually in a new line, as you did for other
> docstrings in the same module.
>

<Edgar> I did add an extra line after "show" as salvatore suggested.

Thanks!

Revision history for this message
Salvatore Orlando (salvatore-orlando) wrote :
Download full text (8.4 KiB)

> Hi Salvatore,
>
> Thank you very much for the meticulous review. Appreciate all of your
> comments. Please find responses in line.
>
> > Hi Rohit,
> >
> > thanks a lot for proposing this significant improvement on the Cisco plugin.
> > The code looks good, and, as usual, it is very well written and easy to
> > understand.
> >
> Thank you !
>
> > I have a few comments below aimed at improving it or understanding whether
> > some bits of it can be "promoted" to quantum core. Please let me know if you
> > have any question.
> >
> > (Relatively) Major comments:
> >
> > 1 === added file 'quantum/common/test_lib.py'
> > 2 --- quantum/common/test_lib.py 1970-01-01 00:00:00 +0000
> > 3 +++ quantum/common/test_lib.py 2011-08-18 18:13:27 +0000
> >
> > This is strange. quantum/common/test_lib.py is already in trunk, and it
> seems
> > it is identical to the one in this branch.
> >
> This file wasn't touched at all in this branch. I have made a checkin based on
> some of the changes proposed below. I'll try to sync this branch with top of
> quantum and see if this diff file goes away.

It seems the problem disappeared with your latest push.

>
> > 1104 +def create_vlanids():
> > 1105 + """Prepopulates the vlan_bindings table"""
> > 1106 + session = db.get_session()
> > 1107 + try:
> > 1108 + vlanid = session.query(l2network_models.VlanID).\
> > 1109 + one()
> > 1110 + except exc.MultipleResultsFound:
> > 1111 + pass
> > 1112 + except exc.NoResultFound:
> > 1113 + start = int(conf.VLAN_START)
> > 1114 + end = int(conf.VLAN_END)
> > 1115 + while start <= end:
> > 1116 + vlanid = l2network_models.VlanID(start)
> > 1117 + session.add(vlanid)
> > 1118 + start += 1
> > 1119 + session.flush()
> > 1120 + return
> >
> > IMHO this routine could be improved. Pre-population is skipped if a single
> > record is found in the DB. This means that if I change VLAN_START or
> VLAN_END
> > and I do not destroy the DB, the DB will not be updated.
> >
>
> Fine observation. Currently, a changed config would require to start on a
> clean slate as the cleanup of the old config needs to happen at other levels
> as well. We realize this limitation and have made a note in the cisco plugins
> README file.

Fine.

>
> > 4168 -4323: These are unit tests specific for quantum.db. I'd propose to
> have
> > them in a separate file in /tests/unit. Thank you very much for implementing
> > these much-needed unit tests!!!
> >
>
> Thank you. I'd be very motivated to place them in the quantum framework
> structure. To begin with, we didn't want to propose directly and wanted to get
> comments if such tests could be useful (which seems like they are). Also,
> currently, at the quantum layer we dont have a mysql database that these tests
> need. I'm thinking of using in-memory database for these tests to run at the
> quantum level. I also have some extra tests within this class that needs
> changes at the db/api module (mentioned below). If you think the way it is
> currently is ok, then I already have this as an action item to followup/work
> on this as a separate activity.
>

I think they can stay in the cisco dir...

Read more...

review: Approve
Revision history for this message
Rohit Agarwalla (rohitagarwalla) wrote :
Download full text (4.4 KiB)

> > (Relatively) Major comments:
> >
> > 1 === added file 'quantum/common/test_lib.py'
> > 2 --- quantum/common/test_lib.py 1970-01-01 00:00:00 +0000
> > 3 +++ quantum/common/test_lib.py 2011-08-18 18:13:27 +0000
> >
> > This is strange. quantum/common/test_lib.py is already in trunk, and it
> seems
> > it is identical to the one in this branch.
> >
> This file wasn't touched at all in this branch. I have made a checkin based on
> some of the changes proposed below. I'll try to sync this branch with top of
> quantum and see if this diff file goes away.

It seems the problem disappeared with your latest push.

Rohit: Yes, a new test_lib.py seems to have been added in one of the revisions on lp:quantum. So, we had to ensure that the cisco branch had that new file to avoid the conflict.

>
> > 4168 -4323: These are unit tests specific for quantum.db. I'd propose to
> have
> > them in a separate file in /tests/unit. Thank you very much for implementing
> > these much-needed unit tests!!!
> >
>
> Thank you. I'd be very motivated to place them in the quantum framework
> structure. To begin with, we didn't want to propose directly and wanted to get
> comments if such tests could be useful (which seems like they are). Also,
> currently, at the quantum layer we dont have a mysql database that these tests
> need. I'm thinking of using in-memory database for these tests to run at the
> quantum level. I also have some extra tests within this class that needs
> changes at the db/api module (mentioned below). If you think the way it is
> currently is ok, then I already have this as an action item to followup/work
> on this as a separate activity.
>

I think they can stay in the cisco directory at the moment. I think we should move them into the main "tests" folder before diablo release though. I will post to the mailing list in order to decide together the best course of action.

Rohit: Sounds like a plan.

>
> > 3517 - 3905: L2NetworkDB and QuantumDB are wrappers around database apis
> uses
> > by test cases. For improve code readability, these classes are typycally put
> > in a separate module. (see /tests/unit/extensions)
> >
>
> Absolutely, I'd make this activity as part of moving the reusable tests to the
> quantum level (mentioned in the above comment)
>

No problem.

Rohit: Thanks.

> > Curiosities:
> >
> > 807 === added file 'quantum/plugins/cisco/db/api.py'
> >
> > Have you considered re-using the code in quantum/db/api.py? If yes, why
> wasn't
> > this code suitable for your needs? I'm asking because it seems this module
> > seems very similar to the db api in quantum.
> >
> > Similar comment for the module quantum/plugins/cisco/db/models.py
> > If the reason is the InnoDB engine then we can try and improve modules in
> > quantum/db, thus avoiding code duplication.
> >
>
> Yes, we have indeed considered to reuse this code. We have also preserved the
> credits/authors so that the reviewers are aware of it. Like its mentioned in
> the merge proposal, we made couple of changes in these modules -
> * specify mysql engine for models (InnoDB) - this engine imposes foreign key
> constraints
> * early loading of tables...

Read more...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'quantum/plugins/cisco/README'
--- quantum/plugins/cisco/README 2011-08-15 17:13:08 +0000
+++ quantum/plugins/cisco/README 2011-08-23 20:09:26 +0000
@@ -1,8 +1,8 @@
1=====================================================================1=========================================================================================
2README: A Framework for a Quantum Plugin Supporting Multiple Switches2README: A Quantum Plugin Framework for Supporting L2 Networks Spannning Multiple Switches
3=====================================================================3=========================================================================================
44
5:Author: Sumit Naiksatam, Ram Durairaj, Mark Voelker, Edgar Magana, Shweta Padubidri, Rohit Agarwalla, Ying Liu5:Author: Sumit Naiksatam, Ram Durairaj, Mark Voelker, Edgar Magana, Shweta Padubidri, Rohit Agarwalla, Ying Liu, Debo Dutta
6:Contact: netstack@lists.launchpad.net6:Contact: netstack@lists.launchpad.net
7:Web site: https://launchpad.net/~cisco-openstack7:Web site: https://launchpad.net/~cisco-openstack
8:Copyright: 2011 Cisco Systems, Inc.8:Copyright: 2011 Cisco Systems, Inc.
@@ -15,9 +15,11 @@
15This plugin implementation provides the following capabilities15This plugin implementation provides the following capabilities
16to help you take your Layer 2 network for a Quantum leap:16to help you take your Layer 2 network for a Quantum leap:
1717
18* A reference implementation a framework for a Quantum Plugin 18* A reference implementation for a Quantum Plugin Framework
19to use multiple devices/switches in a L2 network19(For details see: http://wiki.openstack.org/quantum-multi-switch-plugin)
20* Supports multiple switches in the network
20* Supports multiple models of switches concurrently21* Supports multiple models of switches concurrently
22* Supports use of multiple L2 technologies
21* Supports Cisco UCS blade servers with M81KR Virtual Interface Cards 23* Supports Cisco UCS blade servers with M81KR Virtual Interface Cards
22 (aka "Palo adapters") via 802.1Qbh.24 (aka "Palo adapters") via 802.1Qbh.
23* Supports the Cisco Nexus family of switches.25* Supports the Cisco Nexus family of switches.
@@ -119,6 +121,8 @@
119# Port number on the Nexus switch to which the UCSM 6120 is connected121# Port number on the Nexus switch to which the UCSM 6120 is connected
120# Use shortened interface syntax, e.g. "3/23" not "Ethernet3/23".122# Use shortened interface syntax, e.g. "3/23" not "Ethernet3/23".
121nexus_port=3/23123nexus_port=3/23
124#Port number where the SSH will be running at Nexus Switch, e.g.: 22 (Default)
125nexus_ssh_port=22
122126
123[DRIVER]127[DRIVER]
124name=quantum.plugins.cisco.nexus.cisco_nexus_network_driver.CiscoNEXUSDriver128name=quantum.plugins.cisco.nexus.cisco_nexus_network_driver.CiscoNEXUSDriver
@@ -130,8 +134,23 @@
130 host key changes (e.g. due to replacement of the supervisor or134 host key changes (e.g. due to replacement of the supervisor or
131 clearing of the SSH config on the switch), you may need to repeat135 clearing of the SSH config on the switch), you may need to repeat
132 this step and remove the old hostkey from ~/.ssh/known_hosts.136 this step and remove the old hostkey from ~/.ssh/known_hosts.
133137
1345. Verify that you have the correct credentials for each IP address listed1385. Plugin Persistence framework setup:
139 5a. Create quantum_l2network database in mysql with the following command -
140
141mysql -u<mysqlusername> -p<mysqlpassword> -e "create database quantum_l2network"
142
143 5b. Enter the quantum_l2network database configuration info in the
144 quantum/plugins/cisco/conf/db_conn.ini file.
145
146 5c. If there is a change in the plugin configuration, service would need
147 to be restarted after dropping and re-creating the database using
148 the following commands -
149
150mysql -u<mysqlusername> -p<mysqlpassword> -e "drop database quantum_l2network"
151mysql -u<mysqlusername> -p<mysqlpassword> -e "create database quantum_l2network"
152
1536. Verify that you have the correct credentials for each IP address listed
135 in quantum/plugins/cisco/conf/credentials.ini. Example:154 in quantum/plugins/cisco/conf/credentials.ini. Example:
136155
137# Provide the UCSM credentials156# Provide the UCSM credentials
@@ -152,7 +171,7 @@
152username=admin171username=admin
153password=mySecretPasswordForNexus172password=mySecretPasswordForNexus
154173
1556. Start the Quantum service. If something doesn't work, verify that1747. Start the Quantum service. If something doesn't work, verify that
156 your configuration of each of the above files hasn't gone a little kaka.175 your configuration of each of the above files hasn't gone a little kaka.
157 Once you've put right what once went wrong, leap on.176 Once you've put right what once went wrong, leap on.
158177
@@ -160,7 +179,8 @@
160How to test the installation179How to test the installation
161----------------------------180----------------------------
162The unit tests are located at quantum/plugins/cisco/tests/unit. They can be181The unit tests are located at quantum/plugins/cisco/tests/unit. They can be
163executed from quantum/plugins/cisco/ using the run_tests.py script.182executed from the main folder using the run_tests.sh or to get a more detailed
183result the quantum/plugins/cisco/run_tests.py script.
164184
1651. Testing the core API (without UCS/Nexus/RHEL hardware, and can be run on1851. Testing the core API (without UCS/Nexus/RHEL hardware, and can be run on
166 Ubuntu):186 Ubuntu):
@@ -168,18 +188,41 @@
168 quantum/plugins/cisco/conf/plugins.ini188 quantum/plugins/cisco/conf/plugins.ini
169 Then run the test script:189 Then run the test script:
170190
171python run_tests.py unit.test_l2networkApi191 Set the environment variable PLUGIN_DIR to the location of the plugin
192 directory. This is manadatory if the run_tests.sh script is used.
193
194 export PLUGIN_DIR=quantum/plugins/cisco
195 ./run_tests.sh quantum.plugins.cisco.tests.unit.test_l2networkApi
196
197 or
198
199 python quantum/plugins/cisco/run_tests.py
200 quantum.plugins.cisco.tests.unit.test_l2networkApi
172201
1732. Specific Plugin unit test (needs environment setup as indicated in the 2022. Specific Plugin unit test (needs environment setup as indicated in the
174 pre-requisites):203 pre-requisites):
175 python run_tests.py unit.<name_of_the file>204
205 export PLUGIN_DIR=quantum/plugins/cisco
206 ./run_tests.sh quantum.plugins.cisco.tests.unit.<name_of_the file>
207
208 or
209
210 python <path to the plugin directory>/run_tests.py
211 quantum.plugins.cisco.tests.unit.<name_of_the file>
176 E.g.:212 E.g.:
177213
178python run_tests.py unit.test_ucs_plugin.py214 python quantum/plugins/cisco/run_tests.py
215 quantum.plugins.cisco.tests.unit.test_ucs_plugin.py
179216
1803. All unit tests (needs environment setup as indicated in the pre-requisites):2173. All unit tests (needs environment setup as indicated in the pre-requisites):
181 218
182python run_tests.py unit219 export PLUGIN_DIR=quantum/plugins/cisco
220 ./run_tests.sh quantum.plugins.cisco.tests.unit
221
222 or
223
224 python quantum/plugins/cisco/run_tests.py quantum.plugins.cisco.tests.unit
225
183226
184227
185Additional installation required on Nova Compute228Additional installation required on Nova Compute
186229
=== modified file 'quantum/plugins/cisco/__init__.py'
--- quantum/plugins/cisco/__init__.py 2011-07-31 19:04:01 +0000
+++ quantum/plugins/cisco/__init__.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -16,3 +17,4 @@
16#17#
17# @author: Sumit Naiksatam, Cisco Systems, Inc.18# @author: Sumit Naiksatam, Cisco Systems, Inc.
18#19#
20"""
1921
=== modified file 'quantum/plugins/cisco/common/__init__.py'
--- quantum/plugins/cisco/common/__init__.py 2011-07-31 19:04:01 +0000
+++ quantum/plugins/cisco/common/__init__.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -16,3 +17,4 @@
16#17#
17# @author: Sumit Naiksatam, Cisco Systems, Inc.18# @author: Sumit Naiksatam, Cisco Systems, Inc.
18#19#
20"""
1921
=== modified file 'quantum/plugins/cisco/common/cisco_configparser.py'
--- quantum/plugins/cisco/common/cisco_configparser.py 2011-08-14 01:28:02 +0000
+++ quantum/plugins/cisco/common/cisco_configparser.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -16,25 +17,23 @@
16#17#
17# @author: Sumit Naiksatam, Cisco Systems, Inc.18# @author: Sumit Naiksatam, Cisco Systems, Inc.
18#19#
20"""
1921
20import logging as LOG22import logging as LOG
21import os
22
23from configobj import ConfigObj23from configobj import ConfigObj
24from validate import Validator
25
26from quantum.plugins.cisco.common import cisco_constants as const24from quantum.plugins.cisco.common import cisco_constants as const
27from quantum.plugins.cisco.common import cisco_exceptions as cexc
2825
29LOG.basicConfig(level=LOG.WARN)26LOG.basicConfig(level=LOG.WARN)
30LOG.getLogger(const.LOGGER_COMPONENT_NAME)27LOG.getLogger(const.LOGGER_COMPONENT_NAME)
3128
3229
33class CiscoConfigParser(ConfigObj):30class CiscoConfigParser(ConfigObj):
31 """Config Parser based on the ConfigObj module"""
3432
35 def __init__(self, filename):33 def __init__(self, filename):
36 super(CiscoConfigParser, self).__init__(filename, raise_errors=True,34 super(CiscoConfigParser, self).__init__(filename, raise_errors=True,
37 file_error=True)35 file_error=True)
3836
39 def dummy(self, section, key):37 def dummy(self, section, key):
38 """Dummy function to return the same key, used in walk"""
40 return section[key]39 return section[key]
4140
=== modified file 'quantum/plugins/cisco/common/cisco_constants.py'
--- quantum/plugins/cisco/common/cisco_constants.py 2011-08-07 11:58:50 +0000
+++ quantum/plugins/cisco/common/cisco_constants.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -16,13 +17,29 @@
16#17#
17# @author: Sumit Naiksatam, Cisco Systems, Inc.18# @author: Sumit Naiksatam, Cisco Systems, Inc.
18#19#
20"""
1921
20PLUGINS = 'PLUGINS'22PLUGINS = 'PLUGINS'
2123
22PORT_STATE = 'port-state'24PORT_STATE = 'port-state'
23PORT_UP = "UP"25PORT_UP = "ACTIVE"
24PORT_DOWN = "DOWN"26PORT_DOWN = "DOWN"
2527
28UUID = 'uuid'
29TENANTID = 'tenant_id'
30NETWORKID = 'network_id'
31NETWORKNAME = 'name'
32NETWORKPORTS = 'ports'
33INTERFACEID = 'interface_id'
34PORTSTATE = 'state'
35PORTID = 'port_id'
36PPNAME = 'name'
37PPVLANID = 'vlan_id'
38PPQOS = 'qos'
39PPID = 'portprofile_id'
40PPDEFAULT = 'default'
41VLANID = 'vlan_id'
42
26ATTACHMENT = 'attachment'43ATTACHMENT = 'attachment'
27PORT_ID = 'port-id'44PORT_ID = 'port-id'
2845
@@ -101,3 +118,5 @@
101PARAM_LIST = 'param-list'118PARAM_LIST = 'param-list'
102119
103DEVICE_IP = 'device-ip'120DEVICE_IP = 'device-ip'
121
122NO_VLAN_ID = 0
104123
=== modified file 'quantum/plugins/cisco/common/cisco_credentials.py'
--- quantum/plugins/cisco/common/cisco_credentials.py 2011-08-14 01:28:02 +0000
+++ quantum/plugins/cisco/common/cisco_credentials.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -16,6 +17,7 @@
16#17#
17# @author: Sumit Naiksatam, Cisco Systems, Inc.18# @author: Sumit Naiksatam, Cisco Systems, Inc.
18#19#
20"""
1921
20import logging as LOG22import logging as LOG
21import os23import os
@@ -34,27 +36,35 @@
3436
3537
36class Store(object):38class Store(object):
39 """Credential Store"""
40
37 @staticmethod41 @staticmethod
38 def putCredential(id, username, password):42 def putCredential(id, username, password):
43 """Set the username and password"""
39 _creds_dictionary[id] = {const.USERNAME: username,44 _creds_dictionary[id] = {const.USERNAME: username,
40 const.PASSWORD: password}45 const.PASSWORD: password}
4146
42 @staticmethod47 @staticmethod
43 def getUsername(id):48 def getUsername(id):
49 """Get the username"""
44 return _creds_dictionary[id][const.USERNAME]50 return _creds_dictionary[id][const.USERNAME]
4551
46 @staticmethod52 @staticmethod
47 def getPassword(id):53 def getPassword(id):
54 """Get the password"""
48 return _creds_dictionary[id][const.PASSWORD]55 return _creds_dictionary[id][const.PASSWORD]
4956
50 @staticmethod57 @staticmethod
51 def getCredential(id):58 def getCredential(id):
59 """Get the username and password"""
52 return _creds_dictionary[id]60 return _creds_dictionary[id]
5361
54 @staticmethod62 @staticmethod
55 def getCredentials():63 def getCredentials():
64 """Get all usernames and passwords"""
56 return _creds_dictionary65 return _creds_dictionary
5766
58 @staticmethod67 @staticmethod
59 def deleteCredential(id):68 def deleteCredential(id):
69 """Delete a credential"""
60 return _creds_dictionary.pop(id)70 return _creds_dictionary.pop(id)
6171
=== modified file 'quantum/plugins/cisco/common/cisco_exceptions.py'
--- quantum/plugins/cisco/common/cisco_exceptions.py 2011-07-31 18:38:26 +0000
+++ quantum/plugins/cisco/common/cisco_exceptions.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -15,43 +16,89 @@
15# under the License.16# under the License.
16#17#
17# @author: Sumit Naiksatam, Cisco Systems, Inc.18# @author: Sumit Naiksatam, Cisco Systems, Inc.
18#19# @author: Rohit Agarwalla, Cisco Systems, Inc.
1920"""
20"""21"""
21Exceptions used by the Cisco plugin22Exceptions used by the Cisco plugin
22"""23"""
23
24from quantum.common import exceptions24from quantum.common import exceptions
2525
2626
27class NoMoreNics(exceptions.QuantumException):27class NoMoreNics(exceptions.QuantumException):
28 message = _("Unable to complete operation on port %(port_id)s " \28 """No more dynamic nics are available in the system"""
29 "for network %(net_id)s. No more dynamic nics are available" \29 message = _("Unable to complete operation. No more dynamic nics are " \
30 "in the system.")30 "available in the system.")
3131
3232
33class PortProfileLimit(exceptions.QuantumException):33class PortProfileLimit(exceptions.QuantumException):
34 """Port profile limit has been hit"""
34 message = _("Unable to complete operation on port %(port_id)s " \35 message = _("Unable to complete operation on port %(port_id)s " \
35 "for network %(net_id)s. The system has reached the maximum" \36 "for network %(net_id)s. The system has reached the maximum" \
36 "limit of allowed port profiles.")37 "limit of allowed port profiles.")
3738
3839
39class UCSMPortProfileLimit(exceptions.QuantumException):40class UCSMPortProfileLimit(exceptions.QuantumException):
41 """UCSM Port profile limit has been hit"""
40 message = _("Unable to complete operation on port %(port_id)s " \42 message = _("Unable to complete operation on port %(port_id)s " \
41 "for network %(net_id)s. The system has reached the maximum" \43 "for network %(net_id)s. The system has reached the maximum" \
42 "limit of allowed UCSM port profiles.")44 "limit of allowed UCSM port profiles.")
4345
4446
45class NetworksLimit(exceptions.QuantumException):47class NetworksLimit(exceptions.QuantumException):
48 """Total number of network objects limit has been hit"""
46 message = _("Unable to create new network. Number of networks" \49 message = _("Unable to create new network. Number of networks" \
47 "for the system has exceeded the limit")50 "for the system has exceeded the limit")
4851
4952
50class PortProfileNotFound(exceptions.QuantumException):53class PortProfileNotFound(exceptions.QuantumException):
54 """Port profile cannot be found"""
51 message = _("Port profile %(portprofile_id)s could not be found " \55 message = _("Port profile %(portprofile_id)s could not be found " \
52 "for tenant %(tenant_id)s")56 "for tenant %(tenant_id)s")
5357
5458
55class PortProfileInvalidDelete(exceptions.QuantumException):59class PortProfileInvalidDelete(exceptions.QuantumException):
60 """Port profile cannot be deleted since its being used"""
56 message = _("Port profile %(profile_id)s could not be deleted " \61 message = _("Port profile %(profile_id)s could not be deleted " \
57 "for tenant %(tenant_id)s since port associations exist")62 "for tenant %(tenant_id)s since port associations exist")
63
64
65class NetworkVlanBindingAlreadyExists(exceptions.QuantumException):
66 """Binding cannot be created, since it already exists"""
67 message = _("NetworkVlanBinding for %(vlan_id)s and network " \
68 "%(network_id)s already exists")
69
70
71class PortProfileAlreadyExists(exceptions.QuantumException):
72 """Port profile cannot be created since it already exisits"""
73 message = _("PortProfile %(pp_name) for %(tenant_id)s " \
74 "already exists")
75
76
77class PortProfileBindingAlreadyExists(exceptions.QuantumException):
78 """Binding cannot be created, since it already exists"""
79 message = _("PortProfileBinding for port profile %(pp_id)s to " \
80 "port %(port_id) already exists")
81
82
83class VlanIDNotFound(exceptions.QuantumException):
84 """VLAN ID cannot be found"""
85 message = _("Vlan ID %(vlan_id)s not found")
86
87
88class VlanIDNotAvailable(exceptions.QuantumException):
89 """VLAN ID is reserved"""
90 message = _("No available Vlan ID found")
91
92try:
93 _("test")
94except NameError:
95
96 def _(a_string):
97 """
98 Default implementation of the gettext string
99 translation function: no translation
100 """
101 return a_string
102except TypeError:
103 # during doctesting, _ might mean something else
104 pass
58105
=== modified file 'quantum/plugins/cisco/common/cisco_nova_configuration.py'
--- quantum/plugins/cisco/common/cisco_nova_configuration.py 2011-08-14 01:28:02 +0000
+++ quantum/plugins/cisco/common/cisco_nova_configuration.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -16,6 +17,7 @@
16#17#
17# @author: Sumit Naiksatam, Cisco Systems, Inc.18# @author: Sumit Naiksatam, Cisco Systems, Inc.
18#19#
20"""
1921
20import os22import os
2123
@@ -23,13 +25,13 @@
2325
24CONF_FILE = "../conf/nova.ini"26CONF_FILE = "../conf/nova.ini"
2527
26cp = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \28CP = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \
27 + "/" + CONF_FILE)29 + "/" + CONF_FILE)
2830
29section = cp['NOVA']31SECTION = CP['NOVA']
30DB_SERVER_IP = section['db_server_ip']32DB_SERVER_IP = SECTION['db_server_ip']
31DB_NAME = section['db_name']33DB_NAME = SECTION['db_name']
32DB_USERNAME = section['db_username']34DB_USERNAME = SECTION['db_username']
33DB_PASSWORD = section['db_password']35DB_PASSWORD = SECTION['db_password']
34NOVA_HOST_NAME = section['nova_host_name']36NOVA_HOST_NAME = SECTION['nova_host_name']
35NOVA_PROJ_NAME = section['nova_proj_name']37NOVA_PROJ_NAME = SECTION['nova_proj_name']
3638
=== modified file 'quantum/plugins/cisco/common/cisco_utils.py'
--- quantum/plugins/cisco/common/cisco_utils.py 2011-08-05 09:59:54 +0000
+++ quantum/plugins/cisco/common/cisco_utils.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -16,27 +17,36 @@
16#17#
17# @author: Sumit Naiksatam, Cisco Systems, Inc.18# @author: Sumit Naiksatam, Cisco Systems, Inc.
18#19#
20"""
1921
22import hashlib
23import logging as LOG
20import MySQLdb24import MySQLdb
21import logging as LOG
22import sys
23import traceback25import traceback
2426
25from quantum.common import exceptions as exc
26from quantum.plugins.cisco.common import cisco_constants as const27from quantum.plugins.cisco.common import cisco_constants as const
27from quantum.plugins.cisco.common import cisco_credentials as cred
28from quantum.plugins.cisco.common import cisco_nova_configuration as conf28from quantum.plugins.cisco.common import cisco_nova_configuration as conf
2929
30LOG.basicConfig(level=LOG.WARN)30LOG.basicConfig(level=LOG.WARN)
31LOG.getLogger(const.LOGGER_COMPONENT_NAME)31LOG.getLogger(const.LOGGER_COMPONENT_NAME)
3232
3333
34def get16ByteUUID(uuid):
35 """
36 Return a 16 byte has of the UUID, used when smaller unique
37 ID is required.
38 """
39 return hashlib.md5(uuid).hexdigest()[:16]
40
41
34class DBUtils(object):42class DBUtils(object):
43 """Utilities to use connect to MySQL DB and execute queries"""
3544
36 def __init__(self):45 def __init__(self):
37 pass46 pass
3847
39 def _get_db_connection(self):48 def _get_db_connection(self):
49 """Get a connection to the DB"""
40 db_ip = conf.DB_SERVER_IP50 db_ip = conf.DB_SERVER_IP
41 db_username = conf.DB_USERNAME51 db_username = conf.DB_USERNAME
42 db_password = conf.DB_PASSWORD52 db_password = conf.DB_PASSWORD
@@ -45,6 +55,7 @@
45 return self.db55 return self.db
4656
47 def execute_db_query(self, sql_query):57 def execute_db_query(self, sql_query):
58 """Execute a DB query"""
48 db = self._get_db_connection()59 db = self._get_db_connection()
49 cursor = db.cursor()60 cursor = db.cursor()
50 try:61 try:
@@ -52,6 +63,7 @@
52 results = cursor.fetchall()63 results = cursor.fetchall()
53 db.commit()64 db.commit()
54 LOG.debug("DB query execution succeeded: %s" % sql_query)65 LOG.debug("DB query execution succeeded: %s" % sql_query)
66 db.close()
55 except:67 except:
56 db.rollback()68 db.rollback()
57 LOG.debug("DB query execution failed: %s" % sql_query)69 LOG.debug("DB query execution failed: %s" % sql_query)
5870
=== added file 'quantum/plugins/cisco/conf/db_conn.ini'
--- quantum/plugins/cisco/conf/db_conn.ini 1970-01-01 00:00:00 +0000
+++ quantum/plugins/cisco/conf/db_conn.ini 2011-08-23 20:09:26 +0000
@@ -0,0 +1,5 @@
1[DATABASE]
2name = quantum_l2network
3user = <put_db_user_name_here>
4pass = <put_db_password_here>
5host = <put_quantum_mysql_host_here>
06
=== modified file 'quantum/plugins/cisco/conf/nexus.ini'
--- quantum/plugins/cisco/conf/nexus.ini 2011-08-05 09:59:54 +0000
+++ quantum/plugins/cisco/conf/nexus.ini 2011-08-23 20:09:26 +0000
@@ -3,6 +3,8 @@
3nexus_ip_address=<put_nexus_switch_ip_address_here>3nexus_ip_address=<put_nexus_switch_ip_address_here>
4#Port number of the Interface connected from the Nexus 7K Switch to UCSM 6120, e.g.: 3/234#Port number of the Interface connected from the Nexus 7K Switch to UCSM 6120, e.g.: 3/23
5nexus_port=<put_interface_name_here>5nexus_port=<put_interface_name_here>
6#Port number where the SSH will be running at the Nexus Switch, e.g.: 22 (Default)
7nexus_ssh_port=22
68
7[DRIVER]9[DRIVER]
8name=quantum.plugins.cisco.nexus.cisco_nexus_network_driver.CiscoNEXUSDriver10name=quantum.plugins.cisco.nexus.cisco_nexus_network_driver.CiscoNEXUSDriver
911
=== added file 'quantum/plugins/cisco/db/api.py'
--- quantum/plugins/cisco/db/api.py 1970-01-01 00:00:00 +0000
+++ quantum/plugins/cisco/db/api.py 2011-08-23 20:09:26 +0000
@@ -0,0 +1,254 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2# Copyright 2011 Nicira Networks, Inc.
3# All Rights Reserved.
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
16# @author: Somik Behera, Nicira Networks, Inc.
17# @author: Brad Hall, Nicira Networks, Inc.
18# @author: Dan Wendlandt, Nicira Networks, Inc.
19
20from sqlalchemy import create_engine
21from sqlalchemy.orm import sessionmaker, exc, joinedload
22
23from quantum.common import exceptions as q_exc
24from quantum.plugins.cisco.db import models
25
26_ENGINE = None
27_MAKER = None
28BASE = models.BASE
29
30
31def configure_db(options):
32 """
33 Establish the database, create an engine if needed, and
34 register the models.
35
36 :param options: Mapping of configuration options
37 """
38 global _ENGINE
39 if not _ENGINE:
40 _ENGINE = create_engine(options['sql_connection'],
41 echo=False,
42 echo_pool=True,
43 pool_recycle=3600)
44 register_models()
45
46
47def clear_db():
48 global _ENGINE
49 assert _ENGINE
50 for table in reversed(BASE.metadata.sorted_tables):
51 _ENGINE.execute(table.delete())
52
53
54def get_session(autocommit=True, expire_on_commit=False):
55 """Helper method to grab session"""
56 global _MAKER, _ENGINE
57 if not _MAKER:
58 assert _ENGINE
59 _MAKER = sessionmaker(bind=_ENGINE,
60 autocommit=autocommit,
61 expire_on_commit=expire_on_commit)
62 return _MAKER()
63
64
65def register_models():
66 """Register Models and create properties"""
67 global _ENGINE
68 assert _ENGINE
69 BASE.metadata.create_all(_ENGINE)
70
71
72def unregister_models():
73 """Unregister Models, useful clearing out data before testing"""
74 global _ENGINE
75 assert _ENGINE
76 BASE.metadata.drop_all(_ENGINE)
77
78
79def _check_duplicate_net_name(tenant_id, net_name):
80 session = get_session()
81 try:
82 net = session.query(models.Network).\
83 filter_by(tenant_id=tenant_id, name=net_name).\
84 one()
85 raise q_exc.NetworkNameExists(tenant_id=tenant_id,
86 net_name=net_name, net_id=net.uuid)
87 except exc.NoResultFound:
88 # this is the "normal" path, as API spec specifies
89 # that net-names are unique within a tenant
90 pass
91
92
93def network_create(tenant_id, name):
94 session = get_session()
95
96 _check_duplicate_net_name(tenant_id, name)
97 with session.begin():
98 net = models.Network(tenant_id, name)
99 session.add(net)
100 session.flush()
101 return net
102
103
104def network_list(tenant_id):
105 session = get_session()
106 return session.query(models.Network).\
107 options(joinedload(models.Network.ports)). \
108 filter_by(tenant_id=tenant_id).\
109 all()
110
111
112def network_get(net_id):
113 session = get_session()
114 try:
115 return session.query(models.Network).\
116 options(joinedload(models.Network.ports)). \
117 filter_by(uuid=net_id).\
118 one()
119 except exc.NoResultFound, e:
120 raise q_exc.NetworkNotFound(net_id=net_id)
121
122
123def network_rename(tenant_id, net_id, new_name):
124 session = get_session()
125 net = network_get(net_id)
126 _check_duplicate_net_name(tenant_id, new_name)
127 net.name = new_name
128 session.merge(net)
129 session.flush()
130 return net
131
132
133def network_destroy(net_id):
134 session = get_session()
135 try:
136 net = session.query(models.Network).\
137 filter_by(uuid=net_id).\
138 one()
139 session.delete(net)
140 session.flush()
141 return net
142 except exc.NoResultFound:
143 raise q_exc.NetworkNotFound(net_id=net_id)
144
145
146def port_create(net_id, state=None):
147 # confirm network exists
148 network_get(net_id)
149
150 session = get_session()
151 with session.begin():
152 port = models.Port(net_id)
153 port['state'] = state or 'DOWN'
154 session.add(port)
155 session.flush()
156 return port
157
158
159def port_list(net_id):
160 session = get_session()
161 return session.query(models.Port).\
162 options(joinedload(models.Port.network)). \
163 filter_by(network_id=net_id).\
164 all()
165
166
167def port_get(net_id, port_id):
168 # confirm network exists
169 network_get(net_id)
170 session = get_session()
171 try:
172 return session.query(models.Port).\
173 filter_by(uuid=port_id).\
174 filter_by(network_id=net_id).\
175 one()
176 except exc.NoResultFound:
177 raise q_exc.PortNotFound(net_id=net_id, port_id=port_id)
178
179
180def port_set_state(net_id, port_id, new_state):
181 if new_state not in ('ACTIVE', 'DOWN'):
182 raise q_exc.StateInvalid(port_state=new_state)
183
184 # confirm network exists
185 network_get(net_id)
186
187 port = port_get(net_id, port_id)
188 session = get_session()
189 port.state = new_state
190 session.merge(port)
191 session.flush()
192 return port
193
194
195def port_set_attachment(net_id, port_id, new_interface_id):
196 # confirm network exists
197 network_get(net_id)
198
199 session = get_session()
200 port = port_get(net_id, port_id)
201
202 if new_interface_id != "":
203 # We are setting, not clearing, the attachment-id
204 if port['interface_id']:
205 raise q_exc.PortInUse(net_id=net_id, port_id=port_id,
206 att_id=port['interface_id'])
207
208 try:
209 port = session.query(models.Port).\
210 filter_by(interface_id=new_interface_id).\
211 one()
212 raise q_exc.AlreadyAttached(net_id=net_id,
213 port_id=port_id,
214 att_id=new_interface_id,
215 att_port_id=port['uuid'])
216 except exc.NoResultFound:
217 # this is what should happen
218 pass
219 port.interface_id = new_interface_id
220 session.merge(port)
221 session.flush()
222 return port
223
224
225def port_unset_attachment(net_id, port_id):
226 # confirm network exists
227 network_get(net_id)
228
229 session = get_session()
230 port = port_get(net_id, port_id)
231 port.interface_id = None
232 session.merge(port)
233 session.flush()
234 return port
235
236
237def port_destroy(net_id, port_id):
238 # confirm network exists
239 network_get(net_id)
240
241 session = get_session()
242 try:
243 port = session.query(models.Port).\
244 filter_by(uuid=port_id).\
245 filter_by(network_id=net_id).\
246 one()
247 if port['interface_id']:
248 raise q_exc.PortInUse(net_id=net_id, port_id=port_id,
249 att_id=port['interface_id'])
250 session.delete(port)
251 session.flush()
252 return port
253 except exc.NoResultFound:
254 raise q_exc.PortNotFound(port_id=port_id)
0255
=== added file 'quantum/plugins/cisco/db/l2network_db.py'
--- quantum/plugins/cisco/db/l2network_db.py 1970-01-01 00:00:00 +0000
+++ quantum/plugins/cisco/db/l2network_db.py 2011-08-23 20:09:26 +0000
@@ -0,0 +1,346 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2011, Cisco Systems, Inc.
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
16# @author: Rohit Agarwalla, Cisco Systems, Inc.
17
18from sqlalchemy.orm import exc
19
20from quantum.common import exceptions as q_exc
21from quantum.plugins.cisco import l2network_plugin_configuration as conf
22from quantum.plugins.cisco.common import cisco_exceptions as c_exc
23from quantum.plugins.cisco.db import l2network_models
24
25import quantum.plugins.cisco.db.api as db
26
27
28def initialize():
29 'Establish database connection and load models'
30 options = {"sql_connection": "mysql://%s:%s@%s/%s" % (conf.DB_USER,
31 conf.DB_PASS, conf.DB_HOST, conf.DB_NAME)}
32 db.configure_db(options)
33
34
35def create_vlanids():
36 """Prepopulates the vlan_bindings table"""
37 session = db.get_session()
38 try:
39 vlanid = session.query(l2network_models.VlanID).\
40 one()
41 except exc.MultipleResultsFound:
42 pass
43 except exc.NoResultFound:
44 start = int(conf.VLAN_START)
45 end = int(conf.VLAN_END)
46 while start <= end:
47 vlanid = l2network_models.VlanID(start)
48 session.add(vlanid)
49 start += 1
50 session.flush()
51 return
52
53
54def get_all_vlanids():
55 """Gets all the vlanids"""
56 session = db.get_session()
57 try:
58 vlanids = session.query(l2network_models.VlanID).\
59 all()
60 return vlanids
61 except exc.NoResultFound:
62 return []
63
64
65def is_vlanid_used(vlan_id):
66 """Checks if a vlanid is in use"""
67 session = db.get_session()
68 try:
69 vlanid = session.query(l2network_models.VlanID).\
70 filter_by(vlan_id=vlan_id).\
71 one()
72 return vlanid["vlan_used"]
73 except exc.NoResultFound:
74 raise c_exc.VlanIDNotFound(vlan_id=vlan_id)
75
76
77def release_vlanid(vlan_id):
78 """Sets the vlanid state to be unused"""
79 session = db.get_session()
80 try:
81 vlanid = session.query(l2network_models.VlanID).\
82 filter_by(vlan_id=vlan_id).\
83 one()
84 vlanid["vlan_used"] = False
85 session.merge(vlanid)
86 session.flush()
87 return vlanid["vlan_used"]
88 except exc.NoResultFound:
89 raise c_exc.VlanIDNotFound(vlan_id=vlan_id)
90 return
91
92
93def delete_vlanid(vlan_id):
94 """Deletes a vlanid entry from db"""
95 session = db.get_session()
96 try:
97 vlanid = session.query(l2network_models.VlanID).\
98 filter_by(vlan_id=vlan_id).\
99 one()
100 session.delete(vlanid)
101 session.flush()
102 return vlanid
103 except exc.NoResultFound:
104 pass
105
106
107def reserve_vlanid():
108 """Reserves the first unused vlanid"""
109 session = db.get_session()
110 try:
111 rvlan = session.query(l2network_models.VlanID).\
112 filter_by(vlan_used=False).\
113 first()
114 rvlanid = session.query(l2network_models.VlanID).\
115 filter_by(vlan_id=rvlan["vlan_id"]).\
116 one()
117 rvlanid["vlan_used"] = True
118 session.merge(rvlanid)
119 session.flush()
120 return rvlan["vlan_id"]
121 except exc.NoResultFound:
122 raise c_exc.VlanIDNotAvailable()
123
124
125def get_all_vlan_bindings():
126 """Lists all the vlan to network associations"""
127 session = db.get_session()
128 try:
129 bindings = session.query(l2network_models.VlanBinding).\
130 all()
131 return bindings
132 except exc.NoResultFound:
133 return []
134
135
136def get_vlan_binding(netid):
137 """Lists the vlan given a network_id"""
138 session = db.get_session()
139 try:
140 binding = session.query(l2network_models.VlanBinding).\
141 filter_by(network_id=netid).\
142 one()
143 return binding
144 except exc.NoResultFound:
145 raise q_exc.NetworkNotFound(net_id=netid)
146
147
148def add_vlan_binding(vlanid, vlanname, netid):
149 """Adds a vlan to network association"""
150 session = db.get_session()
151 try:
152 binding = session.query(l2network_models.VlanBinding).\
153 filter_by(vlan_id=vlanid).\
154 one()
155 raise c_exc.NetworkVlanBindingAlreadyExists(vlan_id=vlanid,
156 network_id=netid)
157 except exc.NoResultFound:
158 binding = l2network_models.VlanBinding(vlanid, vlanname, netid)
159 session.add(binding)
160 session.flush()
161 return binding
162
163
164def remove_vlan_binding(netid):
165 """Removes a vlan to network association"""
166 session = db.get_session()
167 try:
168 binding = session.query(l2network_models.VlanBinding).\
169 filter_by(network_id=netid).\
170 one()
171 session.delete(binding)
172 session.flush()
173 return binding
174 except exc.NoResultFound:
175 pass
176
177
178def update_vlan_binding(netid, newvlanid=None, newvlanname=None):
179 """Updates a vlan to network association"""
180 session = db.get_session()
181 try:
182 binding = session.query(l2network_models.VlanBinding).\
183 filter_by(network_id=netid).\
184 one()
185 if newvlanid:
186 binding["vlan_id"] = newvlanid
187 if newvlanname:
188 binding["vlan_name"] = newvlanname
189 session.merge(binding)
190 session.flush()
191 return binding
192 except exc.NoResultFound:
193 raise q_exc.NetworkNotFound(net_id=netid)
194
195
196def get_all_portprofiles():
197 """Lists all the port profiles"""
198 session = db.get_session()
199 try:
200 pps = session.query(l2network_models.PortProfile).\
201 all()
202 return pps
203 except exc.NoResultFound:
204 return []
205
206
207def get_portprofile(tenantid, ppid):
208 """Lists a port profile"""
209 session = db.get_session()
210 try:
211 pp = session.query(l2network_models.PortProfile).\
212 filter_by(uuid=ppid).\
213 one()
214 return pp
215 except exc.NoResultFound:
216 raise c_exc.PortProfileNotFound(tenant_id=tenantid,
217 portprofile_id=ppid)
218
219
220def add_portprofile(tenantid, ppname, vlanid, qos):
221 """Adds a port profile"""
222 session = db.get_session()
223 try:
224 pp = session.query(l2network_models.PortProfile).\
225 filter_by(name=ppname).\
226 one()
227 raise c_exc.PortProfileAlreadyExists(tenant_id=tenantid,
228 pp_name=ppname)
229 except exc.NoResultFound:
230 pp = l2network_models.PortProfile(ppname, vlanid, qos)
231 session.add(pp)
232 session.flush()
233 return pp
234
235
236def remove_portprofile(tenantid, ppid):
237 """Removes a port profile"""
238 session = db.get_session()
239 try:
240 pp = session.query(l2network_models.PortProfile).\
241 filter_by(uuid=ppid).\
242 one()
243 session.delete(pp)
244 session.flush()
245 return pp
246 except exc.NoResultFound:
247 pass
248
249
250def update_portprofile(tenantid, ppid, newppname=None, newvlanid=None,
251 newqos=None):
252 """Updates port profile"""
253 session = db.get_session()
254 try:
255 pp = session.query(l2network_models.PortProfile).\
256 filter_by(uuid=ppid).\
257 one()
258 if newppname:
259 pp["name"] = newppname
260 if newvlanid:
261 pp["vlan_id"] = newvlanid
262 if newqos:
263 pp["qos"] = newqos
264 session.merge(pp)
265 session.flush()
266 return pp
267 except exc.NoResultFound:
268 raise c_exc.PortProfileNotFound(tenant_id=tenantid,
269 portprofile_id=ppid)
270
271
272def get_all_pp_bindings():
273 """Lists all the port profiles"""
274 session = db.get_session()
275 try:
276 bindings = session.query(l2network_models.PortProfileBinding).\
277 all()
278 return bindings
279 except exc.NoResultFound:
280 return []
281
282
283def get_pp_binding(tenantid, ppid):
284 """Lists a port profile binding"""
285 session = db.get_session()
286 try:
287 binding = session.query(l2network_models.PortProfileBinding).\
288 filter_by(portprofile_id=ppid).\
289 one()
290 return binding
291 except exc.NoResultFound:
292 return []
293
294
295def add_pp_binding(tenantid, portid, ppid, default):
296 """Adds a port profile binding"""
297 session = db.get_session()
298 try:
299 binding = session.query(l2network_models.PortProfileBinding).\
300 filter_by(portprofile_id=ppid).\
301 one()
302 raise c_exc.PortProfileBindingAlreadyExists(pp_id=ppid,
303 port_id=portid)
304 except exc.NoResultFound:
305 binding = l2network_models.PortProfileBinding(tenantid, portid, \
306 ppid, default)
307 session.add(binding)
308 session.flush()
309 return binding
310
311
312def remove_pp_binding(tenantid, portid, ppid):
313 """Removes a port profile binding"""
314 session = db.get_session()
315 try:
316 binding = session.query(l2network_models.PortProfileBinding).\
317 filter_by(portprofile_id=ppid).\
318 filter_by(port_id=portid).\
319 one()
320 session.delete(binding)
321 session.flush()
322 return binding
323 except exc.NoResultFound:
324 pass
325
326
327def update_pp_binding(tenantid, ppid, newtenantid=None, newportid=None,
328 newdefault=None):
329 """Updates port profile binding"""
330 session = db.get_session()
331 try:
332 binding = session.query(l2network_models.PortProfileBinding).\
333 filter_by(portprofile_id=ppid).\
334 one()
335 if newtenantid:
336 binding["tenant_id"] = newtenantid
337 if newportid:
338 binding["port_id"] = newportid
339 if newdefault:
340 binding["default"] = newdefault
341 session.merge(binding)
342 session.flush()
343 return binding
344 except exc.NoResultFound:
345 raise c_exc.PortProfileNotFound(tenant_id=tenantid,
346 portprofile_id=ppid)
0347
=== added file 'quantum/plugins/cisco/db/l2network_models.py'
--- quantum/plugins/cisco/db/l2network_models.py 1970-01-01 00:00:00 +0000
+++ quantum/plugins/cisco/db/l2network_models.py 2011-08-23 20:09:26 +0000
@@ -0,0 +1,147 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2011, Cisco Systems, Inc.
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
16# @author: Rohit Agarwalla, Cisco Systems, Inc.
17
18import uuid
19
20from sqlalchemy import Column, Integer, String, ForeignKey, Boolean
21from sqlalchemy.orm import relation, object_mapper
22
23from quantum.plugins.cisco.db.models import BASE
24from quantum.plugins.cisco.db import models
25
26
27class L2NetworkBase(object):
28 """Base class for L2Network Models."""
29 __table_args__ = {'mysql_engine': 'InnoDB'}
30
31 def __setitem__(self, key, value):
32 """Internal Dict set method"""
33 setattr(self, key, value)
34
35 def __getitem__(self, key):
36 """Internal Dict get method"""
37 return getattr(self, key)
38
39 def get(self, key, default=None):
40 """Dict get method"""
41 return getattr(self, key, default)
42
43 def __iter__(self):
44 """Iterate over table columns"""
45 self._i = iter(object_mapper(self).columns)
46 return self
47
48 def next(self):
49 """Next method for the iterator"""
50 n = self._i.next().name
51 return n, getattr(self, n)
52
53 def update(self, values):
54 """Make the model object behave like a dict"""
55 for k, v in values.iteritems():
56 setattr(self, k, v)
57
58 def iteritems(self):
59 """Make the model object behave like a dict"
60 Includes attributes from joins."""
61 local = dict(self)
62 joined = dict([(k, v) for k, v in self.__dict__.iteritems()
63 if not k[0] == '_'])
64 local.update(joined)
65 return local.iteritems()
66
67
68class VlanID(BASE, L2NetworkBase):
69 """Represents a vlan_id usage"""
70 __tablename__ = 'vlan_ids'
71
72 vlan_id = Column(Integer, primary_key=True)
73 vlan_used = Column(Boolean)
74
75 def __init__(self, vlan_id):
76 self.vlan_id = vlan_id
77 self.vlan_used = False
78
79 def __repr__(self):
80 return "<VlanBinding(%d,%s)>" % \
81 (self.vlan_id, self.vlan_used)
82
83
84class VlanBinding(BASE, L2NetworkBase):
85 """Represents a binding of vlan_id to network_id"""
86 __tablename__ = 'vlan_bindings'
87
88 vlan_id = Column(Integer, primary_key=True)
89 vlan_name = Column(String(255))
90 network_id = Column(String(255), ForeignKey("networks.uuid"), \
91 nullable=False)
92 network = relation(models.Network, uselist=False)
93
94 def __init__(self, vlan_id, vlan_name, network_id):
95 self.vlan_id = vlan_id
96 self.vlan_name = vlan_name
97 self.network_id = network_id
98
99 def __repr__(self):
100 return "<VlanBinding(%d,%s,%s)>" % \
101 (self.vlan_id, self.vlan_name, self.network_id)
102
103
104class PortProfile(BASE, L2NetworkBase):
105 """Represents L2 network plugin level PortProfile for a network"""
106 __tablename__ = 'portprofiles'
107
108 uuid = Column(String(255), primary_key=True)
109 name = Column(String(255))
110 vlan_id = Column(Integer)
111 qos = Column(String(255))
112
113 def __init__(self, name, vlan_id, qos=None):
114 self.uuid = uuid.uuid4()
115 self.name = name
116 self.vlan_id = vlan_id
117 self.qos = qos
118
119 def __repr__(self):
120 return "<PortProfile(%s,%s,%d,%s)>" % \
121 (self.uuid, self.name, self.vlan_id, self.qos)
122
123
124class PortProfileBinding(BASE, L2NetworkBase):
125 """Represents PortProfile binding to tenant and network"""
126 __tablename__ = 'portprofile_bindings'
127
128 id = Column(Integer, primary_key=True, autoincrement=True)
129 tenant_id = Column(String(255))
130
131 port_id = Column(String(255), ForeignKey("ports.uuid"), \
132 nullable=False)
133 portprofile_id = Column(String(255), ForeignKey("portprofiles.uuid"), \
134 nullable=False)
135 default = Column(Boolean)
136 ports = relation(models.Port)
137 portprofile = relation(PortProfile, uselist=False)
138
139 def __init__(self, tenant_id, port_id, portprofile_id, default):
140 self.tenant_id = tenant_id
141 self.port_id = port_id
142 self.portprofile_id = portprofile_id
143 self.default = default
144
145 def __repr__(self):
146 return "<PortProfile Binding(%s,%s,%s,%s)>" % \
147 (self.tenant_id, self.port_id, self.portprofile_id, self.default)
0148
=== added file 'quantum/plugins/cisco/db/models.py'
--- quantum/plugins/cisco/db/models.py 1970-01-01 00:00:00 +0000
+++ quantum/plugins/cisco/db/models.py 2011-08-23 20:09:26 +0000
@@ -0,0 +1,102 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2# Copyright 2011 Nicira Networks, Inc.
3# All Rights Reserved.
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
16# @author: Somik Behera, Nicira Networks, Inc.
17# @author: Brad Hall, Nicira Networks, Inc.
18# @author: Dan Wendlandt, Nicira Networks, Inc.
19
20import uuid
21
22from sqlalchemy import Column, String, ForeignKey
23from sqlalchemy.ext.declarative import declarative_base
24from sqlalchemy.orm import relation, object_mapper
25
26BASE = declarative_base()
27
28
29class QuantumBase(object):
30 """Base class for Quantum Models."""
31 __table_args__ = {'mysql_engine': 'InnoDB'}
32
33 def __setitem__(self, key, value):
34 setattr(self, key, value)
35
36 def __getitem__(self, key):
37 return getattr(self, key)
38
39 def get(self, key, default=None):
40 return getattr(self, key, default)
41
42 def __iter__(self):
43 self._i = iter(object_mapper(self).columns)
44 return self
45
46 def next(self):
47 n = self._i.next().name
48 return n, getattr(self, n)
49
50 def update(self, values):
51 """Make the model object behave like a dict"""
52 for k, v in values.iteritems():
53 setattr(self, k, v)
54
55 def iteritems(self):
56 """Make the model object behave like a dict.
57 Includes attributes from joins."""
58 local = dict(self)
59 joined = dict([(k, v) for k, v in self.__dict__.iteritems()
60 if not k[0] == '_'])
61 local.update(joined)
62 return local.iteritems()
63
64
65class Port(BASE, QuantumBase):
66 """Represents a port on a quantum network"""
67 __tablename__ = 'ports'
68
69 uuid = Column(String(255), primary_key=True)
70 network_id = Column(String(255), ForeignKey("networks.uuid"),
71 nullable=False)
72 interface_id = Column(String(255))
73 # Port state - Hardcoding string value at the moment
74 state = Column(String(8))
75
76 def __init__(self, network_id):
77 self.uuid = str(uuid.uuid4())
78 self.network_id = network_id
79 self.state = "DOWN"
80
81 def __repr__(self):
82 return "<Port(%s,%s,%s,%s)>" % (self.uuid, self.network_id,
83 self.state, self.interface_id)
84
85
86class Network(BASE, QuantumBase):
87 """Represents a quantum network"""
88 __tablename__ = 'networks'
89
90 uuid = Column(String(255), primary_key=True)
91 tenant_id = Column(String(255), nullable=False)
92 name = Column(String(255))
93 ports = relation(Port, order_by=Port.uuid, backref="network")
94
95 def __init__(self, tenant_id, name):
96 self.uuid = str(uuid.uuid4())
97 self.tenant_id = tenant_id
98 self.name = name
99
100 def __repr__(self):
101 return "<Network(%s,%s,%s)>" % \
102 (self.uuid, self.name, self.tenant_id)
0103
=== modified file 'quantum/plugins/cisco/l2device_plugin_base.py'
--- quantum/plugins/cisco/l2device_plugin_base.py 2011-08-07 11:58:50 +0000
+++ quantum/plugins/cisco/l2device_plugin_base.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -16,12 +17,19 @@
16#17#
17# @author: Sumit Naiksatam, Cisco Systems, Inc.18# @author: Sumit Naiksatam, Cisco Systems, Inc.
18#19#
20"""
1921
20import inspect22import inspect
21from abc import ABCMeta, abstractmethod23from abc import ABCMeta, abstractmethod
2224
2325
24class L2DevicePluginBase(object):26class L2DevicePluginBase(object):
27 """
28 Base class for a device-specific plugin.
29 An example of a device-specific plugin is a Nexus switch plugin.
30 The network model relies on device-category-specific plugins to perform
31 the configuration on each device.
32 """
2533
26 __metaclass__ = ABCMeta34 __metaclass__ = ABCMeta
2735
@@ -133,7 +141,7 @@
133 marked with the abstractmethod decorator is141 marked with the abstractmethod decorator is
134 provided by the plugin class.142 provided by the plugin class.
135 """143 """
136 if cls is QuantumPluginBase:144 if cls is L2DevicePluginBase:
137 for method in cls.__abstractmethods__:145 for method in cls.__abstractmethods__:
138 method_ok = False146 method_ok = False
139 for base in klass.__mro__:147 for base in klass.__mro__:
140148
=== modified file 'quantum/plugins/cisco/l2network_model.py'
--- quantum/plugins/cisco/l2network_model.py 2011-08-14 01:28:02 +0000
+++ quantum/plugins/cisco/l2network_model.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -16,6 +17,7 @@
16#17#
17# @author: Sumit Naiksatam, Cisco Systems, Inc.18# @author: Sumit Naiksatam, Cisco Systems, Inc.
18#19#
20"""
1921
20import inspect22import inspect
21import logging as LOG23import logging as LOG
@@ -30,71 +32,92 @@
3032
3133
32class L2NetworkModel(L2NetworkModelBase):34class L2NetworkModel(L2NetworkModelBase):
35 """
36 Implements the L2NetworkModelBase
37 This implementation works with UCS and Nexus plugin,
38 with one UCS blade, and one Nexus switch.
39 """
33 _plugins = {}40 _plugins = {}
3441
35 def __init__(self):42 def __init__(self):
36 for key in conf.plugins[const.PLUGINS].keys():43 for key in conf.PLUGINS[const.PLUGINS].keys():
37 self._plugins[key] = utils.import_object(44 self._plugins[key] = utils.import_object(
38 conf.plugins[const.PLUGINS][key])45 conf.PLUGINS[const.PLUGINS][key])
39 LOG.debug("Loaded device plugin %s\n" % \46 LOG.debug("Loaded device plugin %s" % \
40 conf.plugins[const.PLUGINS][key])47 conf.PLUGINS[const.PLUGINS][key])
4148
42 def _funcName(self, offset=0):49 def _func_name(self, offset=0):
50 """Get the name of the calling function"""
43 return inspect.stack()[1 + offset][3]51 return inspect.stack()[1 + offset][3]
4452
45 def _invokeAllDevicePlugins(self, function_name, args, kwargs):53 def _invoke_all_device_plugins(self, function_name, args, kwargs):
46 for pluginObjRef in self._plugins.values():54 """Invoke all device plugins for this model implementation"""
47 getattr(pluginObjRef, function_name)(*args, **kwargs)55 for plugin_obj_ref in self._plugins.values():
56 getattr(plugin_obj_ref, function_name)(*args, **kwargs)
4857
49 def _invokeUCSPlugin(self, function_name, args, kwargs):58 def _invoke_ucs_plugin(self, function_name, args, kwargs):
59 """Invoke only the UCS plugin"""
50 if const.UCS_PLUGIN in self._plugins.keys():60 if const.UCS_PLUGIN in self._plugins.keys():
51 getattr(self._plugins[const.UCS_PLUGIN],61 getattr(self._plugins[const.UCS_PLUGIN],
52 function_name)(*args, **kwargs)62 function_name)(*args, **kwargs)
5363
54 def _invokeNexusPlugin(self, function_name, args, kwargs):64 def _invoke_nexus_plugin(self, function_name, args, kwargs):
65 """Invoke only the Nexus plugin"""
55 if const.NEXUS_PLUGIN in self._plugins.keys():66 if const.NEXUS_PLUGIN in self._plugins.keys():
56 getattr(self._plugins[const.NEXUS_PLUGIN],67 getattr(self._plugins[const.NEXUS_PLUGIN],
57 function_name)(*args, **kwargs)68 function_name)(*args, **kwargs)
5869
59 def get_all_networks(self, args):70 def get_all_networks(self, args):
71 """Not implemented for this model"""
60 pass72 pass
6173
62 def create_network(self, args):74 def create_network(self, args):
63 deviceParams = {const.DEVICE_IP: ""}75 """Support for the Quantum core API call"""
64 self._invokeAllDevicePlugins(self._funcName(), args, deviceParams)76 device_params = {const.DEVICE_IP: ""}
77 self._invoke_all_device_plugins(self._func_name(), args, device_params)
6578
66 def delete_network(self, args):79 def delete_network(self, args):
67 deviceParams = {const.DEVICE_IP: ""}80 """Support for the Quantum core API call"""
68 self._invokeAllDevicePlugins(self._funcName(), args, deviceParams)81 device_params = {const.DEVICE_IP: ""}
82 self._invoke_all_device_plugins(self._func_name(), args, device_params)
6983
70 def get_network_details(self, args):84 def get_network_details(self, args):
85 """Not implemented for this model"""
71 pass86 pass
7287
73 def rename_network(self, args):88 def rename_network(self, args):
74 deviceParams = {const.DEVICE_IP: ""}89 """Support for the Quantum core API call"""
75 self._invokeAllDevicePlugins(self._funcName(), args, deviceParams)90 device_params = {const.DEVICE_IP: ""}
91 self._invoke_all_device_plugins(self._func_name(), args, device_params)
7692
77 def get_all_ports(self, args):93 def get_all_ports(self, args):
94 """Not implemented for this model"""
78 pass95 pass
7996
80 def create_port(self, args):97 def create_port(self, args):
81 deviceParams = {const.DEVICE_IP: ""}98 """Support for the Quantum core API call"""
82 self._invokeUCSPlugin(self._funcName(), args, deviceParams)99 device_params = {const.DEVICE_IP: ""}
100 self._invoke_ucs_plugin(self._func_name(), args, device_params)
83101
84 def delete_port(self, args):102 def delete_port(self, args):
85 deviceParams = {const.DEVICE_IP: ""}103 """Support for the Quantum core API call"""
86 self._invokeUCSPlugin(self._funcName(), args, deviceParams)104 device_params = {const.DEVICE_IP: ""}
105 self._invoke_ucs_plugin(self._func_name(), args, device_params)
87106
88 def update_port(self, args):107 def update_port(self, args):
108 """Not implemented for this model"""
89 pass109 pass
90110
91 def get_port_details(self, args):111 def get_port_details(self, args):
112 """Not implemented for this model"""
92 pass113 pass
93114
94 def plug_interface(self, args):115 def plug_interface(self, args):
95 deviceParams = {const.DEVICE_IP: ""}116 """Support for the Quantum core API call"""
96 self._invokeUCSPlugin(self._funcName(), args, deviceParams)117 device_params = {const.DEVICE_IP: ""}
118 self._invoke_ucs_plugin(self._func_name(), args, device_params)
97119
98 def unplug_interface(self, args):120 def unplug_interface(self, args):
99 deviceParams = {const.DEVICE_IP: ""}121 """Support for the Quantum core API call"""
100 self._invokeUCSPlugin(self._funcName(), args, deviceParams)122 device_params = {const.DEVICE_IP: ""}
123 self._invoke_ucs_plugin(self._func_name(), args, device_params)
101124
=== modified file 'quantum/plugins/cisco/l2network_model_base.py'
--- quantum/plugins/cisco/l2network_model_base.py 2011-08-07 11:58:50 +0000
+++ quantum/plugins/cisco/l2network_model_base.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -16,12 +17,20 @@
16#17#
17# @author: Sumit Naiksatam, Cisco Systems, Inc.18# @author: Sumit Naiksatam, Cisco Systems, Inc.
18#19#
20"""
1921
20import inspect22import inspect
21from abc import ABCMeta, abstractmethod23from abc import ABCMeta, abstractmethod
2224
2325
24class L2NetworkModelBase(object):26class L2NetworkModelBase(object):
27 """
28 Base class for L2 Network Model
29 It relies on a pluggable network configuration module to gather
30 knowledge of the system, but knows which device-specific plugins
31 to invoke for a corresponding core API call, and what parameters to pass
32 to that plugin.
33 """
2534
26 __metaclass__ = ABCMeta35 __metaclass__ = ABCMeta
2736
@@ -131,7 +140,7 @@
131 marked with the abstractmethod decorator is140 marked with the abstractmethod decorator is
132 provided by the plugin class.141 provided by the plugin class.
133 """142 """
134 if cls is QuantumPluginBase:143 if cls is L2NetworkModelBase:
135 for method in cls.__abstractmethods__:144 for method in cls.__abstractmethods__:
136 method_ok = False145 method_ok = False
137 for base in klass.__mro__:146 for base in klass.__mro__:
138147
=== modified file 'quantum/plugins/cisco/l2network_plugin.py'
--- quantum/plugins/cisco/l2network_plugin.py 2011-08-14 01:28:02 +0000
+++ quantum/plugins/cisco/l2network_plugin.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -16,6 +17,7 @@
16#17#
17# @author: Sumit Naiksatam, Cisco Systems, Inc.18# @author: Sumit Naiksatam, Cisco Systems, Inc.
18#19#
20"""
1921
20import inspect22import inspect
21import logging as LOG23import logging as LOG
@@ -26,22 +28,22 @@
26from quantum.plugins.cisco import l2network_plugin_configuration as conf28from quantum.plugins.cisco import l2network_plugin_configuration as conf
27from quantum.plugins.cisco.common import cisco_constants as const29from quantum.plugins.cisco.common import cisco_constants as const
28from quantum.plugins.cisco.common import cisco_exceptions as cexc30from quantum.plugins.cisco.common import cisco_exceptions as cexc
31from quantum.plugins.cisco.db import api as db
32from quantum.plugins.cisco.db import l2network_db as cdb
2933
30LOG.basicConfig(level=LOG.WARN)34LOG.basicConfig(level=LOG.WARN)
31LOG.getLogger(const.LOGGER_COMPONENT_NAME)35LOG.getLogger(const.LOGGER_COMPONENT_NAME)
3236
3337
34class L2Network(QuantumPluginBase):38class L2Network(QuantumPluginBase):
35 _networks = {}39 """ L2 Network Framework Plugin """
36 _tenants = {}
37 _portprofiles = {}
3840
39 def __init__(self):41 def __init__(self):
40 self._net_counter = 0
41 self._portprofile_counter = 0
42 self._port_counter = 0
43 self._vlan_counter = int(conf.VLAN_START) - 142 self._vlan_counter = int(conf.VLAN_START) - 1
44 self._model = utils.import_object(conf.MODEL_CLASS)43 self._model = utils.import_object(conf.MODEL_CLASS)
44 cdb.initialize()
45 # TODO (Sumit): The following should move to the segmentation module
46 cdb.create_vlanids()
4547
46 """48 """
47 Core API implementation49 Core API implementation
@@ -53,8 +55,16 @@
53 the specified tenant.55 the specified tenant.
54 """56 """
55 LOG.debug("get_all_networks() called\n")57 LOG.debug("get_all_networks() called\n")
56 self._invokeDevicePlugins(self._funcName(), [tenant_id])58 self._invoke_device_plugins(self._func_name(), [tenant_id])
57 return self._networks.values()59 networks_list = db.network_list(tenant_id)
60 new_networks_list = []
61 for network in networks_list:
62 new_network_dict = self._make_net_dict(network[const.UUID],
63 network[const.NETWORKNAME],
64 [])
65 new_networks_list.append(new_network_dict)
66
67 return new_networks_list
5868
59 def create_network(self, tenant_id, net_name):69 def create_network(self, tenant_id, net_name):
60 """70 """
@@ -62,22 +72,17 @@
62 a symbolic name.72 a symbolic name.
63 """73 """
64 LOG.debug("create_network() called\n")74 LOG.debug("create_network() called\n")
65 new_net_id = self._get_unique_net_id(tenant_id)75 new_network = db.network_create(tenant_id, net_name)
76 new_net_id = new_network[const.UUID]
66 vlan_id = self._get_vlan_for_tenant(tenant_id, net_name)77 vlan_id = self._get_vlan_for_tenant(tenant_id, net_name)
67 vlan_name = self._get_vlan_name(new_net_id, str(vlan_id))78 vlan_name = self._get_vlan_name(new_net_id, str(vlan_id))
68 self._invokeDevicePlugins(self._funcName(), [tenant_id, net_name,79 self._invoke_device_plugins(self._func_name(), [tenant_id, net_name,
69 new_net_id, vlan_name,80 new_net_id, vlan_name,
70 vlan_id])81 vlan_id])
82 cdb.add_vlan_binding(vlan_id, vlan_name, new_net_id)
71 new_net_dict = {const.NET_ID: new_net_id,83 new_net_dict = {const.NET_ID: new_net_id,
72 const.NET_NAME: net_name,84 const.NET_NAME: net_name,
73 const.NET_PORTS: {},85 const.NET_PORTS: []}
74 const.NET_VLAN_NAME: vlan_name,
75 const.NET_VLAN_ID: vlan_id,
76 const.NET_TENANTS: [tenant_id]}
77 self._networks[new_net_id] = new_net_dict
78 tenant = self._get_tenant(tenant_id)
79 tenant_networks = tenant[const.TENANT_NETWORKS]
80 tenant_networks[new_net_id] = new_net_dict
81 return new_net_dict86 return new_net_dict
8287
83 def delete_network(self, tenant_id, net_id):88 def delete_network(self, tenant_id, net_id):
@@ -86,22 +91,24 @@
86 belonging to the specified tenant.91 belonging to the specified tenant.
87 """92 """
88 LOG.debug("delete_network() called\n")93 LOG.debug("delete_network() called\n")
89 net = self._networks.get(net_id)94 net = db.network_get(net_id)
90 if net:95 if net:
91 if len(net[const.NET_PORTS].values()) > 0:96 if len(net[const.NETWORKPORTS]) > 0:
92 ports_on_net = net[const.NET_PORTS].values()97 ports_on_net = db.port_list(net_id)
93 for port in ports_on_net:98 for port in ports_on_net:
94 if port[const.ATTACHMENT]:99 if port[const.INTERFACEID]:
95 raise exc.NetworkInUse(net_id=net_id)100 raise exc.NetworkInUse(net_id=net_id)
96 for port in ports_on_net:101 for port in ports_on_net:
97 self.delete_port(tenant_id, net_id, port[const.PORT_ID])102 self.delete_port(tenant_id, net_id, port[const.PORTID])
98103
99 self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id])104 self._invoke_device_plugins(self._func_name(), [tenant_id, net_id])
100 self._networks.pop(net_id)105 net_dict = self._make_net_dict(net[const.UUID],
101 tenant = self._get_tenant(tenant_id)106 net[const.NETWORKNAME],
102 tenant_networks = tenant[const.TENANT_NETWORKS]107 [])
103 tenant_networks.pop(net_id)108 self._release_vlan_for_tenant(tenant_id, net_id)
104 return net109 cdb.remove_vlan_binding(net_id)
110 db.network_destroy(net_id)
111 return net_dict
105 # Network not found112 # Network not found
106 raise exc.NetworkNotFound(net_id=net_id)113 raise exc.NetworkNotFound(net_id=net_id)
107114
@@ -110,12 +117,22 @@
110 Gets the details of a particular network117 Gets the details of a particular network
111 """118 """
112 LOG.debug("get_network_details() called\n")119 LOG.debug("get_network_details() called\n")
113 self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id])120 self._invoke_device_plugins(self._func_name(), [tenant_id, net_id])
114 network = self._get_network(tenant_id, net_id)121 network = db.network_get(net_id)
115 ports_on_net = network[const.NET_PORTS].values()122 ports_list = network[const.NETWORKPORTS]
116 return {const.NET_ID: network[const.NET_ID],123 ports_on_net = []
117 const.NET_NAME: network[const.NET_NAME],124 for port in ports_list:
118 const.NET_PORTS: ports_on_net}125 new_port = self._make_port_dict(port[const.UUID],
126 port[const.PORTSTATE],
127 port[const.NETWORKID],
128 port[const.INTERFACEID])
129 ports_on_net.append(new_port)
130
131 new_network = self._make_net_dict(network[const.UUID],
132 network[const.NETWORKNAME],
133 ports_on_net)
134
135 return new_network
119136
120 def rename_network(self, tenant_id, net_id, new_name):137 def rename_network(self, tenant_id, net_id, new_name):
121 """138 """
@@ -123,11 +140,13 @@
123 Virtual Network.140 Virtual Network.
124 """141 """
125 LOG.debug("rename_network() called\n")142 LOG.debug("rename_network() called\n")
126 self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id,143 self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
127 new_name])144 new_name])
128 network = self._get_network(tenant_id, net_id)145 network = db.network_rename(tenant_id, net_id, new_name)
129 network[const.NET_NAME] = new_name146 net_dict = self._make_net_dict(network[const.UUID],
130 return network147 network[const.NETWORKNAME],
148 [])
149 return net_dict
131150
132 def get_all_ports(self, tenant_id, net_id):151 def get_all_ports(self, tenant_id, net_id):
133 """152 """
@@ -135,9 +154,17 @@
135 specified Virtual Network.154 specified Virtual Network.
136 """155 """
137 LOG.debug("get_all_ports() called\n")156 LOG.debug("get_all_ports() called\n")
138 self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id])157 self._invoke_device_plugins(self._func_name(), [tenant_id, net_id])
139 network = self._get_network(tenant_id, net_id)158 network = db.network_get(net_id)
140 ports_on_net = network[const.NET_PORTS].values()159 ports_list = network[const.NETWORKPORTS]
160 ports_on_net = []
161 for port in ports_list:
162 new_port = self._make_port_dict(port[const.UUID],
163 port[const.PORTSTATE],
164 port[const.NETWORKID],
165 port[const.INTERFACEID])
166 ports_on_net.append(new_port)
167
141 return ports_on_net168 return ports_on_net
142169
143 def create_port(self, tenant_id, net_id, port_state=None):170 def create_port(self, tenant_id, net_id, port_state=None):
@@ -145,16 +172,15 @@
145 Creates a port on the specified Virtual Network.172 Creates a port on the specified Virtual Network.
146 """173 """
147 LOG.debug("create_port() called\n")174 LOG.debug("create_port() called\n")
148 net = self._get_network(tenant_id, net_id)175 port = db.port_create(net_id, port_state)
149 ports = net[const.NET_PORTS]176 unique_port_id_string = port[const.UUID]
150 unique_port_id_string = self._get_unique_port_id(tenant_id, net_id)177 self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
151 self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id,
152 port_state,178 port_state,
153 unique_port_id_string])179 unique_port_id_string])
154 new_port_dict = {const.PORT_ID: unique_port_id_string,180 new_port_dict = self._make_port_dict(port[const.UUID],
155 const.PORT_STATE: const.PORT_UP,181 port[const.PORTSTATE],
156 const.ATTACHMENT: None}182 port[const.NETWORKID],
157 ports[unique_port_id_string] = new_port_dict183 port[const.INTERFACEID])
158 return new_port_dict184 return new_port_dict
159185
160 def delete_port(self, tenant_id, net_id, port_id):186 def delete_port(self, tenant_id, net_id, port_id):
@@ -165,31 +191,24 @@
165 then the port can be deleted.191 then the port can be deleted.
166 """192 """
167 LOG.debug("delete_port() called\n")193 LOG.debug("delete_port() called\n")
168 port = self._get_port(tenant_id, net_id, port_id)194 self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
169 if port[const.ATTACHMENT]:195 port_id])
170 raise exc.PortInUse(net_id=net_id, port_id=port_id,196 db.port_destroy(net_id, port_id)
171 att_id=port[const.ATTACHMENT])197 new_port_dict = self._make_port_dict(port_id, None, None, None)
172 try:198 return new_port_dict
173 #TODO (Sumit): Before deleting port profile make sure that there
174 # is no VM using this port profile
175 self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id,
176 port_id])
177 net = self._get_network(tenant_id, net_id)
178 net[const.NET_PORTS].pop(port_id)
179 except KeyError:
180 raise exc.PortNotFound(net_id=net_id, port_id=port_id)
181199
182 def update_port(self, tenant_id, net_id, port_id, port_state):200 def update_port(self, tenant_id, net_id, port_id, port_state):
183 """201 """
184 Updates the state of a port on the specified Virtual Network.202 Updates the state of a port on the specified Virtual Network.
185 """203 """
186 LOG.debug("update_port() called\n")204 LOG.debug("update_port() called\n")
187 self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id,205 self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
188 port_id, port_state])206 port_id, port_state])
189 port = self._get_port(tenant_id, net_id, port_id)
190 self._validate_port_state(port_state)207 self._validate_port_state(port_state)
191 port[const.PORT_STATE] = port_state208 db.port_set_state(net_id, port_id, port_state)
192 return port209 new_port_dict = self._make_port_dict(port_id, port_state, net_id,
210 None)
211 return new_port_dict
193212
194 def get_port_details(self, tenant_id, net_id, port_id):213 def get_port_details(self, tenant_id, net_id, port_id):
195 """214 """
@@ -197,9 +216,14 @@
197 that is attached to this particular port.216 that is attached to this particular port.
198 """217 """
199 LOG.debug("get_port_details() called\n")218 LOG.debug("get_port_details() called\n")
200 self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id,219 self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
201 port_id])220 port_id])
202 return self._get_port(tenant_id, net_id, port_id)221 port = db.port_get(net_id, port_id)
222 new_port_dict = self._make_port_dict(port[const.UUID],
223 port[const.PORTSTATE],
224 port[const.NETWORKID],
225 port[const.INTERFACEID])
226 return new_port_dict
203227
204 def plug_interface(self, tenant_id, net_id, port_id,228 def plug_interface(self, tenant_id, net_id, port_id,
205 remote_interface_id):229 remote_interface_id):
@@ -208,16 +232,10 @@
208 specified Virtual Network.232 specified Virtual Network.
209 """233 """
210 LOG.debug("plug_interface() called\n")234 LOG.debug("plug_interface() called\n")
211 self._validate_attachment(tenant_id, net_id, port_id,235 self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
212 remote_interface_id)
213 port = self._get_port(tenant_id, net_id, port_id)
214 if port[const.ATTACHMENT]:
215 raise exc.PortInUse(net_id=net_id, port_id=port_id,
216 att_id=port[const.ATTACHMENT])
217 self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id,
218 port_id,236 port_id,
219 remote_interface_id])237 remote_interface_id])
220 port[const.ATTACHMENT] = remote_interface_id238 db.port_set_attachment(net_id, port_id, remote_interface_id)
221239
222 def unplug_interface(self, tenant_id, net_id, port_id):240 def unplug_interface(self, tenant_id, net_id, port_id):
223 """241 """
@@ -225,170 +243,165 @@
225 specified Virtual Network.243 specified Virtual Network.
226 """244 """
227 LOG.debug("unplug_interface() called\n")245 LOG.debug("unplug_interface() called\n")
228 port = self._get_port(tenant_id, net_id, port_id)246 self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
229 self._invokeDevicePlugins(self._funcName(), [tenant_id, net_id,
230 port_id])247 port_id])
231 port[const.ATTACHMENT] = None248 db.port_unset_attachment(net_id, port_id)
232249
233 """250 """
234 Extension API implementation251 Extension API implementation
235 """252 """
236 def get_all_portprofiles(self, tenant_id):253 def get_all_portprofiles(self, tenant_id):
237 return self._portprofiles.values()254 """Get all port profiles"""
255 pplist = cdb.get_all_portprofiles()
256 new_pplist = []
257 for portprofile in pplist:
258 new_pp = self._make_portprofile_dict(tenant_id,
259 portprofile[const.UUID],
260 portprofile[const.PPNAME],
261 portprofile[const.PPQOS])
262 new_pplist.append(new_pp)
263
264 return new_pplist
238265
239 def get_portprofile_details(self, tenant_id, profile_id):266 def get_portprofile_details(self, tenant_id, profile_id):
240 return self._get_portprofile(tenant_id, profile_id)267 """Get port profile details"""
268 portprofile = cdb.get_portprofile(tenant_id, profile_id)
269 new_pp = self._make_portprofile_dict(tenant_id,
270 portprofile[const.UUID],
271 portprofile[const.PPNAME],
272 portprofile[const.PPQOS])
273 return new_pp
241274
242 def create_portprofile(self, tenant_id, profile_name, vlan_id):275 def create_portprofile(self, tenant_id, profile_name, qos):
243 profile_id = self._get_unique_profile_id(tenant_id)276 """Create port profile"""
244 new_port_profile_dict = {const.PROFILE_ID: profile_id,277 portprofile = cdb.add_portprofile(tenant_id, profile_name,
245 const.PROFILE_NAME: profile_name,278 const.NO_VLAN_ID, qos)
246 const.PROFILE_ASSOCIATIONS: [],279 new_pp = self._make_portprofile_dict(tenant_id,
247 const.PROFILE_VLAN_ID: vlan_id,280 portprofile[const.UUID],
248 const.PROFILE_QOS: None}281 portprofile[const.PPNAME],
249 self._portprofiles[profile_id] = new_port_profile_dict282 portprofile[const.PPQOS])
250 tenant = self._get_tenant(tenant_id)283 return new_pp
251 portprofiles = tenant[const.TENANT_PORTPROFILES]
252 portprofiles[profile_id] = new_port_profile_dict
253 return new_port_profile_dict
254284
255 def delete_portprofile(self, tenant_id, profile_id):285 def delete_portprofile(self, tenant_id, profile_id):
256 portprofile = self._get_portprofile(tenant_id, profile_id)286 """Delete portprofile"""
257 associations = portprofile[const.PROFILE_ASSOCIATIONS]287 try:
258 if len(associations) > 0:288 portprofile = cdb.get_portprofile(tenant_id, profile_id)
289 except Exception, exc:
290 raise cexc.PortProfileNotFound(tenant_id=tenant_id,
291 portprofile_id=profile_id)
292
293 plist = cdb.get_pp_binding(tenant_id, profile_id)
294 if plist:
259 raise cexc.PortProfileInvalidDelete(tenant_id=tenant_id,295 raise cexc.PortProfileInvalidDelete(tenant_id=tenant_id,
260 profile_id=profile_id)296 profile_id=profile_id)
261 else:297 else:
262 self._portprofiles.pop(profile_id)298 cdb.remove_portprofile(tenant_id, profile_id)
263 tenant = self._get_tenant(tenant_id)
264 tenant[const.TENANT_PORTPROFILES].pop(profile_id)
265299
266 def rename_portprofile(self, tenant_id, profile_id, new_name):300 def rename_portprofile(self, tenant_id, profile_id, new_name):
267 portprofile = self._get_portprofile(tenant_id, profile_id)301 """Rename port profile"""
268 portprofile[const.PROFILE_NAME] = new_name302 try:
269 return portprofile303 portprofile = cdb.get_portprofile(tenant_id, profile_id)
304 except Exception, exc:
305 raise cexc.PortProfileNotFound(tenant_id=tenant_id,
306 portprofile_id=profile_id)
307 portprofile = cdb.update_portprofile(tenant_id, profile_id, new_name)
308 new_pp = self._make_portprofile_dict(tenant_id,
309 portprofile[const.UUID],
310 portprofile[const.PPNAME],
311 portprofile[const.PPQOS])
312 return new_pp
270313
271 def associate_portprofile(self, tenant_id, net_id,314 def associate_portprofile(self, tenant_id, net_id,
272 port_id, portprofile_id):315 port_id, portprofile_id):
273 portprofile = self._get_portprofile(tenant_id, portprofile_id)316 """Associate port profile"""
274 associations = portprofile[const.PROFILE_ASSOCIATIONS]317 try:
275 associations.append(port_id)318 portprofile = cdb.get_portprofile(tenant_id, portprofile_id)
319 except Exception, exc:
320 raise cexc.PortProfileNotFound(tenant_id=tenant_id,
321 portprofile_id=portprofile_id)
322
323 cdb.add_pp_binding(tenant_id, port_id, portprofile_id, False)
276324
277 def disassociate_portprofile(self, tenant_id, net_id,325 def disassociate_portprofile(self, tenant_id, net_id,
278 port_id, portprofile_id):326 port_id, portprofile_id):
279 portprofile = self._get_portprofile(tenant_id, portprofile_id)327 """Disassociate port profile"""
280 associations = portprofile[const.PROFILE_ASSOCIATIONS]328 try:
281 associations.remove(port_id)329 portprofile = cdb.get_portprofile(tenant_id, portprofile_id)
330 except Exception, exc:
331 raise cexc.PortProfileNotFound(tenant_id=tenant_id,
332 portprofile_id=portprofile_id)
282333
283 def create_defaultPProfile(self, tenant_id, network_id, profile_name,334 cdb.remove_pp_binding(tenant_id, port_id, portprofile_id)
284 vlan_id):
285 pass
286335
287 """336 """
288 Private functions337 Private functions
289 """338 """
290 def _invokeDevicePlugins(self, function_name, args):339 def _invoke_device_plugins(self, function_name, args):
291 """340 """
292 All device-specific calls are delegate to the model341 All device-specific calls are delegate to the model
293 """342 """
294 getattr(self._model, function_name)(args)343 getattr(self._model, function_name)(args)
295344
296 def _get_vlan_for_tenant(self, tenant_id, net_name):345 def _get_vlan_for_tenant(self, tenant_id, net_name):
346 """Get vlan ID"""
297 # TODO (Sumit):347 # TODO (Sumit):
298 # The VLAN ID for a tenant might need to be obtained from348 # The VLAN ID for a tenant might need to be obtained from
299 # somewhere (from Donabe/Melange?)349 # somewhere (from Donabe/Melange?)
300 # Also need to make sure that the VLAN ID is not being used already350 # Also need to make sure that the VLAN ID is not being used already
301 # Currently, just a wrap-around counter ranging from VLAN_START to351 # Currently, just a wrap-around counter ranging from VLAN_START to
302 # VLAN_END352 # VLAN_END
303 self._vlan_counter += 1353 return cdb.reserve_vlanid()
304 self._vlan_counter %= int(conf.VLAN_END)354
305 if self._vlan_counter < int(conf.VLAN_START):355 def _release_vlan_for_tenant(self, tenant_id, net_id):
306 self._vlan_counter = int(conf.VLAN_START)356 """Relase VLAN"""
307 return self._vlan_counter357 vlan_binding = cdb.get_vlan_binding(net_id)
358 return cdb.release_vlanid(vlan_binding[const.VLANID])
308359
309 def _get_vlan_name(self, net_id, vlan):360 def _get_vlan_name(self, net_id, vlan):
310 vlan_name = conf.VLAN_NAME_PREFIX + net_id + "-" + vlan361 """Getting the vlan name from the tenant and vlan"""
362 vlan_name = conf.VLAN_NAME_PREFIX + vlan
311 return vlan_name363 return vlan_name
312364
313 def _validate_port_state(self, port_state):365 def _validate_port_state(self, port_state):
366 """Checking the port state"""
314 if port_state.upper() not in (const.PORT_UP, const.PORT_DOWN):367 if port_state.upper() not in (const.PORT_UP, const.PORT_DOWN):
315 raise exc.StateInvalid(port_state=port_state)368 raise exc.StateInvalid(port_state=port_state)
316 return True369 return True
317370
318 def _validate_attachment(self, tenant_id, network_id, port_id,371 def _func_name(self, offset=0):
319 remote_interface_id):372 """Getting the name of the calling funciton"""
320 network = self._get_network(tenant_id, network_id)
321 for port in network[const.NET_PORTS].values():
322 if port[const.ATTACHMENT] == remote_interface_id:
323 raise exc.AlreadyAttached(net_id=network_id,
324 port_id=port_id,
325 att_id=port[const.ATTACHMENT],
326 att_port_id=port[const.PORT_ID])
327
328 def _get_network(self, tenant_id, network_id):
329 network = self._networks.get(network_id)
330 if not network:
331 raise exc.NetworkNotFound(net_id=network_id)
332 return network
333
334 def _get_tenant(self, tenant_id):
335 tenant = self._tenants.get(tenant_id)
336 if not tenant:
337 LOG.debug("Creating new tenant record with tenant id %s\n" %
338 tenant_id)
339 tenant = {const.TENANT_ID: tenant_id,
340 const.TENANT_NAME: tenant_id,
341 const.TENANT_NETWORKS: {},
342 const.TENANT_PORTPROFILES: {}}
343 self._tenants[tenant_id] = tenant
344 return tenant
345
346 def _get_port(self, tenant_id, network_id, port_id):
347 net = self._get_network(tenant_id, network_id)
348 port = net[const.NET_PORTS].get(port_id)
349 if not port:
350 raise exc.PortNotFound(net_id=network_id, port_id=port_id)
351 return port
352
353 def _get_portprofile(self, tenant_id, portprofile_id):
354 portprofile = self._portprofiles.get(portprofile_id)
355 if not portprofile:
356 raise cexc.PortProfileNotFound(tenant_id=tenant_id,
357 portprofile_id=portprofile_id)
358 return portprofile
359
360 def _get_unique_net_id(self, tenant_id):
361 self._net_counter += 1
362 self._net_counter %= int(conf.MAX_NETWORKS)
363 id = tenant_id[:3] + \
364 "-n-" + ("0" * (6 - len(str(self._net_counter)))) + \
365 str(self._net_counter)
366 # TODO (Sumit): Need to check if the ID has already been allocated
367 # ID will be generated by DB
368 return id
369
370 def _get_unique_port_id(self, tenant_id, net_id):
371 self._port_counter += 1
372 self._port_counter %= int(conf.MAX_PORTS)
373 id = net_id + "-p-" + str(self._port_counter)
374 # TODO (Sumit): Need to check if the ID has already been allocated
375 # ID will be generated by DB
376 return id
377
378 def _get_unique_profile_id(self, tenant_id):
379 self._portprofile_counter += 1
380 self._portprofile_counter %= int(conf.MAX_PORT_PROFILES)
381 id = tenant_id[:3] + "-pp-" + \
382 ("0" * (6 - len(str(self._net_counter)))) \
383 + str(self._portprofile_counter)
384 # TODO (Sumit): Need to check if the ID has already been allocated
385 # ID will be generated by DB
386 return id
387
388 def _funcName(self, offset=0):
389 return inspect.stack()[1 + offset][3]373 return inspect.stack()[1 + offset][3]
390374
391"""375 def _make_net_dict(self, net_id, net_name, ports):
392TODO (Sumit):376 """Helper funciton"""
393(1) Persistent storage377 res = {const.NET_ID: net_id, const.NET_NAME: net_name}
394"""378 res[const.NET_PORTS] = ports
379 return res
380
381 def _make_port_dict(self, port_id, port_state, net_id, attachment):
382 """Helper funciton"""
383 res = {const.PORT_ID: port_id, const.PORT_STATE: port_state}
384 res[const.NET_ID] = net_id
385 res[const.ATTACHMENT] = attachment
386 return res
387
388 def _make_portprofile_dict(self, tenant_id, profile_id, profile_name,
389 qos):
390 """Helper funciton"""
391 profile_associations = self._make_portprofile_assc_list(tenant_id,
392 profile_id)
393 res = {const.PROFILE_ID: str(profile_id),
394 const.PROFILE_NAME: profile_name,
395 const.PROFILE_ASSOCIATIONS: profile_associations,
396 const.PROFILE_VLAN_ID: None,
397 const.PROFILE_QOS: qos}
398 return res
399
400 def _make_portprofile_assc_list(self, tenant_id, profile_id):
401 """Helper function to create port profile association list"""
402 plist = cdb.get_pp_binding(tenant_id, profile_id)
403 assc_list = []
404 for port in plist:
405 assc_list.append(port[const.PORTID])
406
407 return assc_list
395408
=== modified file 'quantum/plugins/cisco/l2network_plugin_configuration.py'
--- quantum/plugins/cisco/l2network_plugin_configuration.py 2011-08-14 01:28:02 +0000
+++ quantum/plugins/cisco/l2network_plugin_configuration.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -15,7 +16,8 @@
15# under the License.16# under the License.
16#17#
17# @author: Sumit Naiksatam, Cisco Systems, Inc.18# @author: Sumit Naiksatam, Cisco Systems, Inc.
18#19# @author: Rohit Agarwalla, Cisco Systems, Inc.
20"""
1921
20import os22import os
2123
@@ -23,28 +25,43 @@
2325
24CONF_FILE = "conf/l2network_plugin.ini"26CONF_FILE = "conf/l2network_plugin.ini"
2527
26cp = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \28CONF_PARSER_OBJ = confp.\
27 + "/" + CONF_FILE)29CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) + \
2830"/" + CONF_FILE)
29section = cp['VLANS']31
30VLAN_NAME_PREFIX = section['vlan_name_prefix']32SECTION_CONF = CONF_PARSER_OBJ['VLANS']
31VLAN_START = section['vlan_start']33VLAN_NAME_PREFIX = SECTION_CONF['vlan_name_prefix']
32VLAN_END = section['vlan_end']34VLAN_START = SECTION_CONF['vlan_start']
3335VLAN_END = SECTION_CONF['vlan_end']
34section = cp['PORTS']36
35MAX_PORTS = section['max_ports']37SECTION_CONF = CONF_PARSER_OBJ['PORTS']
3638MAX_PORTS = SECTION_CONF['max_ports']
37section = cp['PORTPROFILES']39
38MAX_PORT_PROFILES = section['max_port_profiles']40SECTION_CONF = CONF_PARSER_OBJ['PORTPROFILES']
3941MAX_PORT_PROFILES = SECTION_CONF['max_port_profiles']
40section = cp['NETWORKS']42
41MAX_NETWORKS = section['max_networks']43SECTION_CONF = CONF_PARSER_OBJ['NETWORKS']
4244MAX_NETWORKS = SECTION_CONF['max_networks']
43section = cp['MODEL']45
44MODEL_CLASS = section['model_class']46SECTION_CONF = CONF_PARSER_OBJ['MODEL']
47MODEL_CLASS = SECTION_CONF['model_class']
4548
46CONF_FILE = "conf/plugins.ini"49CONF_FILE = "conf/plugins.ini"
4750
48cp = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \51CONF_PARSER_OBJ = confp.\
49 + "/" + CONF_FILE)52CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) + \
50plugins = cp.walk(cp.dummy)53"/" + CONF_FILE)
54
55PLUGINS = CONF_PARSER_OBJ.walk(CONF_PARSER_OBJ.dummy)
56
57CONF_FILE = "conf/db_conn.ini"
58
59CONF_PARSER_OBJ = confp.\
60CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) + \
61"/" + CONF_FILE)
62
63SECTION_CONF = CONF_PARSER_OBJ['DATABASE']
64DB_NAME = SECTION_CONF['name']
65DB_USER = SECTION_CONF['user']
66DB_PASS = SECTION_CONF['pass']
67DB_HOST = SECTION_CONF['host']
5168
=== modified file 'quantum/plugins/cisco/nexus/__init__.py'
--- quantum/plugins/cisco/nexus/__init__.py 2011-07-31 19:04:01 +0000
+++ quantum/plugins/cisco/nexus/__init__.py 2011-08-23 20:09:26 +0000
@@ -15,4 +15,7 @@
15# under the License.15# under the License.
16#16#
17# @author: Sumit Naiksatam, Cisco Systems, Inc.17# @author: Sumit Naiksatam, Cisco Systems, Inc.
18#18# @author: Edgar Magana, Cisco Systems, Inc.
19"""
20Init module for Nexus Driver
21"""
1922
=== modified file 'quantum/plugins/cisco/nexus/cisco_nexus_configuration.py'
--- quantum/plugins/cisco/nexus/cisco_nexus_configuration.py 2011-08-14 01:28:02 +0000
+++ quantum/plugins/cisco/nexus/cisco_nexus_configuration.py 2011-08-23 20:09:26 +0000
@@ -17,19 +17,24 @@
17# @author: Sumit Naiksatam, Cisco Systems, Inc.17# @author: Sumit Naiksatam, Cisco Systems, Inc.
18# @author: Edgar Magana, Cisco Systems, Inc.18# @author: Edgar Magana, Cisco Systems, Inc.
19#19#
2020"""
21Configuration consolidation for the Nexus Driver
22This module will export the configuration parameters
23from the nexus.ini file
24"""
21import os25import os
2226
23from quantum.plugins.cisco.common import cisco_configparser as confp27from quantum.plugins.cisco.common import cisco_configparser as confp
2428
25CONF_FILE = "../conf/nexus.ini"29CONF_FILE = "../conf/nexus.ini"
2630
27cp = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \31CP = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \
28 + "/" + CONF_FILE)32 + "/" + CONF_FILE)
2933
30section = cp['SWITCH']34SECTION = CP['SWITCH']
31NEXUS_IP_ADDRESS = section['nexus_ip_address']35NEXUS_IP_ADDRESS = SECTION['nexus_ip_address']
32NEXUS_PORT = section['nexus_port']36NEXUS_PORT = SECTION['nexus_port']
37NEXUS_SSH_PORT = SECTION['nexus_ssh_port']
3338
34section = cp['DRIVER']39SECTION = CP['DRIVER']
35NEXUS_DRIVER = section['name']40NEXUS_DRIVER = SECTION['name']
3641
=== modified file 'quantum/plugins/cisco/nexus/cisco_nexus_network_driver.py'
--- quantum/plugins/cisco/nexus/cisco_nexus_network_driver.py 2011-08-15 16:02:24 +0000
+++ quantum/plugins/cisco/nexus/cisco_nexus_network_driver.py 2011-08-23 20:09:26 +0000
@@ -22,11 +22,9 @@
22"""22"""
2323
24import logging as LOG24import logging as LOG
25import string
26import subprocess
2725
28from quantum.plugins.cisco.common import cisco_constants as const26from quantum.plugins.cisco.common import cisco_constants as const
29from quantum.plugins.cisco.common import cisco_exceptions as cexc27from quantum.plugins.cisco.nexus import cisco_nexus_snippets as snipp
3028
31from ncclient import manager29from ncclient import manager
3230
@@ -34,193 +32,101 @@
34LOG.getLogger(const.LOGGER_COMPONENT_NAME)32LOG.getLogger(const.LOGGER_COMPONENT_NAME)
3533
3634
37# The following are standard strings, messages used to communicate with Nexus,
38#only place holder values change for each message
39exec_conf_prefix = """
40 <config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
41 <configure xmlns="http://www.cisco.com/nxos:1.0:vlan_mgr_cli">
42 <__XML__MODE__exec_configure>
43"""
44
45
46exec_conf_postfix = """
47 </__XML__MODE__exec_configure>
48 </configure>
49 </config>
50"""
51
52
53cmd_vlan_conf_snippet = """
54 <vlan>
55 <vlan-id-create-delete>
56 <__XML__PARAM_value>%s</__XML__PARAM_value>
57 <__XML__MODE_vlan>
58 <name>
59 <vlan-name>%s</vlan-name>
60 </name>
61 <state>
62 <vstate>active</vstate>
63 </state>
64 <no>
65 <shutdown/>
66 </no>
67 </__XML__MODE_vlan>
68 </vlan-id-create-delete>
69 </vlan>
70"""
71
72cmd_no_vlan_conf_snippet = """
73 <no>
74 <vlan>
75 <vlan-id-create-delete>
76 <__XML__PARAM_value>%s</__XML__PARAM_value>
77 </vlan-id-create-delete>
78 </vlan>
79 </no>
80"""
81
82cmd_vlan_int_snippet = """
83 <interface>
84 <ethernet>
85 <interface>%s</interface>
86 <__XML__MODE_if-ethernet-switch>
87 <switchport></switchport>
88 <switchport>
89 <trunk>
90 <allowed>
91 <vlan>
92 <__XML__BLK_Cmd_switchport_trunk_allowed_allow-vlans>
93 <allow-vlans>%s</allow-vlans>
94 </__XML__BLK_Cmd_switchport_trunk_allowed_allow-vlans>
95 </vlan>
96 </allowed>
97 </trunk>
98 </switchport>
99 </__XML__MODE_if-ethernet-switch>
100 </ethernet>
101 </interface>
102"""
103
104cmd_port_trunk = """
105 <interface>
106 <ethernet>
107 <interface>%s</interface>
108 <__XML__MODE_if-ethernet-switch>
109 <switchport></switchport>
110 <switchport>
111 <mode>
112 <trunk>
113 </trunk>
114 </mode>
115 </switchport>
116 </__XML__MODE_if-ethernet-switch>
117 </ethernet>
118 </interface>
119"""
120
121cmd_no_switchport = """
122 <interface>
123 <ethernet>
124 <interface>%s</interface>
125 <__XML__MODE_if-ethernet-switch>
126 <no>
127 <switchport>
128 </switchport>
129 </no>
130 </__XML__MODE_if-ethernet-switch>
131 </ethernet>
132 </interface>
133"""
134
135
136cmd_no_vlan_int_snippet = """
137 <interface>
138 <ethernet>
139 <interface>%s</interface>
140 <__XML__MODE_if-ethernet-switch>
141 <switchport></switchport>
142 <no>
143 <switchport>
144 <trunk>
145 <allowed>
146 <vlan>
147 <__XML__BLK_Cmd_switchport_trunk_allowed_allow-vlans>
148 <allow-vlans>%s</allow-vlans>
149 </__XML__BLK_Cmd_switchport_trunk_allowed_allow-vlans>
150 </vlan>
151 </allowed>
152 </trunk>
153 </switchport>
154 </no>
155 </__XML__MODE_if-ethernet-switch>
156 </ethernet>
157 </interface>
158"""
159
160
161filter_show_vlan_brief_snippet = """
162 <show xmlns="http://www.cisco.com/nxos:1.0:vlan_mgr_cli">
163 <vlan>
164 <brief/>
165 </vlan>
166 </show> """
167
168
169class CiscoNEXUSDriver():35class CiscoNEXUSDriver():
17036 """
37 Nexus Driver Main Class
38 """
171 def __init__(self):39 def __init__(self):
172 pass40 pass
17341
174 def nxos_connect(self, nexus_host, port, nexus_user, nexus_password):42 def nxos_connect(self, nexus_host, nexus_ssh_port, nexus_user,
175 m = manager.connect(host=nexus_host, port=22, username=nexus_user,43 nexus_password):
176 password=nexus_password)44 """
177 return m45 Makes the SSH connection to the Nexus Switch
46 """
47 man = manager.connect(host=nexus_host, port=nexus_ssh_port,
48 username=nexus_user, password=nexus_password)
49 return man
50
51 def create_xml_snippet(self, cutomized_config):
52 """
53 Creates the Proper XML structure for the Nexus Switch Configuration
54 """
55 conf_xml_snippet = snipp.EXEC_CONF_SNIPPET % (cutomized_config)
56 return conf_xml_snippet
17857
179 def enable_vlan(self, mgr, vlanid, vlanname):58 def enable_vlan(self, mgr, vlanid, vlanname):
180 confstr = cmd_vlan_conf_snippet % (vlanid, vlanname)59 """
181 confstr = exec_conf_prefix + confstr + exec_conf_postfix60 Creates a VLAN on Nexus Switch given the VLAN ID and Name
61 """
62 confstr = snipp.CMD_VLAN_CONF_SNIPPET % (vlanid, vlanname)
63 confstr = self.create_xml_snippet(confstr)
182 mgr.edit_config(target='running', config=confstr)64 mgr.edit_config(target='running', config=confstr)
18365
184 def disable_vlan(self, mgr, vlanid):66 def disable_vlan(self, mgr, vlanid):
185 confstr = cmd_no_vlan_conf_snippet % vlanid67 """
186 confstr = exec_conf_prefix + confstr + exec_conf_postfix68 Delete a VLAN on Nexus Switch given the VLAN ID
69 """
70 confstr = snipp.CMD_NO_VLAN_CONF_SNIPPET % vlanid
71 confstr = self.create_xml_snippet(confstr)
187 mgr.edit_config(target='running', config=confstr)72 mgr.edit_config(target='running', config=confstr)
18873
189 def enable_port_trunk(self, mgr, interface):74 def enable_port_trunk(self, mgr, interface):
190 confstr = cmd_port_trunk % (interface)75 """
191 confstr = exec_conf_prefix + confstr + exec_conf_postfix76 Enables trunk mode an interface on Nexus Switch
192 print confstr77 """
78 confstr = snipp.CMD_PORT_TRUNK % (interface)
79 confstr = self.create_xml_snippet(confstr)
80 LOG.debug("NexusDriver: %s" % confstr)
193 mgr.edit_config(target='running', config=confstr)81 mgr.edit_config(target='running', config=confstr)
19482
195 def disable_switch_port(self, mgr, interface):83 def disable_switch_port(self, mgr, interface):
196 confstr = cmd_no_switchport % (interface)84 """
197 confstr = exec_conf_prefix + confstr + exec_conf_postfix85 Disables trunk mode an interface on Nexus Switch
198 print confstr86 """
87 confstr = snipp.CMD_NO_SWITCHPORT % (interface)
88 confstr = self.create_xml_snippet(confstr)
89 LOG.debug("NexusDriver: %s" % confstr)
199 mgr.edit_config(target='running', config=confstr)90 mgr.edit_config(target='running', config=confstr)
20091
201 def enable_vlan_on_trunk_int(self, mgr, interface, vlanid):92 def enable_vlan_on_trunk_int(self, mgr, interface, vlanid):
202 confstr = cmd_vlan_int_snippet % (interface, vlanid)93 """
203 confstr = exec_conf_prefix + confstr + exec_conf_postfix94 Enables trunk mode vlan access an interface on Nexus Switch given
204 print confstr95 VLANID
96 """
97 confstr = snipp.CMD_VLAN_INT_SNIPPET % (interface, vlanid)
98 confstr = self.create_xml_snippet(confstr)
99 LOG.debug("NexusDriver: %s" % confstr)
205 mgr.edit_config(target='running', config=confstr)100 mgr.edit_config(target='running', config=confstr)
206101
207 def disable_vlan_on_trunk_int(self, mgr, interface, vlanid):102 def disable_vlan_on_trunk_int(self, mgr, interface, vlanid):
208 confstr = cmd_no_vlan_int_snippet % (interface, vlanid)103 """
209 confstr = exec_conf_prefix + confstr + exec_conf_postfix104 Enables trunk mode vlan access an interface on Nexus Switch given
210 print confstr105 VLANID
106 """
107 confstr = snipp.CMD_NO_VLAN_INT_SNIPPET % (interface, vlanid)
108 confstr = self.create_xml_snippet(confstr)
109 LOG.debug("NexusDriver: %s" % confstr)
211 mgr.edit_config(target='running', config=confstr)110 mgr.edit_config(target='running', config=confstr)
212111
213 def create_vlan(self, vlan_name, vlan_id, nexus_host, nexus_user,112 def create_vlan(self, vlan_name, vlan_id, nexus_host, nexus_user,
214 nexus_password, nexus_interface):113 nexus_password, nexus_interface, nexus_ssh_port):
215 #TODO (Edgar) Move the SSH port to the configuration file114 """
216 with self.nxos_connect(nexus_host, 22, nexus_user,115 Creates a VLAN and Enable on trunk mode an interface on Nexus Switch
217 nexus_password) as m:116 given the VLAN ID and Name and Interface Number
218 self.enable_vlan(m, vlan_id, vlan_name)117 """
219 self.enable_vlan_on_trunk_int(m, nexus_interface, vlan_id)118 with self.nxos_connect(nexus_host, int(nexus_ssh_port), nexus_user,
119 nexus_password) as man:
120 self.enable_vlan(man, vlan_id, vlan_name)
121 self.enable_vlan_on_trunk_int(man, nexus_interface, vlan_id)
220122
221 def delete_vlan(self, vlan_id, nexus_host, nexus_user,123 def delete_vlan(self, vlan_id, nexus_host, nexus_user,
222 nexus_password, nexus_interface):124 nexus_password, nexus_interface, nexus_ssh_port):
223 with self.nxos_connect(nexus_host, 22, nexus_user,125 """
224 nexus_password) as m:126 Delete a VLAN and Disables trunk mode an interface on Nexus Switch
225 self.disable_vlan(m, vlan_id)127 given the VLAN ID and Interface Number
226 self.disable_switch_port(m, nexus_interface)128 """
129 with self.nxos_connect(nexus_host, int(nexus_ssh_port), nexus_user,
130 nexus_password) as man:
131 self.disable_vlan(man, vlan_id)
132 self.disable_switch_port(man, nexus_interface)
227133
=== modified file 'quantum/plugins/cisco/nexus/cisco_nexus_plugin.py'
--- quantum/plugins/cisco/nexus/cisco_nexus_plugin.py 2011-08-07 11:58:50 +0000
+++ quantum/plugins/cisco/nexus/cisco_nexus_plugin.py 2011-08-23 20:09:26 +0000
@@ -17,14 +17,15 @@
17# @author: Sumit Naiksatam, Cisco Systems, Inc.17# @author: Sumit Naiksatam, Cisco Systems, Inc.
18# @author: Edgar Magana, Cisco Systems, Inc.18# @author: Edgar Magana, Cisco Systems, Inc.
19#19#
20"""
21PlugIn for Nexus OS driver
22"""
20import logging as LOG23import logging as LOG
2124
22from quantum.common import exceptions as exc25from quantum.common import exceptions as exc
23from quantum.common import utils26from quantum.common import utils
24from quantum.plugins.cisco.common import cisco_constants as const27from quantum.plugins.cisco.common import cisco_constants as const
25from quantum.plugins.cisco.common import cisco_credentials as cred28from quantum.plugins.cisco.common import cisco_credentials as cred
26from quantum.plugins.cisco.common import cisco_exceptions as cexc
27from quantum.plugins.cisco.common import cisco_utils as cutil
28from quantum.plugins.cisco.l2device_plugin_base import L2DevicePluginBase29from quantum.plugins.cisco.l2device_plugin_base import L2DevicePluginBase
29from quantum.plugins.cisco.nexus import cisco_nexus_configuration as conf30from quantum.plugins.cisco.nexus import cisco_nexus_configuration as conf
3031
@@ -33,16 +34,22 @@
3334
3435
35class NexusPlugin(L2DevicePluginBase):36class NexusPlugin(L2DevicePluginBase):
37 """
38 Nexus PLugIn Main Class
39 """
36 _networks = {}40 _networks = {}
3741
38 def __init__(self):42 def __init__(self):
43 """
44 Extracts the configuration parameters from the configuration file
45 """
39 self._client = utils.import_object(conf.NEXUS_DRIVER)46 self._client = utils.import_object(conf.NEXUS_DRIVER)
40 LOG.debug("Loaded driver %s\n" % conf.NEXUS_DRIVER)47 LOG.debug("Loaded driver %s\n" % conf.NEXUS_DRIVER)
41 #TODO (Edgar) Using just one Nexus 7K Switch and Port
42 self._nexus_ip = conf.NEXUS_IP_ADDRESS48 self._nexus_ip = conf.NEXUS_IP_ADDRESS
43 self._nexus_username = cred.Store.getUsername(conf.NEXUS_IP_ADDRESS)49 self._nexus_username = cred.Store.getUsername(conf.NEXUS_IP_ADDRESS)
44 self._nexus_password = cred.Store.getPassword(conf.NEXUS_IP_ADDRESS)50 self._nexus_password = cred.Store.getPassword(conf.NEXUS_IP_ADDRESS)
45 self._nexus_port = conf.NEXUS_PORT51 self._nexus_port = conf.NEXUS_PORT
52 self._nexus_ssh_port = conf.NEXUS_SSH_PORT
4653
47 def get_all_networks(self, tenant_id):54 def get_all_networks(self, tenant_id):
48 """55 """
@@ -61,7 +68,8 @@
61 """68 """
62 LOG.debug("NexusPlugin:create_network() called\n")69 LOG.debug("NexusPlugin:create_network() called\n")
63 self._client.create_vlan(vlan_name, str(vlan_id), self._nexus_ip,70 self._client.create_vlan(vlan_name, str(vlan_id), self._nexus_ip,
64 self._nexus_username, self._nexus_password, self._nexus_port)71 self._nexus_username, self._nexus_password, self._nexus_port,
72 self._nexus_ssh_port)
6573
66 new_net_dict = {const.NET_ID: net_id,74 new_net_dict = {const.NET_ID: net_id,
67 const.NET_NAME: net_name,75 const.NET_NAME: net_name,
@@ -81,7 +89,8 @@
81 vlan_id = self._get_vlan_id_for_network(tenant_id, net_id)89 vlan_id = self._get_vlan_id_for_network(tenant_id, net_id)
82 if net:90 if net:
83 self._client.delete_vlan(str(vlan_id), self._nexus_ip,91 self._client.delete_vlan(str(vlan_id), self._nexus_ip,
84 self._nexus_username, self._nexus_password, self._nexus_port)92 self._nexus_username, self._nexus_password, self._nexus_port,
93 self._nexus_ssh_port)
85 self._networks.pop(net_id)94 self._networks.pop(net_id)
86 return net95 return net
87 # Network not found96 # Network not found
@@ -100,7 +109,6 @@
100 Updates the symbolic name belonging to a particular109 Updates the symbolic name belonging to a particular
101 Virtual Network.110 Virtual Network.
102 """111 """
103 #TODO (Edgar) We need to add an update method in the Nexus Driver
104 LOG.debug("NexusPlugin:rename_network() called\n")112 LOG.debug("NexusPlugin:rename_network() called\n")
105 network = self._get_network(tenant_id, net_id)113 network = self._get_network(tenant_id, net_id)
106 network[const.NET_NAME] = new_name114 network[const.NET_NAME] = new_name
@@ -157,11 +165,17 @@
157 LOG.debug("NexusPlugin:unplug_interface() called\n")165 LOG.debug("NexusPlugin:unplug_interface() called\n")
158166
159 def _get_vlan_id_for_network(self, tenant_id, network_id):167 def _get_vlan_id_for_network(self, tenant_id, network_id):
168 """
169 Obtain the VLAN ID given the Network ID
170 """
160 net = self._get_network(tenant_id, network_id)171 net = self._get_network(tenant_id, network_id)
161 vlan_id = net[const.NET_VLAN_ID]172 vlan_id = net[const.NET_VLAN_ID]
162 return vlan_id173 return vlan_id
163174
164 def _get_network(self, tenant_id, network_id):175 def _get_network(self, tenant_id, network_id):
176 """
177 Gets the NETWORK ID
178 """
165 network = self._networks.get(network_id)179 network = self._networks.get(network_id)
166 if not network:180 if not network:
167 raise exc.NetworkNotFound(net_id=network_id)181 raise exc.NetworkNotFound(net_id=network_id)
168182
=== added file 'quantum/plugins/cisco/nexus/cisco_nexus_snippets.py'
--- quantum/plugins/cisco/nexus/cisco_nexus_snippets.py 1970-01-01 00:00:00 +0000
+++ quantum/plugins/cisco/nexus/cisco_nexus_snippets.py 2011-08-23 20:09:26 +0000
@@ -0,0 +1,156 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
16#
17# @author: Edgar Magana, Cisco Systems, Inc.
18
19"""
20Nexus-OS XML-based configuration snippets
21"""
22
23import logging as LOG
24
25from quantum.plugins.cisco.common import cisco_constants as const
26
27LOG.basicConfig(level=LOG.WARN)
28LOG.getLogger(const.LOGGER_COMPONENT_NAME)
29
30
31# The following are standard strings, messages used to communicate with Nexus,
32EXEC_CONF_SNIPPET = """
33 <config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
34 <configure xmlns="http://www.cisco.com/nxos:1.0:vlan_mgr_cli">
35 <__XML__MODE__exec_configure>%s
36 </__XML__MODE__exec_configure>
37 </configure>
38 </config>
39"""
40
41
42CMD_VLAN_CONF_SNIPPET = """
43 <vlan>
44 <vlan-id-create-delete>
45 <__XML__PARAM_value>%s</__XML__PARAM_value>
46 <__XML__MODE_vlan>
47 <name>
48 <vlan-name>%s</vlan-name>
49 </name>
50 <state>
51 <vstate>active</vstate>
52 </state>
53 <no>
54 <shutdown/>
55 </no>
56 </__XML__MODE_vlan>
57 </vlan-id-create-delete>
58 </vlan>
59"""
60
61CMD_NO_VLAN_CONF_SNIPPET = """
62 <no>
63 <vlan>
64 <vlan-id-create-delete>
65 <__XML__PARAM_value>%s</__XML__PARAM_value>
66 </vlan-id-create-delete>
67 </vlan>
68 </no>
69"""
70
71CMD_VLAN_INT_SNIPPET = """
72 <interface>
73 <ethernet>
74 <interface>%s</interface>
75 <__XML__MODE_if-ethernet-switch>
76 <switchport></switchport>import logging as LOG
77 <switchport>
78 <trunk>
79 <allowed>
80 <vlan>
81 <__XML__BLK_Cmd_switchport_trunk_allowed_allow-vlans>
82 <allow-vlans>%s</allow-vlans>
83 </__XML__BLK_Cmd_switchport_trunk_allowed_allow-vlans>
84 </vlan>
85 </allowed>
86 </trunk>
87 </switchport>
88 </__XML__MODE_if-ethernet-switch>
89 </ethernet>
90 </interface>
91"""
92
93CMD_PORT_TRUNK = """
94 <interface>
95 <ethernet>
96 <interface>%s</interface>
97 <__XML__MODE_if-ethernet-switch>
98 <switchport></switchport>
99 <switchport>
100 <mode>
101 <trunk>
102 </trunk>
103 </mode>
104 </switchport>
105 </__XML__MODE_if-ethernet-switch>C: 1: Missing docstring
106 </ethernet>
107 </interface>
108"""
109
110CMD_NO_SWITCHPORT = """
111 <interface>
112 <ethernet>
113 <interface>%s</interface>
114 <__XML__MODE_if-ethernet-switch>
115 <no>
116 <switchport>
117 </switchport>
118 </no>
119 </__XML__MODE_if-ethernet-switch>
120 </ethernet>
121 </interface>
122"""
123
124
125CMD_NO_VLAN_INT_SNIPPET = """
126 <interface>
127 <ethernet>C: 1: Missing docstring
128 <interface>%s</interface>
129 <__XML__MODE_if-ethernet-switch>
130 <switchport></switchport>
131 <no>
132 <switchport>
133 <trunk>
134 <allowed>
135 <vlan>
136 <__XML__BLK_Cmd_switchport_trunk_allowed_allow-vlans>
137 <allow-vlans>%s</allow-vlans>
138 </__XML__BLK_Cmd_switchport_trunk_allowed_allow-vlans>
139 </vlan>
140 </allowed>
141 </trunk>
142 </switchport>
143 </no>
144 </__XML__MODE_if-ethernet-switch>
145 </ethernet>
146 </interface>
147"""
148
149
150FILTER_SHOW_VLAN_BRIEF_SNIPPET = """
151 <show xmlns="http://www.cisco.com/nxos:1.0:vlan_mgr_cli">
152 <vlan>
153 <brief/>
154 </vlan>
155 </show>
156"""
0157
=== modified file 'quantum/plugins/cisco/run_tests.py'
--- quantum/plugins/cisco/run_tests.py 2011-08-08 07:23:44 +0000
+++ quantum/plugins/cisco/run_tests.py 2011-08-23 20:09:26 +0000
@@ -16,50 +16,34 @@
16# See the License for the specific language governing permissions and16# See the License for the specific language governing permissions and
17# limitations under the License.17# limitations under the License.
1818
19# Colorizer Code is borrowed from Twisted:19
20# Copyright (c) 2001-2010 Twisted Matrix Laboratories.20"""Unittest runner for quantum Cisco plugin
21#21
22# Permission is hereby granted, free of charge, to any person obtaining22This file should be run from the top dir in the quantum directory
23# a copy of this software and associated documentation files (the
24# "Software"), to deal in the Software without restriction, including
25# without limitation the rights to use, copy, modify, merge, publish,
26# distribute, sublicense, and/or sell copies of the Software, and to
27# permit persons to whom the Software is furnished to do so, subject to
28# the following conditions:
29#
30# The above copyright notice and this permission notice shall be
31# included in all copies or substantial portions of the Software.
32#
33# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
35# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
37# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
38# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
39# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40
41"""Unittest runner for quantum
4223
43To run all test::24To run all test::
44 python run_tests.py25 python quantum/plugins/cisco/run_tests.py
4526
46To run all unit tests::27To run all unit tests::
47 python run_tests.py unit28 python quantum/plugins/cisco/run_tests.py quantum.plugins.cisco.tests.unit
4829
49To run all functional tests::30To run all functional tests::
50 python run_tests.py functional31 python quantum/plugins/cisco/run_tests.py functional
5132
52To run a single unit test::33To run a single unit test::
53 python run_tests.py unit.test_stores:TestSwiftBackend.test_get34 python quantum/plugins/cisco/run_tests.py \
35 quantum.plugins.cisco.tests.unit.test_stores:TestSwiftBackend.test_get
5436
55To run a single functional test::37To run a single functional test::
56 python run_tests.py functional.test_service:TestController.test_create38 python quantum/plugins/cisco/run_tests.py \
39 quantum.plugins.cisco.tests.functional.test_service \
40 :TestController.test_create
5741
58To run a single unit test module::42To run a single unit test module::
59 python run_tests.py unit.test_stores43 python quantum/plugins/cisco/run_tests.py unit.test_stores
6044
61To run a single functional test module::45To run a single functional test module::
62 python run_tests.py functional.test_stores46 python quantum/plugins/cisco/run_tests.py functional.test_stores
63"""47"""
6448
65import gettext49import gettext
@@ -69,233 +53,37 @@
69import sys53import sys
7054
71from nose import config55from nose import config
72from nose import result56
73from nose import core57sys.path.append(os.getcwd())
7458
7559from quantum.common.test_lib import run_tests, test_config
76class _AnsiColorizer(object):
77 """
78 A colorizer is an object that loosely wraps around a stream, allowing
79 callers to write text to the stream in a particular color.
80
81 Colorizer classes must implement C{supported()} and C{write(text, color)}.
82 """
83 _colors = dict(black=30, red=31, green=32, yellow=33,
84 blue=34, magenta=35, cyan=36, white=37)
85
86 def __init__(self, stream):
87 self.stream = stream
88
89 def supported(cls, stream=sys.stdout):
90 """
91 A class method that returns True if the current platform supports
92 coloring terminal output using this method. Returns False otherwise.
93 """
94 if not stream.isatty():
95 return False # auto color only on TTYs
96 try:
97 import curses
98 except ImportError:
99 return False
100 else:
101 try:
102 try:
103 return curses.tigetnum("colors") > 2
104 except curses.error:
105 curses.setupterm()
106 return curses.tigetnum("colors") > 2
107 except:
108 raise
109 # guess false in case of error
110 return False
111 supported = classmethod(supported)
112
113 def write(self, text, color):
114 """
115 Write the given text to the stream in the given color.
116
117 @param text: Text to be written to the stream.
118
119 @param color: A string label for a color. e.g. 'red', 'white'.
120 """
121 color = self._colors[color]
122 self.stream.write('\x1b[%s;1m%s\x1b[0m' % (color, text))
123
124
125class _Win32Colorizer(object):
126 """
127 See _AnsiColorizer docstring.
128 """
129 def __init__(self, stream):
130 from win32console import GetStdHandle, STD_OUT_HANDLE, \
131 FOREGROUND_RED, FOREGROUND_BLUE, FOREGROUND_GREEN, \
132 FOREGROUND_INTENSITY
133 red, green, blue, bold = (FOREGROUND_RED, FOREGROUND_GREEN,
134 FOREGROUND_BLUE, FOREGROUND_INTENSITY)
135 self.stream = stream
136 self.screenBuffer = GetStdHandle(STD_OUT_HANDLE)
137 self._colors = {
138 'normal': red | green | blue,
139 'red': red | bold,
140 'green': green | bold,
141 'blue': blue | bold,
142 'yellow': red | green | bold,
143 'magenta': red | blue | bold,
144 'cyan': green | blue | bold,
145 'white': red | green | blue | bold}
146
147 def supported(cls, stream=sys.stdout):
148 try:
149 import win32console
150 screenBuffer = win32console.GetStdHandle(
151 win32console.STD_OUT_HANDLE)
152 except ImportError:
153 return False
154 import pywintypes
155 try:
156 screenBuffer.SetConsoleTextAttribute(
157 win32console.FOREGROUND_RED |
158 win32console.FOREGROUND_GREEN |
159 win32console.FOREGROUND_BLUE)
160 except pywintypes.error:
161 return False
162 else:
163 return True
164 supported = classmethod(supported)
165
166 def write(self, text, color):
167 color = self._colors[color]
168 self.screenBuffer.SetConsoleTextAttribute(color)
169 self.stream.write(text)
170 self.screenBuffer.SetConsoleTextAttribute(self._colors['normal'])
171
172
173class _NullColorizer(object):
174 """
175 See _AnsiColorizer docstring.
176 """
177 def __init__(self, stream):
178 self.stream = stream
179
180 def supported(cls, stream=sys.stdout):
181 return True
182 supported = classmethod(supported)
183
184 def write(self, text, color):
185 self.stream.write(text)
186
187
188class QuantumTestResult(result.TextTestResult):
189 def __init__(self, *args, **kw):
190 result.TextTestResult.__init__(self, *args, **kw)
191 self._last_case = None
192 self.colorizer = None
193 # NOTE(vish, tfukushima): reset stdout for the terminal check
194 stdout = sys.__stdout__
195 for colorizer in [_Win32Colorizer, _AnsiColorizer, _NullColorizer]:
196 if colorizer.supported():
197 self.colorizer = colorizer(self.stream)
198 break
199 sys.stdout = stdout
200
201 def getDescription(self, test):
202 return str(test)
203
204 # NOTE(vish, tfukushima): copied from unittest with edit to add color
205 def addSuccess(self, test):
206 unittest.TestResult.addSuccess(self, test)
207 if self.showAll:
208 self.colorizer.write("OK", 'green')
209 self.stream.writeln()
210 elif self.dots:
211 self.stream.write('.')
212 self.stream.flush()
213
214 # NOTE(vish, tfukushima): copied from unittest with edit to add color
215 def addFailure(self, test, err):
216 unittest.TestResult.addFailure(self, test, err)
217 if self.showAll:
218 self.colorizer.write("FAIL", 'red')
219 self.stream.writeln()
220 elif self.dots:
221 self.stream.write('F')
222 self.stream.flush()
223
224 # NOTE(vish, tfukushima): copied from unittest with edit to add color
225 def addError(self, test, err):
226 """Overrides normal addError to add support for errorClasses.
227 If the exception is a registered class, the error will be added
228 to the list for that class, not errors.
229 """
230 stream = getattr(self, 'stream', None)
231 ec, ev, tb = err
232 try:
233 exc_info = self._exc_info_to_string(err, test)
234 except TypeError:
235 # This is for compatibility with Python 2.3.
236 exc_info = self._exc_info_to_string(err)
237 for cls, (storage, label, isfail) in self.errorClasses.items():
238 if result.isclass(ec) and issubclass(ec, cls):
239 if isfail:
240 test.passwd = False
241 storage.append((test, exc_info))
242 # Might get patched into a streamless result
243 if stream is not None:
244 if self.showAll:
245 message = [label]
246 detail = result._exception_details(err[1])
247 if detail:
248 message.append(detail)
249 stream.writeln(": ".join(message))
250 elif self.dots:
251 stream.write(label[:1])
252 return
253 self.errors.append((test, exc_info))
254 test.passed = False
255 if stream is not None:
256 if self.showAll:
257 self.colorizer.write("ERROR", 'red')
258 self.stream.writeln()
259 elif self.dots:
260 stream.write('E')
261
262 def startTest(self, test):
263 unittest.TestResult.startTest(self, test)
264 current_case = test.test.__class__.__name__
265
266 if self.showAll:
267 if current_case != self._last_case:
268 self.stream.writeln(current_case)
269 self._last_case = current_case
270
271 self.stream.write(
272 ' %s' % str(test.test._testMethodName).ljust(60))
273 self.stream.flush()
274
275
276class QuantumTestRunner(core.TextTestRunner):
277 def _makeResult(self):
278 return QuantumTestResult(self.stream,
279 self.descriptions,
280 self.verbosity,
281 self.config)
282
28360
284if __name__ == '__main__':61if __name__ == '__main__':
285 # Set up test logger.62 exit_status = False
286 logger = logging.getLogger()63
287 hdlr = logging.StreamHandler()64 # if a single test case was specified,
288 formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')65 # we should only invoked the tests once
289 hdlr.setFormatter(formatter)66 invoke_once = len(sys.argv) > 1
290 logger.addHandler(hdlr)67
291 logger.setLevel(logging.DEBUG)68 cwd = os.getcwd()
29269
293 working_dir = os.path.abspath("tests")70 working_dir = os.path.abspath("tests")
294 c = config.Config(stream=sys.stdout,71 c = config.Config(stream=sys.stdout,
295 env=os.environ,72 env=os.environ,
296 verbosity=3,73 verbosity=3,
297 workingDir=working_dir)74 workingDir=working_dir)
298 runner = QuantumTestRunner(stream=c.stream,75 exit_status = run_tests(c)
299 verbosity=c.verbosity,76
300 config=c)77 if invoke_once:
301 sys.exit(not core.run(config=c, testRunner=runner))78 sys.exit(0)
79
80 os.chdir(cwd)
81
82 working_dir = os.path.abspath("quantum/plugins/cisco/tests")
83 c = config.Config(stream=sys.stdout,
84 env=os.environ,
85 verbosity=3,
86 workingDir=working_dir)
87 exit_status = exit_status or run_tests(c)
88
89 sys.exit(exit_status)
30290
=== added file 'quantum/plugins/cisco/tests/unit/test_database.py'
--- quantum/plugins/cisco/tests/unit/test_database.py 1970-01-01 00:00:00 +0000
+++ quantum/plugins/cisco/tests/unit/test_database.py 2011-08-23 20:09:26 +0000
@@ -0,0 +1,840 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2011, Cisco Systems, Inc.
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
16# @author: Rohit Agarwalla, Cisco Systems, Inc.
17
18"""
19test_database.py is an independent test suite
20that tests the database api method calls
21"""
22import logging as LOG
23import unittest
24
25from quantum.plugins.cisco.common import cisco_constants as const
26
27import quantum.plugins.cisco.db.api as db
28import quantum.plugins.cisco.db.l2network_db as l2network_db
29
30
31LOG.getLogger(const.LOGGER_COMPONENT_NAME)
32
33
34class L2networkDB(object):
35 """Class conisting of methods to call L2network db methods"""
36 def get_all_vlan_bindings(self):
37 """Get all vlan binding into a list of dict"""
38 vlans = []
39 try:
40 for vlan_bind in l2network_db.get_all_vlan_bindings():
41 LOG.debug("Getting vlan bindings for vlan: %s" % \
42 vlan_bind.vlan_id)
43 vlan_dict = {}
44 vlan_dict["vlan-id"] = str(vlan_bind.vlan_id)
45 vlan_dict["vlan-name"] = vlan_bind.vlan_name
46 vlan_dict["net-id"] = str(vlan_bind.network_id)
47 vlans.append(vlan_dict)
48 except Exception, exc:
49 LOG.error("Failed to get all vlan bindings: %s" % str(exc))
50 return vlans
51
52 def get_vlan_binding(self, network_id):
53 """Get a vlan binding"""
54 vlan = []
55 try:
56 for vlan_bind in l2network_db.get_vlan_binding(network_id):
57 LOG.debug("Getting vlan binding for vlan: %s" \
58 % vlan_bind.vlan_id)
59 vlan_dict = {}
60 vlan_dict["vlan-id"] = str(vlan_bind.vlan_id)
61 vlan_dict["vlan-name"] = vlan_bind.vlan_name
62 vlan_dict["net-id"] = str(vlan_bind.network_id)
63 vlan.append(vlan_dict)
64 except Exception, exc:
65 LOG.error("Failed to get vlan binding: %s" % str(exc))
66 return vlan
67
68 def create_vlan_binding(self, vlan_id, vlan_name, network_id):
69 """Create a vlan binding"""
70 vlan_dict = {}
71 try:
72 res = l2network_db.add_vlan_binding(vlan_id, vlan_name, network_id)
73 LOG.debug("Created vlan binding for vlan: %s" % res.vlan_id)
74 vlan_dict["vlan-id"] = str(res.vlan_id)
75 vlan_dict["vlan-name"] = res.vlan_name
76 vlan_dict["net-id"] = str(res.network_id)
77 return vlan_dict
78 except Exception, exc:
79 LOG.error("Failed to create vlan binding: %s" % str(exc))
80
81 def delete_vlan_binding(self, network_id):
82 """Delete a vlan binding"""
83 try:
84 res = l2network_db.remove_vlan_binding(network_id)
85 LOG.debug("Deleted vlan binding for vlan: %s" % res.vlan_id)
86 vlan_dict = {}
87 vlan_dict["vlan-id"] = str(res.vlan_id)
88 return vlan_dict
89 except Exception, exc:
90 raise Exception("Failed to delete vlan binding: %s" % str(exc))
91
92 def update_vlan_binding(self, network_id, vlan_id, vlan_name):
93 """Update a vlan binding"""
94 try:
95 res = l2network_db.update_vlan_binding(network_id, vlan_id, \
96 vlan_name)
97 LOG.debug("Updating vlan binding for vlan: %s" % res.vlan_id)
98 vlan_dict = {}
99 vlan_dict["vlan-id"] = str(res.vlan_id)
100 vlan_dict["vlan-name"] = res.vlan_name
101 vlan_dict["net-id"] = str(res.network_id)
102 return vlan_dict
103 except Exception, exc:
104 raise Exception("Failed to update vlan binding: %s" % str(exc))
105
106 def get_all_portprofiles(self):
107 """Get all portprofiles"""
108 pps = []
109 try:
110 for portprof in l2network_db.get_all_portprofiles():
111 LOG.debug("Getting port profile : %s" % portprof.uuid)
112 pp_dict = {}
113 pp_dict["portprofile-id"] = str(portprof.uuid)
114 pp_dict["portprofile-name"] = portprof.name
115 pp_dict["vlan-id"] = str(portprof.vlan_id)
116 pp_dict["qos"] = portprof.qos
117 pps.append(pp_dict)
118 except Exception, exc:
119 LOG.error("Failed to get all port profiles: %s" % str(exc))
120 return pps
121
122 def get_portprofile(self, tenant_id, pp_id):
123 """Get a portprofile"""
124 pp_list = []
125 try:
126 for portprof in l2network_db.get_portprofile(tenant_id, pp_id):
127 LOG.debug("Getting port profile : %s" % portprof.uuid)
128 pp_dict = {}
129 pp_dict["portprofile-id"] = str(portprof.uuid)
130 pp_dict["portprofile-name"] = portprof.name
131 pp_dict["vlan-id"] = str(portprof.vlan_id)
132 pp_dict["qos"] = portprof.qos
133 pp_list.append(pp_dict)
134 except Exception, exc:
135 LOG.error("Failed to get port profile: %s" % str(exc))
136 return pp
137
138 def create_portprofile(self, tenant_id, name, vlan_id, qos):
139 """Create a portprofile"""
140 pp_dict = {}
141 try:
142 res = l2network_db.add_portprofile(tenant_id, name, vlan_id, qos)
143 LOG.debug("Created port profile: %s" % res.uuid)
144 pp_dict["portprofile-id"] = str(res.uuid)
145 pp_dict["portprofile-name"] = res.name
146 pp_dict["vlan-id"] = str(res.vlan_id)
147 pp_dict["qos"] = res.qos
148 return pp_dict
149 except Exception, exc:
150 LOG.error("Failed to create port profile: %s" % str(exc))
151
152 def delete_portprofile(self, tenant_id, pp_id):
153 """Delete a portprofile"""
154 try:
155 res = l2network_db.remove_portprofile(tenant_id, pp_id)
156 LOG.debug("Deleted port profile : %s" % res.uuid)
157 pp_dict = {}
158 pp_dict["pp-id"] = str(res.uuid)
159 return pp_dict
160 except Exception, exc:
161 raise Exception("Failed to delete port profile: %s" % str(exc))
162
163 def update_portprofile(self, tenant_id, pp_id, name, vlan_id, qos):
164 """Update a portprofile"""
165 try:
166 res = l2network_db.update_portprofile(tenant_id, pp_id, name,
167 vlan_id, qos)
168 LOG.debug("Updating port profile : %s" % res.uuid)
169 pp_dict = {}
170 pp_dict["portprofile-id"] = str(res.uuid)
171 pp_dict["portprofile-name"] = res.name
172 pp_dict["vlan-id"] = str(res.vlan_id)
173 pp_dict["qos"] = res.qos
174 return pp_dict
175 except Exception, exc:
176 raise Exception("Failed to update port profile: %s" % str(exc))
177
178 def get_all_pp_bindings(self):
179 """Get all portprofile bindings"""
180 pp_bindings = []
181 try:
182 for pp_bind in l2network_db.get_all_pp_bindings():
183 LOG.debug("Getting port profile binding: %s" % \
184 pp_bind.portprofile_id)
185 ppbinding_dict = {}
186 ppbinding_dict["portprofile-id"] = str(pp_bind.portprofile_id)
187 ppbinding_dict["port-id"] = str(pp_bind.port_id)
188 ppbinding_dict["tenant-id"] = pp_bind.tenant_id
189 ppbinding_dict["default"] = pp_bind.default
190 pp_bindings.append(ppbinding_dict)
191 except Exception, exc:
192 LOG.error("Failed to get all port profiles: %s" % str(exc))
193 return pp_bindings
194
195 def get_pp_binding(self, tenant_id, pp_id):
196 """Get a portprofile binding"""
197 pp_binding = []
198 try:
199 for pp_bind in l2network_db.get_pp_binding(tenant_id, pp_id):
200 LOG.debug("Getting port profile binding: %s" % \
201 pp_bind.portprofile_id)
202 ppbinding_dict = {}
203 ppbinding_dict["portprofile-id"] = str(pp_bind.portprofile_id)
204 ppbinding_dict["port-id"] = str(pp_bind.port_id)
205 ppbinding_dict["tenant-id"] = pp_bind.tenant_id
206 ppbinding_dict["default"] = pp_bind.default
207 pp_binding.append(ppbinding_dict)
208 except Exception, exc:
209 LOG.error("Failed to get port profile binding: %s" % str(exc))
210 return pp_binding
211
212 def create_pp_binding(self, tenant_id, port_id, pp_id, default):
213 """Add a portprofile binding"""
214 ppbinding_dict = {}
215 try:
216 res = l2network_db.add_pp_binding(tenant_id, port_id, pp_id, \
217 default)
218 LOG.debug("Created port profile binding: %s" % res.portprofile_id)
219 ppbinding_dict["portprofile-id"] = str(res.portprofile_id)
220 ppbinding_dict["port-id"] = str(res.port_id)
221 ppbinding_dict["tenant-id"] = res.tenant_id
222 ppbinding_dict["default"] = res.default
223 return ppbinding_dict
224 except Exception, exc:
225 LOG.error("Failed to create port profile binding: %s" % str(exc))
226
227 def delete_pp_binding(self, tenant_id, port_id, pp_id):
228 """Delete a portprofile binding"""
229 try:
230 res = l2network_db.remove_pp_binding(tenant_id, port_id, pp_id)
231 LOG.debug("Deleted port profile binding : %s" % res.portprofile_id)
232 ppbinding_dict = {}
233 ppbinding_dict["portprofile-id"] = str(res.portprofile_id)
234 return ppbinding_dict
235 except Exception, exc:
236 raise Exception("Failed to delete port profile: %s" % str(exc))
237
238 def update_pp_binding(self, tenant_id, pp_id, newtenant_id, \
239 port_id, default):
240 """Update portprofile binding"""
241 try:
242 res = l2network_db.update_pp_binding(tenant_id, pp_id,
243 newtenant_id, port_id, default)
244 LOG.debug("Updating port profile binding: %s" % res.portprofile_id)
245 ppbinding_dict = {}
246 ppbinding_dict["portprofile-id"] = str(res.portprofile_id)
247 ppbinding_dict["port-id"] = str(res.port_id)
248 ppbinding_dict["tenant-id"] = res.tenant_id
249 ppbinding_dict["default"] = res.default
250 return ppbinding_dict
251 except Exception, exc:
252 raise Exception("Failed to update portprofile binding:%s" \
253 % str(exc))
254
255
256class QuantumDB(object):
257 """Class conisting of methods to call Quantum db methods"""
258 def get_all_networks(self, tenant_id):
259 """Get all networks"""
260 nets = []
261 try:
262 for net in db.network_list(tenant_id):
263 LOG.debug("Getting network: %s" % net.uuid)
264 net_dict = {}
265 net_dict["tenant-id"] = net.tenant_id
266 net_dict["net-id"] = str(net.uuid)
267 net_dict["net-name"] = net.name
268 nets.append(net_dict)
269 except Exception, exc:
270 LOG.error("Failed to get all networks: %s" % str(exc))
271 return nets
272
273 def get_network(self, network_id):
274 """Get a network"""
275 net = []
276 try:
277 for net in db.network_get(network_id):
278 LOG.debug("Getting network: %s" % net.uuid)
279 net_dict = {}
280 net_dict["tenant-id"] = net.tenant_id
281 net_dict["net-id"] = str(net.uuid)
282 net_dict["net-name"] = net.name
283 net.append(net_dict)
284 except Exception, exc:
285 LOG.error("Failed to get network: %s" % str(exc))
286 return net
287
288 def create_network(self, tenant_id, net_name):
289 """Create a network"""
290 net_dict = {}
291 try:
292 res = db.network_create(tenant_id, net_name)
293 LOG.debug("Created network: %s" % res.uuid)
294 net_dict["tenant-id"] = res.tenant_id
295 net_dict["net-id"] = str(res.uuid)
296 net_dict["net-name"] = res.name
297 return net_dict
298 except Exception, exc:
299 LOG.error("Failed to create network: %s" % str(exc))
300
301 def delete_network(self, net_id):
302 """Delete a network"""
303 try:
304 net = db.network_destroy(net_id)
305 LOG.debug("Deleted network: %s" % net.uuid)
306 net_dict = {}
307 net_dict["net-id"] = str(net.uuid)
308 return net_dict
309 except Exception, exc:
310 raise Exception("Failed to delete port: %s" % str(exc))
311
312 def rename_network(self, tenant_id, net_id, new_name):
313 """Rename a network"""
314 try:
315 net = db.network_rename(tenant_id, net_id, new_name)
316 LOG.debug("Renamed network: %s" % net.uuid)
317 net_dict = {}
318 net_dict["net-id"] = str(net.uuid)
319 net_dict["net-name"] = net.name
320 return net_dict
321 except Exception, exc:
322 raise Exception("Failed to rename network: %s" % str(exc))
323
324 def get_all_ports(self, net_id):
325 """Get all ports"""
326 ports = []
327 try:
328 for port in db.port_list(net_id):
329 LOG.debug("Getting port: %s" % port.uuid)
330 port_dict = {}
331 port_dict["port-id"] = str(port.uuid)
332 port_dict["net-id"] = str(port.network_id)
333 port_dict["int-id"] = port.interface_id
334 port_dict["state"] = port.state
335 port_dict["net"] = port.network
336 ports.append(port_dict)
337 return ports
338 except Exception, exc:
339 LOG.error("Failed to get all ports: %s" % str(exc))
340
341 def get_port(self, net_id, port_id):
342 """Get a port"""
343 port_list = []
344 port = db.port_get(net_id, port_id)
345 try:
346 LOG.debug("Getting port: %s" % port.uuid)
347 port_dict = {}
348 port_dict["port-id"] = str(port.uuid)
349 port_dict["net-id"] = str(port.network_id)
350 port_dict["int-id"] = port.interface_id
351 port_dict["state"] = port.state
352 port_list.append(port_dict)
353 return port_list
354 except Exception, exc:
355 LOG.error("Failed to get port: %s" % str(exc))
356
357 def create_port(self, net_id):
358 """Add a port"""
359 port_dict = {}
360 try:
361 port = db.port_create(net_id)
362 LOG.debug("Creating port %s" % port.uuid)
363 port_dict["port-id"] = str(port.uuid)
364 port_dict["net-id"] = str(port.network_id)
365 port_dict["int-id"] = port.interface_id
366 port_dict["state"] = port.state
367 return port_dict
368 except Exception, exc:
369 LOG.error("Failed to create port: %s" % str(exc))
370
371 def delete_port(self, net_id, port_id):
372 """Delete a port"""
373 try:
374 port = db.port_destroy(net_id, port_id)
375 LOG.debug("Deleted port %s" % port.uuid)
376 port_dict = {}
377 port_dict["port-id"] = str(port.uuid)
378 return port_dict
379 except Exception, exc:
380 raise Exception("Failed to delete port: %s" % str(exc))
381
382 def update_port(self, net_id, port_id, port_state):
383 """Update a port"""
384 try:
385 port = db.port_set_state(net_id, port_id, port_state)
386 LOG.debug("Updated port %s" % port.uuid)
387 port_dict = {}
388 port_dict["port-id"] = str(port.uuid)
389 port_dict["net-id"] = str(port.network_id)
390 port_dict["int-id"] = port.interface_id
391 port_dict["state"] = port.state
392 return port_dict
393 except Exception, exc:
394 raise Exception("Failed to update port state: %s" % str(exc))
395
396 def plug_interface(self, net_id, port_id, int_id):
397 """Plug interface to a port"""
398 try:
399 port = db.port_set_attachment(net_id, port_id, int_id)
400 LOG.debug("Attached interface to port %s" % port.uuid)
401 port_dict = {}
402 port_dict["port-id"] = str(port.uuid)
403 port_dict["net-id"] = str(port.network_id)
404 port_dict["int-id"] = port.interface_id
405 port_dict["state"] = port.state
406 return port_dict
407 except Exception, exc:
408 raise Exception("Failed to plug interface: %s" % str(exc))
409
410 def unplug_interface(self, net_id, port_id):
411 """Unplug interface to a port"""
412 try:
413 port = db.port_unset_attachment(net_id, port_id)
414 LOG.debug("Detached interface from port %s" % port.uuid)
415 port_dict = {}
416 port_dict["port-id"] = str(port.uuid)
417 port_dict["net-id"] = str(port.network_id)
418 port_dict["int-id"] = port.interface_id
419 port_dict["state"] = port.state
420 return port_dict
421 except Exception, exc:
422 raise Exception("Failed to unplug interface: %s" % str(exc))
423
424
425class L2networkDBTest(unittest.TestCase):
426 """Class conisting of L2network DB unit tests"""
427 def setUp(self):
428 """Setup for tests"""
429 l2network_db.initialize()
430 self.dbtest = L2networkDB()
431 self.quantum = QuantumDB()
432 LOG.debug("Setup")
433
434 def tearDown(self):
435 """Tear Down"""
436 db.clear_db()
437
438 def testa_create_vlanbinding(self):
439 """test add vlan binding"""
440 net1 = self.quantum.create_network("t1", "netid1")
441 vlan1 = self.dbtest.create_vlan_binding(10, "vlan1", net1["net-id"])
442 self.assertTrue(vlan1["vlan-id"] == "10")
443 self.teardown_vlanbinding()
444 self.teardown_network()
445
446 def testb_getall_vlanbindings(self):
447 """test get all vlan binding"""
448 net1 = self.quantum.create_network("t1", "netid1")
449 net2 = self.quantum.create_network("t1", "netid2")
450 vlan1 = self.dbtest.create_vlan_binding(10, "vlan1", net1["net-id"])
451 self.assertTrue(vlan1["vlan-id"] == "10")
452 vlan2 = self.dbtest.create_vlan_binding(20, "vlan2", net2["net-id"])
453 self.assertTrue(vlan2["vlan-id"] == "20")
454 vlans = self.dbtest.get_all_vlan_bindings()
455 count = 0
456 for vlan in vlans:
457 if "vlan" in vlan["vlan-name"]:
458 count += 1
459 self.assertTrue(count == 2)
460 self.teardown_vlanbinding()
461 self.teardown_network()
462
463 def testc_delete_vlanbinding(self):
464 """test delete vlan binding"""
465 net1 = self.quantum.create_network("t1", "netid1")
466 vlan1 = self.dbtest.create_vlan_binding(10, "vlan1", net1["net-id"])
467 self.assertTrue(vlan1["vlan-id"] == "10")
468 self.dbtest.delete_vlan_binding(net1["net-id"])
469 vlans = self.dbtest.get_all_vlan_bindings()
470 count = 0
471 for vlan in vlans:
472 if "vlan " in vlan["vlan-name"]:
473 count += 1
474 self.assertTrue(count == 0)
475 self.teardown_vlanbinding()
476 self.teardown_network()
477
478 def testd_update_vlanbinding(self):
479 """test update vlan binding"""
480 net1 = self.quantum.create_network("t1", "netid1")
481 vlan1 = self.dbtest.create_vlan_binding(10, "vlan1", net1["net-id"])
482 self.assertTrue(vlan1["vlan-id"] == "10")
483 vlan1 = self.dbtest.update_vlan_binding(net1["net-id"], 11, "newvlan1")
484 vlans = self.dbtest.get_all_vlan_bindings()
485 count = 0
486 for vlan in vlans:
487 if "new" in vlan["vlan-name"]:
488 count += 1
489 self.assertTrue(count == 1)
490 self.teardown_vlanbinding()
491 self.teardown_network()
492
493 def teste_create_portprofile(self):
494 """test add port profile"""
495 pp1 = self.dbtest.create_portprofile("t1", "portprofile1", 10, "qos1")
496 self.assertTrue(pp1["portprofile-name"] == "portprofile1")
497 self.teardown_portprofile()
498 self.teardown_network()
499
500 def testf_getall_portprofile(self):
501 """test get all portprofiles"""
502 pp1 = self.dbtest.create_portprofile("t1", "portprofile1", 10, "qos1")
503 self.assertTrue(pp1["portprofile-name"] == "portprofile1")
504 pp2 = self.dbtest.create_portprofile("t1", "portprofile2", 20, "qos2")
505 self.assertTrue(pp2["portprofile-name"] == "portprofile2")
506 pps = self.dbtest.get_all_portprofiles()
507 count = 0
508 for pprofile in pps:
509 if "portprofile" in pprofile["portprofile-name"]:
510 count += 1
511 self.assertTrue(count == 2)
512 self.teardown_portprofile()
513
514 def testg_delete_portprofile(self):
515 """test delete portprofile"""
516 pp1 = self.dbtest.create_portprofile("t1", "portprofile1", 10, "qos1")
517 self.assertTrue(pp1["portprofile-name"] == "portprofile1")
518 self.dbtest.delete_portprofile("t1", pp1["portprofile-id"])
519 pps = self.dbtest.get_all_portprofiles()
520 count = 0
521 for pprofile in pps:
522 if "portprofile " in pprofile["portprofile-name"]:
523 count += 1
524 self.assertTrue(count == 0)
525 self.teardown_portprofile()
526
527 def testh_update_portprofile(self):
528 """test update portprofile"""
529 pp1 = self.dbtest.create_portprofile("t1", "portprofile1", 10, "qos1")
530 self.assertTrue(pp1["portprofile-name"] == "portprofile1")
531 pp1 = self.dbtest.update_portprofile("t1", pp1["portprofile-id"], \
532 "newportprofile1", 20, "qos2")
533 pps = self.dbtest.get_all_portprofiles()
534 count = 0
535 for pprofile in pps:
536 if "new" in pprofile["portprofile-name"]:
537 count += 1
538 self.assertTrue(count == 1)
539 self.teardown_portprofile()
540
541 def testi_create_portprofilebinding(self):
542 """test create portprofile binding"""
543 net1 = self.quantum.create_network("t1", "netid1")
544 port1 = self.quantum.create_port(net1["net-id"])
545 pp1 = self.dbtest.create_portprofile("t1", "portprofile1", 10, "qos1")
546 pp_binding1 = self.dbtest.create_pp_binding("t1", port1["port-id"], \
547 pp1["portprofile-id"], "0")
548 self.assertTrue(pp_binding1["tenant-id"] == "t1")
549 self.teardown_portprofilebinding()
550 self.teardown_port()
551 self.teardown_network()
552 self.teardown_portprofile()
553
554 def testj_getall_portprofilebinding(self):
555 """test get all portprofile binding"""
556 net1 = self.quantum.create_network("t1", "netid1")
557 port1 = self.quantum.create_port(net1["net-id"])
558 port2 = self.quantum.create_port(net1["net-id"])
559 pp1 = self.dbtest.create_portprofile("t1", "portprofile1", 10, "qos1")
560 pp2 = self.dbtest.create_portprofile("t1", "portprofile2", 20, "qos2")
561 pp_binding1 = self.dbtest.create_pp_binding("t1", port1["port-id"], \
562 pp1["portprofile-id"], "0")
563 self.assertTrue(pp_binding1["tenant-id"] == "t1")
564 pp_binding2 = self.dbtest.create_pp_binding("t1", port2["port-id"], \
565 pp2["portprofile-id"], "0")
566 self.assertTrue(pp_binding2["tenant-id"] == "t1")
567 pp_bindings = self.dbtest.get_all_pp_bindings()
568 count = 0
569 for pp_bind in pp_bindings:
570 if "t1" in pp_bind["tenant-id"]:
571 count += 1
572 self.assertTrue(count == 2)
573 self.teardown_portprofilebinding()
574 self.teardown_port()
575 self.teardown_network()
576 self.teardown_portprofile()
577
578 def testk_delete_portprofilebinding(self):
579 """test delete portprofile binding"""
580 net1 = self.quantum.create_network("t1", "netid1")
581 port1 = self.quantum.create_port(net1["net-id"])
582 pp1 = self.dbtest.create_portprofile("t1", "portprofile1", 10, "qos1")
583 pp_binding1 = self.dbtest.create_pp_binding("t1", port1["port-id"], \
584 pp1["portprofile-id"], "0")
585 self.assertTrue(pp_binding1["tenant-id"] == "t1")
586 self.dbtest.delete_pp_binding("t1", port1["port-id"], \
587 pp_binding1["portprofile-id"])
588 pp_bindings = self.dbtest.get_all_pp_bindings()
589 count = 0
590 for pp_bind in pp_bindings:
591 if "t1 " in pp_bind["tenant-id"]:
592 count += 1
593 self.assertTrue(count == 0)
594 self.teardown_portprofilebinding()
595 self.teardown_port()
596 self.teardown_network()
597 self.teardown_portprofile()
598
599 def testl_update_portprofilebinding(self):
600 """test update portprofile binding"""
601 net1 = self.quantum.create_network("t1", "netid1")
602 port1 = self.quantum.create_port(net1["net-id"])
603 pp1 = self.dbtest.create_portprofile("t1", "portprofile1", 10, "qos1")
604 pp_binding1 = self.dbtest.create_pp_binding("t1", port1["port-id"], \
605 pp1["portprofile-id"], "0")
606 self.assertTrue(pp_binding1["tenant-id"] == "t1")
607 pp_binding1 = self.dbtest.update_pp_binding("t1", \
608 pp1["portprofile-id"], "newt1", port1["port-id"], "1")
609 pp_bindings = self.dbtest.get_all_pp_bindings()
610 count = 0
611 for pp_bind in pp_bindings:
612 if "new" in pp_bind["tenant-id"]:
613 count += 1
614 self.assertTrue(count == 1)
615 self.teardown_portprofilebinding()
616 self.teardown_port()
617 self.teardown_network()
618 self.teardown_portprofile()
619
620 def testm_test_vlanids(self):
621 """test vlanid methods"""
622 l2network_db.create_vlanids()
623 vlanids = l2network_db.get_all_vlanids()
624 self.assertTrue(len(vlanids) > 0)
625 vlanid = l2network_db.reserve_vlanid()
626 used = l2network_db.is_vlanid_used(vlanid)
627 self.assertTrue(used == True)
628 used = l2network_db.release_vlanid(vlanid)
629 self.assertTrue(used == False)
630 self.teardown_vlanid()
631
632 def teardown_network(self):
633 """tearDown Network table"""
634 LOG.debug("Tearing Down Network")
635 nets = self.quantum.get_all_networks("t1")
636 for net in nets:
637 netid = net["net-id"]
638 self.quantum.delete_network(netid)
639
640 def teardown_port(self):
641 """tearDown Port table"""
642 LOG.debug("Tearing Down Port")
643 nets = self.quantum.get_all_networks("t1")
644 for net in nets:
645 netid = net["net-id"]
646 ports = self.quantum.get_all_ports(netid)
647 for port in ports:
648 portid = port["port-id"]
649 self.quantum.delete_port(netid, portid)
650
651 def teardown_vlanbinding(self):
652 """tearDown VlanBinding table"""
653 LOG.debug("Tearing Down Vlan Binding")
654 vlans = self.dbtest.get_all_vlan_bindings()
655 for vlan in vlans:
656 netid = vlan["net-id"]
657 self.dbtest.delete_vlan_binding(netid)
658
659 def teardown_portprofile(self):
660 """tearDown PortProfile table"""
661 LOG.debug("Tearing Down Port Profile")
662 pps = self.dbtest.get_all_portprofiles()
663 for pprofile in pps:
664 ppid = pprofile["portprofile-id"]
665 self.dbtest.delete_portprofile("t1", ppid)
666
667 def teardown_portprofilebinding(self):
668 """tearDown PortProfileBinding table"""
669 LOG.debug("Tearing Down Port Profile Binding")
670 pp_bindings = self.dbtest.get_all_pp_bindings()
671 for pp_binding in pp_bindings:
672 ppid = pp_binding["portprofile-id"]
673 portid = pp_binding["port-id"]
674 self.dbtest.delete_pp_binding("t1", portid, ppid)
675
676 def teardown_vlanid(self):
677 """tearDown VlanID table"""
678 LOG.debug("Tearing Down Vlan IDs")
679 vlanids = l2network_db.get_all_vlanids()
680 for vlanid in vlanids:
681 vlan_id = vlanid["vlan_id"]
682 l2network_db.delete_vlanid(vlan_id)
683
684
685class QuantumDBTest(unittest.TestCase):
686 """Class conisting of Quantum DB unit tests"""
687 def setUp(self):
688 """Setup for tests"""
689 l2network_db.initialize()
690 self.dbtest = QuantumDB()
691 self.tenant_id = "t1"
692 LOG.debug("Setup")
693
694 def tearDown(self):
695 """Tear Down"""
696 db.clear_db()
697
698 def testa_create_network(self):
699 """test to create network"""
700 net1 = self.dbtest.create_network(self.tenant_id, "plugin_test1")
701 self.assertTrue(net1["net-name"] == "plugin_test1")
702 self.teardown_network_port()
703
704 def testb_get_networks(self):
705 """test to get all networks"""
706 net1 = self.dbtest.create_network(self.tenant_id, "plugin_test1")
707 self.assertTrue(net1["net-name"] == "plugin_test1")
708 net2 = self.dbtest.create_network(self.tenant_id, "plugin_test2")
709 self.assertTrue(net2["net-name"] == "plugin_test2")
710 nets = self.dbtest.get_all_networks(self.tenant_id)
711 count = 0
712 for net in nets:
713 if "plugin_test" in net["net-name"]:
714 count += 1
715 self.assertTrue(count == 2)
716 self.teardown_network_port()
717
718 def testc_delete_network(self):
719 """test to delete network"""
720 net1 = self.dbtest.create_network(self.tenant_id, "plugin_test1")
721 self.assertTrue(net1["net-name"] == "plugin_test1")
722 self.dbtest.delete_network(net1["net-id"])
723 nets = self.dbtest.get_all_networks(self.tenant_id)
724 count = 0
725 for net in nets:
726 if "plugin_test1" in net["net-name"]:
727 count += 1
728 self.assertTrue(count == 0)
729 self.teardown_network_port()
730
731 def testd_rename_network(self):
732 """test to rename network"""
733 net1 = self.dbtest.create_network(self.tenant_id, "plugin_test1")
734 self.assertTrue(net1["net-name"] == "plugin_test1")
735 net = self.dbtest.rename_network(self.tenant_id, net1["net-id"],
736 "plugin_test1_renamed")
737 self.assertTrue(net["net-name"] == "plugin_test1_renamed")
738 self.teardown_network_port()
739
740 def teste_create_port(self):
741 """test to create port"""
742 net1 = self.dbtest.create_network(self.tenant_id, "plugin_test1")
743 port = self.dbtest.create_port(net1["net-id"])
744 self.assertTrue(port["net-id"] == net1["net-id"])
745 ports = self.dbtest.get_all_ports(net1["net-id"])
746 count = 0
747 for por in ports:
748 count += 1
749 self.assertTrue(count == 1)
750 self.teardown_network_port()
751
752 def testf_delete_port(self):
753 """test to delete port"""
754 net1 = self.dbtest.create_network(self.tenant_id, "plugin_test1")
755 port = self.dbtest.create_port(net1["net-id"])
756 self.assertTrue(port["net-id"] == net1["net-id"])
757 ports = self.dbtest.get_all_ports(net1["net-id"])
758 count = 0
759 for por in ports:
760 count += 1
761 self.assertTrue(count == 1)
762 for por in ports:
763 self.dbtest.delete_port(net1["net-id"], por["port-id"])
764 ports = self.dbtest.get_all_ports(net1["net-id"])
765 count = 0
766 for por in ports:
767 count += 1
768 self.assertTrue(count == 0)
769 self.teardown_network_port()
770
771 def testg_plug_unplug_interface(self):
772 """test to plug/unplug interface"""
773 net1 = self.dbtest.create_network(self.tenant_id, "plugin_test1")
774 port1 = self.dbtest.create_port(net1["net-id"])
775 self.dbtest.plug_interface(net1["net-id"], port1["port-id"], "vif1.1")
776 port = self.dbtest.get_port(net1["net-id"], port1["port-id"])
777 self.assertTrue(port[0]["int-id"] == "vif1.1")
778 self.dbtest.unplug_interface(net1["net-id"], port1["port-id"])
779 port = self.dbtest.get_port(net1["net-id"], port1["port-id"])
780 self.assertTrue(port[0]["int-id"] == None)
781 self.teardown_network_port()
782
783 def testh_joined_test(self):
784 """test to get network and port"""
785 net1 = self.dbtest.create_network("t1", "net1")
786 port1 = self.dbtest.create_port(net1["net-id"])
787 self.assertTrue(port1["net-id"] == net1["net-id"])
788 port2 = self.dbtest.create_port(net1["net-id"])
789 self.assertTrue(port2["net-id"] == net1["net-id"])
790 ports = self.dbtest.get_all_ports(net1["net-id"])
791 for port in ports:
792 net = port["net"]
793 LOG.debug("Port id %s Net id %s" % (port["port-id"], net.uuid))
794 self.teardown_joined_test()
795
796 def teardown_network_port(self):
797 """tearDown for Network and Port table"""
798 networks = self.dbtest.get_all_networks(self.tenant_id)
799 for net in networks:
800 netid = net["net-id"]
801 name = net["net-name"]
802 if "plugin_test" in name:
803 ports = self.dbtest.get_all_ports(netid)
804 for por in ports:
805 self.dbtest.delete_port(netid, por["port-id"])
806 self.dbtest.delete_network(netid)
807
808 def teardown_joined_test(self):
809 """tearDown for joined Network and Port test"""
810 LOG.debug("Tearing Down Network and Ports")
811 nets = self.dbtest.get_all_networks("t1")
812 for net in nets:
813 netid = net["net-id"]
814 ports = self.dbtest.get_all_ports(netid)
815 for port in ports:
816 self.dbtest.delete_port(port["net-id"], port["port-id"])
817 self.dbtest.delete_network(netid)
818
819"""
820if __name__ == "__main__":
821 usagestr = "Usage: %prog [OPTIONS] <command> [args]"
822 parser = OptionParser(usage=usagestr)
823 parser.add_option("-v", "--verbose", dest="verbose",
824 action="store_true", default=False, help="turn on verbose logging")
825
826 options, args = parser.parse_args()
827
828 if options.verbose:
829 LOG.basicConfig(level=LOG.DEBUG)
830 else:
831 LOG.basicConfig(level=LOG.WARN)
832
833 l2network_db.initialize()
834
835 # Run the tests
836 suite = unittest.TestLoader().loadTestsFromTestCase(QuantumDBTest)
837 unittest.TextTestRunner(verbosity=2).run(suite)
838 suite = unittest.TestLoader().loadTestsFromTestCase(L2networkDBTest)
839 unittest.TextTestRunner(verbosity=2).run(suite)
840"""
0841
=== modified file 'quantum/plugins/cisco/tests/unit/test_l2networkApi.py'
--- quantum/plugins/cisco/tests/unit/test_l2networkApi.py 2011-08-08 07:23:44 +0000
+++ quantum/plugins/cisco/tests/unit/test_l2networkApi.py 2011-08-23 20:09:26 +0000
@@ -24,6 +24,8 @@
24from quantum.plugins.cisco.common import cisco_exceptions as cexc24from quantum.plugins.cisco.common import cisco_exceptions as cexc
25from quantum.plugins.cisco import l2network_plugin25from quantum.plugins.cisco import l2network_plugin
26from quantum.plugins.cisco import l2network_plugin_configuration as conf26from quantum.plugins.cisco import l2network_plugin_configuration as conf
27from quantum.plugins.cisco.db import api as db
28from quantum.plugins.cisco.db import l2network_db as cdb
2729
28LOG = logging.getLogger('quantum.tests.test_core_api_func')30LOG = logging.getLogger('quantum.tests.test_core_api_func')
2931
@@ -47,6 +49,8 @@
47 network_name = self.network_name49 network_name = self.network_name
48 new_net_dict = self._l2network_plugin.create_network(50 new_net_dict = self._l2network_plugin.create_network(
49 tenant_id, network_name)51 tenant_id, network_name)
52 net = db.network_get(new_net_dict[const.NET_ID])
53 self.assertEqual(net[const.NETWORKNAME], network_name)
50 self.assertEqual(new_net_dict[const.NET_NAME], network_name)54 self.assertEqual(new_net_dict[const.NET_NAME], network_name)
51 self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])55 self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
52 LOG.debug("test_create_network - END")56 LOG.debug("test_create_network - END")
@@ -64,6 +68,8 @@
64 tenant_id, self.network_name)68 tenant_id, self.network_name)
65 delete_net_dict = self._l2network_plugin.delete_network(69 delete_net_dict = self._l2network_plugin.delete_network(
66 tenant_id, new_net_dict[const.NET_ID])70 tenant_id, new_net_dict[const.NET_ID])
71 self.assertRaises(exc.NetworkNotFound, db.network_get,
72 new_net_dict[const.NET_ID])
67 self.assertEqual(73 self.assertEqual(
68 new_net_dict[const.NET_ID], delete_net_dict[const.NET_ID])74 new_net_dict[const.NET_ID], delete_net_dict[const.NET_ID])
69 LOG.debug("test_delete_network - END")75 LOG.debug("test_delete_network - END")
@@ -117,6 +123,8 @@
117 tenant_id, self.network_name)123 tenant_id, self.network_name)
118 result_net_dict = self._l2network_plugin.get_network_details(124 result_net_dict = self._l2network_plugin.get_network_details(
119 tenant_id, new_net_dict[const.NET_ID])125 tenant_id, new_net_dict[const.NET_ID])
126 net = db.network_get(new_net_dict[const.NET_ID])
127 self.assertEqual(net[const.UUID], new_net_dict[const.NET_ID])
120 self.assertEqual(128 self.assertEqual(
121 new_net_dict[const.NET_ID], result_net_dict[const.NET_ID])129 new_net_dict[const.NET_ID], result_net_dict[const.NET_ID])
122 self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])130 self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
@@ -152,6 +160,8 @@
152 tenant_id, self.network_name)160 tenant_id, self.network_name)
153 rename_net_dict = self._l2network_plugin.rename_network(161 rename_net_dict = self._l2network_plugin.rename_network(
154 tenant_id, new_net_dict[const.NET_ID], new_name)162 tenant_id, new_net_dict[const.NET_ID], new_name)
163 net = db.network_get(new_net_dict[const.NET_ID])
164 self.assertEqual(net[const.NETWORKNAME], new_name)
155 self.assertEqual(new_name, rename_net_dict[const.NET_NAME])165 self.assertEqual(new_name, rename_net_dict[const.NET_NAME])
156 self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])166 self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
157 LOG.debug("test_rename_network - END")167 LOG.debug("test_rename_network - END")
@@ -184,9 +194,18 @@
184 tenant_id, 'test_net2')194 tenant_id, 'test_net2')
185 net_list = self._l2network_plugin.get_all_networks(tenant_id)195 net_list = self._l2network_plugin.get_all_networks(tenant_id)
186 net_temp_list = [new_net_dict, new_net_dict2]196 net_temp_list = [new_net_dict, new_net_dict2]
197 networks_list = db.network_list(tenant_id)
198 new_networks_list = []
199 for network in networks_list:
200 new_network_dict = self._make_net_dict(network[const.UUID],
201 network[const.NETWORKNAME],
202 [])
203 new_networks_list.append(new_network_dict)
187 self.assertEqual(len(net_list), 2)204 self.assertEqual(len(net_list), 2)
188 self.assertTrue(net_list[0] in net_temp_list)205 self.assertTrue(net_list[0] in net_temp_list)
189 self.assertTrue(net_list[1] in net_temp_list)206 self.assertTrue(net_list[1] in net_temp_list)
207 self.assertTrue(new_networks_list[0] in net_temp_list)
208 self.assertTrue(new_networks_list[1] in net_temp_list)
190 self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])209 self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
191 self.tearDownNetwork(tenant_id, new_net_dict2[const.NET_ID])210 self.tearDownNetwork(tenant_id, new_net_dict2[const.NET_ID])
192 LOG.debug("test_list_networks - END")211 LOG.debug("test_list_networks - END")
@@ -206,9 +225,20 @@
206 port_list = self._l2network_plugin.get_all_ports(225 port_list = self._l2network_plugin.get_all_ports(
207 tenant_id, new_net_dict[const.NET_ID])226 tenant_id, new_net_dict[const.NET_ID])
208 port_temp_list = [port_dict, port_dict2]227 port_temp_list = [port_dict, port_dict2]
228 network = db.network_get(new_net_dict[const.NET_ID])
229 ports_list = network[const.NETWORKPORTS]
230 ports_on_net = []
231 for port in ports_list:
232 new_port = self._make_port_dict(port[const.UUID],
233 port[const.PORTSTATE],
234 port[const.NETWORKID],
235 port[const.INTERFACEID])
236 ports_on_net.append(new_port)
209 self.assertEqual(len(port_list), 2)237 self.assertEqual(len(port_list), 2)
210 self.assertTrue(port_list[0] in port_temp_list)238 self.assertTrue(port_list[0] in port_temp_list)
211 self.assertTrue(port_list[1] in port_temp_list)239 self.assertTrue(port_list[1] in port_temp_list)
240 self.assertTrue(ports_on_net[0] in port_temp_list)
241 self.assertTrue(ports_on_net[1] in port_temp_list)
212242
213 self.tearDownPortOnly(tenant_id, new_net_dict[const.NET_ID],243 self.tearDownPortOnly(tenant_id, new_net_dict[const.NET_ID],
214 port_dict[const.PORT_ID])244 port_dict[const.PORT_ID])
@@ -227,7 +257,12 @@
227 tenant_id, self.network_name)257 tenant_id, self.network_name)
228 port_dict = self._l2network_plugin.create_port(258 port_dict = self._l2network_plugin.create_port(
229 tenant_id, new_net_dict[const.NET_ID], port_state)259 tenant_id, new_net_dict[const.NET_ID], port_state)
260 port = db.port_get(new_net_dict[const.NET_ID],
261 port_dict[const.PORT_ID])
230 self.assertEqual(port_dict[const.PORT_STATE], port_state)262 self.assertEqual(port_dict[const.PORT_STATE], port_state)
263 self.assertEqual(port_dict[const.NET_ID], new_net_dict[const.NET_ID])
264 self.assertEqual(port[const.PORTSTATE], port_state)
265 self.assertEqual(port[const.NETWORKID], new_net_dict[const.NET_ID])
231 self.tearDownNetworkPort(tenant_id, new_net_dict[const.NET_ID],266 self.tearDownNetworkPort(tenant_id, new_net_dict[const.NET_ID],
232 port_dict[const.PORT_ID])267 port_dict[const.PORT_ID])
233 LOG.debug("test_create_port - END")268 LOG.debug("test_create_port - END")
@@ -263,8 +298,11 @@
263 delete_port_dict = self._l2network_plugin.delete_port(298 delete_port_dict = self._l2network_plugin.delete_port(
264 tenant_id, new_net_dict[const.NET_ID],299 tenant_id, new_net_dict[const.NET_ID],
265 port_dict[const.PORT_ID])300 port_dict[const.PORT_ID])
301 self.assertRaises(exc.PortNotFound, db.port_get,
302 new_net_dict[const.NET_ID], port_dict[const.PORT_ID])
266 self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])303 self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
267 self.assertEqual(delete_port_dict, None)304 self.assertEqual(delete_port_dict[const.PORT_ID],
305 port_dict[const.PORT_ID])
268 LOG.debug("test_delete_port - END")306 LOG.debug("test_delete_port - END")
269307
270 def test_delete_port_networkDNE(self, tenant_id='test_tenant',308 def test_delete_port_networkDNE(self, tenant_id='test_tenant',
@@ -327,6 +365,9 @@
327 update_port_dict = self._l2network_plugin.update_port(365 update_port_dict = self._l2network_plugin.update_port(
328 tenant_id, new_net_dict[const.NET_ID],366 tenant_id, new_net_dict[const.NET_ID],
329 port_dict[const.PORT_ID], port_state)367 port_dict[const.PORT_ID], port_state)
368 new_port = db.port_get(new_net_dict[const.NET_ID],
369 port_dict[const.PORT_ID])
370 self.assertEqual(new_port[const.PORTSTATE], port_state)
330 self.assertEqual(update_port_dict[const.PORT_STATE], port_state)371 self.assertEqual(update_port_dict[const.PORT_STATE], port_state)
331 self.tearDownNetworkPort(tenant_id, new_net_dict[const.NET_ID],372 self.tearDownNetworkPort(tenant_id, new_net_dict[const.NET_ID],
332 port_dict[const.PORT_ID])373 port_dict[const.PORT_ID])
@@ -341,7 +382,7 @@
341 LOG.debug("test_update_port_networkDNE - START")382 LOG.debug("test_update_port_networkDNE - START")
342 self.assertRaises(exc.NetworkNotFound,383 self.assertRaises(exc.NetworkNotFound,
343 self._l2network_plugin.update_port, tenant_id,384 self._l2network_plugin.update_port, tenant_id,
344 net_id, port_id, self.port_state)385 net_id, port_id, const.PORT_UP)
345 LOG.debug("test_update_port_networkDNE - END")386 LOG.debug("test_update_port_networkDNE - END")
346387
347 def test_update_portDNE(self, tenant_id='test_tenant', port_id='p0005'):388 def test_update_portDNE(self, tenant_id='test_tenant', port_id='p0005'):
@@ -354,7 +395,7 @@
354 tenant_id, self.network_name)395 tenant_id, self.network_name)
355 self.assertRaises(396 self.assertRaises(
356 exc.PortNotFound, self._l2network_plugin.update_port, tenant_id,397 exc.PortNotFound, self._l2network_plugin.update_port, tenant_id,
357 new_net_dict[const.NET_ID], port_id, self.port_state)398 new_net_dict[const.NET_ID], port_id, const.PORT_UP)
358 self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])399 self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
359 LOG.debug("test_update_portDNE - END")400 LOG.debug("test_update_portDNE - END")
360401
@@ -371,6 +412,9 @@
371 get_port_dict = self._l2network_plugin.get_port_details(412 get_port_dict = self._l2network_plugin.get_port_details(
372 tenant_id, new_net_dict[const.NET_ID],413 tenant_id, new_net_dict[const.NET_ID],
373 port_dict[const.PORT_ID])414 port_dict[const.PORT_ID])
415 port = db.port_get(new_net_dict[const.NET_ID],
416 port_dict[const.PORT_ID])
417 self.assertEqual(port[const.PORTSTATE], self.port_state)
374 self.assertEqual(get_port_dict[const.PORT_STATE], self.port_state)418 self.assertEqual(get_port_dict[const.PORT_STATE], self.port_state)
375 self.tearDownNetworkPort(tenant_id, new_net_dict[const.NET_ID],419 self.tearDownNetworkPort(tenant_id, new_net_dict[const.NET_ID],
376 port_dict[const.PORT_ID])420 port_dict[const.PORT_ID])
@@ -416,10 +460,9 @@
416 self._l2network_plugin.plug_interface(460 self._l2network_plugin.plug_interface(
417 tenant_id, new_net_dict[const.NET_ID],461 tenant_id, new_net_dict[const.NET_ID],
418 port_dict[const.PORT_ID], remote_interface)462 port_dict[const.PORT_ID], remote_interface)
419 self.assertEqual(463 port = db.port_get(new_net_dict[const.NET_ID],
420 self._l2network_plugin._networks[new_net_dict[const.NET_ID]]464 port_dict[const.PORT_ID])
421 [const.NET_PORTS][port_dict[const.PORT_ID]]465 self.assertEqual(port[const.INTERFACEID], remote_interface)
422 [const.ATTACHMENT], remote_interface)
423 self.tearDownNetworkPortInterface(466 self.tearDownNetworkPortInterface(
424 tenant_id, new_net_dict[const.NET_ID],467 tenant_id, new_net_dict[const.NET_ID],
425 port_dict[const.PORT_ID])468 port_dict[const.PORT_ID])
@@ -470,7 +513,7 @@
470 self._l2network_plugin.plug_interface(513 self._l2network_plugin.plug_interface(
471 tenant_id, new_net_dict[const.NET_ID],514 tenant_id, new_net_dict[const.NET_ID],
472 port_dict[const.PORT_ID], remote_interface)515 port_dict[const.PORT_ID], remote_interface)
473 self.assertRaises(exc.AlreadyAttached,516 self.assertRaises(exc.PortInUse,
474 self._l2network_plugin.plug_interface, tenant_id,517 self._l2network_plugin.plug_interface, tenant_id,
475 new_net_dict[const.NET_ID],518 new_net_dict[const.NET_ID],
476 port_dict[const.PORT_ID], remote_interface)519 port_dict[const.PORT_ID], remote_interface)
@@ -496,9 +539,9 @@
496 self._l2network_plugin.unplug_interface(539 self._l2network_plugin.unplug_interface(
497 tenant_id, new_net_dict[const.NET_ID],540 tenant_id, new_net_dict[const.NET_ID],
498 port_dict[const.PORT_ID])541 port_dict[const.PORT_ID])
499 self.assertEqual(self._l2network_plugin._networks542 port = db.port_get(new_net_dict[const.NET_ID],
500 [new_net_dict[const.NET_ID]][const.NET_PORTS]543 port_dict[const.PORT_ID])
501 [port_dict[const.PORT_ID]][const.ATTACHMENT], None)544 self.assertEqual(port[const.INTERFACEID], None)
502 self.tearDownNetworkPort(tenant_id, new_net_dict[const.NET_ID],545 self.tearDownNetworkPort(tenant_id, new_net_dict[const.NET_ID],
503 port_dict[const.PORT_ID])546 port_dict[const.PORT_ID])
504 LOG.debug("test_unplug_interface - END")547 LOG.debug("test_unplug_interface - END")
@@ -533,7 +576,7 @@
533 LOG.debug("test_unplug_interface_portDNE - END")576 LOG.debug("test_unplug_interface_portDNE - END")
534577
535 def test_create_portprofile(self, net_tenant_id=None,578 def test_create_portprofile(self, net_tenant_id=None,
536 net_profile_name=None, net_vlan_id=None):579 net_profile_name=None, net_qos=None):
537 """580 """
538 Tests creation of a port-profile581 Tests creation of a port-profile
539 """582 """
@@ -548,19 +591,16 @@
548 profile_name = net_profile_name591 profile_name = net_profile_name
549 else:592 else:
550 profile_name = self.profile_name593 profile_name = self.profile_name
551 if net_vlan_id:594 if net_qos:
552 vlan_id = net_vlan_id595 qos = net_qos
553 else:596 else:
554 vlan_id = self.vlan_id597 qos = self.qos
555 port_profile_dict = self._l2network_plugin.create_portprofile(598 port_profile_dict = self._l2network_plugin.create_portprofile(
556 tenant_id, profile_name, vlan_id)599 tenant_id, profile_name, qos)
557 port_profile_id = port_profile_dict['profile-id']600 port_profile_id = port_profile_dict['profile-id']
558 self.assertEqual(601 port_profile = cdb.get_portprofile(tenant_id, port_profile_id)
559 self._l2network_plugin._portprofiles[port_profile_id]['vlan-id'],602 self.assertEqual(port_profile[const.PPNAME], profile_name)
560 vlan_id)603 self.assertEqual(port_profile[const.PPQOS], qos)
561 self.assertEqual(
562 self._l2network_plugin._portprofiles[port_profile_id]
563 ['profile-name'], profile_name)
564 self.tearDownPortProfile(tenant_id, port_profile_id)604 self.tearDownPortProfile(tenant_id, port_profile_id)
565 LOG.debug("test_create_portprofile - tenant id: %s - END",605 LOG.debug("test_create_portprofile - tenant id: %s - END",
566 net_tenant_id)606 net_tenant_id)
@@ -577,10 +617,10 @@
577 else:617 else:
578 tenant_id = self.tenant_id618 tenant_id = self.tenant_id
579 port_profile_dict = self._l2network_plugin.create_portprofile(619 port_profile_dict = self._l2network_plugin.create_portprofile(
580 tenant_id, self.profile_name, self.vlan_id)620 tenant_id, self.profile_name, self.qos)
581 port_profile_id = port_profile_dict['profile-id']621 port_profile_id = port_profile_dict['profile-id']
582 self._l2network_plugin.delete_portprofile(tenant_id, port_profile_id)622 self._l2network_plugin.delete_portprofile(tenant_id, port_profile_id)
583 self.assertEqual(self._l2network_plugin._portprofiles, {})623 self.assertRaises(Exception, cdb.get_portprofile, port_profile_id)
584 LOG.debug("test_delete_portprofile - tenant id: %s - END",624 LOG.debug("test_delete_portprofile - tenant id: %s - END",
585 net_tenant_id)625 net_tenant_id)
586626
@@ -604,15 +644,23 @@
604644
605 LOG.debug("test_delete_portprofileAssociated - START")645 LOG.debug("test_delete_portprofileAssociated - START")
606 port_profile_dict = self._l2network_plugin.create_portprofile(646 port_profile_dict = self._l2network_plugin.create_portprofile(
607 tenant_id, self.profile_name, self.vlan_id)647 tenant_id, self.profile_name, self.qos)
608 port_profile_id = port_profile_dict['profile-id']648 port_profile_id = port_profile_dict['profile-id']
649 new_net_dict = self._l2network_plugin.create_network(
650 tenant_id, 'test_network')
651 port_dict = self._l2network_plugin.create_port(
652 tenant_id, new_net_dict[const.NET_ID], 'const.PORT_UP')
609 self._l2network_plugin.associate_portprofile(653 self._l2network_plugin.associate_portprofile(
610 tenant_id, self.net_id, self.port_id, port_profile_id)654 tenant_id, new_net_dict[const.NET_ID],
655 port_dict[const.PORT_ID], port_profile_id)
611 self.assertRaises(cexc.PortProfileInvalidDelete,656 self.assertRaises(cexc.PortProfileInvalidDelete,
612 self._l2network_plugin.delete_portprofile,657 self._l2network_plugin.delete_portprofile,
613 tenant_id, port_profile_id)658 tenant_id, port_profile_id)
614 self.tearDownAssociatePortProfile(tenant_id, self.net_id,659 self.tearDownAssociatePortProfile(
615 self.port_id, port_profile_id)660 tenant_id, new_net_dict[const.NET_ID],
661 port_dict[const.PORT_ID], port_profile_id)
662 self.tearDownNetworkPort(tenant_id, new_net_dict[const.NET_ID],
663 port_dict[const.PORT_ID])
616 LOG.debug("test_delete_portprofileAssociated - END")664 LOG.debug("test_delete_portprofileAssociated - END")
617665
618 def test_list_portprofile(self, tenant_id='test_tenant'):666 def test_list_portprofile(self, tenant_id='test_tenant'):
@@ -622,24 +670,30 @@
622670
623 LOG.debug("test_list_portprofile - tenant id: %s - START", tenant_id)671 LOG.debug("test_list_portprofile - tenant id: %s - START", tenant_id)
624 profile_name2 = tenant_id + '_port_profile2'672 profile_name2 = tenant_id + '_port_profile2'
625 vlan_id2 = tenant_id + '201'673 qos2 = tenant_id + 'qos2'
626 port_profile_dict1 = self._l2network_plugin.create_portprofile(674 port_profile_dict1 = self._l2network_plugin.create_portprofile(
627 tenant_id, self.profile_name, self.vlan_id)675 tenant_id, self.profile_name, self.qos)
628 port_profile_dict2 = self._l2network_plugin.create_portprofile(676 port_profile_dict2 = self._l2network_plugin.create_portprofile(
629 tenant_id, profile_name2, vlan_id2)677 tenant_id, profile_name2, qos2)
630 port_profile_id1 = port_profile_dict1['profile-id']678 port_profile_id1 = port_profile_dict1['profile-id']
631 port_profile_id2 = port_profile_dict2['profile-id']679 port_profile_id2 = port_profile_dict2['profile-id']
632 list_all_portprofiles = self._l2network_plugin.get_all_portprofiles(680 list_all_portprofiles = self._l2network_plugin.get_all_portprofiles(
633 tenant_id)681 tenant_id)
634 self.assertEqual(self._l2network_plugin._portprofiles682 port_profile_list = [port_profile_dict1, port_profile_dict2]
635 [port_profile_id1]['vlan-id'], self.vlan_id)683 pplist = cdb.get_all_portprofiles()
636 self.assertEqual(self._l2network_plugin._portprofiles684 new_pplist = []
637 [port_profile_id1]['profile-name'], self.profile_name)685 for pp in pplist:
638 self.assertEqual(self._l2network_plugin._portprofiles686 new_pp = self._make_portprofile_dict(tenant_id,
639 [port_profile_id2]['vlan-id'], vlan_id2)687 pp[const.UUID],
640 self.assertEqual(self._l2network_plugin._portprofiles688 pp[const.PPNAME],
641 [port_profile_id2]['profile-name'], profile_name2)689 pp[const.PPQOS])
642 LOG.debug("test_create_portprofile - tenant id: %s - END", tenant_id)690 new_pplist.append(new_pp)
691 self.assertTrue(new_pplist[0] in port_profile_list)
692 self.assertTrue(new_pplist[1] in port_profile_list)
693 self.tearDownPortProfile(tenant_id, port_profile_id1)
694 self.tearDownPortProfile(tenant_id, port_profile_id2)
695
696 LOG.debug("test_list_portprofile - tenant id: %s - END", tenant_id)
643697
644 def test_show_portprofile(self, net_tenant_id=None):698 def test_show_portprofile(self, net_tenant_id=None):
645 """699 """
@@ -652,12 +706,15 @@
652 else:706 else:
653 tenant_id = self.tenant_id707 tenant_id = self.tenant_id
654 port_profile_dict = self._l2network_plugin.create_portprofile(708 port_profile_dict = self._l2network_plugin.create_portprofile(
655 tenant_id, self.profile_name, self.vlan_id)709 tenant_id, self.profile_name, self.qos)
656 port_profile_id = port_profile_dict['profile-id']710 port_profile_id = port_profile_dict['profile-id']
657 result_port_profile = self._l2network_plugin.get_portprofile_details(711 result_port_profile = self._l2network_plugin.get_portprofile_details(
658 tenant_id, port_profile_id)712 tenant_id, port_profile_id)
659 self.assertEqual(result_port_profile[const.PROFILE_VLAN_ID],713 port_profile = cdb.get_portprofile(tenant_id, port_profile_id)
660 self.vlan_id)714 self.assertEqual(port_profile[const.PPQOS], self.qos)
715 self.assertEqual(port_profile[const.PPNAME], self.profile_name)
716 self.assertEqual(result_port_profile[const.PROFILE_QOS],
717 self.qos)
661 self.assertEqual(result_port_profile[const.PROFILE_NAME],718 self.assertEqual(result_port_profile[const.PROFILE_NAME],
662 self.profile_name)719 self.profile_name)
663 self.tearDownPortProfile(tenant_id, port_profile_id)720 self.tearDownPortProfile(tenant_id, port_profile_id)
@@ -670,7 +727,7 @@
670 """727 """
671728
672 LOG.debug("test_show_portprofileDNE - START")729 LOG.debug("test_show_portprofileDNE - START")
673 self.assertRaises(cexc.PortProfileNotFound,730 self.assertRaises(Exception,
674 self._l2network_plugin.get_portprofile_details,731 self._l2network_plugin.get_portprofile_details,
675 tenant_id, profile_id)732 tenant_id, profile_id)
676 LOG.debug("test_show_portprofileDNE - END")733 LOG.debug("test_show_portprofileDNE - END")
@@ -683,10 +740,12 @@
683740
684 LOG.debug("test_rename_portprofile - START")741 LOG.debug("test_rename_portprofile - START")
685 port_profile_dict = self._l2network_plugin.create_portprofile(742 port_profile_dict = self._l2network_plugin.create_portprofile(
686 tenant_id, self.profile_name, self.vlan_id)743 tenant_id, self.profile_name, self.qos)
687 port_profile_id = port_profile_dict['profile-id']744 port_profile_id = port_profile_dict['profile-id']
688 result_port_profile_dict = self._l2network_plugin.rename_portprofile(745 result_port_profile_dict = self._l2network_plugin.rename_portprofile(
689 tenant_id, port_profile_id, new_profile_name)746 tenant_id, port_profile_id, new_profile_name)
747 port_profile = cdb.get_portprofile(tenant_id, port_profile_id)
748 self.assertEqual(port_profile[const.PPNAME], new_profile_name)
690 self.assertEqual(result_port_profile_dict[const.PROFILE_NAME],749 self.assertEqual(result_port_profile_dict[const.PROFILE_NAME],
691 new_profile_name)750 new_profile_name)
692 self.tearDownPortProfile(tenant_id, port_profile_id)751 self.tearDownPortProfile(tenant_id, port_profile_id)
@@ -705,23 +764,32 @@
705 tenant_id, profile_id, new_profile_name)764 tenant_id, profile_id, new_profile_name)
706 LOG.debug("test_rename_portprofileDNE - END")765 LOG.debug("test_rename_portprofileDNE - END")
707766
708 def test_associate_portprofile(self, tenant_id='test_tenant',767 def test_associate_portprofile(self, tenant_id='test_tenant'):
709 net_id='0005', port_id='p00005'):
710 """768 """
711 Tests association of a port-profile769 Tests association of a port-profile
712 """770 """
713771
714 LOG.debug("test_associate_portprofile - START")772 LOG.debug("test_associate_portprofile - START")
773 new_net_dict = self._l2network_plugin.create_network(
774 tenant_id, self.network_name)
775 port_dict = self._l2network_plugin.create_port(
776 tenant_id, new_net_dict[const.NET_ID],
777 self.port_state)
715 port_profile_dict = self._l2network_plugin.create_portprofile(778 port_profile_dict = self._l2network_plugin.create_portprofile(
716 tenant_id, self.profile_name, self.vlan_id)779 tenant_id, self.profile_name, self.qos)
717 port_profile_id = port_profile_dict['profile-id']780 port_profile_id = port_profile_dict['profile-id']
718 self._l2network_plugin.associate_portprofile(781 self._l2network_plugin.associate_portprofile(
719 tenant_id, net_id, port_id, port_profile_id)782 tenant_id, new_net_dict[const.NET_ID],
720 self.assertEqual(783 port_dict[const.PORT_ID], port_profile_id)
721 self._l2network_plugin._portprofiles[port_profile_id]784 port_profile_associate = cdb.get_pp_binding(tenant_id, port_profile_id)
722 [const.PROFILE_ASSOCIATIONS][0], port_id)785 self.assertEqual(port_profile_associate[const.PORTID],
723 self.tearDownAssociatePortProfile(tenant_id, net_id,786 port_dict[const.PORT_ID])
724 port_id, port_profile_id)787 self.tearDownAssociatePortProfile(
788 tenant_id, new_net_dict[const.NET_ID],
789 port_dict[const.PORT_ID], port_profile_id)
790 self.tearDownNetworkPort(
791 tenant_id, new_net_dict[const.NET_ID],
792 port_dict[const.PORT_ID])
725 LOG.debug("test_associate_portprofile - END")793 LOG.debug("test_associate_portprofile - END")
726794
727 def test_associate_portprofileDNE(self, tenant_id='test_tenant',795 def test_associate_portprofileDNE(self, tenant_id='test_tenant',
@@ -738,22 +806,32 @@
738 LOG.debug("test_associate_portprofileDNE - END")806 LOG.debug("test_associate_portprofileDNE - END")
739807
740 def test_disassociate_portprofile(self, tenant_id='test_tenant',808 def test_disassociate_portprofile(self, tenant_id='test_tenant',
741 net_id='0005', port_id='p00005'):809 ):
742 """810 """
743 Tests disassociation of a port-profile811 Tests disassociation of a port-profile
744 """812 """
745813
746 LOG.debug("test_disassociate_portprofile - START")814 LOG.debug("test_disassociate_portprofile - START")
815 new_net_dict = self._l2network_plugin.create_network(
816 tenant_id, self.network_name)
817 port_dict = self._l2network_plugin.create_port(
818 tenant_id, new_net_dict[const.NET_ID],
819 self.port_state)
747 port_profile_dict = self._l2network_plugin.create_portprofile(820 port_profile_dict = self._l2network_plugin.create_portprofile(
748 tenant_id, self.profile_name, self.vlan_id)821 tenant_id, self.profile_name, self.qos)
749 port_profile_id = port_profile_dict['profile-id']822 port_profile_id = port_profile_dict['profile-id']
750 self._l2network_plugin.associate_portprofile(tenant_id, net_id,823 self._l2network_plugin.associate_portprofile(
751 port_id, port_profile_id)824 tenant_id, new_net_dict[const.NET_ID],
825 port_dict[const.PORT_ID], port_profile_id)
752 self._l2network_plugin.disassociate_portprofile(826 self._l2network_plugin.disassociate_portprofile(
753 tenant_id, net_id, port_id, port_profile_id)827 tenant_id, new_net_dict[const.NET_ID],
754 self.assertEqual(self._l2network_plugin._portprofiles828 port_dict[const.PORT_ID], port_profile_id)
755 [port_profile_id][const.PROFILE_ASSOCIATIONS], [])829 port_profile_associate = cdb.get_pp_binding(tenant_id, port_profile_id)
830 self.assertEqual(port_profile_associate, [])
756 self.tearDownPortProfile(tenant_id, port_profile_id)831 self.tearDownPortProfile(tenant_id, port_profile_id)
832 self.tearDownNetworkPort(
833 tenant_id, new_net_dict[const.NET_ID],
834 port_dict[const.PORT_ID])
757 LOG.debug("test_disassociate_portprofile - END")835 LOG.debug("test_disassociate_portprofile - END")
758836
759 def test_disassociate_portprofileDNE(self, tenant_id='test_tenant',837 def test_disassociate_portprofileDNE(self, tenant_id='test_tenant',
@@ -768,24 +846,7 @@
768 tenant_id, net_id, port_id, profile_id)846 tenant_id, net_id, port_id, profile_id)
769 LOG.debug("test_disassociate_portprofileDNE - END")847 LOG.debug("test_disassociate_portprofileDNE - END")
770848
771# def test_disassociate_portprofile_Unassociated849 def test_get_vlan_name(self, net_tenant_id=None, vlan_id="NewVlan",
772
773 def test_get_tenant(self, net_tenant_id=None):
774 """
775 Tests get tenant
776 """
777
778 LOG.debug("test_get_tenant - START")
779 if net_tenant_id:
780 tenant_id = net_tenant_id
781 else:
782 tenant_id = self.tenant_id
783 tenant_dict = self._l2network_plugin._get_tenant(tenant_id)
784 self.assertEqual(tenant_dict[const.TENANT_ID], tenant_id)
785 self.assertEqual(tenant_dict[const.TENANT_NAME], tenant_id)
786 LOG.debug("test_get_tenant - END")
787
788 def test_get_vlan_name(self, net_tenant_id=None, vlan_name="NewVlan",
789 vlan_prefix=conf.VLAN_NAME_PREFIX):850 vlan_prefix=conf.VLAN_NAME_PREFIX):
790 """851 """
791 Tests get vlan name852 Tests get vlan name
@@ -797,8 +858,8 @@
797 else:858 else:
798 tenant_id = self.tenant_id859 tenant_id = self.tenant_id
799 result_vlan_name = self._l2network_plugin._get_vlan_name(tenant_id,860 result_vlan_name = self._l2network_plugin._get_vlan_name(tenant_id,
800 vlan_name)861 vlan_id)
801 expected_output = vlan_prefix + tenant_id + "-" + vlan_name862 expected_output = vlan_prefix + vlan_id
802 self.assertEqual(result_vlan_name, expected_output)863 self.assertEqual(result_vlan_name, expected_output)
803 LOG.debug("test_get_vlan_name - END")864 LOG.debug("test_get_vlan_name - END")
804865
@@ -823,39 +884,11 @@
823 port_state)884 port_state)
824 LOG.debug("test_validate_port_state - END")885 LOG.debug("test_validate_port_state - END")
825886
826 def test_validate_attachment(self, net_tenant_id=None,
827 remote_interface_id="new_interface"):
828 """
829 Tests validate attachment
830 """
831
832 LOG.debug("test_validate_attachment - START")
833 if net_tenant_id:
834 tenant_id = net_tenant_id
835 else:
836 tenant_id = self.tenant_id
837 net_name = self.network_name
838 new_network_dict = self._l2network_plugin.create_network(tenant_id,
839 net_name)
840 network_id = new_network_dict[const.NET_ID]
841 new_port_dict = self._l2network_plugin.create_port(tenant_id,
842 network_id)
843 port_id = new_port_dict[const.PORT_ID]
844 self._l2network_plugin.plug_interface(
845 tenant_id, new_network_dict[const.NET_ID], port_id,
846 remote_interface_id)
847 self.assertRaises(exc.AlreadyAttached,
848 self._l2network_plugin._validate_attachment,
849 tenant_id, network_id, port_id, remote_interface_id)
850 self.tearDownNetworkPortInterface(
851 tenant_id, new_network_dict[const.NET_ID], port_id)
852 LOG.debug("test_validate_attachment - END")
853
854 def setUp(self):887 def setUp(self):
855 self.tenant_id = "test_tenant"888 self.tenant_id = "test_tenant"
856 self.network_name = "test_network"889 self.network_name = "test_network"
857 self.profile_name = "test_tenant_port_profile"890 self.profile_name = "test_tenant_port_profile"
858 self.vlan_id = "test_tenant_vlanid300"891 self.qos = "test_qos"
859 self.port_state = const.PORT_UP892 self.port_state = const.PORT_UP
860 self.net_id = '00005'893 self.net_id = '00005'
861 self.port_id = 'p0005'894 self.port_id = 'p0005'
@@ -865,6 +898,10 @@
865 """898 """
866 Clean up functions after the tests899 Clean up functions after the tests
867 """900 """
901 def tearDown(self):
902 """Clear the test environment"""
903 # Remove database contents
904 db.clear_db()
868905
869 def tearDownNetwork(self, tenant_id, network_dict_id):906 def tearDownNetwork(self, tenant_id, network_dict_id):
870 self._l2network_plugin.delete_network(tenant_id, network_dict_id)907 self._l2network_plugin.delete_network(tenant_id, network_dict_id)
@@ -885,8 +922,41 @@
885 def tearDownPortProfile(self, tenant_id, port_profile_id):922 def tearDownPortProfile(self, tenant_id, port_profile_id):
886 self._l2network_plugin.delete_portprofile(tenant_id, port_profile_id)923 self._l2network_plugin.delete_portprofile(tenant_id, port_profile_id)
887924
925 def tearDownPortProfileBinding(self, tenant_id, port_profile_id):
926 self._l2network_plugin.delete_portprofile(tenant_id, port_profile_id)
927
888 def tearDownAssociatePortProfile(self, tenant_id, net_id, port_id,928 def tearDownAssociatePortProfile(self, tenant_id, net_id, port_id,
889 port_profile_id):929 port_profile_id):
890 self._l2network_plugin.disassociate_portprofile(930 self._l2network_plugin.disassociate_portprofile(
891 tenant_id, net_id, port_id, port_profile_id)931 tenant_id, net_id, port_id, port_profile_id)
892 self.tearDownPortProfile(tenant_id, port_profile_id)932 self.tearDownPortProfile(tenant_id, port_profile_id)
933
934 def _make_net_dict(self, net_id, net_name, ports):
935 res = {const.NET_ID: net_id, const.NET_NAME: net_name}
936 res[const.NET_PORTS] = ports
937 return res
938
939 def _make_port_dict(self, port_id, port_state, net_id, attachment):
940 res = {const.PORT_ID: port_id, const.PORT_STATE: port_state}
941 res[const.NET_ID] = net_id
942 res[const.ATTACHMENT] = attachment
943 return res
944
945 def _make_portprofile_dict(self, tenant_id, profile_id, profile_name,
946 qos):
947 profile_associations = self._make_portprofile_assc_list(
948 tenant_id, profile_id)
949 res = {const.PROFILE_ID: str(profile_id),
950 const.PROFILE_NAME: profile_name,
951 const.PROFILE_ASSOCIATIONS: profile_associations,
952 const.PROFILE_VLAN_ID: None,
953 const.PROFILE_QOS: qos}
954 return res
955
956 def _make_portprofile_assc_list(self, tenant_id, profile_id):
957 plist = cdb.get_pp_binding(tenant_id, profile_id)
958 assc_list = []
959 for port in plist:
960 assc_list.append(port[const.PORTID])
961
962 return assc_list
893963
=== modified file 'quantum/plugins/cisco/tests/unit/test_nexus_plugin.py'
--- quantum/plugins/cisco/tests/unit/test_nexus_plugin.py 2011-08-08 07:23:44 +0000
+++ quantum/plugins/cisco/tests/unit/test_nexus_plugin.py 2011-08-23 20:09:26 +0000
@@ -259,11 +259,10 @@
259 self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])259 self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
260 LOG.debug("test_get_vlan_id_for_network - END")260 LOG.debug("test_get_vlan_id_for_network - END")
261261
262 """262 def tearDownNetwork(self, tenant_id, network_dict_id):
263 """
263 Clean up functions after the tests264 Clean up functions after the tests
264 """265 """
265
266 def tearDownNetwork(self, tenant_id, network_dict_id):
267 self._cisco_nexus_plugin.delete_network(tenant_id, network_dict_id)266 self._cisco_nexus_plugin.delete_network(tenant_id, network_dict_id)
268267
269# def test_create_network(self):268# def test_create_network(self):
270269
=== modified file 'quantum/plugins/cisco/tests/unit/test_ucs_driver.py'
--- quantum/plugins/cisco/tests/unit/test_ucs_driver.py 2011-08-08 07:23:44 +0000
+++ quantum/plugins/cisco/tests/unit/test_ucs_driver.py 2011-08-23 20:09:26 +0000
@@ -24,13 +24,13 @@
2424
25LOG = logging.getLogger('quantum.tests.test_ucs_driver')25LOG = logging.getLogger('quantum.tests.test_ucs_driver')
2626
27create_vlan_output = "<configConfMos cookie=\"cookie_placeholder\" "\27CREATE_VLAN_OUTPUT = "<configConfMos cookie=\"cookie_placeholder\" "\
28"inHierarchical=\"true\"> <inConfigs><pair key=\"fabric/lan/net-New Vlan\"> "\28"inHierarchical=\"true\"> <inConfigs><pair key=\"fabric/lan/net-New Vlan\"> "\
29"<fabricVlan defaultNet=\"no\" dn=\"fabric/lan/net-New Vlan\" id=\"200\" "\29"<fabricVlan defaultNet=\"no\" dn=\"fabric/lan/net-New Vlan\" id=\"200\" "\
30"name=\"New Vlan\" status=\"created\"></fabricVlan> </pair> </inConfigs> "\30"name=\"New Vlan\" status=\"created\"></fabricVlan> </pair> </inConfigs> "\
31"</configConfMos>"31"</configConfMos>"
3232
33create_profile_output = "<configConfMos cookie=\"cookie_placeholder\" "\33CREATE_PROFILE_OUTPUT = "<configConfMos cookie=\"cookie_placeholder\" "\
34"inHierarchical=\"true\"> <inConfigs><pair key=\"fabric/lan/profiles/vnic-"\34"inHierarchical=\"true\"> <inConfigs><pair key=\"fabric/lan/profiles/vnic-"\
35"New Profile\"> <vnicProfile descr=\"Profile created by Cisco OpenStack "\35"New Profile\"> <vnicProfile descr=\"Profile created by Cisco OpenStack "\
36"Quantum Plugin\" dn=\"fabric/lan/profiles/vnic-New Profile\" maxPorts="\36"Quantum Plugin\" dn=\"fabric/lan/profiles/vnic-New Profile\" maxPorts="\
@@ -39,7 +39,7 @@
39"name=\"New Vlan\" rn=\"if-New Vlan\" > </vnicEtherIf> </vnicProfile> "\39"name=\"New Vlan\" rn=\"if-New Vlan\" > </vnicEtherIf> </vnicProfile> "\
40"</pair> </inConfigs> </configConfMos>"40"</pair> </inConfigs> </configConfMos>"
4141
42change_vlan_output = "<configConfMos cookie=\"cookie_placeholder\" "\42CHANGE_VLAN_OUTPUT = "<configConfMos cookie=\"cookie_placeholder\" "\
43"inHierarchical=\"true\"> <inConfigs><pair key=\""\43"inHierarchical=\"true\"> <inConfigs><pair key=\""\
44"fabric/lan/profiles/vnic-New Profile\"> <vnicProfile descr=\"Profile "\44"fabric/lan/profiles/vnic-New Profile\"> <vnicProfile descr=\"Profile "\
45"created by Cisco OpenStack Quantum Plugin\" "\45"created by Cisco OpenStack Quantum Plugin\" "\
@@ -50,18 +50,18 @@
50"<vnicEtherIf defaultNet=\"yes\" name=\"New Vlan\" rn=\"if-New Vlan\" > "\50"<vnicEtherIf defaultNet=\"yes\" name=\"New Vlan\" rn=\"if-New Vlan\" > "\
51"</vnicEtherIf> </vnicProfile> </pair></inConfigs> </configConfMos>"51"</vnicEtherIf> </vnicProfile> </pair></inConfigs> </configConfMos>"
5252
53delete_vlan_output = "<configConfMos cookie=\"cookie_placeholder\" "\53DELETE_VLAN_OUTPUT = "<configConfMos cookie=\"cookie_placeholder\" "\
54"inHierarchical=\"true\"> <inConfigs><pair key=\"fabric/lan/net-New Vlan\"> "\54"inHierarchical=\"true\"> <inConfigs><pair key=\"fabric/lan/net-New Vlan\"> "\
55"<fabricVlan dn=\"fabric/lan/net-New Vlan\" status=\"deleted\"> "\55"<fabricVlan dn=\"fabric/lan/net-New Vlan\" status=\"deleted\"> "\
56"</fabricVlan> </pair> </inConfigs></configConfMos>"56"</fabricVlan> </pair> </inConfigs></configConfMos>"
5757
58delete_profile_output = "<configConfMos cookie=\"cookie_placeholder\" "\58DELETE_PROFILE_OUTPUT = "<configConfMos cookie=\"cookie_placeholder\" "\
59"inHierarchical=\"false\"> <inConfigs><pair key=\""\59"inHierarchical=\"false\"> <inConfigs><pair key=\""\
60"fabric/lan/profiles/vnic-New Profile\"> <vnicProfile "\60"fabric/lan/profiles/vnic-New Profile\"> <vnicProfile "\
61"dn=\"fabric/lan/profiles/vnic-New Profile\" status=\"deleted\"> "\61"dn=\"fabric/lan/profiles/vnic-New Profile\" status=\"deleted\"> "\
62"</vnicProfile></pair> </inConfigs> </configConfMos>"62"</vnicProfile></pair> </inConfigs> </configConfMos>"
6363
64associate_profile_output = "<configConfMos cookie=\"cookie_placeholder\" "\64ASSOCIATE_PROFILE_OUTPUT = "<configConfMos cookie=\"cookie_placeholder\" "\
65"inHierarchical=\"true\"> <inConfigs> <pair key="\65"inHierarchical=\"true\"> <inConfigs> <pair key="\
66"\"fabric/lan/profiles/vnic-New Profile/cl-New Profile Client\">"\66"\"fabric/lan/profiles/vnic-New Profile/cl-New Profile Client\">"\
67" <vmVnicProfCl dcName=\".*\" descr=\"\" dn=\"fabric/lan/profiles/vnic-"\67" <vmVnicProfCl dcName=\".*\" descr=\"\" dn=\"fabric/lan/profiles/vnic-"\
@@ -73,83 +73,86 @@
73class TestUCSDriver(unittest.TestCase):73class TestUCSDriver(unittest.TestCase):
7474
75 def setUp(self):75 def setUp(self):
76 self._ucsmDriver = cisco_ucs_network_driver.CiscoUCSMDriver()76 self.ucsm_driver = cisco_ucs_network_driver.CiscoUCSMDriver()
77 self.vlan_name = 'New Vlan'77 self.vlan_name = 'New Vlan'
78 self.vlan_id = '200'78 self.vlan_id = '200'
79 self.profile_name = 'New Profile'79 self.profile_name = 'New Profile'
80 self.old_vlan_name = 'Old Vlan'80 self.old_vlan_name = 'Old Vlan'
81 self.profile_client_name = 'New Profile Client'81 self.profile_client_name = 'New Profile Client'
8282
83 def test_create_vlan_post_data(self, expected_output=create_vlan_output):83 def test_create_vlan_post_data(self, expected_output=CREATE_VLAN_OUTPUT):
84 """84 """
85 Tests creation of vlan post Data85 Tests creation of vlan post Data
86 """86 """
8787
88 LOG.debug("test_create_vlan")88 LOG.debug("test_create_vlan")
89 vlan_details = self._ucsmDriver._create_vlan_post_data(89 vlan_details = self.ucsm_driver._create_vlan_post_data(
90 self.vlan_name, self.vlan_id)90 self.vlan_name, self.vlan_id)
91 self.assertEqual(vlan_details, expected_output)91 self.assertEqual(vlan_details, expected_output)
92 LOG.debug("test_create_vlan - END")92 LOG.debug("test_create_vlan - END")
9393
94 def test_create_profile_post_data(94 def test_create_profile_post_data(
95 self, expected_output=create_profile_output):95 self, expected_output=CREATE_PROFILE_OUTPUT):
96 """96 """
97 Tests creation of profile post Data97 Tests creation of profile post Data
98 """98 """
9999
100 LOG.debug("test_create_profile_post_data - START")100 LOG.debug("test_create_profile_post_data - START")
101 profile_details = self._ucsmDriver._create_profile_post_data(101 profile_details = self.ucsm_driver._create_profile_post_data(
102 self.profile_name, self.vlan_name)102 self.profile_name, self.vlan_name)
103 self.assertEqual(profile_details, expected_output)103 self.assertEqual(profile_details, expected_output)
104 LOG.debug("test_create_profile_post - END")104 LOG.debug("test_create_profile_post - END")
105105
106 def test_change_vlan_in_profile_post_data(106 def test_change_vlan_profile_data(
107 self, expected_output=change_vlan_output):107 self, expected_output=CHANGE_VLAN_OUTPUT):
108 """108 """
109 Tests creation of change vlan in profile post Data109 Tests creation of change vlan in profile post Data
110 """110 """
111111
112 LOG.debug("test_create_profile_post_data - START")112 LOG.debug("test_create_profile_post_data - START")
113 profile_details = self._ucsmDriver._change_vlan_in_profile_post_data(113 profile_details = self.ucsm_driver._change_vlaninprof_post_data(
114 self.profile_name, self.old_vlan_name, self.vlan_name)114 self.profile_name, self.old_vlan_name, self.vlan_name)
115 self.assertEqual(profile_details, expected_output)115 self.assertEqual(profile_details, expected_output)
116 LOG.debug("test_create_profile_post - END")116 LOG.debug("test_create_profile_post - END")
117117
118 def test_delete_vlan_post_data(self, expected_output=delete_vlan_output):118 def test_delete_vlan_post_data(self, expected_output=DELETE_VLAN_OUTPUT):
119 LOG.debug("test_create_profile_post_data - START")
120 """119 """
121 Tests deletion of vlan post Data120 Tests deletion of vlan post Data
122 """121 """
123122
124 vlan_details = self._ucsmDriver._create_vlan_post_data(123 LOG.debug("test_create_profile_post_data - START")
124
125 self.ucsm_driver._create_vlan_post_data(
125 self.vlan_name, self.vlan_id)126 self.vlan_name, self.vlan_id)
126 vlan_delete_details = self._ucsmDriver._delete_vlan_post_data(127 vlan_delete_details = self.ucsm_driver._delete_vlan_post_data(
127 self.vlan_name)128 self.vlan_name)
128 self.assertEqual(vlan_delete_details, expected_output)129 self.assertEqual(vlan_delete_details, expected_output)
129 LOG.debug("test_create_profile_post - END")130 LOG.debug("test_create_profile_post - END")
130131
131 def test_delete_profile_post_data(132 def test_delete_profile_post_data(
132 self, expected_output=delete_profile_output):133 self, expected_output=DELETE_PROFILE_OUTPUT):
133 """134 """
134 Tests deletion of profile post Data135 Tests deletion of profile post Data
135 """136 """
136137
137 LOG.debug("test_create_profile_post_data - START")138 LOG.debug("test_create_profile_post_data - START")
138 profile_details = self._ucsmDriver._create_profile_post_data(139 #profile_details = self.ucsm_driver._create_profile_post_data(
140 # self.profile_name, self.vlan_name)
141 self.ucsm_driver._create_profile_post_data(
139 self.profile_name, self.vlan_name)142 self.profile_name, self.vlan_name)
140 profile_delete_details = self._ucsmDriver._delete_profile_post_data(143 profile_delete_details = self.ucsm_driver._delete_profile_post_data(
141 self.profile_name)144 self.profile_name)
142 self.assertEqual(profile_delete_details, expected_output)145 self.assertEqual(profile_delete_details, expected_output)
143 LOG.debug("test_create_profile_post - END")146 LOG.debug("test_create_profile_post - END")
144147
145 def test_create_profile_client_post_data(148 def test_create_profile_client_data(
146 self, expected_output=associate_profile_output):149 self, expected_output=ASSOCIATE_PROFILE_OUTPUT):
147 """150 """
148 Tests creation of profile client post Data151 Tests creation of profile client post Data
149 """152 """
150153
151 LOG.debug("test_create_profile_client_post_data - START")154 LOG.debug("test_create_profile_client_data - START")
152 profile_details = self._ucsmDriver._create_profile_client_post_data(155 profile_details = self.ucsm_driver._create_pclient_post_data(
153 self.profile_name, self.profile_client_name)156 self.profile_name, self.profile_client_name)
154 self.assertEqual(profile_details, expected_output)157 self.assertEqual(profile_details, expected_output)
155 LOG.debug("test_create_profile_post - END")158 LOG.debug("test_create_profile_post - END")
@@ -160,6 +163,6 @@
160 """163 """
161164
162 LOG.debug("test_get_next_dynamic_nic - START")165 LOG.debug("test_get_next_dynamic_nic - START")
163 dynamic_nic_id = self._ucsmDriver._get_next_dynamic_nic()166 dynamic_nic_id = self.ucsm_driver._get_next_dynamic_nic()
164 self.assertTrue(len(dynamic_nic_id) > 0)167 self.assertTrue(len(dynamic_nic_id) > 0)
165 LOG.debug("test_get_next_dynamic_nic - END")168 LOG.debug("test_get_next_dynamic_nic - END")
166169
=== modified file 'quantum/plugins/cisco/tests/unit/test_ucs_plugin.py'
--- quantum/plugins/cisco/tests/unit/test_ucs_plugin.py 2011-08-08 07:23:44 +0000
+++ quantum/plugins/cisco/tests/unit/test_ucs_plugin.py 2011-08-23 20:09:26 +0000
@@ -32,7 +32,7 @@
3232
33 self.tenant_id = "test_tenant_cisco12"33 self.tenant_id = "test_tenant_cisco12"
34 self.net_name = "test_network_cisco12"34 self.net_name = "test_network_cisco12"
35 self.net_id = 00000735 self.net_id = 000011
36 self.vlan_name = "q-" + str(self.net_id) + "vlan"36 self.vlan_name = "q-" + str(self.net_id) + "vlan"
37 self.vlan_id = 26637 self.vlan_id = 266
38 self.port_id = "4"38 self.port_id = "4"
@@ -238,12 +238,12 @@
238 self.assertEqual(new_port_profile[const.PROFILE_NAME], profile_name)238 self.assertEqual(new_port_profile[const.PROFILE_NAME], profile_name)
239 self.tearDownNetworkPort(self.tenant_id, self.net_id, self.port_id)239 self.tearDownNetworkPort(self.tenant_id, self.net_id, self.port_id)
240240
241 def _test_get_port_details_state_down(self, port_state):241 def _test_show_port_state_down(self, port_state):
242 """242 """
243 Tests whether user is able to retrieve a remote interface243 Tests whether user is able to retrieve a remote interface
244 that is attached to this particular port when port state is down.244 that is attached to this particular port when port state is down.
245 """245 """
246 LOG.debug("UCSVICTestPlugin:_test_get_port_details_state_down()" +246 LOG.debug("UCSVICTestPlugin:_test_show_port_state_down()" +
247 "called\n")247 "called\n")
248 self._cisco_ucs_plugin.create_network(self.tenant_id, self.net_name,248 self._cisco_ucs_plugin.create_network(self.tenant_id, self.net_name,
249 self.net_id, self.vlan_name,249 self.net_id, self.vlan_name,
@@ -268,8 +268,8 @@
268 def test_get_port_details_state_up(self):268 def test_get_port_details_state_up(self):
269 self._test_get_port_details_state_up(const.PORT_UP)269 self._test_get_port_details_state_up(const.PORT_UP)
270270
271 def test_get_port_details_state_down(self):271 def test_show_port_state_down(self):
272 self._test_get_port_details_state_down(const.PORT_DOWN)272 self._test_show_port_state_down(const.PORT_DOWN)
273273
274 def test_create_port_profile(self):274 def test_create_port_profile(self):
275 LOG.debug("UCSVICTestPlugin:test_create_port_profile() called\n")275 LOG.debug("UCSVICTestPlugin:test_create_port_profile() called\n")
@@ -313,7 +313,6 @@
313 self.tenant_id, self.net_id, self.port_id)313 self.tenant_id, self.net_id, self.port_id)
314 self.assertEqual(port[const.ATTACHMENT], remote_interface_id)314 self.assertEqual(port[const.ATTACHMENT], remote_interface_id)
315 port_profile = port[const.PORT_PROFILE]315 port_profile = port[const.PORT_PROFILE]
316 profile_name = port_profile[const.PROFILE_NAME]
317 new_vlan_name = self._cisco_ucs_plugin._get_vlan_name_for_network(316 new_vlan_name = self._cisco_ucs_plugin._get_vlan_name_for_network(
318 self.tenant_id, self.net_id)317 self.tenant_id, self.net_id)
319 new_vlan_id = self._cisco_ucs_plugin._get_vlan_id_for_network(318 new_vlan_id = self._cisco_ucs_plugin._get_vlan_id_for_network(
@@ -346,7 +345,6 @@
346 self.tenant_id, self.net_id, self.port_id)345 self.tenant_id, self.net_id, self.port_id)
347 self.assertEqual(port[const.ATTACHMENT], None)346 self.assertEqual(port[const.ATTACHMENT], None)
348 port_profile = port[const.PORT_PROFILE]347 port_profile = port[const.PORT_PROFILE]
349 profile_name = port_profile[const.PROFILE_NAME]
350 self.assertEqual(port_profile[const.PROFILE_VLAN_NAME],348 self.assertEqual(port_profile[const.PROFILE_VLAN_NAME],
351 conf.DEFAULT_VLAN_NAME)349 conf.DEFAULT_VLAN_NAME)
352 self.assertEqual(port_profile[const.PROFILE_VLAN_ID],350 self.assertEqual(port_profile[const.PROFILE_VLAN_ID],
@@ -394,12 +392,12 @@
394 def test_get_network_NetworkNotFound(self):392 def test_get_network_NetworkNotFound(self):
395 self.assertRaises(exc.NetworkNotFound,393 self.assertRaises(exc.NetworkNotFound,
396 self._cisco_ucs_plugin._get_network,394 self._cisco_ucs_plugin._get_network,
397 *(self.tenant_id, self.net_id))395 self.tenant_id, self.net_id)
398396
399 def test_delete_network_NetworkNotFound(self):397 def test_delete_network_NetworkNotFound(self):
400 self.assertRaises(exc.NetworkNotFound,398 self.assertRaises(exc.NetworkNotFound,
401 self._cisco_ucs_plugin.delete_network,399 self._cisco_ucs_plugin.delete_network,
402 *(self.tenant_id, self.net_id))400 self.tenant_id, self.net_id)
403401
404 def test_delete_port_PortInUse(self):402 def test_delete_port_PortInUse(self):
405 self._test_delete_port_PortInUse("4")403 self._test_delete_port_PortInUse("4")
@@ -414,7 +412,7 @@
414 self.port_id,412 self.port_id,
415 remote_interface_id)413 remote_interface_id)
416 self.assertRaises(exc.PortInUse, self._cisco_ucs_plugin.delete_port,414 self.assertRaises(exc.PortInUse, self._cisco_ucs_plugin.delete_port,
417 *(self.tenant_id, self.net_id, self.port_id))415 self.tenant_id, self.net_id, self.port_id)
418 self.tearDownNetworkPortInterface(self.tenant_id, self.net_id,416 self.tearDownNetworkPortInterface(self.tenant_id, self.net_id,
419 self.port_id)417 self.port_id)
420418
@@ -423,7 +421,7 @@
423 self.net_id, self.vlan_name,421 self.net_id, self.vlan_name,
424 self.vlan_id)422 self.vlan_id)
425 self.assertRaises(exc.PortNotFound, self._cisco_ucs_plugin.delete_port,423 self.assertRaises(exc.PortNotFound, self._cisco_ucs_plugin.delete_port,
426 *(self.tenant_id, self.net_id, self.port_id))424 self.tenant_id, self.net_id, self.port_id)
427 self.tearDownNetwork(self.tenant_id, self.net_id)425 self.tearDownNetwork(self.tenant_id, self.net_id)
428426
429 def test_plug_interface_PortInUse(self):427 def test_plug_interface_PortInUse(self):
@@ -441,16 +439,16 @@
441 self.port_id,439 self.port_id,
442 remote_interface_id1)440 remote_interface_id1)
443 self.assertRaises(exc.PortInUse, self._cisco_ucs_plugin.plug_interface,441 self.assertRaises(exc.PortInUse, self._cisco_ucs_plugin.plug_interface,
444 *(self.tenant_id, self.net_id, self.port_id,442 self.tenant_id, self.net_id, self.port_id,
445 remote_interface_id2))443 remote_interface_id2)
446 self.tearDownNetworkPortInterface(self.tenant_id, self.net_id,444 self.tearDownNetworkPortInterface(self.tenant_id, self.net_id,
447 self.port_id)445 self.port_id)
448446
449 def test_validate_attachment_AlreadyAttached(self):447 def test_attachment_exists(self):
450 LOG.debug("UCSVICTestPlugin:testValidateAttachmentAlreadyAttached")448 LOG.debug("UCSVICTestPlugin:testValidateAttachmentAlreadyAttached")
451 self._test_validate_attachment_AlreadyAttached("4")449 self._test_attachment_exists("4")
452450
453 def _test_validate_attachment_AlreadyAttached(self, remote_interface_id):451 def _test_attachment_exists(self, remote_interface_id):
454 LOG.debug("UCSVICTestPlugin:_test_validate_attachmentAlreadyAttached")452 LOG.debug("UCSVICTestPlugin:_test_validate_attachmentAlreadyAttached")
455 self._cisco_ucs_plugin.create_network(self.tenant_id, self.net_name,453 self._cisco_ucs_plugin.create_network(self.tenant_id, self.net_name,
456 self.net_id, self.vlan_name,454 self.net_id, self.vlan_name,
@@ -461,8 +459,8 @@
461 self.port_id,459 self.port_id,
462 remote_interface_id)460 remote_interface_id)
463 self.assertRaises(461 self.assertRaises(
464 exc.AlreadyAttached, self._cisco_ucs_plugin._validate_attachment,462 exc.PortInUse, self._cisco_ucs_plugin._validate_attachment,
465 *(self.tenant_id, self.net_id, self.port_id, remote_interface_id))463 self.tenant_id, self.net_id, self.port_id, remote_interface_id)
466 self.tearDownNetworkPortInterface(self.tenant_id, self.net_id,464 self.tearDownNetworkPortInterface(self.tenant_id, self.net_id,
467 self.port_id)465 self.port_id)
468466
469467
=== modified file 'quantum/plugins/cisco/ucs/__init__.py'
--- quantum/plugins/cisco/ucs/__init__.py 2011-07-31 19:04:01 +0000
+++ quantum/plugins/cisco/ucs/__init__.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -16,3 +17,4 @@
16#17#
17# @author: Sumit Naiksatam, Cisco Systems, Inc.18# @author: Sumit Naiksatam, Cisco Systems, Inc.
18#19#
20"""
1921
=== modified file 'quantum/plugins/cisco/ucs/cisco_getvif.py'
--- quantum/plugins/cisco/ucs/cisco_getvif.py 2011-08-14 01:28:02 +0000
+++ quantum/plugins/cisco/ucs/cisco_getvif.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -16,11 +17,13 @@
16#17#
17# @author: Rohit Agarwalla, Cisco Systems Inc.18# @author: Rohit Agarwalla, Cisco Systems Inc.
18#19#
19import sys20"""
21
20import subprocess22import subprocess
2123
2224
23def get_next_dynic(argv=[]):25def get_next_dynic(argv=[]):
26 """Get the next available dynamic nic on this host"""
24 cmd = ["ifconfig", "-a"]27 cmd = ["ifconfig", "-a"]
25 f_cmd_output = subprocess.Popen(cmd, stdout=subprocess.PIPE).\28 f_cmd_output = subprocess.Popen(cmd, stdout=subprocess.PIPE).\
26 communicate()[0]29 communicate()[0]
2730
=== modified file 'quantum/plugins/cisco/ucs/cisco_ucs_configuration.py'
--- quantum/plugins/cisco/ucs/cisco_ucs_configuration.py 2011-08-14 01:28:02 +0000
+++ quantum/plugins/cisco/ucs/cisco_ucs_configuration.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -16,6 +17,7 @@
16#17#
17# @author: Sumit Naiksatam, Cisco Systems, Inc.18# @author: Sumit Naiksatam, Cisco Systems, Inc.
18#19#
20"""
1921
20import os22import os
2123
@@ -23,15 +25,15 @@
2325
24CONF_FILE = "../conf/ucs.ini"26CONF_FILE = "../conf/ucs.ini"
2527
26cp = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \28CP = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \
27 + "/" + CONF_FILE)29 + "/" + CONF_FILE)
2830
29section = cp['UCSM']31SECTION = CP['UCSM']
30UCSM_IP_ADDRESS = section['ip_address']32UCSM_IP_ADDRESS = SECTION['ip_address']
31DEFAULT_VLAN_NAME = section['default_vlan_name']33DEFAULT_VLAN_NAME = SECTION['default_vlan_name']
32DEFAULT_VLAN_ID = section['default_vlan_id']34DEFAULT_VLAN_ID = SECTION['default_vlan_id']
33MAX_UCSM_PORT_PROFILES = section['max_ucsm_port_profiles']35MAX_UCSM_PORT_PROFILES = SECTION['max_ucsm_port_profiles']
34PROFILE_NAME_PREFIX = section['profile_name_prefix']36PROFILE_NAME_PREFIX = SECTION['profile_name_prefix']
3537
36section = cp['DRIVER']38SECTION = CP['DRIVER']
37UCSM_DRIVER = section['name']39UCSM_DRIVER = SECTION['name']
3840
=== modified file 'quantum/plugins/cisco/ucs/cisco_ucs_network_driver.py'
--- quantum/plugins/cisco/ucs/cisco_ucs_network_driver.py 2011-08-14 01:28:02 +0000
+++ quantum/plugins/cisco/ucs/cisco_ucs_network_driver.py 2011-08-23 20:09:26 +0000
@@ -1,3 +1,4 @@
1"""
1# vim: tabstop=4 shiftwidth=4 softtabstop=42# vim: tabstop=4 shiftwidth=4 softtabstop=4
2#3#
3# Copyright 2011 Cisco Systems, Inc. All rights reserved.4# Copyright 2011 Cisco Systems, Inc. All rights reserved.
@@ -17,15 +18,14 @@
17# @author: Sumit Naiksatam, Cisco Systems Inc.18# @author: Sumit Naiksatam, Cisco Systems Inc.
18#19#
19"""20"""
21
22"""
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches