ʹÓÃOpenStack·þÎñµÄ·½Ê½
OpenStackÏîÄ¿×÷Ϊһ¸öIaaSƽ̨£¬ÌṩÁËÈýÖÖʹÓ÷½Ê½£º
ͨ¹ýWeb½çÃæ£¬Ò²¾ÍÊÇͨ¹ýDashboard£¨Ãæ°å£©À´Ê¹ÓÃÆ½Ì¨ÉϵŦÄÜ¡£
ͨ¹ýÃüÁîÐУ¬Ò²¾ÍÊÇͨ¹ýkeystone, nova, neutronµÈÃüÁ»òÕßͨ¹ý×îеÄOpenStackÃüÁîÀ´Ê¹Óø÷¸ö·þÎñµÄ¹¦ÄÜ£¨ÉçÇøÄ¿Ç°µÄ·¢Õ¹Ä¿±êÊÇʹÓÃÒ»¸öµ¥Ò»µÄOpenStackÃüÁîÌæ´ú¹ýÈ¥µÄÿ¸öÏîĿһ¸öÃüÁîµÄ·½Ê½£¬ÒÔºó»áÖ»´æÔÚÒ»¸öOpenStackÃüÁ¡£
ͨ¹ýAPI£¬Ò²¾ÍÊÇͨ¹ý¸÷¸öOpenStackÏîÄ¿ÌṩµÄAPIÀ´Ê¹Óø÷¸ö·þÎñµÄ¹¦ÄÜ¡£
ÉÏÃæÌáµ½µÄÈýÖÖ·½Ê½ÖУ¬Í¨¹ýAPIÕâÖÖ·½Ê½ÊÇ»ù´¡£¬ÊÇÆäËûÁ½ÖÖ·½Ê½¿ÉÐеĻù´¡¡£
ͨ¹ýWeb½çÃæÊ¹ÓÃOpenStack·þÎñÕâÖÖ·½Ê½ÊÇͨ¹ýOpenStackµÄHorizonÏîÄ¿ÌṩµÄ¡£HorizonÏîÄ¿ÊÇÒ»¸öDjangoÓ¦Óã¬ÊµÏÖÁËÒ»¸öÃæ°å¹¦ÄÜ£¬°üº¬ÁËǰºó¶ËµÄ´úÂ루³ýÁËPython£¬»¹°üÀ¨ÁËCSSºÍJS£©¡£HorizonÏîÄ¿Ö÷ÒªÊÇÌṩһÖÖ½»»¥½çÃæ£¬Ëü»áͨ¹ýAPIÀ´ºÍ¸÷¸öOpenStack·þÎñ½øÐн»»¥£¬È»ºóÔÚWeb½çÃæÉÏչʾ¸÷¸ö·þÎñµÄ״̬£»ËüÒ²»á½ÓÊÕÓû§µÄ²Ù×÷£¬È»ºóµ÷Óø÷¸ö·þÎñµÄAPIÀ´Íê³ÉÓû§¶Ô¸÷¸ö·þÎñµÄʹÓá£
ͨ¹ýÃüÁîÐÐÊÇÓÃOpenStack·þÎñµÄ·½Ê½ÊÇÓÉһϵÁÐÏîÄ¿À´ÌṩµÄ£¬ÕâЩÏîĿһ°ã¶¼ÃüÃûΪpython-projectclient£¬±ÈÈçpython-keystoneclient£¬python-novaclietnµÈ¡£ÕâЩÃüÁîÐÐÏîÄ¿·Ö±ð¶ÔÓ¦µ½¸÷¸öÖ÷ÒªµÄ·þÎñ£¬ÎªÓû§ÌṩÃüÁîÐвÙ×÷½çÃæºÍPythonµÄSDK¡£±ÈÈçpython-keystoneclient¶ÔÓ¦µ½keystone£¬ÎªÓû§ÌṩÁËkeystoneÕâ¸öÃüÁͬʱҲÌṩÁËkeystonÏîÄ¿µÄSDK£¨ÆäʵÊÇÔÚSDKµÄ»ù´¡ÉÏʵÏÖÁËÃüÁîÐУ©¡£ÕâЩclientÏîÄ¿ÌṩµÄSDKÆäʵҲÊÇ·â×°Á˶Ը÷×Ô·þÎñµÄAPIµÄµ÷Óá£ÓÉÓÚÿ¸öÖ÷ÒªÏîÄ¿¶¼ÓÐÒ»¸ö×Ô¼ºµÄÃüÁîÐй¤¾ß£¬ÉçÇø¾õµÃ²»ºÃ£¬ÓÚÊÇÓÖÓÐÁËÒ»¸öеÄÏîÄ¿python-OpenStackclient£¬ÓÃÀ´Ìṩһ¸öͳһµÄÃüÁîÐй¤¾ßOpenStack£¨ÃüÁîµÄÃû×־ͽÐ×öOpenStack£©£¬Õâ¸ö¹¤¾ßʵÏÖÁËÃüÁîÐУ¬È»ºóʹÓø÷¸ö·þÎñµÄclientÏîÄ¿ÌṩµÄSDKÀ´Íê³É¶ÔÓ¦µÄ²Ù×÷¡£
ͨ¹ýAPIʹÓÃOpenStackµÄ·½Ê½ÊÇÓɸ÷¸ö·þÎñ×Ô¼ºÊµÏֵ쬱ÈÈ縺Ôð¼ÆËãµÄnovaÏîĿʵÏÖÁ˼ÆËãÏà¹ØµÄAPI£¬¸ºÔðÈÏÖ¤µÄkeystoneÏîĿʵÏÖÁËÈÏÖ¤ºÍÊÚȨÏà¹ØµÄAPI¡£ÕâЩAPI¶¼ÊÇÓÐͳһµÄÐÎʽµÄ£¬¶¼ÊDzÉÓÃÁËHTTPÐÒéʵÏֵķûºÏREST¹æ·¶µÄAPI¡£OpenStackÖÐÈçºÎʵÏÖÕâЩAPI¾ÍÊDZ¾ÎÄÖØµãÒª½«µÄÄÚÈÝ¡£
»ùÓÚHTTPÐÒéµÄRESTful API
RESTµÄÈ«³ÆÊÇRepresentational State Transfer£¬ÖÐÎÄ·Òë¹ýÀ´ÊDZíÕ÷×´Ì¬×ªÒÆ£¬ÊÇRoy
FieldingÔÚËûµÄ²©Ê¿ÂÛÎÄArchitectural Styles and the Design of
Network-based Software ArchitecturesÌá³öµÄÒ»ÖÖÈí¼þ¼Ü¹¹·ç¸ñ¡£¿ÉÒÔÏȵ½wikipediaÒ³ÃæÁ˽âÒ»ÏÂÕâ¸ö·ç¸ñµÄÌØµã¡£Ò»°ã»á°ÑÂú×ãÕâÖÖÉè¼Æ·ç¸ñµÄAPI³ÉΪRESTful
API¡£ÓÉÓÚÕâÖÖÈí¼þÉè¼Æ·ç¸ñ·Ç³£ÊʺϲÉÓÃHTTPÐÒéÀ´ÊµÏÖ£¬Òò´ËHTTPÐÒéÊÇĿǰʵÏÖRESTful APIµÄÖ÷Òª·½°¸¡£
OpenStack¾ÍÊÇ»ùÓÚHTTPÐÒéºÍJSONÀ´ÊµÏÖ×Ô¼ºµÄRESTful
API£¨Ö®Ç°OpenStack»¹ÓвÉÓÃXMLÀ´±íʾÊý¾ÝµÄ£¬ÏÖÔÚ¶¼ÒѾתµ½JSONÁË£©¡£µ±Ò»¸ö·þÎñÒªÌṩAPIʱ£¬Ëü¾Í»áÆô¶¯Ò»¸öHTTP·þÎñ¶Ë£¬ÓÃÀ´¶ÔÍâÌṩRESTful
API¡£
OpenStackµÄAPI¶¼ÊÇÓÐÏêϸµÄÎĵµ¼Ç¼µÄ£¬¿ÉÒԲ鿴ËùÓеÄAPIÎĵµ¡£Ã¿¸öAPIµÄÎĵµÐÎʽÈçÏ£º

