From 65579cc6c5764c64f75f8d438cfd6671d8247385 Mon Sep 17 00:00:00 2001 From: Luke Sneeringer Date: Mon, 3 May 2021 16:35:11 -0700 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20AIP-128=20=E2=80=93=20Declarative-f?= =?UTF-8?q?riendly=20interfaces?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aip/general/0128/aip.md.j2 | 116 ++++++++++++++++++ aip/general/0128/aip.yaml | 7 ++ .../0128/declarative_friendly.oas.yaml | 17 +++ aip/general/0128/declarative_friendly.proto | 32 +++++ 4 files changed, 172 insertions(+) create mode 100644 aip/general/0128/aip.md.j2 create mode 100644 aip/general/0128/aip.yaml create mode 100644 aip/general/0128/declarative_friendly.oas.yaml create mode 100644 aip/general/0128/declarative_friendly.proto diff --git a/aip/general/0128/aip.md.j2 b/aip/general/0128/aip.md.j2 new file mode 100644 index 00000000..431bf28e --- /dev/null +++ b/aip/general/0128/aip.md.j2 @@ -0,0 +1,116 @@ +# Declarative-friendly interfaces + +Many services need to interact with common DevOps tools, particularly those +that create and manage network-addressible resources (such as virtual machines, +load balancers, database instances, and so on). These tools revolve around the +principle of "configuration as code": the user specifies the complete intended +landscape, and tooling is responsible for making whatever changes are necessary +to achieve the user's specification. + +These tools are **declarative**: rather than specifying specific _actions_ to +take, they specify the desired _outcome_, with the actions being derived based +on the differences between the current landscape and the intended one. + +Furthermore, there are numerous popular DevOps tools, with more being +introduced each year. Integrating hundreds of resource types with multiple +tools requires strong consistency, so that integration can be automated. + +## Guidance + +Services **should** clearly delineate between "control plane" operations and +"data plane" operations, ideally through the use of distinct services with +their own interface definition documents. + +- Control plane operations are responsible for managing the _lifecycle_ of + resources. +- Data plane operations are responsible for managing the _content_ of + resources. + +The same resource **may** have both control plane operations and data plane +operations associated with it. For example, a database API would have +operations to create or delete database tables (control plane) as well as +operations to write and read rows to that table (data plane). + +### Resources + +Resources that are declarative-friendly **must** use only strongly-consistent +standard methods for managing resource lifecycle, which allows tools to support +these resources generically, as well as conforming to other +declarative-friendly guidance (see [further reading](#further-reading)). + +Declarative-friendly resources **should** designate that they follow the +declarative-friendly style: + +{% tab proto %} + +{% sample 'declarative_friendly.proto', 'message Book' %} + +{% tab oas %} + +{% sample 'declarative_friendly.oas.yaml', 'schema' %} + +{% endtabs %} + +### Annotations + +Declarative-friendly resources **must** include a `annotations` field to allow +clients to store small amounts of arbitrary data: + +```typescript +// A representation of a single book. +interface Book { + // The name of the book. + // Format: publishers/{publisher}/books/{book} + name: string; + + // Other fields... + + // A dictionary of key-value pairs. + // This has no effect on the service's behavior, but clients may use it + // to persistently store small amounts of information related to this + // resource. + annotations: { [key: string]: string }; +} +``` + +The `annotations` field **must** use the [Kubernetes limits][] to maintain wire +compatibility, and **should** require dot-namespaced annotation keys to prevent +tools from trampling over one another. + +**Note:** Annotations are distinct from various forms of labels. Labels can be +used by server-side policies, such as IAM conditions. Annotations exist to +allow client tools to store their own state information without requiring a +database. + + +[kubernetes limits]: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/#syntax-and-character-set + +### Reconciliation + +If a resource takes time (more than a few seconds) for updates to be realized, +the resource **should** include a `bool reconciling` field to disclose that +changes are in flight. This field **must** be output only. + +A resource **must** set the `reconciling` field to `true` if the current state +of the resource does not match the user's intended state, and the system is +working to reconcile them. This is regardless of whether the root cause of +going into reconciliation was user or system action. + +**Note:** Services responding to a `GET` request **must** return the resource's +current state (not the intended state). + +## Further reading + +A significant amount of guidance is more strict for declarative-friendly +interfaces, due to the focus on automation on top of these resources. This list +is a comprehensive reference to declarative-friendly guidance in other AIPs: + +- Resources **must** use user-settable resource IDs: see AIP-133. +- Resources **must** permit "create or update": see AIP-134. +- Resources **should** permit "delete if existing": see AIP-135. +- Resources **should not** employ custom methods: see AIP-136. +- Resources **must** use the `Update` method for repeated fields: see AIP-144. +- Resources **must** include certain standard fields: see AIP-148. +- Resources **must** have an `etag` field: see AIP-154. +- Resources **must** provide change validation: see AIP-163. +- Resources **should** support soft delete: see AIP-164. diff --git a/aip/general/0128/aip.yaml b/aip/general/0128/aip.yaml new file mode 100644 index 00000000..2d62a6cc --- /dev/null +++ b/aip/general/0128/aip.yaml @@ -0,0 +1,7 @@ +--- +id: 128 +state: approved +created: 2020-10-06 +placement: + category: resource-design + order: 65 diff --git a/aip/general/0128/declarative_friendly.oas.yaml b/aip/general/0128/declarative_friendly.oas.yaml new file mode 100644 index 00000000..848c4813 --- /dev/null +++ b/aip/general/0128/declarative_friendly.oas.yaml @@ -0,0 +1,17 @@ +--- +openapi: 3.0.3 +info: + title: Library + version: 1.0.0 +components: + schema: + Book: + description: A representation of a single book. + x-declarative-friendly: true + properties: + name: + type: string + description: | + The name of the book. + Format: publishers/{publisher}/books/{book} + # Additional fields... diff --git a/aip/general/0128/declarative_friendly.proto b/aip/general/0128/declarative_friendly.proto new file mode 100644 index 00000000..803e3021 --- /dev/null +++ b/aip/general/0128/declarative_friendly.proto @@ -0,0 +1,32 @@ +// Copyright 2020 Google LLC +// +// 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 +// +// https://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. + +syntax = "proto3"; + +import "google/api/resource.proto"; + +// A representation of a book. +message Book { + option (google.api.resource) = { + type: "library.googleapis.com/Book" + pattern: "publishers/{publisher}/books/{book}" + style: DECLARATIVE_FRIENDLY + }; + + // The name of the book. + // Format: publishers/{publisher}/books/{book} + string name = 1; + + // Other fields... +} From aaff1f9adb31b480eaffb5ab3f498a52ec11f6b7 Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Sun, 30 Oct 2022 11:38:51 -0500 Subject: [PATCH 2/2] Minor improvements to oas example --- aip/general/0128/declarative_friendly.oas.yaml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/aip/general/0128/declarative_friendly.oas.yaml b/aip/general/0128/declarative_friendly.oas.yaml index 848c4813..88648f80 100644 --- a/aip/general/0128/declarative_friendly.oas.yaml +++ b/aip/general/0128/declarative_friendly.oas.yaml @@ -3,15 +3,25 @@ openapi: 3.0.3 info: title: Library version: 1.0.0 +paths: {} components: - schema: + schemas: Book: description: A representation of a single book. - x-declarative-friendly: true properties: name: type: string description: | The name of the book. Format: publishers/{publisher}/books/{book} + + annotations: + description: | + A dictionary of key-value pairs. + This has no effect on the service's behavior, but clients may use it + to persistently store small amounts of information related to this + resource. + additionalProperties: + type: string + # Additional fields...