| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- Design decisions
- ================
- This document captures outcomes and, in some cases, the through process behind
- some of the design decisions that took place while architecting CloudBridge.
- It is intended as a reference.
- Require zone parameter when creating a default subnet
- -----------------------------------------------------
- Placement zone is required because it is an explicit application decision,
- even though ideally *default* would not require input. Before requiring it,
- the implementations would create a subnet in each availability zone and return
- the first one in the list. This could potentially return different values over
- time. Another factor influencing the decision was the example of creating a
- volume followed by creating an instance with presumably the two needing to be
- in the same zone. By requiring the zone across the board, it is less likely to
- lead to a mismatch. (Related to 63_.)
- Resource identification, naming, and labeling
- ---------------------------------------------
- While it would be reasonable to expect that complex constructs like
- networking would be the most difficult to abstract away uniformly across
- providers, in retrospect, simple naming of objects has arguably been the most
- complex and convoluted to map consistently. CloudBridge has been through
- several iterations of naming and labeling, before finally settling on the
- current design. This section captures that history and design rationale.
- **First iteration**
- In the early days, when CloudBridge supported only AWS and OpenStack, there
- were only two concepts, `id` and `name`. The `id` was straightforward enough,
- as it usually mapped to a unique identifier, auto-generated by the provider.
- The `name` generally mapped to a tag in the case of AWS, and a `name` field
- in the case of OpenStack. However, even then, there were inconsistencies
- within individual providers. For example, while AWS generally supported tags,
- it had a dedicated name field for machine images called ami-name.
- Furthermore, this name field could only be set at image creation time, and
- could not be changed thereafter. Similarly, AWS does not allow VM firewall
- (i.e., security group) names to be changed. Nevertheless, CloudBridge
- continued to use id and name, with the name being changeable for some
- resources, and read-only in others.
- As CloudBridge evolved and support was added for Azure and GCE, things only
- became more complex. Some providers (e.g. Azure and GCE) used a user-provided
- value instead of an auto-generated value as an `id`, which would also be
- displayed in their respective dashboards as `Name`. This meant that they were
- treating their servers as individually named pets, instead of adopting the
- cattle model, should one be tempted to use that macabre `pets vs cattle`_
- analogy. These user-provided names could not be changed after a resource had
- been created. Instead, these providers seemed to be gravitating toward the
- use of tags (or labels) to support arbitrary naming and name changes. Yet,
- not all resources support tags so CloudBridge could not rely solely on tags.
- Further, tags do not need to be unique across multiple resources, while names
- do (at least for some resources, such as vmfirewalls within a private
- network). Overall, consistency was challenging to achieve with resource
- naming. Therefore, it was decided that CloudBridge would continue to support
- resource renaming to the best extent possible and balance between the
- use of the resource name property and resource tags. However, because of the
- inconsistency in rename functionality across providers, using the rename
- capabilities within CloudBridge would lead to cloud-dependent code (Related to
- 131_.) and therefore, the only option was to continue to stick a caveat emptor
- to resource renaming.
-
- **Second iteration**
- However, it soon became apparent that this overloaded terminology was
- continuing to cause confusion. The `id` property in CloudBridge mapped to the
- unchangeable `name` property in Azure and GCE, and the *name* property in
- cloudbridge sometimes mapped to a *tag* in certain providers, and a *name* in
- other providers and they were sometimes read-only, sometimes writable. In an
- attempt to disambiguate these concepts, it was then decided that perhaps
- three concepts were needed - `id`, `display_id`, and `label`. The `id` would
- continue to refer to a unique identifier for a resource and be mapped
- accordingly to the underlying provider. The `display_id` would be a more
- user-friendly version of an id, suitable for display to an end-user and be
- unchangeable, but on rare occasions, not unique. For example, AWS ami-name
- was a `display_id` while the ami-id was an `id`. Similarly, an Azure resource
- name mapped to the `display_id`, since it was an unchangeable, user-friendly
- identifier. Finally, label was a changeable, user-assignable value that would
- be mapped often to a tag on the resource, or the name of the resource, should
- the name be changeable. This clearly disambiguated between unique
- identifiers, user-assignable values and read-only, user-friendly values. At
- object creation, all services would accept a label as an optional parameter.
- If provided, the `display_id` would sometimes be derived from the label by
- appending a uuid to the label, depending on the provider. At other times, it
- would simply map to an id.
- **Third iteration**
- It soon became apparent that some resources like keypairs could not have a
- label at all, yet needed to be named during object creation. However, we
- could not use `display_id` for this purpose became the display_id, by
- definition, is unchangeable. It could not be called `label` because the label,
- in contrast, was changeable. Therefore, it seemed like we were back to
- calling it `name` instead, introducing yet a fourth term. To simplify this,
- it was then decided that `display_id` and `name` would be collapsed together
- into one term and be called `name` instead. All resources would have an `id`
- and a `name`, and resources that support it would have a `label`. To make
- things even simpler and consistent, it was also decided that label would be
- made mandatory for all resources during object creation, and follow the same
- restrictions as name, which is to have a 3 character minimum. (This was to
- deal with an exception in OpenStack, where the label mapped to instance name,
- but could not be empty. Therefore, by making all labels mandatory and adhere
- to minimum length restrictions, we could make the overall conventions uniform
- across all resources and therefore easier to remember and enforce.)
- **TL;DR**
- CloudBridge has three concepts when it comes to naming and identifying
- objects:
- - `id` is a unique identifier for an object, always
- auto-generated;
- - `name` is a read-only, user-friendly value which is
- suitable for display to the end-user;
- - `label` is a user-assignable value that can be changed.
- The `name` is often derived from the `label` but not
- always. Not all resources support `labels`. Some only accept `names`, which
- can be specified at object creation time (e.g. keypairs). Both `names` and
- `labels` adhere to the same restrictions - a minimum length of 3 which
- should be alphanumeric characters or dashes only. Names or labels should
- not begin or end with a dash, or have consecutive dashes.
-
- .. _63: https://github.com/CloudVE/cloudbridge/issues/63
- .. _131: https://github.com/CloudVE/cloudbridge/issues/131
- .. _pets vs cattle: http://cloudscaling.com/blog/cloud-computing/the-history-of-pets-vs-cattle/
|