Trong phiên bản OpenStack Rocky, dịch vụ xác thực Keystone được khởi chạy thông qua giao diện WSGI tích hợp với HTTP daemon (thường là httpd hoặc Apache). Tệp điểm vào chính cho API công khai là
Hàm
Hàm
Cuối cùng,
/usr/bin/keystone-wsgi-public, hoạt động như một ứng dụng WSGI độc lập.
Dưới đây là đoạn mã cốt lõi trong tệp này:
from keystone.server.wsgi import initialize_public_application
if __name__ == "__main__":
import wsgiref.simple_server as wss
# ... xử lý tham số từ dòng lệnh ...
server = wss.make_server(host=args.host, port=args.port,
app=initialize_public_application())
server.serve_forever()
initialize_public_application() không còn phân biệt rõ ràng giữa môi trường public và admin — cả hai đều sử dụng cùng một hàm khởi tạo, thể hiện sự thống nhất kiến trúc trong Rocky:
from keystone.server.flask import core as flask_core
def initialize_public_application():
return flask_core.initialize_application(
name='public',
config_files=flask_core._get_config_files()
)
initialize_admin_application = initialize_public_application
initialize_application() đảm nhiệm vai trò trung tâm trong quá trình khởi tạo. Nó thực hiện tuần tự các bước sau:
- Cấu hình hệ thống logging và đọc file cấu hình (ưu tiên
etc/keystone.confnếu tồn tại trong thư mục nguồn phát triển). - Gọi
keystone.server.configure()để thiết lập các thành phần nền tảng như cơ sở dữ liệu SQL, bộ nhớ đệm (oslo.cache), và phương thức xác thực. - Tải các driver backend thông qua
stevedore.DriverManager, sau đó truyền vào hàm khởi tạo ứng dụng Flask. - Xây dựng đối tượng Flask application thông qua
application_factory(), gắn kết các router API (v3), middleware tùy chỉnh và endpoint kiểm tra sức khỏe. - Áp dụng lớp trung gian
KeystoneDispatcherMiddlewaređể định tuyến yêu cầu dựa trên đường dẫn URI.
configure() bên trong keystone.conf đăng ký thêm các tùy chọn CLI đặc thù như:
standard-threads: tắt cơ chế monkey-patching luồng nếu đặtTrue.pydev-debug-hostvàpydev-debug-port: hỗ trợ gỡ lỗi từ xa qua PyDev.
auth.setup_authentication() đăng ký các phương thức xác thực tiêu chuẩn (password, token, saml2, oauth1…), còn cache.configure(conf) cấu hình bộ nhớ đệm theo cấu hình từ keystone.conf.
Phần quan trọng nhất là việc xây dựng ứng dụng Flask:
def application_factory(name='public'):
if name not in ('admin', 'public'):
raise RuntimeError('Application name must be "admin" or "public".')
app = flask.Flask(name)
app.after_request(_add_vary_x_auth_token_header)
app.config.update(PROPAGATE_EXCEPTIONS=True)
# Đăng ký healthcheck endpoint
hc_app = healthcheck.Healthcheck.app_factory({}, oslo_config_project='keystone')
dispatch_map = {'/healthcheck': hc_app}
# Thiết lập route mapper cho API v3
mapper = routes.Mapper()
for api_routers in ALL_API_ROUTERS:
routers_instance = api_routers.Routers()
routers_instance.append_v3_routers(mapper, sub_routers)
# Đăng ký tất cả API Blueprint vào ứng dụng Flask
for api_module in keystone.api.__apis__:
for bp_class in api_module.APIs:
bp_class.instantiate_and_register_to_app(app)
# Gắn middleware định tuyến
legacy_dispatcher = keystone_wsgi.ComposingRouter(mapper, sub_routers)
for prefix in itertools.chain(*[r._path_prefixes for r in ALL_API_ROUTERS]):
dispatch_map[f'/v3/{prefix}'] = legacy_dispatcher
app.wsgi_app = KeystoneDispatcherMiddleware(app.wsgi_app, dispatch_map)
return app
setup_app_middleware() sử dụng stevedore để nạp và chèn các lớp middleware chuẩn (như auth_token, cors, profiler) vào chuỗi xử lý yêu cầu. Toàn bộ quy trình kết thúc khi máy chủ WSGI bắt đầu lắng nghe và xử lý yêu cầu HTTP.