Просмотр исходного кода

Updated design decisions docs to document names and labels

Nuwan Goonasekera 7 лет назад
Родитель
Сommit
10587e5e65
1 измененных файлов с 118 добавлено и 0 удалено
  1. 118 0
      docs/topics/design_decisions.rst

+ 118 - 0
docs/topics/design_decisions.rst

@@ -0,0 +1,118 @@
+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 constrast, 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/