Browse Source

Clean useless tables in Tricircle after splitting

1. What is the problem?
Tricircle now is dedicated for networking automation across Neutron. Some
tables used in APIs gateway should be removed, like aggregation table, pod
binding table, etc. They should not reside in the Tricircle any more. Other
tables containing old meanings but are still in use should be renamed for
better understanding. We can see the blueprint[1] for further explanation.

2. What is the solution to the problem?
The data models, tables and APIs about aggregation, pod binding, etc. should
be removed. After the pod binding table is removed, the az_hint used for
external network creation is hard to match. So special handle needs to be
implemented. Other tables will have vague meaning after this splitting, but
they still take effective in the Tricircle, So they should be renamed for
better understanding. What's more, the pod_name in the pod table is renamed
to region_name, which coordinates better with its availability zone.

  1)Tables to be removed:
    *aggregates
    *aggregate_metadata
    *instance_types
    *instance_type_projects
    *instance_type_extra_specs
    *key_pairs
    *pod_binding
  2)Tables need to be renamed:
    *cascaded_pod_service_configuration (new name: cached_endpoints)
    *cascaded_pods (new name: pods)
    *cascaded_pods_resource_routing (new name: resource_routings)
    *job (new name: async_jobs)

3. What the features need to be implemented to the Tricircle to realize
the solution?
After the pod binding table is removed, the az_hint used for external
network creation is hard to match. New features will be implemented to solve
this problem.

[1] https://blueprints.launchpad.net/tricircle/+spec/clean-legacy-tables
Change-Id: I025b4fb48c70abf424bd458fac0dc888e5fa19fd
changes/25/412325/11
Dongfeng Huang 6 years ago
parent
commit
d65601a4ff
  1. 2
      devstack/local.conf.node_1.sample
  2. 2
      devstack/local.conf.node_2.sample
  3. 2
      devstack/local.conf.sample
  4. 4
      devstack/plugin.sh
  5. 6
      devstack/verify_cross_pod_install.sh
  6. 4
      devstack/verify_top_install.sh
  7. 306
      doc/source/api_v1.rst
  8. 4
      doc/source/configuration.rst
  9. 8
      doc/source/installation-manual.rst
  10. 8
      doc/source/multi-pod-installation-devstack.rst
  11. 6
      doc/source/single-pod-installation-devstack.rst
  12. 9
      specs/ocata/legacy_tables_clean.rst
  13. 161
      tricircle/api/controllers/pod.py
  14. 1
      tricircle/api/controllers/root.py
  15. 46
      tricircle/api/controllers/routing.py
  16. 178
      tricircle/common/az_ag.py
  17. 28
      tricircle/common/client.py
  18. 6
      tricircle/common/exceptions.py
  19. 14
      tricircle/common/httpclient.py
  20. 18
      tricircle/common/policy.py
  21. 1
      tricircle/common/resource_handle.py
  22. 12
      tricircle/common/utils.py
  23. 125
      tricircle/db/api.py
  24. 37
      tricircle/db/migrate_repo/versions/001_init.py
  25. 116
      tricircle/db/migrate_repo/versions/002_resource.py
  26. 162
      tricircle/db/models.py
  27. 117
      tricircle/network/central_plugin.py
  28. 3
      tricircle/network/exceptions.py
  29. 28
      tricircle/network/helper.py
  30. 8
      tricircle/network/security_groups.py
  31. 4
      tricircle/tempestplugin/post_test_hook.sh
  32. 293
      tricircle/tests/functional/api/controllers/test_pod.py
  33. 54
      tricircle/tests/unit/api/controllers/test_pod.py
  34. 135
      tricircle/tests/unit/api/controllers/test_routing.py
  35. 169
      tricircle/tests/unit/common/test_az_ag.py
  36. 28
      tricircle/tests/unit/common/test_client.py
  37. 30
      tricircle/tests/unit/common/test_httpclient.py
  38. 6
      tricircle/tests/unit/db/test_api.py
  39. 32
      tricircle/tests/unit/db/test_models.py
  40. 137
      tricircle/tests/unit/network/test_central_plugin.py
  41. 48
      tricircle/tests/unit/xjob/test_xmanager.py
  42. 56
      tricircle/xjob/xmanager.py

2
devstack/local.conf.node_1.sample

@ -75,7 +75,7 @@ admin_username=admin
admin_password=$ADMIN_PASSWORD
admin_tenant=demo
auto_refresh_endpoint=True
top_pod_name=$CENTRAL_REGION_NAME
top_region_name=$CENTRAL_REGION_NAME
[tricircle]
real_core_plugin=neutron.plugins.ml2.plugin.Ml2Plugin

2
devstack/local.conf.node_2.sample

@ -76,7 +76,7 @@ admin_username=admin
admin_password=$ADMIN_PASSWORD
admin_tenant=demo
auto_refresh_endpoint=True
top_pod_name=$CENTRAL_REGION_NAME
top_region_name=$CENTRAL_REGION_NAME
[tricircle]
real_core_plugin=neutron.plugins.ml2.plugin.Ml2Plugin

2
devstack/local.conf.sample

@ -65,7 +65,7 @@ admin_username=admin
admin_password=$ADMIN_PASSWORD
admin_tenant=demo
auto_refresh_endpoint=True
top_pod_name=$CENTRAL_REGION_NAME
top_region_name=$CENTRAL_REGION_NAME
[tricircle]
real_core_plugin=neutron.plugins.ml2.plugin.Ml2Plugin

4
devstack/plugin.sh

