From 856b240f9e485af4a5c943428639bd4b42b503fd Mon Sep 17 00:00:00 2001 From: Dolph Mathews Date: Tue, 24 Apr 2018 14:10:11 +0000 Subject: [PATCH] Add conceptual overview of the service catalog During the Liberty summit in Vancouver, there was a session on the standardization of the service catalog: https://etherpad.openstack.org/p/service-catalog-cross-project-vancouver As a result, Dolph put together a really good post condensing that information for client developers as well as developers working on integrating their services into the OpenStack ecosystem: https://blog.dolphm.com/openstack-keystone-service-catalog/ This commit massages some of the wording and proposes the guide as a section of our own contributor documentation. Co-Authored-By: Lance Bragstad Change-Id: Ie3328a8f7e093e894903a48809761fcbad279154 Closes-Bug: 1459402 --- doc/source/contributor/external-dev.rst | 1 + doc/source/contributor/service-catalog.rst | 165 +++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 doc/source/contributor/service-catalog.rst diff --git a/doc/source/contributor/external-dev.rst b/doc/source/contributor/external-dev.rst index 025aef5db3..97527cea40 100644 --- a/doc/source/contributor/external-dev.rst +++ b/doc/source/contributor/external-dev.rst @@ -23,3 +23,4 @@ External Developers services.rst developing-drivers.rst + service-catalog.rst diff --git a/doc/source/contributor/service-catalog.rst b/doc/source/contributor/service-catalog.rst new file mode 100644 index 0000000000..7ec63b74f0 --- /dev/null +++ b/doc/source/contributor/service-catalog.rst @@ -0,0 +1,165 @@ +.. + 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. + +======================== +Service Catalog Overview +======================== + +The OpenStack keystone service catalog allows API clients to dynamically +discover and navigate to cloud services. The service catalog may differ from +deployment-to-deployment, user-to-user, and project-to-project. + +The service catalog is the first hurdle that API consumers will need to +understand after successfully authenticating with Keystone, making it a +critical focal point for the overall user experience of OpenStack. + +*If you're integrating your OpenStack service with Keystone*, then please +follow the guidelines provided below. + +*If you're writing an OpenStack client*, hopefully this helps you navigate the +service catalog that you're being presented so that you can quickly move on to +the business of consuming cloud services. + +An example service catalog +========================== + +The following is an example service catalog. It actually excludes several +common attributes such as ``id``, which are of no concern to end users, +``region_id``, which are a bit out of scope for this topic, and ``enabled``, +which is always ``true`` for end users. + +This service catalog contains just one service, "Keystone", which is accessible +via a single endpoint URL: + +.. code-block:: json + + { + "catalog": [ + { + "name": "Keystone", + "type": "identity", + "endpoints": [ + { + "interface": "public", + "url": "https://identity.example.com:5000/" + } + ] + } + ] + } + +The service catalog itself may appear in a token creation response (``POST +/v3/auth/tokens``), a token validation response (``GET /v3/auth/tokens``), or +as a standalone resource (``GET /v3/auth/catalog``). + +Services +======== + +The service catalog itself is composed of a list of services. + +Service entities represent web services in the OpenStack deployment. A service +may have zero or more endpoints associated with it, although a service with +zero endpoints is essentially useless in an OpenStack configuration. + +In addition to the related endpoints, there are two attributes of services that +important to end users: + +* ``name`` (string): user-facing name of the service + +This attribute is not intended to be machine-parseable or otherwise meaningful +beyond branding or name-recognition for end users. Logical values might include +"Keystone" or maybe "Brand X Public Cloud Identity Service". Deployers should +be free to rename, and therefore rebrand, a service at will. + +* ``type`` (string): describes the API implemented by the service. To support + future projects, the value should not be validated against a list. + +An OpenStack-wide effort to standardize service types has been done outside of +Keystone and is known as the `service-types authority`_. + +This should not convey the version of the API implemented by the service (as in +Cinder's ``volumev2`` service type) because both the ``volume`` service and +``volumev2`` service provide "block storage as a service" which is what the +service type is meant to convey. The underlying implementation is completely +irrelevant here. + +In the general case, there should only be one service in a deployment per +service type, although Keystone does not enforce this today. + +.. _service-types authority: https://service-types.openstack.org/ + +Endpoints +========= + +Each service should have one or more related endpoints. An endpoint is +essentially a base URL for an API, along with some metadata about the endpoint +itself and represents a set of URL endpoints for OpenStack web services. + +* ``interface`` (string): describes the visibility of the endpoint according to + one of three values (``public``, ``internal``, and ``admin``) + +``public`` endpoints are intended for consumption by end users or other service +users, generally on a publicly available network interface. + +``internal`` endpoints are intended for consumption by end users, generally on +an unmetered internal network interface. + +``admin`` endpoints are intended only for consumption by those needing +administrative access to the service, generally on a secure network interface. + +You might also think of each interface value as the result of a matrix of use +cases: + +* **Public API** on a **public network**: use a ``public`` interface. +* **Public API** on an **internal network**: use an ``internal`` interface. +* **Privileged API** on a **public network**: unsupported! Use access controls + on your ``public`` endpoint instead. +* **Privileged API** on an **internal network**: ``admin`` interface, but use + access controls on your ``public`` endpoint instead. The notion of a + "privileged API" endpoint makes security-conscious developers instantly lazy + (security becomes someone else's problem), and is an obvious attack vector if + someone were to infiltrate your internal network. It also adds more + complexity to your API architecture which makes documentation, testing, and + API evolution that much more difficult. + +* ``url`` (string): fully qualified URL of the service endpoint + +This should be unversioned base URL for an API. Good examples include +``https://identity.example.com:5000/`` and ``https://keystone.example.com/``. + +Conversely, ``https://identity.example.com:5000/v3/`` is an unfortunate example +because it directs all clients to connect to a versioned endpoint, regardless +of which API versions they understand. This makes it hard for services to do +any sort of API versioning, and for clients to dynamically discover additional +available versions. + +For a period of time, keystone was stuck in a position where it implements a +``/v3/`` API, but for backwards compatibility with existing v2 clients, was +forced to continue advertising the ``/v2.0/`` endpoint in the service catalog +until it was reasonable to assume that all clients in the ecosystem are capable +of handling an unversioned URL. As a side effect, this has had a tremendous +impact on the awareness of, and thus adoption of, Keystone's Identity API v3 +(which has been enabled by default — and stable — since the 2013.1 Grizzly +release). Don't put your project in that position! + +Similarly, ``https://object-store.example.com/v1/KEY_\$(project_id)s`` (which +would ultimately be rendered to clients as a project-specific URL, such as +``https://object-store.example.com/v1/KEY_d12af07f4e2c4390a21acc31517ebec9``) +is an unfortunate example because not only does it hardcode an API version as +in the above example, but it also exposes the client's project ID directly to +the client. Instead, the operational scope or a request can be determined by +inspecting the user's token or consuming values populated by +``keystonemiddleware.auth_token``. It's also far less cacheable than a URL that +is neither project nor user specific, which is important given that every +client needs access to consume the service catalog prior to nearly every API +request.