| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- 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 miss match. (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, 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. The `id` is a unique identifier for an object, always
- auto-generated. The `name` is a read-only, user-friendly value which is
- suitable for display to the end-user. The `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/
|