@ -49,7 +49,7 @@ function init_common_tricircle_conf {
iniset $conf_file client admin_password $ADMIN_PASSWORD
iniset $conf_file client admin_tenant demo
iniset $conf_file client auto_refresh_endpoint True
iniset $conf_file client top_pod_name $CENTRAL_REGION_NAME
iniset $conf_file client top_region_name $CENTRAL_REGION_NAME
iniset $conf_file oslo_concurrency lock_path $TRICIRCLE_STATE_PATH/lock
}
@ -115,7 +115,7 @@ function start_central_neutron_server {
iniset $NEUTRON_CONF.$server_index client admin_password $ADMIN_PASSWORD
iniset $NEUTRON_CONF.$server_index client admin_tenant demo
iniset $NEUTRON_CONF.$server_index client auto_refresh_endpoint True
iniset $NEUTRON_CONF.$server_index client top_pod_name $CENTRAL_REGION_NAME
iniset $NEUTRON_CONF.$server_index client top_region_name $CENTRAL_REGION_NAME
if [ "$Q_ML2_PLUGIN_VLAN_TYPE_OPTIONS" != "" ]; then
iniset $NEUTRON_CONF.$server_index tricircle type_drivers local,shared_vlan

6
devstack/verify_cross_pod_install.sh

@ -48,13 +48,13 @@ token=$(openstack token issue | awk 'NR==5 {print $4}')
echo $token
curl -X POST http://127.0.0.1:19999/v1.0/pods -H "Content-Type: application/json" \
-H "X-Auth-Token: $token" -d '{"pod": {"pod_name": "RegionOne"}}'
-H "X-Auth-Token: $token" -d '{"pod": {"region_name": "RegionOne"}}'
curl -X POST http://127.0.0.1:19999/v1.0/pods -H "Content-Type: application/json" \
-H "X-Auth-Token: $token" -d '{"pod": {"pod_name": "Pod1", "az_name": "az1"}}'
-H "X-Auth-Token: $token" -d '{"pod": {"region_name": "Pod1", "az_name": "az1"}}'
curl -X POST http://127.0.0.1:19999/v1.0/pods -H "Content-Type: application/json" \
-H "X-Auth-Token: $token" -d '{"pod": {"pod_name": "Pod2", "az_name": "az2"}}'
-H "X-Auth-Token: $token" -d '{"pod": {"region_name": "Pod2", "az_name": "az2"}}'
echo "******************************"
echo "* Verify Nova *"

4
devstack/verify_top_install.sh

@ -44,10 +44,10 @@ token=$(openstack token issue | awk 'NR==5 {print $4}')
echo $token
curl -X POST http://127.0.0.1:19999/v1.0/pods -H "Content-Type: application/json" \
-H "X-Auth-Token: $token" -d '{"pod": {"pod_name": "RegionOne"}}'
-H "X-Auth-Token: $token" -d '{"pod": {"region_name": "RegionOne"}}'
curl -X POST http://127.0.0.1:19999/v1.0/pods -H "Content-Type: application/json" \
-H "X-Auth-Token: $token" -d '{"pod": {"pod_name": "Pod1", "az_name": "az1"}}'
-H "X-Auth-Token: $token" -d '{"pod": {"region_name": "Pod1", "az_name": "az1"}}'
echo "******************************"
echo "* Verify Nova *"

306
doc/source/api_v1.rst

@ -58,18 +58,14 @@ following table.
+===========+=======+===============+=====================================================+
|pod_id |body | string |pod_id is a uuid attribute of the pod object. |
+-----------+-------+---------------+-----------------------------------------------------+
|pod_name |body | string |pod_name is specified by user but must match the |
| | | |region name registered in Keystone. When creating a |
| | | |pod for local Neutron, the Tricircle automatically |
| | | |creates a host aggregation and assigns the new |
| | | |availability zone id to it. |
|region_name|body | string |region_name is specified by user but must match the |
| | | |region name registered in Keystone. |
+-----------+-------+---------------+-----------------------------------------------------+
|az_name |body | string |When az_name is empty, it means this is a pod for |
| | | |central Neutron, no host aggregation will be |
| | | |generated. If az_name is not empty, it means the pod |
| | | |will belong to this availability zone. Multiple pods |
| | | |with the same az_name means that these pods are under|
| | | |the same availability zone. |
| | | |central Neutron. If az_name is not empty, it means |
| | | |the pod will belong to this availability zone. |
| | | |Multiple pods with the same az_name means that these |
| | | |pods are under the same availability zone. |
+-----------+-------+---------------+-----------------------------------------------------+
|pod_az_name|body | string |pod_az_name is the az name used in the pod for local |
| | | |Neutron when creating network, router objects. It |
@ -97,21 +93,21 @@ This is an example of response information for GET /pods.
"pod_az_name": "",
"pod_id": "1a51bee7-10f0-47e8-bb4a-70f51394069c",
"az_name": "",
"pod_name": "RegionOne"
"region_name": "RegionOne"
},
{
"dc_name": "",
"pod_az_name": "",
"pod_id": "22cca6ad-b791-4805-af14-923c5224fcd2",
"az_name": "az2",
"pod_name": "Pod2"
"region_name": "Pod2"
},
{
"dc_name": "",
"pod_az_name": "",
"pod_id": "3c22e5d4-5fed-45ed-a1e9-d532668cedc2",
"az_name": "az1",
"pod_name": "Pod1"
"region_name": "Pod1"
}
]
}
@ -144,18 +140,14 @@ All of its attributes are described in the following table.
+===========+=======+===============+=====================================================+
|pod_id |body | string |pod_id is a uuid attribute of the pod object. |
+-----------+-------+---------------+-----------------------------------------------------+
|pod_name |body | string |pod_name is specified by user but must match the |
| | | |region name registered in Keystone. When creating a |
| | | |pod for local Neutron, the Tricircle automatically |
| | | |creates a host aggregation and assigns the new |
| | | |availability zone id to it. |
|region_name|body | string |region_name is specified by user but must match the |
| | | |region name registered in Keystone. |
+-----------+-------+---------------+-----------------------------------------------------+
|az_name |body | string |When az_name is empty, it means this is a pod for |
| | | |central Neutron, no host aggregation will be |
| | | |generated. If az_name is not empty, it means the pod |
| | | |will belong to this availability zone. Multiple pods |
| | | |with the same az_name means that these pods are under|
| | | |the same availability zone. |
| | | |central Neutron. If az_name is not empty, it means |
| | | |the pod will belong to this availability zone. |
| | | |Multiple pods with the same az_name means that these |
| | | |pods are under the same availability zone. |
+-----------+-------+---------------+-----------------------------------------------------+
|pod_az_name|body | string |pod_az_name is the az name used in the pod for local |
| | | |Neutron when creating network, router objects. It |
@ -182,7 +174,7 @@ This is an example of response information for GET /pods/{pod_id}.
"pod_az_name": "",
"pod_id": "3c22e5d4-5fed-45ed-a1e9-d532668cedc2",
"az_name": "az1",
"pod_name": "Pod1"
"region_name": "Pod1"
}
}
@ -202,18 +194,14 @@ in the following table.
+-----------+-------+---------------+-----------------------------------------------------+
|Name |In | Type | Description |
+===========+=======+===============+=====================================================+
|pod_name |body | string |pod_name is specified by user but must match the |
| | | |region name registered in Keystone. When creating a |
| | | |pod for local Neutron, the Tricircle automatically |
| | | |creates a host aggregation and assigns the new |
| | | |availability zone id to it. |
|region_name|body | string |region_name is specified by user but must match the |
| | | |region name registered in Keystone. |
+-----------+-------+---------------+-----------------------------------------------------+
|az_name |body | string |When az_name is empty, it means this is a pod for |
| | | |central Neutron, no host aggregation will be |
| | | |generated. If az_name is not empty, it means the pod |
| | | |will belong to this availability zone. Multiple pods |
| | | |with the same az_name means that these pods are under|
| | | |the same availability zone. |
| | | |central Neutron. If az_name is not empty, it means |
| | | |the pod will belong to this availability zone. |
| | | |Multiple pods with the same az_name means that these |
| | | |pods are under the same availability zone. |
+-----------+-------+---------------+-----------------------------------------------------+
|pod_az_name|body | string |pod_az_name is the az name used in the pod for local |
| | | |Neutron when creating network, router objects. It |
@ -238,18 +226,14 @@ are listed below.
+===========+=======+===============+=====================================================+
|pod_id |body | string |pod_id is automatically generated when creating a pod|
+-----------+-------+---------------+-----------------------------------------------------+
|pod_name |body | string |pod_name is specified by user but must match the |
| | | |region name registered in Keystone. When creating a |
| | | |pod for local Neutron, the Tricircle automatically |
| | | |creates a host aggregation and assigns the new |
| | | |availability zone id to it. |
|region_name|body | string |region_name is specified by user but must match the |
| | | |region name registered in Keystone. |
+-----------+-------+---------------+-----------------------------------------------------+
|az_name |body | string |When az_name is empty, it means this is a pod for |
| | | |central Neutron, no host aggregation will be |
| | | |generated. If az_name is not empty, it means the pod |
| | | |will belong to this availability zone. Multiple pods |
| | | |with the same az_name means that these pods are under|
| | | |the same availability zone. |
| | | |central Neutron. If az_name is not empty, it means |
| | | |the pod will belong to this availability zone. |
| | | |Multiple pods with the same az_name means that these |
| | | |pods are under the same availability zone. |
+-----------+-------+---------------+-----------------------------------------------------+
|pod_az_name|body | string |pod_az_name is the az name used in the pod for local |
| | | |Neutron when creating network, router objects. It |
@ -272,7 +256,7 @@ This is an example of request information for POST /pods.
{
"pod": {
"pod_name": "Pod3",
"region_name": "Pod3",
"az_name": "az1",
"pod_az_name": "az1",
"dc_name": "data center 1"
@ -291,7 +275,7 @@ This is an example of response information for POST /pods.
"pod_az_name": "az1",
"pod_id": "e02e03b8-a94f-4eb1-991e-a8a271cc2313",
"az_name": "az1",
"pod_name": "Pod3"
"region_name": "Pod3"
}
}
@ -318,235 +302,6 @@ Normal Response Code: 200
There is no response. But we can list all the pods to verify whether the
specific pod has been deleted or not.
Pod Binding
===========
A pod binding represents a mapping relationship between tenant and pod. Pods
for local Neutron are classified into different categories. A tenant will be
bound to different pod groups for different purposes. Only the pod for local
Neutron could be bound with a tenant. Pod for central Neutron serves as the
coordinator of networking automation across local Neutron servers.
+------------------+------------+---------------------+-------------------------------------+
|**GET** |/bindings | |Retrieve Pod Binding List |
+------------------+------------+---------------------+-------------------------------------+
This fetches all the pod bindings.
Normal Response Code: 200
**Response**
Pod bindings contain one or more binding instances whose attributes
are listed in the following table.
+-------------+-------+---------------+-----------------------------------------------------+
|Name |In | Type | Description |
+=============+=======+===============+=====================================================+
|tenant_id |body | string |tenant_id is automatically generated when adding a |
| | | |uuid of a project object in KeyStone. "Tenant" is an |
| | | |old term for a project in Keystone. Starting in API |
| | | |version 3, "project" is the preferred term. |
| | | |Accordingly, project_id is used instead of tenant_id.|
+-------------+-------+---------------+-----------------------------------------------------+
|pod_id |body | string |pod_id is a uuid attribute of the pod object. |
+-------------+-------+---------------+-----------------------------------------------------+
|id |body | string |id is a uuid attribute of the pod binding. It is |
| | | |automatically generated when new binding relation |
| | | |happens between tenant and pod. |
+-------------+-------+---------------+-----------------------------------------------------+
|created_at |body | timestamp |created time of the pod binding. |
+-------------+-------+---------------+-----------------------------------------------------+
|updated_at |body | timestamp |updated time of the pod binding. |
+-------------+-------+---------------+-----------------------------------------------------+
**Response Example**
This is an example of response information for GET /bindings.
::
{
"pod_bindings": [
{
"updated_at": null,
"tenant_id": "1782b3310f144836aa73c1ac5117d8da",
"created_at": "2016-06-03 07:37:50",
"id": "6ba7510c-baeb-44ad-8815-c4d229b52e46",
"pod_id": "22cca6ad-b791-4805-af14-923c5224fcd2"
},
{
"updated_at": null,
"tenant_id": "1782b3310f144836aa73c1ac5117d8da",
"created_at": "2016-06-03 07:37:06",
"id": "f0a54f30-6208-499d-b087-0ac64f6f2756",
"pod_id": "3c22e5d4-5fed-45ed-a1e9-d532668cedc2"
}
]
}
+------------------+---------------+-------------+---------------------------------------+
|**GET** |/bindings/{id} | |Retrieve a Single Pod Binding |
+------------------+---------------+-------------+---------------------------------------+
This fetches a single pod binding.
Normal Response Code: 200
**Request**
+-------------+-------+---------------+-----------------------------------------------------+
|Name |In | Type | Description |
+=============+=======+===============+=====================================================+
|id |path | string |id is a uuid attribute of the pod binding. It is |
| | | |automatically generated when new binding relation |
| | | |happens between tenant and pod. |
+-------------+-------+---------------+-----------------------------------------------------+
**Response**
Pod binding represents a mapping relationship between tenant and pod. All
of its attributes are described in the following table.
+-------------+-------+---------------+-----------------------------------------------------+
|Name |In | Type | Description |
+=============+=======+===============+=====================================================+
|tenant_id |body | string |tenant_id is automatically generated when adding a |
| | | |uuid of a project object in KeyStone. "Tenant" is an |
| | | |old term for a project in Keystone. Starting in API |
| | | |version 3, "project" is the preferred term. |
| | | |Accordingly, project_id is used instead of tenant_id.|
+-------------+-------+---------------+-----------------------------------------------------+
|pod_id |body | string |pod_id is a uuid attribute of the pod object. |
+-------------+-------+---------------+-----------------------------------------------------+
|id |body | string |id is a uuid attribute of the pod binding. It is |
| | | |automatically generated when new binding relation |
| | | |happens between tenant and pod. |
+-------------+-------+---------------+-----------------------------------------------------+
|created_at |body | timestamp |created time of the pod binding. |
+-------------+-------+---------------+-----------------------------------------------------+
|updated_at |body | timestamp |updated time of the pod binding. |
+-------------+-------+---------------+-----------------------------------------------------+
**Response Example**
This is an example of response information for GET /bindings/{id}.
::
{
"pod_binding": {
"updated_at": null,
"tenant_id": "1782b3310f144836aa73c1ac5117d8da",
"created_at": "2016-06-03 07:37:06",
"id": "f0a54f30-6208-499d-b087-0ac64f6f2756",
"pod_id": "3c22e5d4-5fed-45ed-a1e9-d532668cedc2"
}
}
+---------------+-----------+--------------------+------------------------------------------+
|**POST** |/bindings | |Create a Pod Binding |
+---------------+-----------+--------------------+------------------------------------------+
This creates a pod binding.
Normal Response Code: 200
**Request**
Some essential attributes of the pod binding instance are required and
described in the following table.
+-------------+-------+---------------+-----------------------------------------------------+
|Name |In | Type | Description |
+=============+=======+===============+=====================================================+
|tenant_id |body | string |tenant_id is automatically generated when adding a |
| | | |uuid of a project object in KeyStone. "Tenant" is an |
| | | |old term for a project in Keystone. Starting in API |
| | | |version 3, "project" is the preferred term. |
| | | |Accordingly, project_id is used instead of tenant_id.|
+-------------+-------+---------------+-----------------------------------------------------+
|pod_id |body | string |pod_id is a uuid attribute of the pod object. |
+-------------+-------+---------------+-----------------------------------------------------+
**Response**
An id is assigned to a pod binding instance when it is created, and some other
attribute values are given meanwhile. All of its fields are listed below.
+-------------+-------+---------------+-----------------------------------------------------+
|Name |In | Type | Description |
+=============+=======+===============+=====================================================+
|tenant_id |body | string |tenant_id is automatically generated when adding a |
| | | |uuid of a project object in KeyStone. "Tenant" is an |
| | | |old term for a project in Keystone. Starting in API |
| | | |version 3, "project" is the preferred term. |
| | | |Accordingly, project_id is used instead of tenant_id.|
+-------------+-------+---------------+-----------------------------------------------------+
|pod_id |body | string |pod_id is a uuid attribute of the pod object. |
+-------------+-------+---------------+-----------------------------------------------------+
|id |body | string |id is a uuid attribute of the pod binding. It is |
| | | |automatically generated when new binding relation |
| | | |happens between tenant and pod. |
+-------------+-------+---------------+-----------------------------------------------------+
|created_at |body | timestamp |created time of the pod binding. |
+-------------+-------+---------------+-----------------------------------------------------+
|updated_at |body | timestamp |updated time of the pod binding. |
+-------------+-------+---------------+-----------------------------------------------------+
**Request Example**
This is an example of request information for POST /bindings.
::
{
"pod_binding": {
"tenant_id": "1782b3310f144836aa73c1ac5117d8da",
"pod_id": "e02e03b8-a94f-4eb1-991e-a8a271cc2313"
}
}
**Response Example**
This is an example of response information for POST /bindings.
::
{
"pod_binding": {
"updated_at": null,
"tenant_id": "1782b3310f144836aa73c1ac5117d8da",
"created_at": "2016-08-18 14:06:33",
"id": "b17ac347-c898-4cea-a09d-7b0a6ec34f56",
"pod_id": "e02e03b8-a94f-4eb1-991e-a8a271cc2313"
}
}
+---------------+----------------+---------------+------------------------------------------+
|**DELETE** |/bindings/{id} | |Delete a Pod Binding |
+---------------+----------------+---------------+------------------------------------------+
This deletes a pod binding.
Normal Response Code: 200
**Request**
+-----------+-------+---------------+-----------------------------------------------------+
|Name |In | Type | Description |
+===========+=======+===============+=====================================================+
|id |path | string |id is a uuid attribute of the pod binding. It is |
| | | |automatically generated when new binding relation |
| | | |happens between tenant and pod. |
+-----------+-------+---------------+-----------------------------------------------------+
**Response**
There is no response. But we can list all the pod bindings to verify
whether the specific pod binding has been deleted or not.
Resource Routing
================
The Tricircle is responsible for resource(for example, network, subnet, port,
@ -954,3 +709,4 @@ from the database.
}
}

