Skip to content

Instantly share code, notes, and snippets.

@grkvlt
Created December 14, 2016 21:21
Show Gist options
  • Save grkvlt/db0f57e7c27f7749a9fdb4b36ee0fe2e to your computer and use it in GitHub Desktop.
Save grkvlt/db0f57e7c27f7749a9fdb4b36ee0fe2e to your computer and use it in GitHub Desktop.
Namespaces for Brooklyn catalog entries

Catalog Names

Andrew Kennedy mailto:[email protected] November 2016

This document discusses ways of improving the Brooklyn catalog management, by changing from a flat, versioned namespace, to a hierarchical structure using lexical scoping rules to prevent collisions.

Current Design

The current Brooklyn catalog mechanism is a simple dictionary, using the catalog identifier as the key and the entity specification or template as the stored data. The entries are also versioned, using semantic versioning rules to assert an ordering, and with special semantics being applied to versions that have the form x.y.z-SNAPSHOT, as in Java artifact versioning using Maven.

Using this schema, each catalog entry must have a lexicographically unique identifier, and references to other entries are made using these unique ids. The identifiers can consist of the ASCII alphanumeric characters as well as the symbols '.-_' but no semantics are applied to the structure of the id itself. This has meant that application designers are forced to develop their own ad-hoc mechanisms for grouping similar entries, and ensuring they do not collide with existing entries that may already be present in the catalog.

For example, a prefix indicating the application the entry forms a part of, or the parent entry that an entity is extending, is often used. For a BOM file containing definitions for a Swarm cluster, these might be named as follows:

items:
  - id: swarm-cluster
    type: cluster
  - id: swarm-node
    type: docker-engine
  - id: swarm-node-manager
    type: swarm-node
  - id: swarm-node-manager-tls
    type: swarm-node-manager
  - id: swarm-node-worker
    type: swarm-node
  - id: swarm-node-worker-tls
    type: swarm-node-worker
  - id: swarm-load-balancer
    type: haproxy-load-balancer
  - id: swarm-load-balancer-managers
    type: swarm-load-balancer
  - id: swarm-load-balancer-workers
    type: swarm-load-balancer

The use of the swarm- prefix, as well as the convention of using the parent types identifier as a prefix when extending it, can be seen here. These are useful practices, and help authors to manage complex blueprints by imposing a logical and meaningful naming scheme.

However, this scheme is not enforced, and carries no intrinsic meaning to Brooklyn. The author could equally well have chosen a '.' delimited structure with a different prefix, following the conventions of Java package names. The contents of identifier tokens are essentially opaque and their only requirement is uniqueness. The use of UUIDs would perform the same task, albeit with a loss of readability.

Namespaces and Scopes

Since it is evident that blueprint authors have a need to group related catalog entries together, it would be useful to implement a mechanism for this as part of Brooklyn. If each BOM file had an associated namespace or scope, then all entities defined there would have catalog ids that were associated with that scope. The identifiers would then only require to be unique within that particular scope. This would also require a mechanism to allow referring to catalog entries defined in some other scope. This can be accomplished by making the identifier use an optional prefix that specifies the scope, with the ':' delimiter used to prevent any ambiguity, in a similar fashion to the version suffix.

Our Swarm example then becomes:

namespace: swarm
version: 2.2.0
items:
  - id: cluster
    type: brooklyn:cluster
  - id: node
    type: docker:engine
  - id: manager
    type: node
  - id: manager-tls
    type: manager
  - id: worker
    type: node
  - id: worker-tls
    type: worker
  - id: load-balancer
    type: library:haproxy
  - id: manager-load-balancer
    type: load-balancer
  - id: worker-load-balancer
    type: load-balancer

And, to create a Swarm cluster, the deployment blueprint would then reference swarm:cluster:2.2.0 as the entity type. This cluster entity is based on the brooklyn:cluster entity, which represents one of the core catalog entries from Brooklyn itself. The load-balancer entity is an instance of HAProxy from the Brooklyn entity library, here represented as the library namespace. The docker:engine entity is another cross-namespace example, using the engine catalog entry in the docker namespace. Compare this to the earlier example which used docker-engine as a globally unique catalog entry, using the same principle to generate the identifier but without the ability to enforce the semantics.

Note that we have simply introduced a single extra identifier for entries here. That is, entries are defined by the tuple ( namespace, identifier ) where the namespace identifier is unique among the set of namespaces, and the identifier is unique among the set of identifiers in its namespace. This could easily be extended to a multi-level hierarchy, however, where an ordered list of namespace tokens is followed by an identifier. With such a hierarchy of namespaces, the problem of unique names for catalog entries is essentially irrelevant.

Organization specific namespaces can be created as roots to segregate groups of entities and RBAC policies applied to the namespace, rather than each individual entry, to provide multi-tenant capabilities.

Questions

  1. Allow multiple namespaces in one file
  2. Use directory structure to define
  3. Import namespaces or individual entries

Import

namespace: docker
version: 2.4.1
import:
  - namespace: common
  - namespace: library
    identifiers:
      - haproxy
items:
  - id: engine
    type: centos-software-process
  - id: cluster
    type: brooklyn:cluster
    brooklyn.children:
      - id: etcd
        type: etcd:cluster
      - id: haproxy
        type: haproxy
    brooklyn.config:
      memberSpec:
        $brooklyn:entitySpec:
          type: engine

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment