Initial Kingbird framework code base ( part1:rest )
Fisrt patch to implement the framework of Kingbird, this is the part1 for web service with keystone authentication integrated, and API part with helloworld rest quest example. Blueprint: https://blueprints.launchpad.net/kingbird/+spec/kingbird-framework Change-Id: Ia33247132c6a4945f76f0819cf90acf6e8d2154d Signed-off-by: Chaoyi Huang <joehuang@huawei.com>
This commit is contained in:
parent
811a157a29
commit
72fffc65fe
25
README.rst
25
README.rst
@ -1,19 +1,24 @@
|
|||||||
===============================
|
===============================
|
||||||
kingbird
|
Kingbird
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
Kingbird is a centralised synchronization service for multi-region OpenStack deployments.
|
Centralized service for multi-region OpenStack deployments.
|
||||||
|
|
||||||
|
Kingbird is an centralized OpenStack service that provides resource operation
|
||||||
|
and management across multiple OpenStack instances in a multi-region OpenStack
|
||||||
|
deployments. This service is part of the OPNFV Multisite project that intends
|
||||||
|
to address the use cases related to distributed cloud environments.
|
||||||
|
|
||||||
|
Kingbird provides features like centralized quota management, centralized view
|
||||||
|
for distributed virtual resources, global view for tenant level IP/MAC address
|
||||||
|
space management, synchronisation of ssh keys, images, flavors, security
|
||||||
|
groups, etc. across regions.
|
||||||
|
|
||||||
Please feel here a long description which must be at least 3 lines wrapped on
|
|
||||||
80 cols, so that distribution package maintainers can use it in their packages.
|
|
||||||
Note that this is a hard requirement.
|
|
||||||
|
|
||||||
* Free software: Apache license
|
* Free software: Apache license
|
||||||
|
* Wiki:https://wiki.openstack.org/wiki/kingbird
|
||||||
* Documentation: http://docs.openstack.org/developer/kingbird
|
* Documentation: http://docs.openstack.org/developer/kingbird
|
||||||
* Source: http://git.openstack.org/cgit/openstack/kingbird
|
* Source: https://github.com/openstack/kingbird
|
||||||
* Bugs: http://bugs.launchpad.net/kingbird
|
* Bugs: http://bugs.launchpad.net/kingbird
|
||||||
|
* Blueprints: https://launchpad.net/kingbird
|
||||||
|
|
||||||
Features
|
|
||||||
--------
|
|
||||||
|
|
||||||
* TODO
|
|
||||||
|
64
cmd/api.py
Executable file
64
cmd/api.py
Executable file
@ -0,0 +1,64 @@
|
|||||||
|
# Copyright 2015 Huawei Technologies Co., Ltd.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
# Much of this module is based on the work of the Ironic team
|
||||||
|
# see http://git.openstack.org/cgit/openstack/ironic/tree/ironic/cmd/api.py
|
||||||
|
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
import logging as std_logging
|
||||||
|
|
||||||
|
from werkzeug import serving
|
||||||
|
|
||||||
|
from kingbird.api import apicfg
|
||||||
|
from kingbird.api import app
|
||||||
|
|
||||||
|
from kingbird.common.i18n import _LI
|
||||||
|
from kingbird.common.i18n import _LW
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
apicfg.init(sys.argv[1:])
|
||||||
|
apicfg.setup_logging()
|
||||||
|
application = app.setup_app()
|
||||||
|
|
||||||
|
host = CONF.bind_host
|
||||||
|
port = CONF.bind_port
|
||||||
|
workers = CONF.api_workers
|
||||||
|
|
||||||
|
if workers < 1:
|
||||||
|
LOG.warning(_LW("Wrong worker number, worker = %(workers)s"), workers)
|
||||||
|
workers = 1
|
||||||
|
|
||||||
|
LOG.info(_LI("Server on http://%(host)s:%(port)s with %(workers)s"),
|
||||||
|
{'host': host, 'port': port, 'workers': workers})
|
||||||
|
|
||||||
|
serving.run_simple(host, port,
|
||||||
|
application,
|
||||||
|
processes=workers)
|
||||||
|
|
||||||
|
LOG.info(_LI("Configuration:"))
|
||||||
|
CONF.log_opt_values(LOG, std_logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
370
etc/api.conf
Executable file
370
etc/api.conf
Executable file
@ -0,0 +1,370 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
# Print more verbose output (set logging level to INFO instead of default WARNING level).
|
||||||
|
# verbose = True
|
||||||
|
|
||||||
|
# Print debugging output (set logging level to DEBUG instead of default WARNING level).
|
||||||
|
# debug = False
|
||||||
|
|
||||||
|
# Where to store Kingbird state files. This directory must be writable by the
|
||||||
|
# user executing the agent.
|
||||||
|
# state_path = /var/lib/kingbird
|
||||||
|
|
||||||
|
# log_format = %(asctime)s %(levelname)8s [%(name)s] %(message)s
|
||||||
|
# log_date_format = %Y-%m-%d %H:%M:%S
|
||||||
|
|
||||||
|
# use_syslog -> syslog
|
||||||
|
# log_file and log_dir -> log_dir/log_file
|
||||||
|
# (not log_file) and log_dir -> log_dir/{binary_name}.log
|
||||||
|
# use_stderr -> stderr
|
||||||
|
# (not user_stderr) and (not log_file) -> stdout
|
||||||
|
# publish_errors -> notification system
|
||||||
|
|
||||||
|
# use_syslog = False
|
||||||
|
# syslog_log_facility = LOG_USER
|
||||||
|
|
||||||
|
# use_stderr = True
|
||||||
|
# log_file =
|
||||||
|
# log_dir =
|
||||||
|
|
||||||
|
# publish_errors = False
|
||||||
|
|
||||||
|
# Address to bind the API server to
|
||||||
|
# bind_host = 127.0.0.1
|
||||||
|
|
||||||
|
# Port the bind the API server to
|
||||||
|
# bind_port = 8118
|
||||||
|
|
||||||
|
# Paste configuration file
|
||||||
|
# api_paste_config = api-paste.ini
|
||||||
|
|
||||||
|
# (StrOpt) Hostname to be used by the kingbird server, agents and services
|
||||||
|
# running on this machine. All the agents and services running on this machine
|
||||||
|
# must use the same host value.
|
||||||
|
# The default value is hostname of the machine.
|
||||||
|
#
|
||||||
|
# host =
|
||||||
|
|
||||||
|
# admin_tenant_name = %SERVICE_TENANT_NAME%
|
||||||
|
# admin_user = %SERVICE_USER%
|
||||||
|
# admin_password = %SERVICE_PASSWORD%
|
||||||
|
|
||||||
|
# Enable or disable bulk create/update/delete operations
|
||||||
|
# allow_bulk = True
|
||||||
|
# Enable or disable pagination
|
||||||
|
# allow_pagination = False
|
||||||
|
# Enable or disable sorting
|
||||||
|
# allow_sorting = False
|
||||||
|
|
||||||
|
# Default maximum number of items returned in a single response,
|
||||||
|
# value == infinite and value < 0 means no max limit, and value must
|
||||||
|
# be greater than 0. If the number of items requested is greater than
|
||||||
|
# pagination_max_limit, server will just return pagination_max_limit
|
||||||
|
# of number of items.
|
||||||
|
# pagination_max_limit = -1
|
||||||
|
|
||||||
|
# =========== WSGI parameters related to the API server ==============
|
||||||
|
# Number of separate worker processes to spawn. The default, 0, runs the
|
||||||
|
# worker thread in the current process. Greater than 0 launches that number of
|
||||||
|
# child processes as workers. The parent process manages them.
|
||||||
|
# api_workers = 3
|
||||||
|
|
||||||
|
# Number of separate RPC worker processes to spawn. The default, 0, runs the
|
||||||
|
# worker thread in the current process. Greater than 0 launches that number of
|
||||||
|
# child processes as RPC workers. The parent process manages them.
|
||||||
|
# This feature is experimental until issues are addressed and testing has been
|
||||||
|
# enabled for various plugins for compatibility.
|
||||||
|
# rpc_workers = 0
|
||||||
|
|
||||||
|
# Timeout for client connections socket operations. If an
|
||||||
|
# incoming connection is idle for this number of seconds it
|
||||||
|
# will be closed. A value of '0' means wait forever. (integer
|
||||||
|
# value)
|
||||||
|
# client_socket_timeout = 900
|
||||||
|
|
||||||
|
# wsgi keepalive option. Determines if connections are allowed to be held open
|
||||||
|
# by clients after a request is fulfilled. A value of False will ensure that
|
||||||
|
# the socket connection will be explicitly closed once a response has been
|
||||||
|
# sent to the client.
|
||||||
|
# wsgi_keep_alive = True
|
||||||
|
|
||||||
|
# Sets the value of TCP_KEEPIDLE in seconds to use for each server socket when
|
||||||
|
# starting API server. Not supported on OS X.
|
||||||
|
# tcp_keepidle = 600
|
||||||
|
|
||||||
|
# Number of seconds to keep retrying to listen
|
||||||
|
# retry_until_window = 30
|
||||||
|
|
||||||
|
# Number of backlog requests to configure the socket with.
|
||||||
|
# backlog = 4096
|
||||||
|
|
||||||
|
# Max header line to accommodate large tokens
|
||||||
|
# max_header_line = 16384
|
||||||
|
|
||||||
|
# Enable SSL on the API server
|
||||||
|
# use_ssl = False
|
||||||
|
|
||||||
|
# Certificate file to use when starting API server securely
|
||||||
|
# ssl_cert_file = /path/to/certfile
|
||||||
|
|
||||||
|
# Private key file to use when starting API server securely
|
||||||
|
# ssl_key_file = /path/to/keyfile
|
||||||
|
|
||||||
|
# CA certificate file to use when starting API server securely to
|
||||||
|
# verify connecting clients. This is an optional parameter only required if
|
||||||
|
# API clients need to authenticate to the API server using SSL certificates
|
||||||
|
# signed by a trusted CA
|
||||||
|
# ssl_ca_file = /path/to/cafile
|
||||||
|
# ======== end of WSGI parameters related to the API server ==========
|
||||||
|
|
||||||
|
# The strategy to be used for auth.
|
||||||
|
# Supported values are 'keystone'(default), 'noauth'.
|
||||||
|
auth_strategy = noauth
|
||||||
|
|
||||||
|
[keystone_authtoken]
|
||||||
|
# auth_uri = http://162.3.111.227:35357/v3
|
||||||
|
# identity_uri = http://162.3.111.227:35357
|
||||||
|
# admin_tenant_name = service
|
||||||
|
# admin_user = kingbird
|
||||||
|
# admin_password = 1234
|
||||||
|
# auth_version = 3
|
||||||
|
|
||||||
|
[database]
|
||||||
|
# This line MUST be changed to actually run the plugin.
|
||||||
|
# Example:
|
||||||
|
# connection = mysql://root:pass@127.0.0.1:3306/neutron
|
||||||
|
# Replace 127.0.0.1 above with the IP address of the database used by the
|
||||||
|
# main neutron server. (Leave it as is if the database runs on this host.)
|
||||||
|
# connection = sqlite://
|
||||||
|
# NOTE: In deployment the [database] section and its connection attribute may
|
||||||
|
# be set in the corresponding core plugin '.ini' file. However, it is suggested
|
||||||
|
# to put the [database] section and its connection attribute in this
|
||||||
|
# configuration file.
|
||||||
|
|
||||||
|
# Database engine for which script will be generated when using offline
|
||||||
|
# migration
|
||||||
|
# engine =
|
||||||
|
|
||||||
|
# The SQLAlchemy connection string used to connect to the slave database
|
||||||
|
# slave_connection =
|
||||||
|
|
||||||
|
# Database reconnection retry times - in event connectivity is lost
|
||||||
|
# set to -1 implies an infinite retry count
|
||||||
|
# max_retries = 10
|
||||||
|
|
||||||
|
# Database reconnection interval in seconds - if the initial connection to the
|
||||||
|
# database fails
|
||||||
|
# retry_interval = 10
|
||||||
|
|
||||||
|
# Minimum number of SQL connections to keep open in a pool
|
||||||
|
# min_pool_size = 1
|
||||||
|
|
||||||
|
# Maximum number of SQL connections to keep open in a pool
|
||||||
|
# max_pool_size = 10
|
||||||
|
|
||||||
|
# Timeout in seconds before idle sql connections are reaped
|
||||||
|
# idle_timeout = 3600
|
||||||
|
|
||||||
|
# If set, use this value for max_overflow with sqlalchemy
|
||||||
|
# max_overflow = 20
|
||||||
|
|
||||||
|
# Verbosity of SQL debugging information. 0=None, 100=Everything
|
||||||
|
# connection_debug = 0
|
||||||
|
|
||||||
|
# Add python stack traces to SQL as comment strings
|
||||||
|
# connection_trace = False
|
||||||
|
|
||||||
|
# If set, use this value for pool_timeout with sqlalchemy
|
||||||
|
# pool_timeout = 10
|
||||||
|
|
||||||
|
[oslo_concurrency]
|
||||||
|
|
||||||
|
# Directory to use for lock files. For security, the specified directory should
|
||||||
|
# only be writable by the user running the processes that need locking.
|
||||||
|
# Defaults to environment variable OSLO_LOCK_PATH. If external locks are used,
|
||||||
|
# a lock path must be set.
|
||||||
|
lock_path = $state_path/lock
|
||||||
|
|
||||||
|
# Enables or disables inter-process locks.
|
||||||
|
# disable_process_locking = False
|
||||||
|
|
||||||
|
[oslo_policy]
|
||||||
|
|
||||||
|
# The JSON file that defines policies.
|
||||||
|
# policy_file = policy.json
|
||||||
|
|
||||||
|
# Default rule. Enforced when a requested rule is not found.
|
||||||
|
# policy_default_rule = default
|
||||||
|
|
||||||
|
# Directories where policy configuration files are stored.
|
||||||
|
# They can be relative to any directory in the search path defined by the
|
||||||
|
# config_dir option, or absolute paths. The file defined by policy_file
|
||||||
|
# must exist for these directories to be searched. Missing or empty
|
||||||
|
# directories are ignored.
|
||||||
|
# policy_dirs = policy.d
|
||||||
|
|
||||||
|
[oslo_messaging_amqp]
|
||||||
|
|
||||||
|
#
|
||||||
|
# From oslo.messaging
|
||||||
|
#
|
||||||
|
|
||||||
|
# Address prefix used when sending to a specific server (string value)
|
||||||
|
# server_request_prefix = exclusive
|
||||||
|
|
||||||
|
# Address prefix used when broadcasting to all servers (string value)
|
||||||
|
# broadcast_prefix = broadcast
|
||||||
|
|
||||||
|
# Address prefix when sending to any server in group (string value)
|
||||||
|
# group_request_prefix = unicast
|
||||||
|
|
||||||
|
# Name for the AMQP container (string value)
|
||||||
|
# container_name =
|
||||||
|
|
||||||
|
# Timeout for inactive connections (in seconds) (integer value)
|
||||||
|
# idle_timeout = 0
|
||||||
|
|
||||||
|
# Debug: dump AMQP frames to stdout (boolean value)
|
||||||
|
# trace = false
|
||||||
|
|
||||||
|
# CA certificate PEM file for verifing server certificate (string value)
|
||||||
|
# ssl_ca_file =
|
||||||
|
|
||||||
|
# Identifying certificate PEM file to present to clients (string value)
|
||||||
|
# ssl_cert_file =
|
||||||
|
|
||||||
|
# Private key PEM file used to sign cert_file certificate (string value)
|
||||||
|
# ssl_key_file =
|
||||||
|
|
||||||
|
# Password for decrypting ssl_key_file (if encrypted) (string value)
|
||||||
|
# ssl_key_password =
|
||||||
|
|
||||||
|
# Accept clients using either SSL or plain TCP (boolean value)
|
||||||
|
# allow_insecure_clients = false
|
||||||
|
|
||||||
|
|
||||||
|
[oslo_messaging_qpid]
|
||||||
|
|
||||||
|
#
|
||||||
|
# From oslo.messaging
|
||||||
|
#
|
||||||
|
|
||||||
|
# Use durable queues in AMQP. (boolean value)
|
||||||
|
# amqp_durable_queues = false
|
||||||
|
|
||||||
|
# Auto-delete queues in AMQP. (boolean value)
|
||||||
|
# amqp_auto_delete = false
|
||||||
|
|
||||||
|
# Size of RPC connection pool. (integer value)
|
||||||
|
# rpc_conn_pool_size = 30
|
||||||
|
|
||||||
|
# Qpid broker hostname. (string value)
|
||||||
|
# qpid_hostname = localhost
|
||||||
|
|
||||||
|
# Qpid broker port. (integer value)
|
||||||
|
# qpid_port = 5672
|
||||||
|
|
||||||
|
# Qpid HA cluster host:port pairs. (list value)
|
||||||
|
# qpid_hosts = $qpid_hostname:$qpid_port
|
||||||
|
|
||||||
|
# Username for Qpid connection. (string value)
|
||||||
|
# qpid_username =
|
||||||
|
|
||||||
|
# Password for Qpid connection. (string value)
|
||||||
|
# qpid_password =
|
||||||
|
|
||||||
|
# Space separated list of SASL mechanisms to use for auth. (string value)
|
||||||
|
# qpid_sasl_mechanisms =
|
||||||
|
|
||||||
|
# Seconds between connection keepalive heartbeats. (integer value)
|
||||||
|
# qpid_heartbeat = 60
|
||||||
|
|
||||||
|
# Transport to use, either 'tcp' or 'ssl'. (string value)
|
||||||
|
# qpid_protocol = tcp
|
||||||
|
|
||||||
|
# Whether to disable the Nagle algorithm. (boolean value)
|
||||||
|
# qpid_tcp_nodelay = true
|
||||||
|
|
||||||
|
# The number of prefetched messages held by receiver. (integer value)
|
||||||
|
# qpid_receiver_capacity = 1
|
||||||
|
|
||||||
|
# The qpid topology version to use. Version 1 is what was originally used by
|
||||||
|
# impl_qpid. Version 2 includes some backwards-incompatible changes that allow
|
||||||
|
# broker federation to work. Users should update to version 2 when they are
|
||||||
|
# able to take everything down, as it requires a clean break. (integer value)
|
||||||
|
# qpid_topology_version = 1
|
||||||
|
|
||||||
|
|
||||||
|
[oslo_messaging_rabbit]
|
||||||
|
|
||||||
|
#
|
||||||
|
# From oslo.messaging
|
||||||
|
#
|
||||||
|
|
||||||
|
# Use durable queues in AMQP. (boolean value)
|
||||||
|
# amqp_durable_queues = false
|
||||||
|
|
||||||
|
# Auto-delete queues in AMQP. (boolean value)
|
||||||
|
# amqp_auto_delete = false
|
||||||
|
|
||||||
|
# Size of RPC connection pool. (integer value)
|
||||||
|
# rpc_conn_pool_size = 30
|
||||||
|
|
||||||
|
# SSL version to use (valid only if SSL enabled). Valid values are TLSv1 and
|
||||||
|
# SSLv23. SSLv2, SSLv3, TLSv1_1, and TLSv1_2 may be available on some
|
||||||
|
# distributions. (string value)
|
||||||
|
# kombu_ssl_version =
|
||||||
|
|
||||||
|
# SSL key file (valid only if SSL enabled). (string value)
|
||||||
|
# kombu_ssl_keyfile =
|
||||||
|
|
||||||
|
# SSL cert file (valid only if SSL enabled). (string value)
|
||||||
|
# kombu_ssl_certfile =
|
||||||
|
|
||||||
|
# SSL certification authority file (valid only if SSL enabled). (string value)
|
||||||
|
# kombu_ssl_ca_certs =
|
||||||
|
|
||||||
|
# How long to wait before reconnecting in response to an AMQP consumer cancel
|
||||||
|
# notification. (floating point value)
|
||||||
|
# kombu_reconnect_delay = 1.0
|
||||||
|
|
||||||
|
# The RabbitMQ broker address where a single node is used. (string value)
|
||||||
|
# rabbit_host = localhost
|
||||||
|
|
||||||
|
# The RabbitMQ broker port where a single node is used. (integer value)
|
||||||
|
# rabbit_port = 5672
|
||||||
|
|
||||||
|
# RabbitMQ HA cluster host:port pairs. (list value)
|
||||||
|
# rabbit_hosts = $rabbit_host:$rabbit_port
|
||||||
|
|
||||||
|
# Connect over SSL for RabbitMQ. (boolean value)
|
||||||
|
# rabbit_use_ssl = false
|
||||||
|
|
||||||
|
# The RabbitMQ userid. (string value)
|
||||||
|
# rabbit_userid = guest
|
||||||
|
|
||||||
|
# The RabbitMQ password. (string value)
|
||||||
|
# rabbit_password = guest
|
||||||
|
|
||||||
|
# The RabbitMQ login method. (string value)
|
||||||
|
# rabbit_login_method = AMQPLAIN
|
||||||
|
|
||||||
|
# The RabbitMQ virtual host. (string value)
|
||||||
|
# rabbit_virtual_host = /
|
||||||
|
|
||||||
|
# How frequently to retry connecting with RabbitMQ. (integer value)
|
||||||
|
# rabbit_retry_interval = 1
|
||||||
|
|
||||||
|
# How long to backoff for between retries when connecting to RabbitMQ. (integer
|
||||||
|
# value)
|
||||||
|
# rabbit_retry_backoff = 2
|
||||||
|
|
||||||
|
# Maximum number of RabbitMQ connection retries. Default is 0 (infinite retry
|
||||||
|
# count). (integer value)
|
||||||
|
# rabbit_max_retries = 0
|
||||||
|
|
||||||
|
# Use HA queues in RabbitMQ (x-ha-policy: all). If you change this option, you
|
||||||
|
# must wipe the RabbitMQ database. (boolean value)
|
||||||
|
# rabbit_ha_queues = false
|
||||||
|
|
||||||
|
# Deprecated, use rpc_backend=kombu+memory or rpc_backend=fake (boolean value)
|
||||||
|
# fake_rabbit = false
|
8
etc/policy.json
Executable file
8
etc/policy.json
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"context_is_admin": "role:admin",
|
||||||
|
"admin_or_owner": "is_admin:True or project_id:%(project_id)s",
|
||||||
|
"default": "rule:admin_or_owner",
|
||||||
|
|
||||||
|
"kingbird:create_quota": "rule:admin_or_owner",
|
||||||
|
"kingbird:update_quota": "rule:admin_or_owner"
|
||||||
|
}
|
0
kingbird/api/__init__.py
Executable file
0
kingbird/api/__init__.py
Executable file
95
kingbird/api/apicfg.py
Executable file
95
kingbird/api/apicfg.py
Executable file
@ -0,0 +1,95 @@
|
|||||||
|
# Copyright 2015 Huawei Technologies Co., Ltd.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Routines for configuring kingbird, largely copy from Neutron
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
from kingbird.common.i18n import _
|
||||||
|
from kingbird.common.i18n import _LI
|
||||||
|
|
||||||
|
|
||||||
|
# from kingbird import policy
|
||||||
|
# from kingbird.common import rpc
|
||||||
|
from kingbird.common import version
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
common_opts = [
|
||||||
|
cfg.StrOpt('bind_host', default='0.0.0.0',
|
||||||
|
help=_("The host IP to bind to")),
|
||||||
|
cfg.IntOpt('bind_port', default=8118,
|
||||||
|
help=_("The port to bind to")),
|
||||||
|
cfg.IntOpt('api_workers', default=2,
|
||||||
|
help=_("number of api workers")),
|
||||||
|
cfg.StrOpt('api_paste_config', default="api-paste.ini",
|
||||||
|
help=_("The API paste config file to use")),
|
||||||
|
cfg.StrOpt('api_extensions_path', default="",
|
||||||
|
help=_("The path for API extensions")),
|
||||||
|
cfg.StrOpt('auth_strategy', default='keystone',
|
||||||
|
help=_("The type of authentication to use")),
|
||||||
|
cfg.BoolOpt('allow_bulk', default=True,
|
||||||
|
help=_("Allow the usage of the bulk API")),
|
||||||
|
cfg.BoolOpt('allow_pagination', default=False,
|
||||||
|
help=_("Allow the usage of the pagination")),
|
||||||
|
cfg.BoolOpt('allow_sorting', default=False,
|
||||||
|
help=_("Allow the usage of the sorting")),
|
||||||
|
cfg.StrOpt('pagination_max_limit', default="-1",
|
||||||
|
help=_("The maximum number of items returned in a single "
|
||||||
|
"response, value was 'infinite' or negative integer "
|
||||||
|
"means no limit")),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def init(args, **kwargs):
|
||||||
|
# Register the configuration options
|
||||||
|
cfg.CONF.register_opts(common_opts)
|
||||||
|
|
||||||
|
# ks_session.Session.register_conf_options(cfg.CONF)
|
||||||
|
# auth.register_conf_options(cfg.CONF)
|
||||||
|
logging.register_options(cfg.CONF)
|
||||||
|
|
||||||
|
cfg.CONF(args=args, project='kingbird',
|
||||||
|
version='%%(prog)s %s' % version.version_info.release_string(),
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
|
# rpc.init(cfg.CONF)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_logging():
|
||||||
|
"""Sets up the logging options for a log with supplied name."""
|
||||||
|
product_name = "kingbird"
|
||||||
|
logging.setup(cfg.CONF, product_name)
|
||||||
|
LOG.info(_LI("Logging enabled!"))
|
||||||
|
LOG.info(_LI("%(prog)s version %(version)s"),
|
||||||
|
{'prog': sys.argv[0],
|
||||||
|
'version': version.version_info.release_string()})
|
||||||
|
LOG.debug("command line: %s", " ".join(sys.argv))
|
||||||
|
|
||||||
|
|
||||||
|
def reset_service():
|
||||||
|
# Reset worker in case SIGHUP is called.
|
||||||
|
# Note that this is called only in case a service is running in
|
||||||
|
# daemon mode.
|
||||||
|
setup_logging()
|
||||||
|
|
||||||
|
# TODO(joehuang) enforce policy later
|
||||||
|
# policy.refresh()
|
66
kingbird/api/app.py
Executable file
66
kingbird/api/app.py
Executable file
@ -0,0 +1,66 @@
|
|||||||
|
# Copyright (c) 2015 Huawei, Tech. Co,. Ltd.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from keystonemiddleware import auth_token
|
||||||
|
from oslo_config import cfg
|
||||||
|
from oslo_middleware import request_id
|
||||||
|
import pecan
|
||||||
|
|
||||||
|
from kingbird.common import exceptions as k_exc
|
||||||
|
|
||||||
|
|
||||||
|
def setup_app(*args, **kwargs):
|
||||||
|
config = {
|
||||||
|
'server': {
|
||||||
|
'port': cfg.CONF.bind_port,
|
||||||
|
'host': cfg.CONF.bind_host
|
||||||
|
},
|
||||||
|
'app': {
|
||||||
|
'root': 'kingbird.api.controllers.root.RootController',
|
||||||
|
'modules': ['kingbird.api'],
|
||||||
|
'errors': {
|
||||||
|
400: '/error',
|
||||||
|
'__force_dict__': True
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pecan_config = pecan.configuration.conf_from_dict(config)
|
||||||
|
|
||||||
|
# app_hooks = [], hook collection will be put here later
|
||||||
|
|
||||||
|
app = pecan.make_app(
|
||||||
|
pecan_config.app.root,
|
||||||
|
debug=False,
|
||||||
|
wrap_app=_wrap_app,
|
||||||
|
force_canonical=False,
|
||||||
|
hooks=[],
|
||||||
|
guess_content_type_from_ext=True
|
||||||
|
)
|
||||||
|
|
||||||
|
return app
|
||||||
|
|
||||||
|
|
||||||
|
def _wrap_app(app):
|
||||||
|
app = request_id.RequestId(app)
|
||||||
|
|
||||||
|
if cfg.CONF.auth_strategy == 'noauth':
|
||||||
|
pass
|
||||||
|
elif cfg.CONF.auth_strategy == 'keystone':
|
||||||
|
app = auth_token.AuthProtocol(app, {})
|
||||||
|
else:
|
||||||
|
raise k_exc.InvalidConfigurationOption(
|
||||||
|
opt_name='auth_strategy', opt_value=cfg.CONF.auth_strategy)
|
||||||
|
|
||||||
|
return app
|
0
kingbird/api/controllers/__init__.py
Executable file
0
kingbird/api/controllers/__init__.py
Executable file
63
kingbird/api/controllers/helloworld.py
Executable file
63
kingbird/api/controllers/helloworld.py
Executable file
@ -0,0 +1,63 @@
|
|||||||
|
# Copyright (c) 2015 Huawei Tech. Co., Ltd.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
# from kingbird.jobdaemon import jdrpcapi
|
||||||
|
|
||||||
|
import pecan
|
||||||
|
from pecan import expose
|
||||||
|
from pecan import rest
|
||||||
|
import restcomm
|
||||||
|
|
||||||
|
|
||||||
|
class HelloWorldController(rest.RestController):
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(HelloWorldController, self).__init__(*args, **kwargs)
|
||||||
|
# self.jd_api = jdrpcapi.JobDaemonAPI()
|
||||||
|
|
||||||
|
@expose(generic=True, template='json')
|
||||||
|
def index(self):
|
||||||
|
if pecan.request.method != 'GET':
|
||||||
|
pecan.abort(405)
|
||||||
|
|
||||||
|
context = restcomm.extract_context_from_environ()
|
||||||
|
if context.is_admin:
|
||||||
|
return {'hello world message for admin': 'GET'}
|
||||||
|
else:
|
||||||
|
return {'hello world message for non-admin': 'GET'}
|
||||||
|
|
||||||
|
@index.when(method='PUT', template='json')
|
||||||
|
def put(self, **kw):
|
||||||
|
context = restcomm.extract_context_from_environ()
|
||||||
|
if context.is_admin:
|
||||||
|
return {'hello world message for admin': 'PUT'}
|
||||||
|
else:
|
||||||
|
return {'hello world message for non-admin': 'PUT'}
|
||||||
|
|
||||||
|
@index.when(method='POST', template='json')
|
||||||
|
def post(self, **kw):
|
||||||
|
context = restcomm.extract_context_from_environ()
|
||||||
|
if context.is_admin:
|
||||||
|
return {'hello world message for admin': 'POST'}
|
||||||
|
else:
|
||||||
|
return {'hello world message for non-admin': 'POST'}
|
||||||
|
|
||||||
|
@index.when(method='delete', template='json')
|
||||||
|
def delete(self):
|
||||||
|
context = restcomm.extract_context_from_environ()
|
||||||
|
if context.is_admin:
|
||||||
|
return {'hello world message for admin': 'delete'}
|
||||||
|
else:
|
||||||
|
return {'hello world message for non-admin': 'delete'}
|
40
kingbird/api/controllers/restcomm.py
Executable file
40
kingbird/api/controllers/restcomm.py
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
# Copyright (c) 2015 Huawei Tech. Co., Ltd.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
|
from pecan import request
|
||||||
|
|
||||||
|
import kingbird.common.context as k_context
|
||||||
|
|
||||||
|
|
||||||
|
def extract_context_from_environ():
|
||||||
|
context_paras = {'auth_token': 'HTTP_X_AUTH_TOKEN',
|
||||||
|
'user': 'HTTP_X_USER_ID',
|
||||||
|
'tenant': 'HTTP_X_TENANT_ID',
|
||||||
|
'user_name': 'HTTP_X_USER_NAME',
|
||||||
|
'tenant_name': 'HTTP_X_PROJECT_NAME',
|
||||||
|
'domain': 'HTTP_X_DOMAIN_ID',
|
||||||
|
'user_domain': 'HTTP_X_USER_DOMAIN_ID',
|
||||||
|
'project_domain': 'HTTP_X_PROJECT_DOMAIN_ID',
|
||||||
|
'request_id': 'openstack.request_id'}
|
||||||
|
|
||||||
|
environ = request.environ
|
||||||
|
|
||||||
|
for key in context_paras:
|
||||||
|
context_paras[key] = environ.get(context_paras[key])
|
||||||
|
role = environ.get('HTTP_X_ROLE')
|
||||||
|
|
||||||
|
context_paras['is_admin'] = role == 'admin'
|
||||||
|
return k_context.Context(**context_paras)
|
69
kingbird/api/controllers/root.py
Executable file
69
kingbird/api/controllers/root.py
Executable file
@ -0,0 +1,69 @@
|
|||||||
|
# Copyright (c) 2015 Huawei Tech. Co., Ltd.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import helloworld
|
||||||
|
import pecan
|
||||||
|
|
||||||
|
|
||||||
|
class RootController(object):
|
||||||
|
|
||||||
|
@pecan.expose('json')
|
||||||
|
def _lookup(self, version, *remainder):
|
||||||
|
if version == 'v1.0':
|
||||||
|
return V1Controller(), remainder
|
||||||
|
|
||||||
|
@pecan.expose('json')
|
||||||
|
def index(self):
|
||||||
|
return {
|
||||||
|
"versions": [
|
||||||
|
{
|
||||||
|
"status": "CURRENT",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"rel": "self",
|
||||||
|
"href": pecan.request.application_url + "/v1.0/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id": "v1.0",
|
||||||
|
"updated": "2015-09-09"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class V1Controller(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
self.sub_controllers = {
|
||||||
|
"helloworld": helloworld.HelloWorldController()
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, ctrl in self.sub_controllers.items():
|
||||||
|
setattr(self, name, ctrl)
|
||||||
|
|
||||||
|
@pecan.expose('json')
|
||||||
|
def index(self):
|
||||||
|
return {
|
||||||
|
"version": "1.0",
|
||||||
|
"links": [
|
||||||
|
{"rel": "self",
|
||||||
|
"href": pecan.request.application_url + "/v1.0"}
|
||||||
|
] + [
|
||||||
|
{"rel": name,
|
||||||
|
"href": pecan.request.application_url + "/v1.0/" + name}
|
||||||
|
for name in sorted(self.sub_controllers)
|
||||||
|
]
|
||||||
|
}
|
0
kingbird/common/__init__.py
Executable file
0
kingbird/common/__init__.py
Executable file
70
kingbird/common/context.py
Executable file
70
kingbird/common/context.py
Executable file
@ -0,0 +1,70 @@
|
|||||||
|
# Copyright 2015 Huawei Technologies Co., Ltd.
|
||||||
|
# All Rights Reserved
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from oslo_context import context as oslo_ctx
|
||||||
|
|
||||||
|
|
||||||
|
class ContextBase(oslo_ctx.RequestContext):
|
||||||
|
def __init__(self, auth_token=None, user_id=None, tenant_id=None,
|
||||||
|
is_admin=False, request_id=None, overwrite=True,
|
||||||
|
user_name=None, tenant_name=None, **kwargs):
|
||||||
|
super(ContextBase, self).__init__(
|
||||||
|
auth_token=auth_token,
|
||||||
|
user=user_id or kwargs.get('user', None),
|
||||||
|
tenant=tenant_id or kwargs.get('tenant', None),
|
||||||
|
domain=kwargs.get('domain', None),
|
||||||
|
user_domain=kwargs.get('user_domain', None),
|
||||||
|
project_domain=kwargs.get('project_domain', None),
|
||||||
|
is_admin=is_admin,
|
||||||
|
read_only=kwargs.get('read_only', False),
|
||||||
|
show_deleted=kwargs.get('show_deleted', False),
|
||||||
|
request_id=request_id,
|
||||||
|
resource_uuid=kwargs.get('resource_uuid', None),
|
||||||
|
overwrite=overwrite)
|
||||||
|
self.user_name = user_name
|
||||||
|
self.tenant_name = tenant_name
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
ctx_dict = super(ContextBase, self).to_dict()
|
||||||
|
ctx_dict.update({
|
||||||
|
'user_name': self.user_name,
|
||||||
|
'tenant_name': self.tenant_name
|
||||||
|
})
|
||||||
|
return ctx_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, ctx):
|
||||||
|
return cls(**ctx)
|
||||||
|
|
||||||
|
|
||||||
|
class Context(ContextBase):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super(Context, self).__init__(**kwargs)
|
||||||
|
self._session = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def session(self):
|
||||||
|
# todo get db session in the context
|
||||||
|
# if not self._session:
|
||||||
|
# self._session = dal.get_session()
|
||||||
|
return self._session
|
||||||
|
|
||||||
|
|
||||||
|
def get_admin_context(read_only=True):
|
||||||
|
return ContextBase(user_id=None,
|
||||||
|
project_id=None,
|
||||||
|
is_admin=True,
|
||||||
|
overwrite=False,
|
||||||
|
read_only=read_only)
|
84
kingbird/common/exceptions.py
Executable file
84
kingbird/common/exceptions.py
Executable file
@ -0,0 +1,84 @@
|
|||||||
|
# Copyright 2015 Huawei Technologies Co., Ltd.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Kingbird base exception handling.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from oslo_utils import excutils
|
||||||
|
import six
|
||||||
|
|
||||||
|
from kingbird.common.i18n import _
|
||||||
|
|
||||||
|
|
||||||
|
class KingbirdException(Exception):
|
||||||
|
"""Base Kingbird Exception.
|
||||||
|
|
||||||
|
To correctly use this class, inherit from it and define
|
||||||
|
a 'message' property. That message will get printf'd
|
||||||
|
with the keyword arguments provided to the constructor.
|
||||||
|
"""
|
||||||
|
message = _("An unknown exception occurred.")
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
try:
|
||||||
|
super(KingbirdException, self).__init__(self.message % kwargs)
|
||||||
|
self.msg = self.message % kwargs
|
||||||
|
except Exception:
|
||||||
|
with excutils.save_and_reraise_exception() as ctxt:
|
||||||
|
if not self.use_fatal_exceptions():
|
||||||
|
ctxt.reraise = False
|
||||||
|
# at least get the core message out if something happened
|
||||||
|
super(KingbirdException, self).__init__(self.message)
|
||||||
|
|
||||||
|
if six.PY2:
|
||||||
|
def __unicode__(self):
|
||||||
|
return unicode(self.msg)
|
||||||
|
|
||||||
|
def use_fatal_exceptions(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class BadRequest(KingbirdException):
|
||||||
|
message = _('Bad %(resource)s request: %(msg)s')
|
||||||
|
|
||||||
|
|
||||||
|
class NotFound(KingbirdException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Conflict(KingbirdException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NotAuthorized(KingbirdException):
|
||||||
|
message = _("Not authorized.")
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceUnavailable(KingbirdException):
|
||||||
|
message = _("The service is unavailable")
|
||||||
|
|
||||||
|
|
||||||
|
class AdminRequired(NotAuthorized):
|
||||||
|
message = _("User does not have admin privileges: %(reason)s")
|
||||||
|
|
||||||
|
|
||||||
|
class InUse(KingbirdException):
|
||||||
|
message = _("The resource is inuse")
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidConfigurationOption(KingbirdException):
|
||||||
|
message = _("An invalid value was provided for %(opt_name)s: "
|
||||||
|
"%(opt_value)s")
|
30
kingbird/common/i18n.py
Executable file
30
kingbird/common/i18n.py
Executable file
@ -0,0 +1,30 @@
|
|||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import oslo_i18n
|
||||||
|
|
||||||
|
_translators = oslo_i18n.TranslatorFactory(domain='kingbird')
|
||||||
|
|
||||||
|
# The primary translation function using the well-known name "_"
|
||||||
|
_ = _translators.primary
|
||||||
|
|
||||||
|
# Translators for log levels.
|
||||||
|
#
|
||||||
|
# The abbreviated names are meant to reflect the usual use of a short
|
||||||
|
# name like '_'. The "L" is for "log" and the other letter comes from
|
||||||
|
# the level.
|
||||||
|
_LI = _translators.log_info
|
||||||
|
_LW = _translators.log_warning
|
||||||
|
_LE = _translators.log_error
|
||||||
|
_LC = _translators.log_critical
|
18
kingbird/common/utils.py
Executable file
18
kingbird/common/utils.py
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
# Copyright 2015 Huawei Technologies Co., Ltd.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
# implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
|
def get_import_path(cls):
|
||||||
|
return cls.__module__ + "." + cls.__name__
|
41
kingbird/common/version.py
Executable file
41
kingbird/common/version.py
Executable file
@ -0,0 +1,41 @@
|
|||||||
|
# Copyright 2011 OpenStack Foundation
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import pbr.version
|
||||||
|
|
||||||
|
KINGBIRD_VENDOR = "OpenStack Foundation"
|
||||||
|
KINGBIRD_PRODUCT = "OpenStack Kingbird"
|
||||||
|
KINGBIRD_PACKAGE = None # OS distro package version suffix
|
||||||
|
|
||||||
|
version_info = pbr.version.VersionInfo('kingbird')
|
||||||
|
version_string = version_info.version_string
|
||||||
|
|
||||||
|
|
||||||
|
def vendor_string():
|
||||||
|
return KINGBIRD_VENDOR
|
||||||
|
|
||||||
|
|
||||||
|
def product_string():
|
||||||
|
return KINGBIRD_PRODUCT
|
||||||
|
|
||||||
|
|
||||||
|
def package_string():
|
||||||
|
return KINGBIRD_PACKAGE
|
||||||
|
|
||||||
|
|
||||||
|
def version_string_with_package():
|
||||||
|
if package_string() is None:
|
||||||
|
return version_info.version_string()
|
||||||
|
else:
|
||||||
|
return "%s-%s" % (version_info.version_string(), package_string())
|
@ -1,6 +1,41 @@
|
|||||||
# The order of packages is significant, because pip processes them in the order
|
# The order of packages is significant, because pip processes them in the order
|
||||||
# of appearance. Changing the order has an impact on the overall integration
|
# of appearance. Changing the order has an impact on the overall integration
|
||||||
# process, which may cause wedges in the gate later.
|
# process, which may cause wedges in the gate later.
|
||||||
|
|
||||||
pbr>=1.6
|
pbr>=1.6
|
||||||
Babel>=1.3
|
Babel>=1.3
|
||||||
|
|
||||||
|
Paste
|
||||||
|
PasteDeploy>=1.5.0
|
||||||
|
Routes!=2.0,!=2.1,>=1.12.3;python_version=='2.7'
|
||||||
|
Routes!=2.0,>=1.12.3;python_version!='2.7'
|
||||||
|
debtcollector>=0.3.0 # Apache-2.0
|
||||||
|
eventlet>=0.17.4
|
||||||
|
pecan>=1.0.0
|
||||||
|
greenlet>=0.3.2
|
||||||
|
httplib2>=0.7.5
|
||||||
|
requests!=2.8.0,>=2.5.2
|
||||||
|
Werkzeug>=0.7 # BSD License
|
||||||
|
Jinja2>=2.8 # BSD License (3 clause)
|
||||||
|
keystonemiddleware!=2.4.0,>=2.0.0
|
||||||
|
netaddr!=0.7.16,>=0.7.12
|
||||||
|
retrying!=1.3.0,>=1.2.3 # Apache-2.0
|
||||||
|
SQLAlchemy<1.1.0,>=0.9.9
|
||||||
|
WebOb>=1.2.3
|
||||||
|
python-keystoneclient!=1.8.0,>=1.6.0
|
||||||
|
alembic>=0.8.0
|
||||||
|
six>=1.9.0
|
||||||
|
stevedore>=1.5.0 # Apache-2.0
|
||||||
|
oslo.concurrency>=2.3.0 # Apache-2.0
|
||||||
|
oslo.config>=2.6.0 # Apache-2.0
|
||||||
|
oslo.context>=0.2.0 # Apache-2.0
|
||||||
|
oslo.db>=3.0.0 # Apache-2.0
|
||||||
|
oslo.i18n>=1.5.0 # Apache-2.0
|
||||||
|
oslo.log>=1.12.0 # Apache-2.0
|
||||||
|
oslo.messaging!=2.8.0,>2.6.1 # Apache-2.0
|
||||||
|
oslo.middleware>=2.9.0 # Apache-2.0
|
||||||
|
oslo.policy>=0.5.0 # Apache-2.0
|
||||||
|
oslo.rootwrap>=2.0.0 # Apache-2.0
|
||||||
|
oslo.serialization>=1.10.0 # Apache-2.0
|
||||||
|
oslo.service>=0.12.0 # Apache-2.0
|
||||||
|
oslo.utils!=2.6.0,>=2.4.0 # Apache-2.0
|
||||||
|
oslo.versionedobjects>=0.9.0
|
||||||
|
@ -1,15 +1,23 @@
|
|||||||
# The order of packages is significant, because pip processes them in the order
|
# The order of packages is significant, because pip processes them in the order
|
||||||
# of appearance. Changing the order has an impact on the overall integration
|
# of appearance. Changing the order has an impact on the overall integration
|
||||||
# process, which may cause wedges in the gate later.
|
# process, which may cause wedges in the gate later.
|
||||||
|
|
||||||
hacking<0.11,>=0.10.2
|
hacking<0.11,>=0.10.2
|
||||||
|
|
||||||
|
cliff>=1.14.0 # Apache-2.0
|
||||||
coverage>=3.6
|
coverage>=3.6
|
||||||
discover
|
fixtures>=1.3.1
|
||||||
|
mock>=1.2
|
||||||
python-subunit>=0.0.18
|
python-subunit>=0.0.18
|
||||||
|
requests-mock>=0.6.0 # Apache-2.0
|
||||||
sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2
|
sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2
|
||||||
oslosphinx>=2.5.0 # Apache-2.0
|
oslosphinx>=2.5.0 # Apache-2.0
|
||||||
oslotest>=1.10.0 # Apache-2.0
|
|
||||||
testrepository>=0.0.18
|
testrepository>=0.0.18
|
||||||
testscenarios>=0.4
|
|
||||||
testtools>=1.4.0
|
testtools>=1.4.0
|
||||||
|
testresources>=0.2.4
|
||||||
|
testscenarios>=0.4
|
||||||
|
WebTest>=2.0
|
||||||
|
oslotest>=1.10.0 # Apache-2.0
|
||||||
|
os-testr>=0.4.1
|
||||||
|
tempest-lib>=0.10.0
|
||||||
|
ddt>=0.7.0
|
||||||
|
pylint==1.4.4 # GNU GPL v2
|
||||||
|
Loading…
Reference in New Issue
Block a user