4
doc/source/configuration.rst

@ -51,7 +51,7 @@ Central Plugin.
- (Integer) timeout for neutron client in seconds.
* - ``ns_bridge_cidr`` = ``100.128.0.0/9``
- (String) cidr pool of the north-south bridge network, for example, 100.128.0.0/9
* - ``top_pod_name`` = ``None``
* - ``top_region_name`` = ``None``
- (String) region name of Central Neutron in which client needs to access, for example, CentralRegion.
@ -146,6 +146,8 @@ configured in central Neutron's neutron.conf.
-
* - ``bridge_network_type`` = ``shared_vlan``
- (String) Type of l3 bridge network, this type should be enabled in tenant_network_types and is not local type, for example, shared_vlan.
* - ``default_region_for_external_network`` = ``RegionOne``
- (String) Default region where the external network belongs to, it must exist, for example, RegionOne.
* - ``network_vlan_ranges`` = ``None``
- (String) List of <physical_network>:<vlan_min>:<vlan_max> or <physical_network> specifying physical_network names usable for VLAN provider and tenant networks, as well as ranges of VLAN tags on each available for allocation to tenant networks, for example,bridge:2001:3000.
* - ``tenant_network_types`` = ``local,shared_vlan``

8
doc/source/installation-manual.rst

@ -78,7 +78,7 @@ Installation with Central Neutron Server
[client] auth_url, "keystone authorization url", http://$keystone_service_host:5000/v3
[client] identity_url, "keystone service url", http://$keystone_service_host:35357/v3
[client] auto_refresh_endpoint, "if set to True, endpoint will be automatically refreshed if timeout accessing", True
[client] top_pod_name, "name of central region which client needs to access", CentralRegion
[client] top_region_name, "name of central region which client needs to access", CentralRegion
[client] admin_username, "username of admin account", admin
[client] admin_password, "password of admin account", password
[client] admin_tenant, "project name of admin account", demo
@ -118,7 +118,7 @@ Installation with Central Neutron Server
[client] auth_url, "keystone authorization url", http://$keystone_service_host:5000/v3
[client] identity_url, "keystone service url", http://$keystone_service_host:35357/v3
[client] auto_refresh_endpoint, "if set to True, endpoint will be automatically refreshed if timeout accessing", True
[client] top_pod_name, "name of central region which client needs to access", CentralRegion
[client] top_region_name, "name of central region which client needs to access", CentralRegion
[client] admin_username, "username of admin account", admin
[client] admin_password, "password of admin account", password
[client] admin_tenant, "project name of admin account", demo
@ -161,7 +161,7 @@ Installation with Central Neutron Server
[client] auth_url, "keystone authorization url", http://$keystone_service_host:5000/v3
[client] identity_url, "keystone service url", http://$keystone_service_host:35357/v3
[client] auto_refresh_endpoint, "if set to True, endpoint will be automatically refreshed if timeout accessing", True
[client] top_pod_name, "name of central region which client needs to access", CentralRegion
[client] top_region_name, "name of central region which client needs to access", CentralRegion
[client] admin_username, "username of admin account", admin
[client] admin_password, "password of admin account", password
[client] admin_tenant, "project name of admin account", demo
@ -211,7 +211,7 @@ Installation with Local Neutron Server
[client] auth_url, "keystone authorization url", http://$keystone_service_host:5000/v3
[client] identity_url, "keystone service url", http://$keystone_service_host:35357/v3
[client] auto_refresh_endpoint, "if set to True, endpoint will be automatically refreshed if timeout accessing", True
[client] top_pod_name, "name of central region which client needs to access", CentralRegion
[client] top_region_name, "name of central region which client needs to access", CentralRegion
[client] admin_username, "username of admin account", admin
[client] admin_password, "password of admin account", password
[client] admin_tenant, "project name of admin account", demo

