From 5a7d69be6ec867b140246db16cc8eb6007ab564d Mon Sep 17 00:00:00 2001 From: Bin Sun Date: Fri, 23 Mar 2018 10:58:31 +0800 Subject: Add get all method Change-Id: I85154b3471ecac246b8b2cfc9b3e60887256253f Issue-ID: MULTICLOUD-152 Signed-off-by: Bin Sun --- vio/vio/api_v2/api_definition/hosts.yaml | 25 +++++++++++++++++--- vio/vio/api_v2/api_router/controller_builder.py | 31 ++++++++++++++++++++++++- vio/vio/api_v2/api_router/v0_controller.py | 4 ++++ 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/vio/vio/api_v2/api_definition/hosts.yaml b/vio/vio/api_v2/api_definition/hosts.yaml index e755c77..89662f9 100644 --- a/vio/vio/api_v2/api_definition/hosts.yaml +++ b/vio/vio/api_v2/api_definition/hosts.yaml @@ -27,27 +27,46 @@ "200": schema: $ref: "#/definitions/host" + get_all: + produces: + - "application/json" + responses: + "200": + schema: + type: "array" + items: + $ref: "#/definitions/host" vim_path: "/compute/os-hypervisors" definitions: host: + plural_vim_resource: "hypervisors" + vim_resource: "hypervisor" + plural: "hosts" properties: name: type: string required: true source: hypervisor.hypervisor_hostname + id: + type: string + required: true + source: hypervisor.id + status: + type: string + source: hypervisor.status + state: + type: string + source: hypervisor.state cpu: type: integer minimal: 1 source: hypervisor.vcpus action: copy - required: true disk_gb: type: integer minimal: 0 source: hypervisor.local_gb - required: true memory_mb: type: integer minimal: 0 source: hypervisor.memory_mb - required: true diff --git a/vio/vio/api_v2/api_router/controller_builder.py b/vio/vio/api_v2/api_router/controller_builder.py index 9014377..6fcaf24 100644 --- a/vio/vio/api_v2/api_router/controller_builder.py +++ b/vio/vio/api_v2/api_router/controller_builder.py @@ -57,6 +57,15 @@ def _convert_vim_res_to_mc_res(vim_resource, res_properties): mc_resource = {} for key in res_properties: vim_res, attr = res_properties[key]["source"].split('.') + + if attr not in vim_resource[vim_res]: + if res_properties[key].get("required"): + raise Exception("Required field %s is missed in VIM " + "resource %s", (attr, vim_resource)) + else: + # None required fields missed, just skip. + continue + action = res_properties[key].get("action", "copy") # TODO(xiaohhui): Actions should be in constants. if action == "copy": @@ -86,7 +95,6 @@ def _build_api_controller(api_meta): @pecan.expose("json") def _get(self, vim_id, tenant_id, resource_id): """ General GET """ - session = _get_vim_auth_session(vim_id, tenant_id) service = {'service_type': service_type, 'interface': 'public'} @@ -101,6 +109,27 @@ def _build_api_controller(api_meta): controller_meta["get"] = _get + if "get_all" in path_meta: + # Add get_all method to controller + @pecan.expose("json") + def _get_all(self, vim_id, tenant_id): + """ General GET all """ + session = _get_vim_auth_session(vim_id, tenant_id) + service = {'service_type': service_type, + 'interface': 'public'} + resp = session.get(resource_url, endpoint_filter=service) + vim_res = resp.json()[resource_meta['plural_vim_resource']] + mc_res = [_convert_vim_res_to_mc_res( + {resource_meta['vim_resource']: v}, + resource_properties) + for v in vim_res] + return {"vimName": vim_id, + resource_meta['plural']: mc_res, + "tenantId": tenant_id, + "vimid": vim_id} + + controller_meta["get_all"] = _get_all + return path, type(controller_name, (rest.RestController,), controller_meta) diff --git a/vio/vio/api_v2/api_router/v0_controller.py b/vio/vio/api_v2/api_router/v0_controller.py index 3c7a952..d7d428d 100644 --- a/vio/vio/api_v2/api_router/v0_controller.py +++ b/vio/vio/api_v2/api_router/v0_controller.py @@ -35,6 +35,10 @@ class V0_Controller(rest.RestController): """ Placeholder for sub controllers. """ pecan.abort(405) + def get_all(self, vim_id, tenant_id): + """ Placeholder for sub controllers. """ + pecan.abort(405) + pecan.route(V0_Controller, "swagger.json", swagger_json.SwaggerJson()) -- cgit 1.2.3-korg From c11a895f15d2f8c3848a2912c2948054c9a2ce54 Mon Sep 17 00:00:00 2001 From: Bin Sun Date: Fri, 23 Mar 2018 11:12:44 +0800 Subject: Add default_value support and networks Add network resource and default value support Change-Id: I01e307a8e1b0a5dce0573c9041725a023ab40de7 Issue-ID: MULTICLOUD-152 Signed-off-by: Bin Sun --- vio/vio/api_v2/api_definition/networks.yaml | 85 +++++++++++++++++++++++++ vio/vio/api_v2/api_router/controller_builder.py | 17 +++++ 2 files changed, 102 insertions(+) create mode 100644 vio/vio/api_v2/api_definition/networks.yaml diff --git a/vio/vio/api_v2/api_definition/networks.yaml b/vio/vio/api_v2/api_definition/networks.yaml new file mode 100644 index 0000000..f7c4f57 --- /dev/null +++ b/vio/vio/api_v2/api_definition/networks.yaml @@ -0,0 +1,85 @@ +--- + info: + version: "1.0.0" + title: "Multi Cloud Network" + description: "Definition of Host API" + termsOfService: "http://swagger.io/terms/" + schemes: + - "http" + produces: + - "application/json" + paths: + /{vimid}/{tenantid}/networks/{networkid}: + parameters: + - type: string + name: vimid + - type: string + format: uuid + name: tenantid + - type: string + name: networkid + in: path + required: true + get: + produces: + - "application/json" + responses: + "200": + schema: + $ref: "#/definitions/network" + get_all: + produces: + - "application/json" + responses: + "200": + schema: + type: "array" + items: + $ref: "#/definitions/network" + vim_path: "/network/v2.0/networks" + definitions: + network: + plural_vim_resource: "networks" + vim_resource: "network" + plural: "networks" + properties: + name: + type: string + required: true + source: network.name + id: + type: string + required: true + source: network.id + status: + type: string + source: network.status + required: true + segmentationId: + type: string + source: network.provider:segmentation_id + default: None + physicalNetwork: + type: string + source: network.provider:physical_network + default: None + networkType: + type: string + source: network.provider:network_type + default: None + tenantId: + type: string + source: network.tenant_id + required: true + shared: + type: boolean + source: network.shared + required: true + routerExternal: + type: boolean + source: network.router:external + required: true + vlanTransparent: + type: boolean + source: network.vlan_transparent + default: false diff --git a/vio/vio/api_v2/api_router/controller_builder.py b/vio/vio/api_v2/api_router/controller_builder.py index 6fcaf24..bd5adfb 100644 --- a/vio/vio/api_v2/api_router/controller_builder.py +++ b/vio/vio/api_v2/api_router/controller_builder.py @@ -53,6 +53,19 @@ def _get_vim_auth_session(vim_id, tenant_id): return session.Session(auth=auth) +def _convert_default_value(default): + if default == "None": + return None + + if default == "true": + return True + + if default == "false": + return False + + return default + + def _convert_vim_res_to_mc_res(vim_resource, res_properties): mc_resource = {} for key in res_properties: @@ -63,6 +76,10 @@ def _convert_vim_res_to_mc_res(vim_resource, res_properties): raise Exception("Required field %s is missed in VIM " "resource %s", (attr, vim_resource)) else: + if "default" in res_properties[key]: + mc_resource[key] = _convert_default_value( + res_properties[key]["default"]) + # None required fields missed, just skip. continue -- cgit 1.2.3-korg From ab6e2ab948ac5a24fd0129def9849dd672257485 Mon Sep 17 00:00:00 2001 From: Bin Sun Date: Fri, 23 Mar 2018 14:37:37 +0800 Subject: Add post method in api exposure framework Change-Id: Ib4f63873a6a253a8ee895f2a62a159c4fbc6a82e Issue-ID: MULTICLOUD-152 Signed-off-by: Bin Sun --- vio/vio/api_v2/api_definition/networks.yaml | 10 ++++-- vio/vio/api_v2/api_router/controller_builder.py | 48 +++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/vio/vio/api_v2/api_definition/networks.yaml b/vio/vio/api_v2/api_definition/networks.yaml index f7c4f57..6e13493 100644 --- a/vio/vio/api_v2/api_definition/networks.yaml +++ b/vio/vio/api_v2/api_definition/networks.yaml @@ -36,6 +36,13 @@ type: "array" items: $ref: "#/definitions/network" + post: + produces: + - "application/json" + responses: + "200": + schema: + $ref: "#/definitions/network" vim_path: "/network/v2.0/networks" definitions: network: @@ -49,12 +56,10 @@ source: network.name id: type: string - required: true source: network.id status: type: string source: network.status - required: true segmentationId: type: string source: network.provider:segmentation_id @@ -70,7 +75,6 @@ tenantId: type: string source: network.tenant_id - required: true shared: type: boolean source: network.shared diff --git a/vio/vio/api_v2/api_router/controller_builder.py b/vio/vio/api_v2/api_router/controller_builder.py index bd5adfb..f40bfd4 100644 --- a/vio/vio/api_v2/api_router/controller_builder.py +++ b/vio/vio/api_v2/api_router/controller_builder.py @@ -10,6 +10,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import json from keystoneauth1.identity import v2 as keystone_v2 from keystoneauth1.identity import v3 as keystone_v3 from keystoneauth1 import session @@ -91,6 +92,27 @@ def _convert_vim_res_to_mc_res(vim_resource, res_properties): return mc_resource +def _convert_mc_res_to_vim_res(mc_resource, res_properties): + vim_resource = {} + for key in res_properties: + vim_res, attr = res_properties[key]["source"].split('.') + + if key not in mc_resource: + if res_properties[key].get("required"): + raise Exception("Required field %s is missed in MultiCloud " + "resource %s", (key, mc_resource)) + else: + # None required fields missed, just skip. + continue + + action = res_properties[key].get("action", "copy") + # TODO(xiaohhui): Actions should be in constants. + if action == "copy": + vim_resource[attr] = mc_resource[key] + + return vim_resource + + def _build_api_controller(api_meta): # Assume that only one path path, path_meta = api_meta['paths'].items()[0] @@ -147,6 +169,32 @@ def _build_api_controller(api_meta): controller_meta["get_all"] = _get_all + if "post" in path_meta: + # Add post method to controller + @pecan.expose("json") + def _post(self, vim_id, tenant_id): + """ General POST """ + session = _get_vim_auth_session(vim_id, tenant_id) + service = {'service_type': service_type, + 'interface': 'public'} + vim_res = _convert_mc_res_to_vim_res(pecan.request.json_body, + resource_properties) + + req_body = json.JSONEncoder().encode( + {resource_meta['vim_resource']: vim_res}) + resp = session.post(resource_url, + data=req_body, + endpoint_filter=service) + mc_res = _convert_vim_res_to_mc_res(resp.json(), + resource_properties) + mc_res.update({"vimName": vim_id, + "vimId": vim_id, + "tenantId": tenant_id, + "returnCode": 0}) + return mc_res + + controller_meta["post"] = _post + return path, type(controller_name, (rest.RestController,), controller_meta) -- cgit 1.2.3-korg From 2a2f5024ea1e977b71e7215066da879120b8505d Mon Sep 17 00:00:00 2001 From: Bin Sun Date: Fri, 23 Mar 2018 14:54:51 +0800 Subject: Add delete method in api exposure framework Change-Id: I47547c290e7485f9afd904d6ab1034a9f3969209 Issue-ID: MULTICLOUD-152 Signed-off-by: Bin Sun --- vio/vio/api_v2/api_definition/networks.yaml | 2 ++ vio/vio/api_v2/api_router/controller_builder.py | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/vio/vio/api_v2/api_definition/networks.yaml b/vio/vio/api_v2/api_definition/networks.yaml index 6e13493..2be9943 100644 --- a/vio/vio/api_v2/api_definition/networks.yaml +++ b/vio/vio/api_v2/api_definition/networks.yaml @@ -43,6 +43,8 @@ "200": schema: $ref: "#/definitions/network" + delete: + responses: "204" vim_path: "/network/v2.0/networks" definitions: network: diff --git a/vio/vio/api_v2/api_router/controller_builder.py b/vio/vio/api_v2/api_router/controller_builder.py index f40bfd4..4e6d39d 100644 --- a/vio/vio/api_v2/api_router/controller_builder.py +++ b/vio/vio/api_v2/api_router/controller_builder.py @@ -195,6 +195,19 @@ def _build_api_controller(api_meta): controller_meta["post"] = _post + if "delete" in path_meta: + # Add delete method to controller + @pecan.expose("json") + def _delete(self, vim_id, tenant_id, resource_id): + """ General DELETE """ + session = _get_vim_auth_session(vim_id, tenant_id) + service = {'service_type': service_type, + 'interface': 'public'} + full_url = resource_url + "/%s" % resource_id + session.delete(full_url, endpoint_filter=service) + + controller_meta["delete"] = _delete + return path, type(controller_name, (rest.RestController,), controller_meta) -- cgit 1.2.3-korg