Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
ͨ¹ýdemoѧϰOpenStack¿ª·¢--API·þÎñ£¨ÉÏ£©
 
×÷ÕߣºÎºÐÇ À´Ô´£ºÁõ³Âãü ·¢²¼ÓÚ 2016-2-16
  3721  次浏览      32
 

ʹÓÃ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¿ò¼ÜÀ´¿ª·¢¡£

   
3721 ´Îä¯ÀÀ       32
 
Ïà¹ØÎÄÕÂ

ÔÆ¼ÆËãµÄ¼Ü¹¹
¶ÔÔÆ¼ÆËã·þÎñÄ£ÐÍ
ÔÆ¼ÆËãºËÐļ¼ÊõÆÊÎö
Á˽âÔÆ¼ÆËãµÄ©¶´
 
Ïà¹ØÎĵµ

ÔÆ¼ÆËã¼ò½é
ÔÆ¼ÆËã¼ò½éÓëÔÆ°²È«
ÏÂÒ»´úÍøÂç¼ÆËã--ÔÆ¼ÆËã
ÈídzÎöÔÆ¼ÆËã
 
Ïà¹Ø¿Î³Ì

ÔÆ¼ÆËãÔ­ÀíÓëÓ¦ÓÃ
ÔÆ¼ÆËãÓ¦ÓÃÓ뿪·¢
CMMIÌåϵÓëʵ¼ù
»ùÓÚCMMI±ê×¼µÄÈí¼þÖÊÁ¿±£Ö¤
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

ר¼ÒÊӽǿ´ITÓë¼Ü¹¹
Èí¼þ¼Ü¹¹Éè¼Æ
ÃæÏò·þÎñÌåϵ¼Ü¹¹ºÍÒµÎñ×é¼þµÄ˼¿¼
ÈËÈËÍøÒÆ¶¯¿ª·¢¼Ü¹¹
¼Ü¹¹¸¯»¯Ö®ÃÕ
̸ƽ̨¼´·þÎñPaaS
Ïà¹ØÅàѵ¿Î³Ì

ÔÆ¼ÆËãÔ­ÀíÓëÓ¦ÓÃ
Windows Azure ÔÆ¼ÆËãÓ¦ÓÃ

ĦÍÐÂÞÀ­ ÔÆÆ½Ì¨µÄ¹¹½¨ÓëÓ¦ÓÃ
ͨÓù«Ë¾GE DockerÔ­ÀíÓëʵ¼ù
ijÑз¢ÖÐÐÄ Openstackʵ¼ù
ÖªÃûµç×Ó¹«Ë¾ ÔÆÆ½Ì¨¼Ü¹¹ÓëÓ¦ÓÃ
ijµçÁ¦ÐÐÒµ »ùÓÚÔÆÆ½Ì¨¹¹½¨ÔÆ·þÎñ
ÔÆ¼ÆËãÓëWindows AzureÅàѵ
±±¾© ÔÆ¼ÆËãÔ­ÀíÓëÓ¦ÓÃ