8
doc/source/multi-pod-installation-devstack.rst

@ -261,15 +261,15 @@ How to play
availability zones and OpenStack instances, "$token" is obtained in step 4 ::
curl -X POST http://127.0.0.1:19999/v1.0/pods -H "Content-Type: application/json" \
-H "X-Auth-Token: $token" -d '{"pod": {"pod_name": "CentralRegion"}}'
-H "X-Auth-Token: $token" -d '{"pod": {"region_name": "CentralRegion"}}'
curl -X POST http://127.0.0.1:19999/v1.0/pods -H "Content-Type: application/json" \
-H "X-Auth-Token: $token" -d '{"pod": {"pod_name": "RegionOne", "az_name": "az1"}}'
-H "X-Auth-Token: $token" -d '{"pod": {"region_name": "RegionOne", "az_name": "az1"}}'
curl -X POST http://127.0.0.1:19999/v1.0/pods -H "Content-Type: application/json" \
-H "X-Auth-Token: $token" -d '{"pod": {"pod_name": "RegionTwo", "az_name": "az2"}}'
-H "X-Auth-Token: $token" -d '{"pod": {"region_name": "RegionTwo", "az_name": "az2"}}'
Pay attention to "pod_name" parameter we specify when creating pod. Pod name
Pay attention to "region_name" parameter we specify when creating pod. Pod name
should exactly match the region name registered in Keystone. In the above
commands, we create pods named "CentralRegion", "RegionOne" and "RegionTwo".

