diff options
-rw-r--r-- | docs/release/configguide/feature.configuration.rst | 27 | ||||
-rw-r--r-- | docs/release/configguide/images/screenshot_promise_install.png | bin | 77709 -> 216440 bytes | |||
-rw-r--r-- | docs/release/release-notes/index.rst | 13 | ||||
-rw-r--r-- | docs/release/release-notes/releasenotes.rst | 127 | ||||
-rw-r--r-- | docs/release/userguide/feature.userguide.rst | 29 | ||||
-rw-r--r-- | promise/test/functest/run_promise_tests.py | 90 | ||||
-rw-r--r-- | source/config/custom-environment-variables.yaml | 8 | ||||
-rw-r--r-- | source/config/functest.yaml | 2 | ||||
-rw-r--r-- | source/promise.yaml | 2 | ||||
-rw-r--r-- | source/schema/opnfv-promise.yang | 4 | ||||
-rw-r--r-- | source/spec/promise-intents.coffee | 27 |
11 files changed, 236 insertions, 93 deletions
diff --git a/docs/release/configguide/feature.configuration.rst b/docs/release/configguide/feature.configuration.rst index ad1df0e..3e66020 100644 --- a/docs/release/configguide/feature.configuration.rst +++ b/docs/release/configguide/feature.configuration.rst @@ -14,8 +14,9 @@ Install nodejs, npm and promise git clone https://gerrit.opnfv.org/gerrit/promise cd promise/source npm install + npm ls -Please note that the last command 'npm install' will install all needed dependencies +Please note that the last command 'npm ls' will list all needed dependencies for promise (including yangforge and mocha) .. figure:: images/screenshot_promise_install.png @@ -29,23 +30,25 @@ Please perform the following preparation steps: 1. Set OpenStack environment parameters properly (e.g. source openrc admin demo in DevStack) -2. Create OpenStack tenant (e.g. promise) and tenant user (e.g. promiser) +2. Create OpenStack project (e.g. promise) and user (e.g. myuser) in e.g. the + default domain 3. Create a flavor in Nova with 1 vCPU and 512 MB RAM 4. Create a private network, subnet and router in Neutron 5. Create an image in Glance -Once done, the promise test script can be invoked as follows (as a single line -command): +Once done, the promise test script can be invoked as follows: .. code-block:: bash - NODE_ENV=mytest \ - OS_TENANT_NAME=promise \ - OS_USERNAME=promiser \ - OS_PASSWORD=<user password from Step 2> \ - OS_TEST_FLAVOR=<flavor ID from Step 3> \ - OS_TEST_NETWORK=<network ID from Step 4> \ - OS_TEST_IMAGE=<image ID from Step 5> \ + export OS_PROJECT_NAME=promise + export OS_TENANT_NAME=promise + export OS_PROJECT_DOMAIN_NAME=Default + export OS_USERNAME=myuser + export OS_USER_DOMAIN_NAME=Default + export OS_PASSWORD=<user password from Step 2> + export OS_TEST_FLAVOR=<flavor ID from Step 3> + export OS_TEST_NETWORK=<network ID from Step 4> + export OS_TEST_IMAGE=<image ID from Step 5> npm run -s test -- --reporter json > promise-results.json The results of the tests will be stored in the promise-results.json file. @@ -57,4 +60,4 @@ The results can also be seen in the console ("npm run -s test") :width: 90% All 33 tests passing?! -Congratulations, promise has been successfully installed and configured. +Congratulations, Promise has been successfully installed and configured. diff --git a/docs/release/configguide/images/screenshot_promise_install.png b/docs/release/configguide/images/screenshot_promise_install.png Binary files differindex 2cb27d9..ab78994 100644 --- a/docs/release/configguide/images/screenshot_promise_install.png +++ b/docs/release/configguide/images/screenshot_promise_install.png diff --git a/docs/release/release-notes/index.rst b/docs/release/release-notes/index.rst new file mode 100644 index 0000000..972e9dc --- /dev/null +++ b/docs/release/release-notes/index.rst @@ -0,0 +1,13 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 + +.. _promise-releasenotes: + +********************* +Promise Release Notes +********************* + +.. toctree:: + :maxdepth: 2 + + releasenotes.rst diff --git a/docs/release/release-notes/releasenotes.rst b/docs/release/release-notes/releasenotes.rst new file mode 100644 index 0000000..dba59cf --- /dev/null +++ b/docs/release/release-notes/releasenotes.rst @@ -0,0 +1,127 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 + +======================================= +OPNFV Promise release notes (Euphrates) +======================================= + +Version history +=============== + ++------------+---------------+-----------------+-------------+ +| **Date** | **Ver.** | **Author** | **Comment** | ++============+===============+=================+=============+ +| 2017-07-13 | Euphrates 1.0 | Gerald Kunzmann | | ++------------+---------------+-----------------+-------------+ + +Important notes +=============== + +**Attention:** Please be aware that the Promise shim-layer implementation is marked as DEPREACTED +in Euphrates and both implementation and related test cases may be removed from next release. + +Abstract +=============== + +This document provides an overview of the Promise project in the OPNFV Euphrates +release. Promise is a resource reservation and management project to identify NFV related +requirements and realize resource reservation for future usage by capacity +management of resource pools regarding compute, network and storage. + + +Features +============ + +The following features are provided by the Promise in the OPNFV Euphrates release: + +* Capacity Management +* Reservation Management +* Allocation Management + +The Euphrates implementation of Promise is built with the YangForge data modeling +framework [#f2]_ , using a shim-layer on top of OpenStack to provide +the Promise features. + +In the OPNFV Euphrates release cycle most efforts have been spent to progress the upstream +implementation of a native resource reservation system for OpenStack as part of the Blazar project +[#f3]_. + +Detailed information about Promise use cases, features, interface +specifications, work flows, and the underlying Promise YANG schema can be found +in the Promise requirement document [#f1]_ . + +.. [#f1]_ http://artifacts.opnfv.org/promise/docs/development_requirements/index.html +.. [#f2]_ https://github.com/corenova/yang-forge +.. [#f3]_ https://launchpad.net/blazar/+milestone/0.3.0 + + +Installer support and verification status +========================================= + +Promise project is integrated in OPNFV through the Functest project (`FUNCTEST`_). + ++-----------+----------------------------------------------+--------------+ +| Installer | CI Job | Status | ++===========+==============================================+==============+ +| Fuel | functest-fuel-baremetal-daily-master | | +| | functest-fuel-virtual-daily-master | | +| | functest-fuel-armband-baremetal-daily-master | | ++-----------+----------------------------------------------+--------------+ +| Joid | functest-joid-baremetal-daily-master | | ++-----------+----------------------------------------------+--------------+ + +.. _FUNCTEST: https://wiki.opnfv.org/display/functest + + +Thereby, the following test cases (`TEST_CASES`_) are executed: + + - Add a new OpenStack provider to the reservation service + - Allocation of resources without prior reservation + - Reservation of a VM for immediate use followed by allocation + - Reservation of a VM for future use + - Update reservation + - Query reservation + - Cancel reservation + - Error case: try to create reservation with a conflict + - Capacity management - increase/decrease available capacity of a provider + - Capacity Management - query for available and used capacity + + +.. _TEST_CASES: https://git.opnfv.org/promise/tree/source/test/promise-intents.coffee + + +Open JIRA tickets +================= + ++------------------+-----------------------------------------------+ +| JIRA | Description | ++==================+===============================================+ +| | | +| | | ++------------------+-----------------------------------------------+ + +All the tickets that are not blocking have been fixed or postponed +the next release. + +Promise Euphrates 1.0 is released without known bugs. + + + +Useful links +============ + + - Promise project page: https://wiki.opnfv.org/display/promise + - Promise requirements: http://artifacts.opnfv.org/promise/docs/development_requirements/index.html + +Related Projects +---------------- + + - OpenStack Blazar (Resource reservation for OpenStack): https://blazar.readthedocs.io/en/latest/ + - YangForge data modeling framework: - https://github.com/opnfv/yangforge + +Related ETSI NFV specifications +------------------------------- + + - ETSI NFV MANO GS: http://www.etsi.org/deliver/etsi_gs/NFV-MAN + - ETSI NFV INF GSs: http://www.etsi.org/deliver/etsi_gs/NFV-INF + - ETSI NFV IFA GSs: http://www.etsi.org/deliver/etsi_gs/NFV-IFA diff --git a/docs/release/userguide/feature.userguide.rst b/docs/release/userguide/feature.userguide.rst index 7261f4e..bba2aea 100644 --- a/docs/release/userguide/feature.userguide.rst +++ b/docs/release/userguide/feature.userguide.rst @@ -17,7 +17,7 @@ The following sections provide details on the Promise capabilities and its API u Promise capabilities and usage ============================== -The Danube implementation of Promise is built with the YangForge data modeling +The Euphrates implementation of Promise is built with the YangForge data modeling framework [#f2]_ , using a shim-layer on top of OpenStack to provide the Promise features. This approach requires communication between Consumers/Administrators and OpenStack to pass through the shim-layer. The @@ -34,9 +34,12 @@ Detailed information about Promise use cases, features, interface specifications, work flows, and the underlying Promise YANG schema can be found in the Promise requirement document [#f1]_ . +Keystone v3 support has been added during the Euphrates release. + + Promise features and API usage guidelines and examples ------------------------------------------------------ -This section lists the Promise features and API implemented in OPNFV Danube. +This section lists the Promise features and API implemented in OPNFV Euphrates. Note: The listed parameters are optional unless explicitly marked as "mandatory". @@ -151,7 +154,7 @@ The operation takes the following input parameters: * provider-id: identifier of the provider where the instance shall be created * reservation-id: identifier of a resource reservation the *create-instance* -The Danube implementation of Promise has the following limitations: +The Euphrates implementation of Promise has the following limitations: * All create server instance requests shall pass through the Promise shim-layer such that Promise can keep track of all allocation requests. This @@ -258,7 +261,7 @@ The current implementation supports the following filter criteria: This API towards OpenStack allows a Consumer/Administrator to add and remove resource providers to Promise. Note, Promise supports a multi-provider -configuration, however, for Danube, multi-provider support is not yet +configuration, however, for Euphrates, multi-provider support is not yet fully supported. *add-provider* @@ -267,23 +270,23 @@ fully supported. This operation is used to register a new resource provider into the Promise reservation system. -Note, for Danube, the add-provider operation should only be used to +Note, for Euphrates, the add-provider operation should only be used to register one provider with the Promise shim-layer. Further note that currently only OpenStack is supported as a provider. The operation takes the following input parameters: -* provider-type (mandatory) = 'openstack': select a specific resource provider +* provider-type = 'openstack': select a specific resource provider type. -* endpoint (mandatory): target URL endpoint for the resource provider. -* username (mandatory) -* password (mandatory) -* region: specified region for the provider -* tenant.id: id of the OpenStack tenant/project -* tenant.name: name of the OpenStack tenant/project +* endpoint : target URL endpoint for the resource provider. +* username : name of the user +* password : user password +* user-domain-name : domain name of the user +* project.name : name of the OpenStack project +* project.domain-name : domain name of the OpenStack project .. [#f1] Promise requirement document, - http://artifacts.opnfv.org/promise/docs/requirements/index.html + http://artifacts.opnfv.org/promise/docs/development_requirements/index.html .. [#f2] YangForge framework, http://github.com/opnfv/yangforge diff --git a/promise/test/functest/run_promise_tests.py b/promise/test/functest/run_promise_tests.py index f7e9148..a57918c 100644 --- a/promise/test/functest/run_promise_tests.py +++ b/promise/test/functest/run_promise_tests.py @@ -10,7 +10,6 @@ import argparse import json import logging -import logging.config import os import re import subprocess @@ -29,11 +28,12 @@ parser.add_argument("-r", "--report", args = parser.parse_args() -PROMISE_REPO_DIR = CONST.dir_repo_promise +PROMISE_REPO_DIR = '/src/promise' RESULTS_DIR = CONST.dir_results PROMISE_TENANT_NAME = CONST.promise_tenant_name -TENANT_DESCRIPTION = CONST.promise_tenant_description +PROMISE_PROJECT_NAME = CONST.promise_tenant_name +PROMISE_PROJECT_DESCRIPTION = CONST.promise_tenant_description PROMISE_USER_NAME = CONST.promise_user_name PROMISE_USER_PWD = CONST.promise_user_pwd PROMISE_IMAGE_NAME = CONST.promise_image_name @@ -61,25 +61,8 @@ logger = logging.getLogger('promise') def main(): return_code = -1 - change_keystone_version = False os_auth = os.environ["OS_AUTH_URL"] - # check keystone version - # if keystone v3, for keystone v2 - if os_utils.is_keystone_v3(): - os.environ["OS_IDENTITY_API_VERSION"] = "2" - # the OS_AUTH_URL may have different format according to the installer - # apex: OS_AUTH_URL=http://192.168.37.17:5000/v2.0 - # fuel: OS_AUTH_URL='http://192.168.0.2:5000/' - # OS_AUTH_URL='http://192.168.10.2:5000/v3 - match = re.findall(r'[0-9]+(?:\.[0-9]+){3}:[0-9]+', - os.environ["OS_AUTH_URL"]) - new_url = "http://" + match[0] + "/v2.0" - - os.environ["OS_AUTH_URL"] = new_url - change_keystone_version = True - logger.info("Force Keystone v2") - creds = os_utils.get_credentials() try: @@ -87,27 +70,25 @@ def main(): logger.info("OS_AUTH_URL: %s" % os.environ["OS_AUTH_URL"]) logger.info("OS_IDENTITY_API_VERSION: %s " % os.environ["OS_IDENTITY_API_VERSION"]) + logger.info("OS_USER_DOMAIN_NAME: %s" % + os.environ["OS_USER_DOMAIN_NAME"]) + logger.info("OS_PROJECT_DOMAIN_NAME: %s" % + os.environ["OS_PROJECT_DOMAIN_NAME"]) except KeyError: logger.error("Please set the OS environment variables") keystone_client = os_utils.get_keystone_client() - user_id = os_utils.get_user_id(keystone_client, creds['username']) - if user_id == '': - logger.error("Error : Failed to get id of %s user" % - creds['username']) - return return_code - - logger.info("Creating tenant '%s'..." % PROMISE_TENANT_NAME) - tenant_id = os_utils.create_tenant( - keystone_client, PROMISE_TENANT_NAME, TENANT_DESCRIPTION) - if not tenant_id: - logger.error("Error : Failed to create %s tenant" - % PROMISE_TENANT_NAME) + logger.info("Creating project '%s'..." % PROMISE_PROJECT_NAME) + project_id = os_utils.create_tenant( + keystone_client, PROMISE_PROJECT_NAME, PROMISE_PROJECT_DESCRIPTION) + if not project_id: + logger.error("Error : Failed to create %s project" + % PROMISE_PROJECT_NAME) return return_code - logger.debug("Tenant '%s' created successfully." % PROMISE_TENANT_NAME) + logger.debug("Project '%s' created successfully." % PROMISE_PROJECT_NAME) - roles_name = ["admin", "Admin"] + roles_name = ["_member_", "Member"] role_id = '' for role_name in roles_name: if role_id == '': @@ -117,24 +98,32 @@ def main(): logger.error("Error : Failed to get id for %s role" % role_name) return return_code - logger.info("Adding role '%s' to tenant '%s'..." - % (role_id, PROMISE_TENANT_NAME)) - if not os_utils.add_role_user(keystone_client, user_id, - role_id, tenant_id): - logger.error("Error : Failed to add %s on tenant %s" % - (creds['username'], PROMISE_TENANT_NAME)) + domain_id = '' + domain_id = os_utils.get_domain_id(keystone_client, + os.environ["OS_USER_DOMAIN_NAME"]) + if domain_id == '': + logger.error("Error: Failed to get id for %s domain" % + os.environ["OS_USER_DOMAIN_NAME"]) return return_code - logger.debug("Role added successfully.") logger.info("Creating user '%s'..." % PROMISE_USER_NAME) - user_id = os_utils.create_user( - keystone_client, PROMISE_USER_NAME, PROMISE_USER_PWD, None, tenant_id) - - if not user_id: + try: + user = keystone_client.users.create(name=PROMISE_USER_NAME, + domain=domain_id, + password=PROMISE_USER_PWD) + except Exception as e: logger.error("Error : Failed to create %s user" % PROMISE_USER_NAME) return return_code logger.debug("User '%s' created successfully." % PROMISE_USER_NAME) + try: + keystone_client.roles.grant(role=role_id, user=user.id, + project=project_id) + except Exception as e: + logger.error("Error: Failed to grant member role on project %s" % + project_id) + return return_code + nova_client = os_utils.get_nova_client() glance_client = os_utils.get_glance_client() @@ -188,7 +177,7 @@ def main(): os.environ["OS_TEST_IMAGE"] = image_id os.environ["OS_TEST_FLAVOR"] = flavor_id os.environ["OS_TEST_NETWORK"] = network_dic["net_id"] - os.environ["OS_TENANT_NAME"] = PROMISE_TENANT_NAME + os.environ["OS_PROJECT_NAME"] = PROMISE_PROJECT_NAME os.environ["OS_USERNAME"] = PROMISE_USER_NAME os.chdir(PROMISE_REPO_DIR + '/source/') @@ -239,16 +228,9 @@ def main(): start_time_json, end_time, duration)) end_time = time.time() - # re set default keysone version to 3 if it has been changed for promise - if change_keystone_version: - os.environ["OS_IDENTITY_API_VERSION"] = "3" - os.environ["OS_AUTH_URL"] = os_auth - logger.info("Revert to Keystone v3") - return return_code if __name__ == '__main__': - logging.config.fileConfig( - CONST.__getattribute__('dir_functest_logging_cfg')) + logging.basicConfig(level=logging.INFO) sys.exit(main()) diff --git a/source/config/custom-environment-variables.yaml b/source/config/custom-environment-variables.yaml index 30a72d2..001e799 100644 --- a/source/config/custom-environment-variables.yaml +++ b/source/config/custom-environment-variables.yaml @@ -11,11 +11,13 @@ openstack: auth: endpoint: OS_AUTH_URL strategy: OS_AUTH_STRATEGY - tenant: - id: OS_TENANT_ID - name: OS_TENANT_NAME + project: + id: OS_PROJECT_ID + name: OS_PROJECT_NAME + domain-name: OS_PROJECT_DOMAIN_NAME username: OS_USERNAME password: OS_PASSWORD + user-domain-name: OS_USER_DOMAIN_NAME test: image: OS_TEST_IMAGE flavor: OS_TEST_FLAVOR diff --git a/source/config/functest.yaml b/source/config/functest.yaml index 8cc84d3..6655fc4 100644 --- a/source/config/functest.yaml +++ b/source/config/functest.yaml @@ -5,5 +5,5 @@ opnfv-functest: images: - name: cirros - path: /home/opnfv/functest/data/cirros-0.3.4-x86_64-disk.img + path: /home/opnfv/functest/images/cirros-0.3.5-x86_64-disk.img diff --git a/source/promise.yaml b/source/promise.yaml index be12082..98dcdc4 100644 --- a/source/promise.yaml +++ b/source/promise.yaml @@ -255,7 +255,7 @@ complex-type: services.forEach (service) => switch service.type when 'compute' - url = service.endpoints[0].publicURL + url = service.endpoints[0].url @set 'services.compute.endpoint', url request .get "#{url}/limits" diff --git a/source/schema/opnfv-promise.yang b/source/schema/opnfv-promise.yang index b606382..9ee7564 100644 --- a/source/schema/opnfv-promise.yang +++ b/source/schema/opnfv-promise.yang @@ -620,9 +620,11 @@ module opnfv-promise { default "http://localhost:5000/v2.0"; } } - container tenant { + leaf user-domain-name { type string; } + container project { leaf id { type string; } leaf name { type string; } + leaf domain-name { type string; } } } output { diff --git a/source/spec/promise-intents.coffee b/source/spec/promise-intents.coffee index afb0e24..985e81f 100644 --- a/source/spec/promise-intents.coffee +++ b/source/spec/promise-intents.coffee @@ -320,9 +320,19 @@ module.exports = payload = switch input.get 'provider-type' when 'openstack' auth: - tenantId: input.get 'tenant.id' - tenantName: input.get 'tenant.name' - passwordCredentials: input.get 'username', 'password' + identity: + methods: [ "password" ] + password: + user: + name: input.get 'username' + password: input.get 'password' + domain: + name: input.get 'user-domain-name' + scope: + project: + name: input.get 'project.name' + domain: + name: input.get 'project.domain-name' unless payload? return done 'Sorry, only openstack supported at this time' @@ -330,7 +340,7 @@ module.exports = url = input.get 'endpoint' switch input.get 'strategy' when 'keystone', 'oauth' - url += '/tokens' unless /\/tokens$/.test url + url += '/auth/tokens' unless /\/tokens$/.test url providers = @access 'promise.providers' request @@ -340,11 +350,12 @@ module.exports = .end (err, res) => if err? or !res.ok then return done res.error #console.log JSON.stringify res.body, null, 2 - access = res.body.access + #console.log res.headers + #console.log res.body.token.catalog provider = @create 'ResourceProvider', - token: access?.token?.id - name: access?.token?.tenant?.name - provider.invoke 'update', access.serviceCatalog + token: res.headers['x-subject-token'] + name: res.body.token.project.name + provider.invoke 'update', res.body.token.catalog .then (res) -> res.save() .then -> |