µ±È»£¬Äã¿ÉÒԵ㿪detail¿´µ½ÏêϸµÄ˵Ã÷¡£´ÓÉÏÃæÕâ¸öAPIµÄÎĵµÀ´¿´£¬Äã»á¾õµÃÕâ¸öºÍ¿ª·¢ÍøÕ¾Ê±Ê¹ÓõÄGET·½·¨ºÍPOST·½·¨²î²»¶à£¬Êµ¼ÊÉÏÒ²ÊDz¶àµÄ£¬Ö»²»¹ý¶ÔHTTPÐÒéµÄʹÓ÷½·¨×öÁËÂú×ãREST·ç¸ñµÄ¹æ¶¨¶øÒÑ¡£
PythonÈçºÎʵÏÖRESTful API
ÒòΪPythonÄܹ»½øÐÐWeb¿ª·¢£¬ËùÒÔÓÃÀ´¿ª·¢RESTful APIÒ²¾Í²»³ÉÎÊÌ⣬ÕâÁ½Õߵļ¼Êõ»ù´¡ÊÇÒ»Ñù¡£ÔÚPythonÏ¿ª·¢RESTful
APIÓ¦Óã¬ÎÞ·ÇÊǽâ¾öÁ½¸öÎÊÌ⣺
1.·þÎñÈçºÎ²¿Êð£¿
2.ÓÃʲô¿ò¼Ü¿ª·¢£¿
·þÎñÈçºÎ²¿Êð£¿
˵µ½PythonµÄWeb·þÎñ²¿ÊðÕâ¸öÎÊÌ⣬¾Í²»µÃ²»Ìáµ½WSGI¡£Ä¿Ç°PythonÓÐÁ½ÖÖ·½Ê½À´¿ª·¢ºÍ²¿ÊðÒ»¸öWebÓ¦ÓãºÓÃWSGIºÍ²»ÓÃWSGI¡£Èç¹ûÄã²»Á˽âWSGI£¬ÄÇôÄãÐèÒªÏÈ¿´ÏÂÁíÍâÕâÆª¹ØÓÚWSGIµÄÎÄÕ£ºWSGI¼ò½é¡£
OpenStackµÄAPI·þÎñ¶¼ÊÇʹÓÃWSGIµÄ·½Ê½À´²¿ÊðµÄ¡£ÔÚÉú²ú»·¾³Öв¿ÊðWSGI£¬Ò»°ã»á¿¼ÂÇʹÓÃWeb·þÎñÆ÷
+ Ó¦Ó÷þÎñÆ÷ + Ó¦ÓÃ(¿ò¼Ü)µÄ·½°¸¡£OpenStack¹Ù·½ÍƼöµÄÊÇʹÓÃApache + mod_wsgiµÄ·½°¸£¬²»¹ýÕâ¸öÒª»»³ÉÆäËû·½°¸Ò²ºÜÈÝÒ×£¬ÄãÒ²¿ÉÒÔÑ¡nginx
+ uWSGI¡£¶ÔÓÚ¿ª·¢µ÷ÊÔµÄÄ¿µÄ£¬ÓÐЩÏîĿҲ»áÌṩʹÓÃeventletµÄµ¥½ø³Ì²¿Êð·½°¸£¬±ÈÈçKeystoneÏîÄ¿µÄkeystone-allÃüÁî¡£²ÉÓÃeventletÕâÖÖÒì²½¼Ü¹¹À´½øÐÐÓ¦Óÿª·¢Ò²ÊÇÒ»¸ö±È½Ï´óµÄ»°Ì⣬±¾ÎIJ»¸²¸ÇÕâ·½ÃæµÄÄÚÈÝ¡£
µ±È»£¬Ò²¿ÉÒÔ²»ÓÃWSGI¡£ÔÚPythonÖУ¬Èç¹û²»Ê¹ÓÃWSGIµÄ»¯£¬Ò»°ã¿ª·¢Õß»áÑ¡ÔñһЩרÃŵķþÎñÆ÷ºÍ¿ò¼Ü£¬±ÈÈçTornado£¬»òÕß×îÐÂ×î³±µÄaiohttp¡£²»¹ýÔÚOpenStackµÄÏîÄ¿ÖÐÎÒ»¹Ã»¼û¹ý²»Ê¹ÓÃWSGIµÄ¡£
ÓÃʲô¿ò¼Ü¿ª·¢
PythonµÄWeb¿ª·¢¿ò¼ÜºÜ¶à£¬×î³öÃû×ÔÈ»ÊÇDjangoÁË¡£»ù±¾ÉÏ£¬»¹»îÔ¾µÄ¿ò¼Ü¶¼Ö§³ÖRESTful
APIµÄ¿ª·¢£¬ÓÐЩ¿ò¼Ü»¹×¨ÃÅΪRESTful APIµÄ¿ª·¢ÌṩÁ˱ãÀûµÄ¹¦ÄÜ£¨±ÈÈçPecan£©£¬ÓÐЩ¿ò¼ÜÔòͨ¹ýµÚÈý·½Ä£¿éÀ´ÌṩÕâÖÖ±ãÀû£¬±ÈÈçDjangoºÍFlask¶¼Óв»ÉÙºÍRESTÏà¹ØµÄµÚÈý·½¿â¡£
¶ÔÓÚ¿ò¼ÜÑ¡Ôñ£¬Ò²Ã»ÓÐÊ²Ã´ÌØ±ðºÃµÄ±ê×¼£¬Ò»°ã¶¼ÊDZȽÏÐÔÄÜ¡¢Îĵµ¡¢ÉçÇøÊÇ·ñ»îÔ¾µÈ¡£ÔÚÎÒ¿´À´£¬Ñ¡ÔñÁ÷ÐеÄÒ»°ã¾Í²»»á´í¡£
OpenStackÖеÄRESTful API¿ª·¢
ÉÏÃæÒѾ̸µ½ÁËOpenStack¶¼ÊÇʹÓÃWSGI£¬Ò²Ìáµ½Á˲¿Êð·½Ê½¡£ÕâÒ»ÕÂÀ´ËµÒ»ÏÂOpenStackÖÐʹÓõĿò¼Ü¡£
OpenStackÏîÄ¿ÇãÏòÓÚ²»ÖØÐ·¢Ã÷ÂÖ×Ó£¬Ò»°ã¶¼»áÑ¡ÔñÏÖÓеĿâºÍ¿ò¼ÜÀ´Ê¹Ó㬳ý·ÇÏÖÓеĿò¼Ü²»Âú×ãÐèÇó¡£ÒòΪWeb¿ò¼ÜµÄÑ¡ÔñºÜ¶à£¬¶øÇÒ¶¼Âú×ãÐèÇó£¬ËùÒÔOpenStackÏîÄ¿µ½Ä¿Ç°ÎªÖ¹¶¼ÊÇʹÓÃÏֳɵÄWeb¿ò¼Ü¡£
OpenStackÔçÆÚµÄÏîÄ¿²¢Ã»ÓÐʹÓÃÒ»¸ö¿ò¼Ü£¬¶øÊÇʹÓÃÁ˼¸¸ö²»Í¬µÄÄ£¿éÀ´×éºÏ³öÒ»¸ö¿ò¼Ü£ºPaste
+ PasteDeploy + Routes + WebOb£¬Õ⼸¸ö²»Í¬µÄÄ£¿é·Ö±ð¸ºÔðÓ¦ÓõÄWSGI»¯¡¢URL·ÓɺÍÇëÇó´¦ÀíµÈ¹¦ÄÜ¡£Nova,
Glance, Neutron, KeystoneµÈÔçÆÚµÄÏîÄ¿¶¼ÊÇʹÓÃÕâÑùµÄ¼Ü¹¹À´ÊµÏÖRESTful APIµÄ¡£
ÔçÆÚµÄÕâÖÖ¼¼ÊõÑ¡ÐÍ´øÀ´µÄºÃ´¦ÊÇ¡±¿ò¼Ü¡±¾ß±¸×ã¹»µÄÁé»îÐÔ£¬È±µãÔòÊÇÒª°ÑÕ⼸¸öÄ£¿é×éºÏÆðÀ´ÊµÏÖÒ»¸öREST·þÎñ£¬ÐèҪдºÜ¶à´úÂ룬Á¬WSGIµÄÈë¿Úº¯Êý¶¼Òª×Ô¼ºÊµÏÖ£¨±ÈÈçKeystoneÏîÄ¿µÄkeystone/common/wsgi.pyÎļþÖеÄclass
Application£©¡£ÒòΪÁé»îÐԵĺô¦²»ÊǺÜÃ÷ÏÔ£¬¶ø´úÂëÁ¿´óµÄ»µ´¦ºÜÃ÷ÏÔ£¬±ÈÈçÉÏÃæÄǸöclass ApplicationÐèÒªÔÚÿ¸öÏîÄ¿Öи´ÖÆÒ»±é£¬ËùÒÔÉçÇøµÄÐÂÏîÄ¿¾Í¿ªÊ¼Ê¹ÓÃеÄWeb¿ò¼ÜPecan¡£
PecanÊÇÒ»¸ö»ùÓÚ¶ÔÏó·ÓɵĿò¼Ü£¬¼´Áé»îÓÖ¼òµ¥¡£PecanÖ÷ҪʵÏÖÁËURL·Óɹ¦ÄÜ£¬Ö§³ÖRESTful
API¡£PecanûÓÐʵÏÖÄ£°å¡¢session¹ÜÀíºÍORMµÈ¹¦ÄÜ£¬µ«ÊÇÕâЩ¹¦ÄÜ¿ÉÒÔͨ¹ýÆäËûµÄÄ£¿éÀ´ÊµÏÖ¡£¶ÔÓÚOpenStackÀ´Ëµ£¬PecanÊÇÒ»¸öºÜºÃµÄÑ¡Ôñ£¬ÒòΪOpenStackÏîÄ¿ÖÐͳһʹÓÃsqlalchemyÀ´ÊµÏÖORM£¬APIµÄʵÏÖÒ²²»ÐèҪģ°å¹¦ÄÜ£¬°²È«¿ØÖÆÔò»ùÓÚKeystoneÌåϵ¡£Ê¹ÓÃPecanÀ´¿ª·¢REST·þÎñ£¬´úÂëÁ¿ºÜÉÙ£¬´úÂë½á¹¹Ò²ÇåÎú¡£CeilometerÏîÄ¿¾ÍÊÇʹÓÃÁËPecan¡£
±¾ÎÄ»áÖØµã½²½âOpenStackÖÐʹÓõÄAPI¿ª·¢¿ò¼ÜµÄʹÓᣵ«ÊDZ¾ÎĵÄÄ¿µÄ²¢²»ÊǸ²¸ÇÕâЩ¿ò¼ÜµÄʹÓÃϸ½Ú£¬¶øÊÇͨ¹ý˵Ã÷ÖØÒªµÄ²¿·Ö£¬½µµÍ³õѧÕßµÄÈëÃŵÄÃż÷¡£¿ò¼ÜµÄʹÓÃϸ½Ú¶¼¿ÉÒÔ´ÓÎĵµÖÐÕÒµ½¡£ËµÃ÷һϣ¬³ý·ÇÌØÊâ˵Ã÷£¬±¾ÎÄÖеÄÏà¶Ô·¾¶¶¼ÊÇÏà¶ÔÓÚÏîĿԴÂëĿ¼µÄÏà¶Ô·¾¶¡£
Paste + PasteDeploy + Routes + WebOb
ÎÒÃÇÔÚAPI·þÎñ(1)ÖÐÒѾÌáµ½ÁË£¬Õâ¸ö¿ò¼ÜÖ»ÔÚÔçÆÚ¿ªÊ¼µÄÏîÄ¿ÖÐʹÓã¬ÐµÄÏîÄ¿¶¼ÒѾתµ½Pecan¿ò¼ÜÁË¡£µ«ÊÇ£¬ÔçÆÚµÄÏîÄ¿¶¼ÊDZȽϺËÐĵÄÏîÄ¿£¬Òò´ËÎÒÃÇ»¹ÊÇҪѧ»áÈçºÎʹÓÃÕâ¸ö¿ò¼Ü¡£ÎÒÃÇ»áÒÔKeystoneÏîĿΪÀý£¬À´ËµÃ÷ÈçºÎÔĶÁʹÓÃÕâ¸ö¿ò¼ÜµÄ¿ª·¢µÄAPI´úÂë¡£
ÖØµãÔÚÓÚÈ·¶¨URL·ÓÉ
RESTful API³ÌÐòµÄÖ÷ÒªÌØµã¾ÍÊÇURL path»áºÍ¹¦ÄܶÔÓ¦ÆðÀ´¡£Õâµã´ÓAPIÎĵµ¾Í¿ÉÒÔ¿´µÃ³öÀ´£¬±ÈÈçÓû§¹ÜÀíµÄ¹¦ÄÜÒ»°ã¶¼·ÅÔÚ/userÕâ¸ö·¾¶Ï¡£Òò´Ë£¬¿´Ò»¸öRESTful
API³ÌÐò£¬Ò»°ã¶¼ÊÇ¿´ËüʵÏÖÁËÄÄЩURL path£¬ÒÔ¼°Ã¿¸öpath¶ÔÓ¦ÁËʲô¹¦ÄÜ£¬Õâ¸öÒ»°ã¶¼ÊÇÓÉ¿ò¼ÜµÄURL·Óɹ¦ÄܸºÔðµÄ¡£ËùÒÔ£¬ÊìϤһ¸öRESTful
API³ÌÐòµÄÖØµãÔÚÓÚÈ·¶¨URL·ÓÉ¡£±¾ÕÂËù˵µÄÕâ¸ö¿ò¼Ü¶ÔÓÚ³õѧÕßµÄÄѵãÒ²ÊÇÈçºÎÈ·¶¨URL·ÓÉ¡£
WSGIÈë¿ÚºÍÖмä¼þ×÷Ϊ»ù´¡ÖªÊ¶£¬ÄãÐèÒªÏÈÁ˽âÒ»ÏÂWSGIµÄÏà¹Ø¸ÅÄ¿ÉÒԲο¼ÕâÆªÎÄÕÂWSGI¼ò½é¡£
WSGIÈë¿Ú
ÔÚAPI·þÎñ(1)ÖÐÌáµ½ÁËWSGI¿ÉÒÔʹÓÃApache½øÐв¿Êð£¬Ò²¿ÉÒÔʹÓÃeventlet½øÐв¿Êð¡£KeystoneÏîĿͬʱÌṩÁËÕâÁ½ÖÖ·½°¸µÄ´úÂ룬Ҳ¾ÍÊÇÎÒÃÇÒªÕÒµÄWSGIµÄÈë¿Ú¡£
KeystoneÏîÄ¿ÔÚhttpd/Ŀ¼Ï£¬´æ·ÅÁË¿ÉÒÔÓÃÓÚApache·þÎñÆ÷²¿ÊðWSGI·þÎñµÄÎļþ¡£ÆäÖУ¬wsgi-keystone.confÊÇÒ»¸ömod_wsgiµÄʾÀýÅäÖÃÎļþ£¬keystone.pyÔòÊÇWSGIÓ¦ÓóÌÐòµÄÈë¿ÚÎļþ¡£httpd/keystone.pyÒ²¾ÍÊÇÎÒÃÇÒªÕÒµÄÈë¿ÚÎļþÖ®Ò»¡£Õâ¸öÎļþµÄÄÚÈݺܼòµ¥£º
import os from keystone.server import wsgi as wsgi_server name = os.path.basename(__file__) application = wsgi_server.initialize_application(name) |
ÎļþÖд´½¨ÁËWSGIÈë¿ÚÐèҪʹÓõÄapplication¶ÔÏó¡£
keystone-allÃüÁîÔòÊDzÉÓÃeventletÀ´½øÐв¿ÊðʱµÄÈë¿Ú£¬¿ÉÒÔ´Ósetup.cfgÎļþ°´ÖÐÈ·¶¨keystone-allÃüÁîµÄÈë¿Ú£º
[entry_points] console_scripts = keystone-all = keystone.cmd.all:main keystone-manage = keystone.cmd.manage:main |
´Ósetup.cfgÎļþµÄentry_points²¿·Ö¿ÉÒÔ¿´³ö£¬keystone-allµÄÈë¿ÚÊÇkeystone/cmd/all.pyÎļþÖеÄmain()º¯Êý£¬Õâ¸öº¯ÊýµÄÄÚÈÝÒ²ºÜ¼òµ¥£º
def main(): eventlet_server.run(possible_topdir) |
main()º¯ÊýµÄÖ÷Òª×÷ÓþÍÊÇÆô¶¯Ò»¸öeventlet_server£¬ÅäÖÃÎļþ´Ópossible_topdirÖвéÕÒ¡£ÒòΪeventletµÄ²¿Êð·½Ê½Éæ¼°µ½eventlet¿âµÄʹÓ÷½·¨£¬±¾ÎIJ»ÔÙÕ¹¿ªËµÃ÷¡£¶ÁÕß¿ÉÒÔÔÚѧ»áÈ·¶¨URL·ÓɺóÔÙ»ØÀ´¿´Õâ¸ö´úÂë¡£ÏÂÃæ£¬¼ÌÐøÒÔhttpd/keystone.pyÎļþ×÷ΪÈë¿ÚÀ´ËµÃ÷ÈçºÎÔĶÁ´úÂë¡£
PasteºÍPasteDeploy
httpd/keystone.pyÖе÷ÓõÄinitialize_application(name)º¯ÊýÔØÈëÁËÕû¸öWSGIÓ¦Óã¬ÕâÀïÖ÷ÒªÓõ½ÁËPasteºÍPasteDeploy¿â¡£
def initialize_application(name): ... def loadapp(): return keystone_service.loadapp( 'config:%s' % config.find_paste_config(), name)
_unused, application = common.setup_backends(
startup_application_fn=loadapp)
return application |
ÉÏÃæÊÇɾµôÎ޹شúÂëºóµÄinitialize_application()º¯Êý¡£config.find_paste_config()ÓÃÀ´²éÕÒPasteDeployÐèÒªÓõ½µÄWSGIÅäÖÃÎļþ£¬Õâ¸öÎļþÔÚÔ´ÂëÖÐÊÇetc/keystone-paste.iniÎļþ£¬Èç¹ûÔÚÏßÉÏ»·¾³ÖУ¬Ò»°ãÊÇ/etc/keystone-paste.init¡£keystone_service.loadapp()º¯ÊýÄÚ²¿Ôòµ÷ÓÃÁËpaste.deploy.loadapp()º¯ÊýÀ´¼ÓÔØWSGIÓ¦Óã¬ÈçºÎ¼ÓÔØÔòʹÓÃÁ˸ղÅÌáµ½µÄkeystone-paste.iniÎļþ£¬Õâ¸öÎļþÒ²ÊÇ¿´¶®Õû¸ö³ÌÐòµÄ¹Ø¼ü¡£
nameºÜ¹Ø¼ü
ÔÚÉÏÃæµÄ´úÂëÖÐÎÒÃÇ¿ÉÒÔ¿´µ½£¬nameÕâ¸ö±äÁ¿´Óhttpd/keystone.pyÎļþ´«µÝµ½initialize_application()º¯Êý£¬ÓÖ±»´«µÝµ½keystone_service.loadapp()º¯Êý£¬×îÖÕ±»´«µÝµ½paste.deploy.loadapp()º¯Êý¡£ÄÇô£¬Õâ¸öname±äÁ¿µ½µ×Æðʲô×÷ÓÃÄØ£¿ÏȰÑÕâ¸öÎÊÌâ·ÅÔÚÒ»±ß£¬ÎÒÃǺóÃæÔÙÀ´½â¾öËü¡£
paste.ini
ʹÓÃPasteºÍPasteDeployÄ£¿éÀ´ÊµÏÖWSGI·þÎñʱ£¬¶¼ÐèÒªÒ»¸öpaste.iniÎļþ¡£Õâ¸öÎļþÒ²ÊÇPaste¿ò¼ÜµÄ¾«Ë裬ÕâÀïÐèÒªÖØµã˵Ã÷Ò»ÏÂÕâ¸öÎļþÈçºÎÔĶÁ¡£
paste.iniÎļþµÄ¸ñʽÀàËÆÓÚINI¸ñʽ£¬Ã¿¸ösectionµÄ¸ñʽΪ[type:name]¡£ÕâÀïÖØÒªµÄÊÇÀí½â¼¸ÖÖ²»Í¬typeµÄsectionµÄ×÷Óá£
composite: ÕâÖÖsectionÓÃÓÚ½«HTTPÇëÇó·Ö·¢µ½Ö¸¶¨µÄapp¡£
app: ÕâÖÖsection±íʾ¾ßÌåµÄapp¡£
filter: ʵÏÖÒ»¸ö¹ýÂËÆ÷Öмä¼þ¡£
pipeline: ÓÃÀ´°Ñ°ÑһϵÁеÄfilter´®ÆðÀ´¡£
ÉÏÃæÕâЩsectionÊÇÔÚkeystoneµÄpaste.iniÖÐÓõ½µÄ£¬ÏÂÃæÏêϸ½éÉÜÒ»ÏÂÈçºÎʹÓá£ÕâÀïÐèÒªÓõ½WSGIMiddleware(WSGIÖмä¼þ)µÄ֪ʶ£¬¿ÉÒÔÔÚWSGI¼ò½éÕâÆªÎÄÕÂÖÐÕÒµ½¡£
section composite
ÕâÖÖsectionÓÃÀ´¾ö¶¨ÈçºÎ·Ö·¢HTTPÇëÇó¡£KeystoneµÄpaste.iniÎļþÖÐÓÐÁ½¸öcompositeµÄsection£º
[composite:main] use = egg:Paste#urlmap /v2.0 = public_api /v3 = api_v3 / = public_version_api
[composite:admin]
use = egg:Paste#urlmap
/v2.0 = admin_api
/v3 = api_v3
/ = admin_version_api |
ÔÚcomposite seciontÖУ¬useÊÇÒ»¸ö¹Ø¼ü×Ö£¬Ö¸¶¨´¦ÀíÇëÇóµÄ´úÂë¡£egg:Paste#urlmap±íʾµ½PasteÄ£¿éµÄegg-infoÖÐÈ¥²éÕÒurlmap¹Ø¼ü×ÖËù¶ÔÓ¦µÄº¯Êý¡£ÔÚvirtualenv»·¾³Ï£¬ÊÇÎļþ/lib/python2.7/site-packages/Paste-2.0.2.dist-info/metadata.json£º
{ ... "extensions": { ... "python.exports": { "paste.composite_factory": { "cascade": "paste.cascade:make_cascade", "urlmap": "paste.urlmap:urlmap_factory" }, ... } |
ÔÚÕâ¸öÎļþÖУ¬Äã¿ÉÒÔÕÒµ½urlmap¶ÔÓ¦µÄÊÇpaste.urlmap:urlmap_factory£¬Ò²¾ÍÊÇpaste/urlmap.pyÎļþÖеÄurlmap_factory()º¯Êý¡£
composite sectionÖÐÆäËûµÄ¹Ø¼ü×ÖÔòÊÇurlmap_factory()º¯ÊýµÄ²ÎÊý£¬ÓÃÓÚ±íʾ²»Í¬µÄURL
pathǰ׺¡£urlmap_factory()º¯Êý»á·µ»ØÒ»¸öWSGI app£¬Æä¹¦ÄÜÊǸù¾Ý²»Í¬µÄURL
pathǰ׺£¬°ÑÇëÇó·Óɸø²»Í¬µÄapp¡£ÒÔ[composite:main]ΪÀý£º
[composite:main] use = egg:Paste#urlmap /v2.0 = public_api # /v2.0¡¡¿ªÍ·µÄÇëÇó»á·Óɸøpublic_api´¦Àí /v3 = api_v3 # /v3¡¡¿ªÍ·µÄÇëÇó»á·Óɸöapi_v3´¦Àí / = public_version_api # / ¿ªÍ·µÄÇëÇó»á·Óɸøpublic_version_api´¦Àí |
·ÓɵĶÔÏóÆäʵ¾ÍÊÇpaste.iniÖÐÆäËûsecionµÄÃû×Ö£¬ÀàÐͱØÐëÊÇapp»òÕßpipeline¡£
section pipeline
pipelineÊǰÑfilterºÍapp´®ÆðÀ´µÄÒ»ÖÖsection¡£ËüÖ»ÓÐÒ»¸ö¹Ø¼ü×Ö¾ÍÊÇpipeline¡£ÎÒÃÇÒÔapi_v3Õâ¸öpipelineΪÀý£º
[pipeline:api_v3] # The last item in this pipeline must be service_v3 or an equivalent # application. It cannot be a filter. pipeline = sizelimit url_normalize request_id build_auth_context token_auth admin_token_auth json_body ec2_extension_v3 s3_extension simple_cert_extension revoke_extension federation_extension oauth1_extension endpoint_filter_extension endpoint_policy_extension service_v3 |
pipeline¹Ø¼ü×ÖÖ¸¶¨Á˺ܶà¸öÃû×Ö£¬ÕâЩÃû×ÖÒ²ÊÇpaste.iniÎļþÖÐÆäËûsectionµÄÃû×Ö¡£ÇëÇó»á´Ó×îÇ°ÃæµÄsection¿ªÊ¼´¦Àí£¬Ò»Ö±Ïòºó´«µÝ¡£pipelineÖ¸¶¨µÄsectionÓÐÈçÏÂÒªÇó£º
×îºóÒ»¸öÃû×Ö¶ÔÓ¦µÄsectionÒ»¶¨ÒªÊÇÒ»¸öapp¡£
·Ç×îºóÒ»¸öÃû×Ö¶ÔÓ¦µÄsectionÒ»¶¨ÒªÊÇÒ»¸öfilter¡£
section filter
filterÊÇÓÃÀ´¹ýÂËÇëÇóºÍÏìÓ¦µÄ£¬ÒÔWSGIÖмä¼þµÄ·½Ê½ÊµÏÖ¡£
[filter:sizelimit] paste.filter_factory = oslo_middleware.sizelimit:RequestBodySizeLimiter.factory |
Õâ¸öÊÇapi_v3Õâ¸öpipelineÖ¸¶¨µÄµÚÒ»¸öfilter£¬×÷ÓÃÊÇÏÞÖÆÇëÇóµÄ´óС¡£ÆäÖеÄpaste.filter_factory±íʾµ÷ÓÃÄĸöº¯ÊýÀ´»ñµÃÕâ¸öfilterÖмä¼þ¡£
section app
app±íʾʵÏÖÖ÷Òª¹¦ÄܵÄÓ¦Óã¬ÊÇÒ»¸ö±ê×¼µÄWSGI application¡£
[app:service_v3] paste.app_factory = keystone.service:v3_app_factory |
paste.app_factory±íʾµ÷ÓÃÄĸöº¯ÊýÀ´»ñµÃÕâ¸öapp¡£
×ܽáÒ»ÏÂ
paste.iniÖÐÕâÒ»´ó¶ÑÅäÖõÄ×÷ÓþÍÊǰÑÎÒÃÇÓÃPythonдµÄWSGI
applicationºÍmiddleware´®ÆðÀ´£¬¹æ¶¨ºÃHTTPÇëÇó´¦ÀíµÄ·¾¶¡£
nameÊÇÓÃÀ´È·¶¨Èë¿ÚµÄ
ÉÏÃæÎÒÃÇÌáµ½ÁËÒ»¸öÎÊÌ⣬¾ÍÊÇname±äÁ¿µÄ×÷Óõ½µ×ÊÇʲô£¿name±äÁ¿±íʾpaste.iniÖÐÒ»¸ösectionµÄÃû×Ö£¬Ö¸¶¨Õâ¸ösection×÷ΪHTTPÇëÇó´¦ÀíµÄµÚÒ»Õ¾¡£ÔÚKeystoneµÄpaste.iniÖУ¬ÇëÇó±ØÐëÏÈÓÉ[composite:main]»òÕß[composite:admin]´¦Àí£¬ËùÒÔÔÚkeystoneÏîÄ¿ÖУ¬nameµÄÖµ±ØÐëÊÇmain»òÕßadmin¡£
ÉÏÃæÌáµ½µÄhttpd/keystone.pyÎļþÖУ¬nameµÈÓÚÎļþÃûµÄbasename£¬ËùÒÔʵ¼Ê²¿ÊðÖУ¬±ØÐë°Ñkeystone.pyÖØÃüÃûΪmain.py»òÕßadmin.py¡£
¾Ù¸öÀý×Ó
Ò»°ãÇé¿öÏ£¬´ÓKeystone·þÎñ»ñȡһ¸ötokenʱ£¬»áʹÓÃÏÂÃæÕâ¸öAPI£º
POST http://hostname:35357/v3/auth/tokens |
ÎÒÃǸù¾ÝKeystoneµÄpaste.iniÀ´ËµÃ÷Õâ¸öAPIÊÇÈçºÎ±»´¦ÀíµÄ£º
hostname:35357 ÕâÒ»²¿·ÖÊÇÓÉWeb·þÎñÆ÷´¦ÀíµÄ£¬±ÈÈçApache¡£È»ºó£¬ÇëÇó»á±»×ªµ½WSGIµÄÈë¿Ú£¬Ò²¾ÍÊÇhttpd/keystone.pyÖеÄapplication¶ÔÏóÈ¡´¦Àí¡£
application¶ÔÏóÊǸù¾Ýpaste.iniÖеÄÅäÖÃÀ´´¦ÀíµÄ¡£ÕâÀï»áÏÈÓÉ[composite:admin]À´´¦Àí£¨Ò»°ãÊÇadmin¼àÌý35357¶Ë¿Ú£¬main¼àÌý5000¶Ë¿Ú£©¡£
[composite:admin]·¢ÏÖÇëÇóµÄpathÊÇ/v3¿ªÍ·µÄ£¬ÓÚÊǾͰÑÇëÇóת·¢¸ø[pipeline:api_v3]È¥´¦Àí£¬×ª·¢Ö®Ç°£¬»á°Ñ/v3Õâ¸ö²¿·ÖÈ¥µô¡£
[pipeline:api_v3]ÊÕµ½ÇëÇó£¬pathÊÇ/auth/tokens£¬È»ºó¿ªÊ¼µ÷Óø÷¸öfilterÀ´´¦ÀíÇëÇó¡£×îºó»á°ÑÇëÇ󽻸ø[app:service_v3]½øÐд¦Àí¡£
[app:service_v3]ÊÕµ½ÇëÇó£¬pathÊÇ/auth/tokens£¬È»ºó½»¸ø×îÖÕµÄWSGI
appÈ¥´¦Àí¡£
ÏÂÒ»²½
µ½´ËΪֹ£¬paste.iniÖеÄÅäÖõÄËùÓй¤×÷¶¼ÒѾ×öÍêÁË¡£ÏÂÃæÇëÇó¾ÍÒª×ªÒÆµ½×îÖÕµÄappÄÚ²¿È¥´¦ÀíÁË¡£Ç°ÃæÒѾ˵¹ýÁË£¬ÎÒÃǵÄÖØµãÊÇÈ·¶¨URL·ÓÉ£¬ÄÇôÏÖÔÚ»¹ÓÐÒ»²¿·ÖµÄpathµÄ·ÓÉ»¹Ã»È·¶¨£¬/auth/tokens£¬Õâ¸ö»¹ÐèÒªÏÂÒ»²½µÄ¹¤×÷¡£
Öмä¼þµÄʵÏÖ
ÉÏÃæÎÒÃÇÌáµ½paste.iniÖÐÓõ½ÁËÐí¶àµÄWSGIÖмä¼þ£¬ÄÇôÕâЩÖмä¼þÊÇÈçºÎʵÏÖµÄÄØ£¿ÎÒÃÇÀ´¿´Ò»¸öÀý×Ó¾ÍÖªµÀÁË¡£
[filter:build_auth_context] paste.filter_factory = keystone.middleware:AuthContextMiddleware.factory |
build_auth_contextÕâ¸öÖмä¼þµÄ×÷ÓÃÊÇÔÚWSGIµÄenvironÖÐÌí¼ÓKEYSTONE_AUTH_CONTEXTÕâ¸ö¼ü£¬°üº¬µÄÄÚÈÝÊÇÈÏÖ¤ÐÅÏ¢µÄÉÏÏÂÎÄ¡£ÊµÏÖÕâ¸öÖмä¼þµÄÀà¼Ì³Ð¹ØÏµÈçÏ£º
keystone.middleware.core.AuthContextMiddleware -> keystone.common.wsgi.Middleware -> keystone.common.wsgi.Application -> keystone.common.wsgi.BaseApplication |
ÕâÀïʵÏֵĹؼüÖ÷ÒªÔÚÇ°ÃæÁ½¸öÀàÖС£
keystone.common.wsgi.MiddlewareÀàʵÏÖÁË__call__()·½·¨£¬Õâ¸ö¾ÍÊÇWSGIÖÐapplication¶Ë±»µ÷ÓÃʱÔËÐеķ½·¨¡£
class Middleware(Application): ... @webob.dec.wsgify() def __call__(self, request): try: response = self.process_request(request) if response: return response response = request.get_response(self.application) return self.process_response(request, response) except exceptin.Error as e: ... ... |
__call__()·½·¨ÊµÏÖΪ½ÓÊÕÒ»¸örequest¶ÔÏ󣬷µ»ØÒ»¸öresponse¶ÔÏóµÄÐÎʽ£¬È»ºóʹÓÃWebOBÄ£¿éµÄ×°ÊÎÆ÷webob.dec.wsgify()½«Ëü±ä³É±ê×¼µÄWSGI
application½Ó¿Ú¡£ÕâÀïµÄrequestºÍresponse¶ÔÏó·Ö±ðÊÇwebob.RequestºÍwebob.Response¡£ÕâÀ__call__()·½·¨ÄÚ²¿µ÷ÓÃÁËself.process_request()·½·¨£¬Õâ¸ö·½·¨ÔÚkeystone.middleware.core.AuthContextMiddlewareÖÐʵÏÖ£º
class AuthContextMiddleware(wsgi.Middleware): ... def process_request(self, request): ... request.environ[authorization.AUTH_CONTEXT_ENV] = auth_context |
Õâ¸öº¯Êý»á¸ù¾Ý¹¦ÄÜÉè¼Æ´´½¨auth_context£¬È»ºó¸³Öµ¸ø`request.environ[¡®KEYSTONE_AUTH_CONTEXT]¡°£¬ÕâÑù¾ÍÄÜͨ¹ýWSGI
application·½·¨µÄenviron´«µÝµ½ÏÂÒ»¸öWSGI applicationÖÐÈ¥ÁË¡£
×îºóµÄApplication
ÉÏÃæÎÒÃÇÒѾ¿´µ½ÁË£¬¶ÔÓÚ/v3¿ªÍ·µÄÇëÇó£¬ÔÚpaste.iniÖлᱻ·Óɵ½[app:service_v3]Õâ¸ösection£¬»á½»¸økeystone.service:v3_app_factoryÕâ¸öº¯ÊýÉú³ÉµÄapplication´¦Àí¡£×îºóÕâ¸öapplicationÐèÒª¸ù¾ÝURL
pathÖÐʣϵIJ¿·Ö£¬/auth/tokens£¬À´ÊµÏÖURL·ÓÉ¡£´ÓÕâÀ↑ʼ£¬¾ÍÐèÒªÓõ½RoutesÄ£¿éÁË¡£
ͬÑùÓÉÓÚÆª·ùÏÞÖÆ£¬ÎÒÃÇÖ»ÄÜչʾRoutesÄ£¿éµÄ´ó¸ÅÓ÷¨¡£RoutesÄ£¿éÊÇÓÃPythonʵÏÖµÄÀàËÆRailsµÄURL·ÓÉϵͳ£¬ËüµÄÖ÷Òª¹¦ÄܾÍÊǰÑpathÓ³Éäµ½¶ÔÓ¦µÄ¶¯×÷¡£
RoutesÄ£¿éµÄÒ»°ãÓ÷¨ÊÇ´´½¨Ò»¸öMapper¶ÔÏó£¬È»ºóµ÷ÓøöÔÏóµÄconnect()·½·¨°ÑpathºÍmethodÓ³Éäµ½Ò»¸öcontrollerµÄij¸öactionÉÏ£¬ÕâÀïcontrollerÊÇÒ»¸ö×Ô¶¨ÒåµÄÀàʵÀý£¬actionÊDZíʾcontroller¶ÔÏóµÄ·½·¨µÄ×Ö·û´®¡£Ò»°ãµ÷ÓõÄʱºò»¹»áÖ¸¶¨Ó³ÉäÄÄЩ·½·¨£¬±ÈÈçGET»òÕßPOSTÖ®ÀàµÄ¡£
¾Ù¸öÀý×Ó£¬À´¿´ÏÂkeystone/auth/routers.pyµÄ´úÂ룺
class Routers(wsgi.RoutersBase):
def append_v3_routers(self, mapper, routers): auth_controller = controllers.Auth()
self._add_resource( mapper, auth_controller, path='/auth/tokens', get_action='validate_token', head_action='check_token', post_action='authenticate_for_token', delete_action='revoke_token', rel=json_home.build_v3_resource_relation('auth_tokens'))
...
|
ÕâÀïµ÷ÓÃÁË×Ô¼ºKeystone×Ô¼º·â×°µÄ_add_resource()·½·¨ÅúÁ¿ÎªÒ»¸ö/auth/tokensÕâ¸öpathÌí¼Ó¶à¸ö·½·¨µÄ´¦Àíº¯Êý¡£ÆäÖУ¬controllerÊÇÒ»¸öcontrollers.AuthʵÀý£¬Ò²¾ÍÊÇ
keystone.auth.controllers.Auth¡£ÆäËûµÄ²ÎÊý£¬ÎÒÃÇ´ÓÃû³Æ¿ÉÒԲ³öÆä×÷ÓÃÊÇÖ¸¶¨¶ÔÓ¦·½·¨µÄ´¦Àíº¯Êý£¬±ÈÈçget_actionÓÃÓÚÖ¸¶¨GET·½·¨µÄ´¦Àíº¯ÊýΪvalidate_token¡£ÎÒÃÇÔÙÉîÈëһϣ¬¿´ÏÂ_add_resource()Õâ¸ö·½·¨µÄʵÏÖ£º
def _add_resource(self, mapper, controller, path, rel, get_action=None, head_action=None, get_head_action=None, put_action=None, post_action=None, patch_action=None, delete_action=None, get_post_action=None, path_vars=None, status=json_home.Status.STABLE): ... if get_action: getattr(controller, get_action) # ensure the attribute exists mapper.connect(path, controller=controller, action=get_action, conditions=dict(method=['GET']))
|
Õâ¸öº¯ÊýÆäʵºÜ¼òµ¥£¬¾ÍÊǵ÷ÓÃmapper¶ÔÏóµÄconnect·½·¨Ö¸¶¨Ò»¸öpathµÄijЩmethodµÄ´¦Àíº¯Êý¡£
KeystoneÏîÄ¿µÄ´úÂë½á¹¹
KeystoneÏîÄ¿°Ñÿ¸ö¹¦Äܶ¼·Öµ½µ¥¶ÀµÄĿ¼Ï£¬±ÈÈçtokenÏà¹ØµÄ¹¦ÄÜÊÇ·ÅÔÚkeystone/token/Ŀ¼Ï£¬assignmentÏà¹ØµÄ¹¦ÄÜÊÇ·ÅÔÚkeystone/assignment/Ŀ¼Ï¡£Ä¿Â¼Ï¶¼Ò»°ã»áÓÐÈý¸öÎļþ£ºrouters.py,
controllers.py, core.py¡£routers.pyÖÐʵÏÖÁËURL·ÓÉ£¬°ÑURLºÍcontrollers.pyÖеÄaction¶ÔÓ¦ÆðÀ´£»controllers.pyÖеÄactionµ÷ÓÃcore.pyÖеĵײã½Ó¿ÚʵÏÖRESTful
API³ÐŵµÄ¹¦ÄÜ¡£ËùÒÔ£¬ÎÒÃÇÒª½øÒ»²½È·¶¨URL·ÓÉÊÇÈçºÎ×öµÄ£¬¾ÍÒª¿´routers.pyÎļþ¡£
×¢Ò⣬Õâ¸öÖ»ÊÇKeystoneÏîÄ¿µÄ½á¹¹£¬ÆäËûÏîÄ¿¼´Ê¹ÓÃÁËͬÑùµÄ¿ò¼Ü£¬Ò²²»Ò»¶¨ÊÇÕâô×öµÄ¡£
KeystoneÖеÄ·ÓÉ»ã×Ü
ÿ¸öÄ£¿é¶¼¶¨ÒåÁË×Ô¼ºµÄ·ÓÉ£¬µ«ÊÇÕâЩ·ÓÉ×îÖÕÒª»¹ÊÇҪͨ¹ýÒ»¸öWSGI applicationÀ´µ÷Óõġ£ÉÏÃæÒѾÌáµ½ÁË£¬ÔÚKeystoneÖУ¬/v3¿ªÍ·µÄÇëÇó×îÖÕ¶¼»á½»¸økeystone.service.v3_app_factoryÕâ¸öº¯ÊýÉú³ÉµÄapplicationÀ´´¦Àí¡£Õâ¸öº¯ÊýÀïÒ²°üº¬ÁË·ÓÉ×îºó·Ö·¢µÄÃØÃÜ£¬ÎÒÃÇÀ´¿´´úÂ룺
def v3_app_factory(global_conf, **local_conf): ... mapper = routes.Mapper() ...
router_modules = [auth,
assignment,
catalog,
credential,
identity,
policy,
resource]
...
for module in router_modules:
routers_instance = module.routers.Routers()
_routers.append(routers_instance)
routers_instance.append_v3_routers(mapper, sub_routers)
# Add in the v3 version api
sub_routers.append(routers.VersionV3('public',
_routers))
return wsgi.ComposingRouter(mapper, sub_routers) |
v3_app_factory()º¯ÊýÖÐÏȱéÀúÁËËùÓеÄÄ£¿é£¬½«Ã¿¸öÄ£¿éµÄ·Óɶ¼Ìí¼Óµ½Í¬Ò»¸ömapper¶ÔÏóÖУ¬È»ºó°Ñmapper¶ÔÏó×÷Ϊ²ÎÊýÓÃÓÚ³õʼ»¯wsgi.ComposingRouter¶ÔÏó£¬ËùÒÔÎÒÃÇ¿ÉÒÔÅжϣ¬Õâ¸öwsgi.ComposingRouter¶ÔÏóÒ»¶¨ÊÇÒ»¸öWSGI
application£¬ÎÒÃÇ¿´¿´´úÂë¾ÍÖªµÀÁË£º
class Router(object): """WSGI middleware that maps incoming requests to WSGI apps."""
def __init__(self, mapper):
self.map = mapper
self._router = routes.middleware.RoutesMiddleware(self._dispatch,
self.map)
@webob.dec.wsgify()
def __call__(self, req):
return self._router
...
class ComposingRouter(Router):
def __init__(self, mapper=None, routers=None):
... |
ÉÏÊö´úÂë֤ʵÁËÎÒÃǵIJ²⡣Õâ¸öComposingRouter¶ÔÏó±»µ÷ÓÃʱ£¨ÔÚÆä¸¸ÀàRouterÖÐʵÏÖ£©£¬»á·µ»ØÒ»¸öWSGI
application¡£Õâ¸öapplicationÖÐÔòʹÓÃÁËroutesÄ£¿éµÄÖмä¼þÀ´ÊµÏÖÁËÇëÇó·ÓÉ£¬ÔÚroutes.middleware.RoutesMiddlewareÖÐʵÏÖ¡£ÕâÀï¶Ôpath½øÐзÓɵĽá¹û¾ÍÊÇ·µ»Ø¸÷¸öÄ£¿éµÄcontrollers.pyÖж¨ÒåµÄcontroller¡£¸÷¸öÄ£¿éµÄcontroller¶¼ÊÇÒ»¸öWSGI
application£¬Õâ¸öÄã¿ÉÒÔͨ¹ýÕâЩcontrollerµÄÀà¼Ì³Ð¹ØÏµ¿´³öÀ´¡£
µ«ÊÇÕâÀïÖ»½²µ½ÁË£¬routesÄ£¿é°ÑpathÓ³Éäµ½ÁËÒ»¸öcontroller£¬µ«ÊÇÈçºÎ°Ñ¶ÔpathµÄ´¦ÀíÓ³Éäµ½controllerµÄ·½·¨ÄØ£¿Õâ¸ö¿ÉÒÔ´ÓcontrollerµÄ¸¸Ààkeystone.common.wsgi.ApplicationµÄʵÏÖ¿´³öÀ´¡£Õâ¸öApplicationÀàÖÐʹÓÃÁËenviron['wsgiorg.routing_args']ÖеÄÊý¾ÝÀ´È·¶¨µ÷ÓÃcontrollerµÄÄĸö·½·¨£¬ÕâЩÊý¾ÝÊÇÓÉÉÏÃæÌáµ½µÄroutes.middleware.RoutesMiddlewareÉèÖõġ£
×ܽᵽÕâÀïÎÒÃÇ´ó¸Å°ÑPaste + PasteDeploy + Routes
+ WebObÕâ¸ö¿ò¼ÜµÄÁ÷³Ì½²ÁËÒ»±é£¬´Ó±¾Îĵij¤¶ÈÄã¾Í¿ÉÒÔ¿´³öÕâ¸ö¿ò¼ÜÓÐ¶à†ªà£¬ÓÃÆðÀ´ÓжàÂé·³¡£ÏÂһƪÎÄÕÂÎÒÃǻὲPecan¿ò¼Ü£¬ÎÒÃǵÄdemoÒ²½«»áʹÓÃPecan¿ò¼ÜÀ´¿ª·¢¡£
|