6
doc/source/single-pod-installation-devstack.rst

@ -68,12 +68,12 @@ installing DevStack in virtual machine.
step 7::
curl -X POST http://127.0.0.1:19999/v1.0/pods -H "Content-Type: application/json" \
-H "X-Auth-Token: $token" -d '{"pod": {"pod_name": "CentralRegion"}}'
-H "X-Auth-Token: $token" -d '{"pod": {"region_name": "CentralRegion"}}'
curl -X POST http://127.0.0.1:19999/v1.0/pods -H "Content-Type: application/json" \
-H "X-Auth-Token: $token" -d '{"pod": {"pod_name": "RegionOne", "az_name": "az1"}}'
-H "X-Auth-Token: $token" -d '{"pod": {"region_name": "RegionOne", "az_name": "az1"}}'
Pay attention to "pod_name" parameter we specify when creating pod. Pod name
Pay attention to "region_name" parameter we specify when creating pod. Pod name
should exactly match the region name registered in Keystone. In the above
commands, we create pods named "CentralRegion" and "RegionOne".

9
specs/ocata/legacy_tables_clean.rst

@ -22,17 +22,16 @@ of external network creation, it will take 'availability_zone_hints' (AZ or
az will be used for short for availability zone) as a parameter. Previously
az_hints was searched in the pod binding table by az_name and tenant_id, now
the pod binding table is deprecated and new search strategy is needed to fix
the problem[2]. A function named find_by_az will be developed to find the
the problem[2]. A function named find_pod_by_az will be developed to find the
az_hints by az_name in the pod table. Given the az_name, if it is not empty,
we first match it with region_name in the pod table. When a pod with the same
region_name is found, it will be returned back. The search procedure is
complete. If no pod is found with the same region_name, then we try to match
it with az_name in the pod table. If multiple pods are found, then we will
raise an exception. If only one pod is found, this pod will be returned back.
However, if no pod is matched at the end of the previous search procedure or
the az_name is empty, a new configuration item
"default_region_for_external_network" will be used, a pod with this region_name
will be returned back.
An exception will be raised if no pod is matched at the end of the previous
search procedure. However, if the az_name is empty, we will return None, a new
configuration item "default_region_for_external_network" will be used.
Proposed Change
===============

161
tricircle/api/controllers/pod.py

