Merge "API/interface mapping table ETSI NFV vs Blazar"
authorGerald Kunzmann <kunzmann@docomolab-euro.com>
Mon, 16 Oct 2017 10:08:20 +0000 (10:08 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Mon, 16 Oct 2017 10:08:20 +0000 (10:08 +0000)
docs/release/configguide/feature.configuration.rst
docs/release/configguide/images/screenshot_promise_install.png
docs/release/release-notes/index.rst [new file with mode: 0644]
docs/release/release-notes/releasenotes.rst [new file with mode: 0644]
docs/release/userguide/feature.userguide.rst
promise/test/functest/run_promise_tests.py
source/config/custom-environment-variables.yaml
source/config/functest.yaml
source/promise.yaml
source/schema/opnfv-promise.yang
source/spec/promise-intents.coffee

index ad1df0e..3e66020 100644 (file)
@@ -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.
index 2cb27d9..ab78994 100644 (file)
Binary files a/docs/release/configguide/images/screenshot_promise_install.png and b/docs/release/configguide/images/screenshot_promise_install.png differ
diff --git a/docs/release/release-notes/index.rst b/docs/release/release-notes/index.rst
new file mode 100644 (file)
index 0000000..972e9dc
--- /dev/null
@@ -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 (file)
index 0000000..dba59cf
--- /dev/null
@@ -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
index 7261f4e..bba2aea 100644 (file)
@@ -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
 
index f7e9148..a57918c 100644 (file)
@@ -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())
index 30a72d2..001e799 100644 (file)
@@ -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
index 8cc84d3..6655fc4 100644 (file)
@@ -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
 
index be12082..98dcdc4 100644 (file)
@@ -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"
index b606382..9ee7564 100644 (file)
@@ -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 {
index afb0e24..985e81f 100644 (file)
@@ -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 ->