OpenStack API映射分析
Nova代码阅读
确定服务类型
- RPC服务
- WSGI服务
查询cmd
目录下的对应的服务启动脚本,根据服务创建方式来判断服务类型,service.WSGIService
表示WSGI服务,service.Service.create
表示RPC服务
确认服务的入口
- RPC服务
找到service.py
文件的SERVICE_MANAGERS
变量,这个变量列举了RPC服务的实现类
SERVICE_MANAGERS = {
'nova-compute': 'nova.compute.manager.ComputeManager',
'nova-console': 'nova.console.manager.ConsoleProxyManager',
'nova-consoleauth': 'nova.consoleauth.manager.ConsoleAuthManager',
'nova-cert': 'nova.cert.manager.CertManager',
'nova-conductor': 'nova.conductor.manager.ConductorManager',
'nova-metadata': 'nova.api.manager.MetadataManager',
'nova-scheduler': 'nova.scheduler.manager.SchedulerManager',
'nova-cells': 'nova.cells.manager.CellsManager',
}
以其'nova-compute': 'nova.compute.manager.ComputeManager'
为例,其服务实现位于compute/manager.py
文件中,其对外提供的API接口位于compute/api.py
文件中,两者间的关联通过compute/rpcapi.py
文件完成。
- WSGI服务
首先找到/etc/nova/api-paste.ini
文件,找到app的入口
[app:osapi_compute_app_v21]
paste.app_factory = nova.api.openstack.compute:APIRouterV21.factory
然后找到api/openstack/compute/__init__.py
文件,分析class APIRouterV21
及其基类,找到api_extension_namespace
方法,这决定了需要加载的插件内容(处理类的实例):
@staticmethod
def api_extension_namespace():
return 'nova.api.v21.extensions'
然后我们找到setup.cfg
文件的对应命名空间
nova.api.v21.extensions =
admin_actions = nova.api.openstack.compute.admin_actions:AdminActions
admin_password = nova.api.openstack.compute.admin_password:AdminPassword
agents = nova.api.openstack.compute.agents:Agents
aggregates = nova.api.openstack.compute.aggregates:Aggregates
assisted_volume_snapshots = nova.api.openstack.compute.assisted_volume_snapshots:AssistedVolumeSnapshots
attach_interfaces = nova.api.openstack.compute.attach_interfaces:AttachInterfaces
availability_zone = nova.api.openstack.compute.availability_zone:AvailabilityZone
baremetal_nodes = nova.api.openstack.compute.baremetal_nodes:BareMetalNodes
block_device_mapping = nova.api.openstack.compute.block_device_mapping:BlockDeviceMapping
cells = nova.api.openstack.compute.cells:Cells
certificates = nova.api.openstack.compute.certificates:Certificates
cloudpipe = nova.api.openstack.compute.cloudpipe:Cloudpipe
config_drive = nova.api.openstack.compute.config_drive:ConfigDrive
console_auth_tokens = nova.api.openstack.compute.console_auth_tokens:ConsoleAuthTokens
console_output = nova.api.openstack.compute.console_output:ConsoleOutput
consoles = nova.api.openstack.compute.consoles:Consoles
create_backup = nova.api.openstack.compute.create_backup:CreateBackup
deferred_delete = nova.api.openstack.compute.deferred_delete:DeferredDelete
evacuate = nova.api.openstack.compute.evacuate:Evacuate
extended_availability_zone = nova.api.openstack.compute.extended_availability_zone:ExtendedAvailabilityZone
extended_server_attributes = nova.api.openstack.compute.extended_server_attributes:ExtendedServerAttributes
extended_status = nova.api.openstack.compute.extended_status:ExtendedStatus
extended_volumes = nova.api.openstack.compute.extended_volumes:ExtendedVolumes
extension_info = nova.api.openstack.compute.extension_info:ExtensionInfo
fixed_ips = nova.api.openstack.compute.fixed_ips:FixedIps
flavors = nova.api.openstack.compute.flavors:Flavors
flavors_extraspecs = nova.api.openstack.compute.flavors_extraspecs:FlavorsExtraSpecs
flavor_access = nova.api.openstack.compute.flavor_access:FlavorAccess
flavor_rxtx = nova.api.openstack.compute.flavor_rxtx:FlavorRxtx
flavor_manage = nova.api.openstack.compute.flavor_manage:FlavorManage
floating_ip_dns = nova.api.openstack.compute.floating_ip_dns:FloatingIpDns
floating_ip_pools = nova.api.openstack.compute.floating_ip_pools:FloatingIpPools
floating_ips = nova.api.openstack.compute.floating_ips:FloatingIps
floating_ips_bulk = nova.api.openstack.compute.floating_ips_bulk:FloatingIpsBulk
fping = nova.api.openstack.compute.fping:Fping
hide_server_addresses = nova.api.openstack.compute.hide_server_addresses:HideServerAddresses
hosts = nova.api.openstack.compute.hosts:Hosts
hypervisors = nova.api.openstack.compute.hypervisors:Hypervisors
images = nova.api.openstack.compute.images:Images
image_metadata = nova.api.openstack.compute.image_metadata:ImageMetadata
image_size = nova.api.openstack.compute.image_size:ImageSize
instance_actions = nova.api.openstack.compute.instance_actions:InstanceActions
instance_usage_audit_log = nova.api.openstack.compute.instance_usage_audit_log:InstanceUsageAuditLog
ips = nova.api.openstack.compute.ips:IPs
keypairs = nova.api.openstack.compute.keypairs:Keypairs
limits = nova.api.openstack.compute.limits:Limits
lock_server = nova.api.openstack.compute.lock_server:LockServer
migrate_server = nova.api.openstack.compute.migrate_server:MigrateServer
migrations = nova.api.openstack.compute.migrations:Migrations
multinic = nova.api.openstack.compute.multinic:Multinic
multiple_create = nova.api.openstack.compute.multiple_create:MultipleCreate
networks = nova.api.openstack.compute.networks:Networks
networks_associate = nova.api.openstack.compute.networks_associate:NetworksAssociate
pause_server = nova.api.openstack.compute.pause_server:PauseServer
# NOTE(cyeoh): this is intentionally disabled until microversions is active.
# See https://bugs.launchpad.net/nova/+bug/1426241
# pci = nova.api.openstack.compute.pci:Pci
quota_classes = nova.api.openstack.compute.quota_classes:QuotaClasses
quota_sets = nova.api.openstack.compute.quota_sets:QuotaSets
remote_consoles = nova.api.openstack.compute.remote_consoles:RemoteConsoles
rescue = nova.api.openstack.compute.rescue:Rescue
scheduler_hints = nova.api.openstack.compute.scheduler_hints:SchedulerHints
security_group_default_rules = nova.api.openstack.compute.security_group_default_rules:SecurityGroupDefaultRules
security_groups = nova.api.openstack.compute.security_groups:SecurityGroups
server_diagnostics = nova.api.openstack.compute.server_diagnostics:ServerDiagnostics
server_external_events = nova.api.openstack.compute.server_external_events:ServerExternalEvents
server_metadata = nova.api.openstack.compute.server_metadata:ServerMetadata
server_migrations = nova.api.openstack.compute.server_migrations:ServerMigrations
server_password = nova.api.openstack.compute.server_password:ServerPassword
server_tags = nova.api.openstack.compute.server_tags:ServerTags
server_usage = nova.api.openstack.compute.server_usage:ServerUsage
server_groups = nova.api.openstack.compute.server_groups:ServerGroups
servers = nova.api.openstack.compute.servers:Servers
services = nova.api.openstack.compute.services:Services
shelve = nova.api.openstack.compute.shelve:Shelve
simple_tenant_usage = nova.api.openstack.compute.simple_tenant_usage:SimpleTenantUsage
suspend_server = nova.api.openstack.compute.suspend_server:SuspendServer
tenant_networks = nova.api.openstack.compute.tenant_networks:TenantNetworks
used_limits = nova.api.openstack.compute.used_limits:UsedLimits
user_data = nova.api.openstack.compute.user_data:UserData
versions = nova.api.openstack.compute.versionsV21:Versions
virtual_interfaces = nova.api.openstack.compute.virtual_interfaces:VirtualInterfaces
volumes = nova.api.openstack.compute.volumes:Volumes
接着我们以虚拟机服务为例(servers = nova.api.openstack.compute.servers:Servers
),首先我们看下api/openstack/compute/servers.py
文件的最下面,class Servers
类完成了URL到处理函数的映射,class ServersController
就是我们最终要找的处理方法的入口:
class Servers(extensions.V21APIExtensionBase):
"""Servers."""
name = "Servers"
alias = ALIAS
version = 1
def get_resources(self):
member_actions = {'action': 'POST'}
collection_actions = {'detail': 'GET'}
resources = [
extensions.ResourceExtension(
ALIAS,
ServersController(extension_info=self.extension_info),
member_name='server', collection_actions=collection_actions,
member_actions=member_actions)]
return resources
def get_controller_extensions(self):
return []
Neutron代码阅读
neutron-server服务的entry_points.txt文件
# cat entry_points.txt
[console_scripts]
neutron-db-manage = neutron.db.migration.cli:main
neutron-debug = neutron.debug.shell:main
neutron-dhcp-agent = neutron.cmd.eventlet.agents.dhcp:main
neutron-ipset-cleanup = neutron.cmd.ipset_cleanup:main
neutron-keepalived-state-change = neutron.cmd.keepalived_state_change:main
neutron-l3-agent = neutron.cmd.eventlet.agents.l3:main
neutron-linuxbridge-agent = neutron.cmd.eventlet.plugins.linuxbridge_neutron_agent:main
neutron-linuxbridge-cleanup = neutron.cmd.linuxbridge_cleanup:main
neutron-macvtap-agent = neutron.cmd.eventlet.plugins.macvtap_neutron_agent:main
neutron-metadata-agent = neutron.cmd.eventlet.agents.metadata:main
neutron-metering-agent = neutron.cmd.eventlet.services.metering_agent:main
neutron-netns-cleanup = neutron.cmd.netns_cleanup:main
neutron-ns-metadata-proxy = neutron.cmd.eventlet.agents.metadata_proxy:main
neutron-openvswitch-agent = neutron.cmd.eventlet.plugins.ovs_neutron_agent:main
neutron-ovs-cleanup = neutron.cmd.ovs_cleanup:main
neutron-pd-notify = neutron.cmd.pd_notify:main
neutron-rootwrap = oslo_rootwrap.cmd:main
neutron-rootwrap-daemon = oslo_rootwrap.cmd:daemon
neutron-rpc-server = neutron.cmd.eventlet.server:main_rpc_eventlet
neutron-sanity-check = neutron.cmd.sanity_check:main
neutron-server = neutron.cmd.eventlet.server:main
neutron-sriov-nic-agent = neutron.cmd.eventlet.plugins.sriov_nic_neutron_agent:main
neutron-usage-audit = neutron.cmd.eventlet.usage_audit:main
[neutron.agent.firewall_drivers]
iptables = neutron.agent.linux.iptables_firewall:IptablesFirewallDriver
iptables_hybrid = neutron.agent.linux.iptables_firewall:OVSHybridIptablesFirewallDriver
noop = neutron.agent.firewall:NoopFirewallDriver
openvswitch = neutron.agent.linux.openvswitch_firewall:OVSFirewallDriver
[neutron.agent.l2.extensions]
fdb = neutron.agent.l2.extensions.fdb_population:FdbPopulationAgentExtension
qos = neutron.agent.l2.extensions.qos:QosAgentExtension
[neutron.agent.linux.pd_drivers]
dibbler = neutron.agent.linux.dibbler:PDDibbler
[neutron.core_plugins]
ml2 = neutron.plugins.ml2.plugin:Ml2Plugin
[neutron.db.alembic_migrations]
neutron = neutron.db.migration:alembic_migrations
[neutron.interface_drivers]
ivs = neutron.agent.linux.interface:IVSInterfaceDriver
linuxbridge = neutron.agent.linux.interface:BridgeInterfaceDriver
null = neutron.agent.linux.interface:NullDriver
openvswitch = neutron.agent.linux.interface:OVSInterfaceDriver
[neutron.ipam_drivers]
fake = neutron.tests.unit.ipam.fake_driver:FakeDriver
internal = neutron.ipam.drivers.neutrondb_ipam.driver:NeutronDbPool
[neutron.ml2.extension_drivers]
dns = neutron.plugins.ml2.extensions.dns_integration:DNSExtensionDriverML2
port_security = neutron.plugins.ml2.extensions.port_security:PortSecurityExtensionDriver
qos = neutron.plugins.ml2.extensions.qos:QosExtensionDriver
test = neutron.tests.unit.plugins.ml2.drivers.ext_test:TestExtensionDriver
testdb = neutron.tests.unit.plugins.ml2.drivers.ext_test:TestDBExtensionDriver
[neutron.ml2.mechanism_drivers]
fake_agent = neutron.tests.unit.plugins.ml2.drivers.mech_fake_agent:FakeAgentMechanismDriver
l2population = neutron.plugins.ml2.drivers.l2pop.mech_driver:L2populationMechanismDriver
linuxbridge = neutron.plugins.ml2.drivers.linuxbridge.mech_driver.mech_linuxbridge:LinuxbridgeMechanismDriver
logger = neutron.tests.unit.plugins.ml2.drivers.mechanism_logger:LoggerMechanismDriver
macvtap = neutron.plugins.ml2.drivers.macvtap.mech_driver.mech_macvtap:MacvtapMechanismDriver
openvswitch = neutron.plugins.ml2.drivers.openvswitch.mech_driver.mech_openvswitch:OpenvswitchMechanismDriver
sriovnicswitch = neutron.plugins.ml2.drivers.mech_sriov.mech_driver.mech_driver:SriovNicSwitchMechanismDriver
test = neutron.tests.unit.plugins.ml2.drivers.mechanism_test:TestMechanismDriver
[neutron.ml2.type_drivers]
flat = neutron.plugins.ml2.drivers.type_flat:FlatTypeDriver
geneve = neutron.plugins.ml2.drivers.type_geneve:GeneveTypeDriver
gre = neutron.plugins.ml2.drivers.type_gre:GreTypeDriver
local = neutron.plugins.ml2.drivers.type_local:LocalTypeDriver
vlan = neutron.plugins.ml2.drivers.type_vlan:VlanTypeDriver
vxlan = neutron.plugins.ml2.drivers.type_vxlan:VxlanTypeDriver
[neutron.qos.agent_drivers]
linuxbridge = neutron.plugins.ml2.drivers.linuxbridge.agent.extension_drivers.qos_driver:QosLinuxbridgeAgentDriver
ovs = neutron.plugins.ml2.drivers.openvswitch.agent.extension_drivers.qos_driver:QosOVSAgentDriver
sriov = neutron.plugins.ml2.drivers.mech_sriov.agent.extension_drivers.qos_driver:QosSRIOVAgentDriver
[neutron.qos.notification_drivers]
message_queue = neutron.services.qos.notification_drivers.message_queue:RpcQosServiceNotificationDriver
[neutron.service_plugins]
auto_allocate = neutron.services.auto_allocate.plugin:Plugin
dummy = neutron.tests.unit.dummy_plugin:DummyServicePlugin
flavors = neutron.services.flavors.flavors_plugin:FlavorsPlugin
loki = neutron.services.loki.loki_plugin:LokiPlugin
metering = neutron.services.metering.metering_plugin:MeteringPlugin
network_ip_availability = neutron.services.network_ip_availability.plugin:NetworkIPAvailabilityPlugin
qos = neutron.services.qos.qos_plugin:QoSPlugin
revisions = neutron.services.revisions.revision_plugin:RevisionPlugin
router = neutron.services.l3_router.l3_router_plugin:L3RouterPlugin
segments = neutron.services.segments.plugin:Plugin
tag = neutron.services.tag.tag_plugin:TagPlugin
timestamp = neutron.services.timestamp.timestamp_plugin:TimeStampPlugin
trunk = neutron.services.trunk.plugin:TrunkPlugin
[neutron.services.external_dns_drivers]
designate = neutron.services.externaldns.drivers.designate.driver:Designate
[oslo.config.opts]
neutron = neutron.opts:list_opts
neutron.agent = neutron.opts:list_agent_opts
neutron.az.agent = neutron.opts:list_az_agent_opts
neutron.base.agent = neutron.opts:list_base_agent_opts
neutron.db = neutron.opts:list_db_opts
neutron.dhcp.agent = neutron.opts:list_dhcp_agent_opts
neutron.extensions = neutron.opts:list_extension_opts
neutron.l3.agent = neutron.opts:list_l3_agent_opts
neutron.metadata.agent = neutron.opts:list_metadata_agent_opts
neutron.metering.agent = neutron.opts:list_metering_agent_opts
neutron.ml2 = neutron.opts:list_ml2_conf_opts
neutron.ml2.linuxbridge.agent = neutron.opts:list_linux_bridge_opts
neutron.ml2.macvtap.agent = neutron.opts:list_macvtap_opts
neutron.ml2.ovs.agent = neutron.opts:list_ovs_opts
neutron.ml2.sriov.agent = neutron.opts:list_sriov_agent_opts
neutron.ml2.xenapi = neutron.opts:list_xenapi_opts
neutron.qos = neutron.opts:list_qos_opts
nova.auth = neutron.opts:list_auth_opts
[oslo.config.opts.defaults]
neutron = neutron.common.config:set_cors_middleware_defaults
[tempest.test_plugins]
neutron_tests = neutron.tests.tempest.plugin:NeutronTempestPlugin
确认服务入口
cmd/eventlet/server/__init__.py
文件是neutron-server
服务的入口:
def _main_neutron_server():
if cfg.CONF.web_framework == 'legacy':
wsgi_eventlet.eventlet_wsgi_server()
else:
wsgi_pecan.pecan_wsgi_server()
找到api-paste.ini
对应的app
[app:neutronapiapp_v2_0]
paste.app_factory = neutron.api.v2.router:APIRouter.factory
在api/v2/router.py
的APIRouter
类初始化中完成URL路由规则的建立,其中manager.init()
完成了核心插件neutron.plugins.ml2.plugin.Ml2Plugin
的加载(根据上面的entry_points.txt文件),所有资源的实现函数都在此插件中,_map_resource
建立了资源的URL到Ml2Plugin
插件实现函数的映射关系(例如network
的create
函数映射到Ml2Plugin
插件的create_network
方法上),所以plugins/ml2/plugin.py
就是我们要找的入口文件
glance代码阅读
首先找到/etc/glance-api-paste.ini
文件,找到app的入口
[app:apiv2app]
paste.app_factory = glance.api.v2.router:API.factory
然后找到api/v2/router.py
文件,分析class API
,其映射实现就位于__init__
函数中,例如我们最关心的镜像创建方法:
images_resource = images.create_resource(custom_image_properties)
mapper.connect('/images',
controller=images_resource,
action='create',
conditions={'method': ['POST']})
跟进create_resource
方法,镜像创建方法在控制类ImagesController
的create
中实现