@ -22,13 +22,11 @@ import oslo_db.exception as db_exc
from oslo_log import log as logging
from oslo_utils import uuidutils
from tricircle.common import az_ag
import tricircle.common.context as t_context
import tricircle.common.exceptions as t_exc
from tricircle.common.i18n import _
from tricircle.common.i18n import _LE
from tricircle.common import policy
from tricircle.common import utils
from tricircle.db import api as db_api
from tricircle.db import core
@ -57,18 +55,18 @@ class PodsController(rest.RestController):
pod = kw['pod']
# if az_name is null, and there is already one in db
pod_name = pod.get('pod_name', '').strip()
region_name = pod.get('region_name', '').strip()
pod_az_name = pod.get('pod_az_name', '').strip()
dc_name = pod.get('dc_name', '').strip()
az_name = pod.get('az_name', '').strip()
_uuid = uuidutils.generate_uuid()
if az_name == '' and pod_name == '':
return Response(_('Valid pod_name is required for top region'),
if az_name == '' and region_name == '':
return Response(_('Valid region_name is required for top region'),
422)
if az_name != '' and pod_name == '':
return Response(_('Valid pod_name is required for pod'), 422)
if az_name != '' and region_name == '':
return Response(_('Valid region_name is required for pod'), 422)
if pod.get('az_name') is None:
if self._get_top_region(context) != '':
@ -77,7 +75,8 @@ class PodsController(rest.RestController):
# if az_name is not null, then the pod region name should not
# be same as that the top region
if az_name != '':
if self._get_top_region(context) == pod_name and pod_name != '':
if (self._get_top_region(context) == region_name and
region_name != ''):
return Response(
_('Pod region name duplicated with the top region name'),
409)
@ -88,36 +87,26 @@ class PodsController(rest.RestController):
try:
with context.session.begin():
# if not top region,
# then add corresponding ag and az for the pod
if az_name != '':
ag_name = utils.get_ag_name(pod_name)
aggregate = az_ag.create_ag_az(context,
ag_name=ag_name,
az_name=az_name)
if aggregate is None:
return Response(_('Ag creation failure'), 400)
new_pod = core.create_resource(
context, models.Pod,
{'pod_id': _uuid,
'pod_name': pod_name,
'region_name': region_name,
'pod_az_name': pod_az_name,
'dc_name': dc_name,
'az_name': az_name})
except db_exc.DBDuplicateEntry as e1:
LOG.exception(_LE('Record already exists on %(pod_name)s: '
LOG.exception(_LE('Record already exists on %(region_name)s: '
'%(exception)s'),
{'pod_name': pod_name,
{'region_name': region_name,
'exception': e1})
return Response(_('Record already exists'), 409)
except Exception as e2:
LOG.exception(_LE('Failed to create pod: %(pod_name)s,'
LOG.exception(_LE('Failed to create pod: %(region_name)s,'
'pod_az_name: %(pod_az_name)s,'
'dc_name: %(dc_name)s,'
'az_name: %(az_name)s'
'%(exception)s '),
{'pod_name': pod_name,
{'region_name': region_name,
'pod_az_name': pod_az_name,
'dc_name': dc_name,
'az_name': az_name,
@ -167,12 +156,6 @@ class PodsController(rest.RestController):
try:
with context.session.begin():
pod = core.get_resource(context, models.Pod, _id)
if pod is not None:
ag_name = utils.get_ag_name(pod['pod_name'])
ag = az_ag.get_ag_by_name(context, ag_name)
if ag is not None:
az_ag.delete_ag(context, ag['id'])
core.delete_resource(context, models.Pod, _id)
pecan.response.status = 200
return {}
@ -193,8 +176,8 @@ class PodsController(rest.RestController):
pods = core.query_resource(ctx,
models.Pod, [], [])
for pod in pods:
if pod['az_name'] == '' and pod['pod_name'] != '':
return pod['pod_name']
if pod['az_name'] == '' and pod['region_name'] != '':
return pod['region_name']
except Exception as e:
LOG.exception(_LE('Failed to get top region: %(exception)s '),
{'exception': e})
@ -202,119 +185,3 @@ class PodsController(rest.RestController):
return top_region_name
return top_region_name
class BindingsController(rest.RestController):
def __init__(self):
pass
@expose(generic=True, template='json')
def post(self, **kw):
context = t_context.extract_context_from_environ()
if not policy.enforce(context, policy.ADMIN_API_BINDINGS_CREATE):
pecan.abort(401, _('Unauthorized to create bindings'))
return
if 'pod_binding' not in kw:
pecan.abort(400, _('Request body not found'))
return
pod_b = kw['pod_binding']
tenant_id = pod_b.get('tenant_id', '').strip()
pod_id = pod_b.get('pod_id', '').strip()
if tenant_id == '' or pod_id == '':
return Response(
_('Tenant_id and pod_id can not be empty'),
422)
# the az_pod_map_id should be exist for in the pod map table
try:
with context.session.begin():
pod = core.get_resource(context, models.Pod,
pod_id)
if pod.get('az_name') == '':
return Response(_('Top region can not be bound'), 422)
except t_exc.ResourceNotFound:
return Response(_('pod_id not found in pod'), 422)
except Exception as e:
LOG.exception(_LE('Failed to get_resource for pod_id: '
'%(pod_id)s ,'
'%(exception)s '),
{'pod_id': pod_id,
'exception': e})
pecan.abort(500, _('Failed to create pod binding'))
return
try:
pod_binding = db_api.create_pod_binding(
context, tenant_id, pod_id)
except db_exc.DBDuplicateEntry:
return Response(_('Pod binding already exists'), 409)
except db_exc.DBConstraintError:
return Response(_('pod_id not exists in pod'), 422)
except db_exc.DBReferenceError:
return Response(_('DB reference not exists in pod'), 422)
except Exception as e:
LOG.exception(_LE('Failed to create pod binding: %(exception)s '),
{'exception': e})
pecan.abort(500, _('Failed to create pod binding'))
return
return {'pod_binding': pod_binding}
@expose(generic=True, template='json')
def get_one(self, _id):
context = t_context.extract_context_from_environ()
if not policy.enforce(context, policy.ADMIN_API_BINDINGS_SHOW):
pecan.abort(401, _('Unauthorized to show bindings'))
return
try:
with context.session.begin():
pod_binding = core.get_resource(context,
models.PodBinding,
_id)
return {'pod_binding': pod_binding}
except t_exc.ResourceNotFound:
pecan.abort(404, _('Tenant pod binding not found'))
return
@expose(generic=True, template='json')
def get_all(self):
context = t_context.extract_context_from_environ()
if not policy.enforce(context, policy.ADMIN_API_BINDINGS_LIST):
pecan.abort(401, _('Unauthorized to list bindings'))
return
try:
with context.session.begin():
pod_bindings = core.query_resource(context,
models.PodBinding,
[], [])
except Exception:
pecan.abort(500, _('Fail to list tenant pod bindings'))
return
return {'pod_bindings': pod_bindings}
@expose(generic=True, template='json')
def delete(self, _id):
context = t_context.extract_context_from_environ()
if not policy.enforce(context, policy.ADMIN_API_BINDINGS_DELETE):
pecan.abort(401, _('Unauthorized to delete bindings'))
return
try:
with context.session.begin():
core.delete_resource(context, models.PodBinding, _id)
pecan.response.status = 200
return {}
except t_exc.ResourceNotFound:
pecan.abort(404, _('Pod binding not found'))
return

1
tricircle/api/controllers/root.py

@ -74,7 +74,6 @@ class V1Controller(object):
self.sub_controllers = {
"pods": pod.PodsController(),
"bindings": pod.BindingsController(),
"routings": routing.RoutingController()
}

46
tricircle/api/controllers/routing.py

@ -60,22 +60,6 @@ class RoutingController(rest.RestController):
400, _("Field %(field)s can not be empty") % {
'field': field})
# verify the integrity: the pod_id and the project_id should be bound
pod_id = routing.get('pod_id').strip()
project_id = routing.get('project_id').strip()
bindings = db_api.list_pod_bindings(context,
[{'key': 'pod_id',
'comparator': 'eq',
'value': pod_id
},
{'key': 'tenant_id',
'comparator': 'eq',
'value': project_id}
], [])
if len(bindings) == 0:
return utils.format_api_error(
400, _('The pod_id and project_id have not been bound'))
# the resource type should be properly provisioned.
resource_type = routing.get('resource_type').strip()
if not constants.is_valid_resource_type(resource_type):
@ -85,6 +69,8 @@ class RoutingController(rest.RestController):
try:
top_id = routing.get('top_id').strip()
bottom_id = routing.get('bottom_id').strip()
pod_id = routing.get('pod_id').strip()
project_id = routing.get('project_id').strip()
routing = db_api.create_resource_mapping(context, top_id,
bottom_id, pod_id,
@ -184,7 +170,7 @@ class RoutingController(rest.RestController):
403, _('Unauthorized to update resource routing'))
try:
routing = db_api.get_resource_routing(context, _id)
db_api.get_resource_routing(context, _id)
except t_exc.ResourceNotFound:
return utils.format_api_error(404,
_('Resource routing not found'))
@ -210,32 +196,6 @@ class RoutingController(rest.RestController):
return utils.format_api_error(
400, _('There is no such resource type'))
# verify the integrity: the pod_id and project_id should be bound
if 'pod_id' in update_dict or 'project_id' in update_dict:
if 'pod_id' in update_dict:
pod_id = update_dict['pod_id']
else:
pod_id = routing['pod_id']
if 'project_id' in update_dict:
project_id = update_dict['project_id']
else:
project_id = routing['project_id']
bindings = db_api.list_pod_bindings(context,
[{'key': 'pod_id',
'comparator': 'eq',
'value': pod_id
},
{'key': 'tenant_id',
'comparator': 'eq',
'value': project_id}
], [])
if len(bindings) == 0:
return utils.format_api_error(
400, _('The pod_id and project_id have not been '
'bound'))
try:
routing_updated = db_api.update_resource_routing(
context, _id, update_dict)

178
tricircle/common/az_ag.py

@ -1,178 +0,0 @@
# 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.
from oslo_log import log as logging
from oslo_utils import uuidutils
from tricircle.common.i18n import _LE
from tricircle.db import api as db_api
from tricircle.db import core
from tricircle.db import models
LOG = logging.getLogger(__name__)
def create_ag_az(context, ag_name, az_name):
aggregate = core.create_resource(context, models.Aggregate,
{'name': ag_name})
core.create_resource(
context, models.AggregateMetadata,
{'key': 'availability_zone',
'value': az_name,
'aggregate_id': aggregate['id']})
extra_fields = {
'availability_zone': az_name,
'metadata': {'availability_zone': az_name}
}
aggregate.update(extra_fields)
return aggregate
def get_one_ag(context, aggregate_id):
aggregate = core.get_resource(context, models.Aggregate, aggregate_id)
metadatas = core.query_resource(
context, models.AggregateMetadata,
[{'key': 'key', 'comparator': 'eq',
'value': 'availability_zone'},
{'key': 'aggregate_id', 'comparator': 'eq',
'value': aggregate['id']}], [])
if metadatas:
aggregate['availability_zone'] = metadatas[0]['value']
aggregate['metadata'] = {
'availability_zone': metadatas[0]['value']}
else:
aggregate['availability_zone'] = ''
aggregate['metadata'] = {}
return aggregate
def get_ag_by_name(context, ag_name):
filters = [{'key': 'name',
'comparator': 'eq',
'value': ag_name}]
aggregates = get_all_ag(context, filters)
if aggregates is not None:
if len(aggregates) == 1:
return aggregates[0]
return None
def delete_ag(context, aggregate_id):
core.delete_resources(context, models.AggregateMetadata,
[{'key': 'aggregate_id',
'comparator': 'eq',
'value': aggregate_id}])
core.delete_resource(context, models.Aggregate, aggregate_id)
return
def get_all_ag(context, filters=None, sorts=None):
aggregates = core.query_resource(context,
models.Aggregate,
filters or [],
sorts or [])
metadatas = core.query_resource(
context, models.AggregateMetadata,
[{'key': 'key',
'comparator': 'eq',
'value': 'availability_zone'}], [])
agg_meta_map = {}
for metadata in metadatas:
agg_meta_map[metadata['aggregate_id']] = metadata
for aggregate in aggregates:
extra_fields = {
'availability_zone': '',
'metadata': {}
}
if aggregate['id'] in agg_meta_map:
metadata = agg_meta_map[aggregate['id']]
extra_fields['availability_zone'] = metadata['value']
extra_fields['metadata'] = {
'availability_zone': metadata['value']}
aggregate.update(extra_fields)
return aggregates
def get_pod_by_az_tenant(context, az_name, tenant_id):
pod_bindings = core.query_resource(context,
models.PodBinding,
[{'key': 'tenant_id',
'comparator': 'eq',
'value': tenant_id}],
[])
for pod_b in pod_bindings:
pod = core.get_resource(context,
models.Pod,
pod_b['pod_id'])
if az_name and pod['az_name'] == az_name:
return pod, pod['pod_az_name']
elif az_name == '' and pod['az_name'] != '':
# if the az_name is not specified, a defult bottom
# pod will be selected
return pod, pod['pod_az_name']
else:
pass
# TODO(joehuang): schedule one dynamically in the future
if az_name != '':
filters = [{'key': 'az_name', 'comparator': 'eq', 'value': az_name}]
else:
filters = None
# if az_name is valid, select a pod under this az_name
# if az_name is '', select the first valid bottom pod.
# change to dynamic schedluing in the future
pods = db_api.list_pods(context, filters=filters)
for pod in pods:
if pod['pod_name'] != '' and pod['az_name'] != '':
try:
with context.session.begin():
core.create_resource(
context, models.PodBinding,
{'id': uuidutils.generate_uuid(),
'tenant_id': tenant_id,
'pod_id': pod['pod_id'],
'is_binding': True})
return pod, pod['pod_az_name']
except Exception as e:
LOG.error(_LE('Fail to create pod binding: %(exception)s'),
{'exception': e})
return None, None
return None, None
def list_pods_by_tenant(context, tenant_id):
pod_bindings = core.query_resource(context,
models.PodBinding,
[{'key': 'tenant_id',
'comparator': 'eq',
'value': tenant_id}],
[])
pods = []
if pod_bindings:
for pod_b in pod_bindings:
pod = core.get_resource(context,
models.Pod,
pod_b['pod_id'])
pods.append(pod)
return pods

28
tricircle/common/client.py

@ -45,7 +45,7 @@ client_opts = [
default=False,
help='if set to True, endpoint will be automatically'
'refreshed if timeout accessing endpoint'),
cfg.StrOpt('top_pod_name',
cfg.StrOpt('top_region_name',
help='name of top pod which client needs to access'),
cfg.StrOpt('admin_username',
help='username of admin account, needed when'
@ -167,14 +167,14 @@ class Client(object):
you can call create_resources(self, resource, cxt, body) directly to create
a network, or use create_networks(self, cxt, body) for short.
"""
def __init__(self, pod_name=None):
def __init__(self, region_name=None):
self.auth_url = cfg.CONF.client.auth_url
self.resource_service_map = {}
self.operation_resources_map = collections.defaultdict(set)
self.service_handle_map = {}
self.pod_name = pod_name
if not self.pod_name:
self.pod_name = cfg.CONF.client.top_pod_name
self.region_name = region_name
if not self.region_name:
self.region_name = cfg.CONF.client.top_region_name
for _, handle_class in inspect.getmembers(resource_handle):
if not inspect.isclass(handle_class):
continue
@ -238,7 +238,7 @@ class Client(object):
return region_service_endpoint_map
def _get_config_with_retry(self, cxt, filters, pod, service, retry):
conf_list = api.list_pod_service_configurations(cxt, filters)
conf_list = api.list_cached_endpoints(cxt, filters)
if len(conf_list) == 0:
if not retry:
raise exceptions.EndpointNotFound(pod, service)
@ -250,14 +250,14 @@ class Client(object):
def _ensure_endpoint_set(self, cxt, service):
handle = self.service_handle_map[service]
if not handle.is_endpoint_url_set():
pod_filters = [{'key': 'pod_name',
pod_filters = [{'key': 'region_name',
'comparator': 'eq',
'value': self.pod_name}]
'value': self.region_name}]
pod_list = api.list_pods(cxt, pod_filters)
if len(pod_list) == 0:
raise exceptions.ResourceNotFound(models.Pod,
self.pod_name)
# pod_name is unique key, safe to get the first element
self.region_name)
# region_name is unique key, safe to get the first element
pod_id = pod_list[0]['pod_id']
config_filters = [
{'key': 'pod_id', 'comparator': 'eq', 'value': pod_id},
@ -287,7 +287,7 @@ class Client(object):
for region in endpoint_map:
# use region name to query pod
pod_filters = [{'key': 'pod_name', 'comparator': 'eq',
pod_filters = [{'key': 'region_name', 'comparator': 'eq',
'value': region}]
pod_list = api.list_pods(cxt, pod_filters)
# skip region/pod not registered in cascade service
@ -299,7 +299,7 @@ class Client(object):
'value': pod_id},
{'key': 'service_type', 'comparator': 'eq',
'value': service}]
config_list = api.list_pod_service_configurations(
config_list = api.list_cached_endpoints(
cxt, config_filters)
if len(config_list) > 1:
@ -308,7 +308,7 @@ class Client(object):
config_id = config_list[0]['service_id']
update_dict = {
'service_url': endpoint_map[region][service]}
api.update_pod_service_configuration(
api.update_cached_endpoints(
cxt, config_id, update_dict)
else:
config_dict = {
@ -317,7 +317,7 @@ class Client(object):
'service_type': service,
'service_url': endpoint_map[region][service]
}
api.create_pod_service_configuration(
api.create_cached_endpoints(
cxt, config_dict)
def get_endpoint(self, cxt, pod_id, service):

6
tricircle/common/exceptions.py

@ -191,10 +191,10 @@ class ExternalNetPodNotSpecify(TricircleException):
class PodNotFound(NotFound):
message = "Pod %(pod_name)s could not be found."
message = "Pod %(region_name)s could not be found."
def __init__(self, pod_name):
super(PodNotFound, self).__init__(pod_name=pod_name)
def __init__(self, region_name):
super(PodNotFound, self).__init__(region_name=region_name)
# parameter validation error

14
tricircle/common/httpclient.py

@ -116,9 +116,9 @@ def get_bottom_url(t_ver, t_url, b_ver, b_endpoint):
return b_url
def get_pod_service_endpoint(context, pod_name, st):
def get_pod_service_endpoint(context, region_name, st):
pod = db_api.get_pod_by_name(context, pod_name)
pod = db_api.get_pod_by_name(context, region_name)
if pod:
c = client.Client()
@ -127,10 +127,10 @@ def get_pod_service_endpoint(context, pod_name, st):
return ''
def get_pod_service_ctx(context, t_url, pod_name, s_type=cons.ST_NOVA):
def get_pod_service_ctx(context, t_url, region_name, s_type=cons.ST_NOVA):
t_ver = get_version_from_url(t_url)
b_endpoint = get_pod_service_endpoint(context,
pod_name,
region_name,
s_type)
b_ver = get_version_from_url(b_endpoint)
b_url = ''
@ -169,14 +169,14 @@ def get_res_routing_ref(context, _id, t_url, s_type):
if not pod:
return None
pod_name = pod['pod_name']
region_name = pod['region_name']
s_ctx = get_pod_service_ctx(context, t_url, pod_name,
s_ctx = get_pod_service_ctx(context, t_url, region_name,
s_type=s_type)
if s_ctx['b_url'] == '':
LOG.error(_LE("bottom pod endpoint incorrect %s") %
pod_name)
region_name)
return s_ctx

18
tricircle/common/policy.py

@ -52,11 +52,6 @@ ADMIN_API_PODS_DELETE = 'admin_api:pods:delete'
ADMIN_API_PODS_SHOW = 'admin_api:pods:show'
ADMIN_API_PODS_LIST = 'admin_api:pods:list'
ADMIN_API_BINDINGS_CREATE = 'admin_api:bindings:create'
ADMIN_API_BINDINGS_DELETE = 'admin_api:bindings:delete'
ADMIN_API_BINDINGS_SHOW = 'admin_api:bindings:show'
ADMIN_API_BINDINGS_LIST = 'admin_api:bindings:list'
ADMIN_API_ROUTINGS_CREATE = 'admin_api:routings:create'
ADMIN_API_ROUTINGS_DELETE = 'admin_api:routings:delete'
ADMIN_API_ROUTINGS_PUT = 'admin_api:routings:put'
@ -77,19 +72,6 @@ tricircle_admin_api_policies = [