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.pyAPIRouter类初始化中完成URL路由规则的建立,其中manager.init()完成了核心插件neutron.plugins.ml2.plugin.Ml2Plugin的加载(根据上面的entry_points.txt文件),所有资源的实现函数都在此插件中,_map_resource建立了资源的URL到Ml2Plugin插件实现函数的映射关系(例如networkcreate函数映射到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方法,镜像创建方法在控制类ImagesControllercreate中实现

posted @ 2018-05-25 10:29  银魔术师  阅读(496)  评论(0编辑  收藏  举报