Skip to content

Commit

Permalink
Describe configuration of default storage backends
Browse files Browse the repository at this point in the history
  • Loading branch information
pkosiec committed Dec 16, 2021
1 parent 4cbb698 commit c7ccf0e
Showing 1 changed file with 87 additions and 21 deletions.
108 changes: 87 additions & 21 deletions docs/proposal/20211207-delegated-storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ This document describes the way how we will approach dynamic, external data for
- [Workflow syntax - Create](#workflow-syntax---create)
- [Workflow syntax - Update](#workflow-syntax---update)
- [Storage backend service implementation](#storage-backend-service-implementation)
- [Configuring default storage backends](#configuring-default-storage-backends)
- [Uninstalling storage backends](#uninstalling-storage-backends)
- [GraphQL API](#graphql-api)
* [List storage backends](#list-storage-backends)
Expand All @@ -28,9 +29,10 @@ This document describes the way how we will approach dynamic, external data for
* [Go Template backend storage](#go-template-backend-storage)
* [Helm runner templating](#helm-runner-templating)
- [Rejected ideas](#rejected-ideas)
+ [Registering storage backends](#registering-storage-backends-1)
+ [Workflow syntax](#workflow-syntax)
+ [Storage backend service implementation](#storage-backend-service-implementation-1)
* [Registering storage backends](#registering-storage-backends-1)
* [Workflow syntax](#workflow-syntax)
* [Storage backend service implementation](#storage-backend-service-implementation-1)
* [Configuring default storage backends](#configuring-default-storage-backends-1)
- [Consequences](#consequences)

<!-- tocstop -->
Expand Down Expand Up @@ -94,9 +96,9 @@ Also, the additional, nice-to-have goals are:
## Assumptions

1. Content Developer should be able to:
1. Write manifests without specifying a storage backend (use default one configured by Cluster Admin). In this case, a static TypeInstance value is stored in the default storage backend.
1. Write manifests without specifying a storage backend (use default one configured by System Administrator). In this case, a static TypeInstance value is stored in the default storage backend.
1. Specify a specific storage backend as a part of a given Implementation. This case supports both static and dynamic TypeInstance values.
1. Cluster Admin can configure default backend storage for static values.
1. System Administrator can configure default backend storage for static values.
1. There are two different cases when it comes CRUD operations on TypeInstances:
1. CRUD operations on TypeInstance actually manages external resource (e.g. Vault). That is, CRUD operations on TypeInstances in Local Hub actually creates, updates and deletes a given resource.
1. CRUD operations on TypeInstance represents external resources managed in different way (e.g. by running Helm.install). That is, CRUD operations on TypeInstances in Local Hub actually registers, unregisters and updates references for external state without changing them.
Expand Down Expand Up @@ -176,7 +178,7 @@ Also, the additional, nice-to-have goals are:

> **NOTE:** See also the [Rejected ideas](#rejected-ideas) section to learn why a generic validation idea was rejected.

1. To install new storage backend, Cluster Admin has two options:
1. To install new storage backend, System Administrator has two options:

- use Capact Actions (e.g. `cap.interface.capactio.capact.hub.storage.helm-release.install`).
- Register a storage backend by creating such TypeInstance.
Expand Down Expand Up @@ -233,8 +235,6 @@ Also, the additional, nice-to-have goals are:
metadata:
alias: capact-postgresql
attributes:
- path: cap.core.attribute.hub.storage.default # if more such Typeinstances with default Attribute, select first one
revision: 0.1.0
- path: cap.core.attribute.hub.storage.backend
revision: 0.1.0
value:
Expand All @@ -247,13 +247,9 @@ Also, the additional, nice-to-have goals are:
- The one preregistered storage backend is Capact PostgreSQL. It uses special `backend` property: `abstract: true`.

To use Capact PostgreSQL in workflows, the `capact-postgresql` TypeInstance ID has to be referenced as a backend in workflow syntax.

User is allowed to create TypeInstance with such property, however this is considered as advanced usage. If this will be overused, in future, we can restrict creating TypeInstances with such property by any user and keep it as a reserved system keyword.

- Default storage backend should have `additionalParameters` empty (`null`) or optional, in order to work properly.

We can validate that using custom logic in TypeInstance validation. When User wants to add the `cap.core.attribute.hub.storage.default` Attribute we can see if the `additionalParameters` meet our conditions and if not, prevent such change.

- It is the default backend. To learn more, read the [Configuring default storage backends](#configuring-default-storage-backends) paragraph.

## Workflow syntax - Create

Expand All @@ -270,7 +266,7 @@ Also, the additional, nice-to-have goals are:
```

- This workflow cannot be run unless there is a `helm-release` storage backend installed (where `helm-release` is only workflow alias).
- If there are no specific storage backend requirements set, the default backend will be used.
- If there are no specific storage backend requirements set, the default backend will be used. To learn more, read the [Configuring default storage backends](#configuring-default-storage-backends) paragraph.

1. Content Developer outputs one of the following Argo workflow artifacts:

Expand Down Expand Up @@ -329,7 +325,7 @@ Also, the additional, nice-to-have goals are:
capact-outputTypeInstances:
- name: mattermost-config
from: additional
# no backend definition -> use default (default storage backend (TypeInstance) is annotated with `cap.core.attribute.hub.storage.default`)
# no backend definition -> use default storage backend
# option 2 - specific backend (defined in `Implementation.spec.requires` property)
capact-outputTypeInstances:
Expand Down Expand Up @@ -559,6 +555,66 @@ Capact Local Hub calls proper storage backend service while accessing the TypeIn
- [go-cloud](https://github.com/google/go-cloud)
- [stow](https://github.com/graymeta/stow)

## Configuring default storage backends

1. System Administrator configures default backends in Policy.

```yaml
rules: [...] # rules for Interfaces
# ...
default:
typeInstance:
backend:
id: a36ed738-dfe7-45ec-acd1-8e44e8db893b
description: "Default Capact PostgreSQL backend"
```

Default storage backend should have `additionalParameters` empty (`null`) or optional, in order to work properly. When updating Policy, the default backend storage will be validated to see if it meets the criteria.

1. To make it easy to define default backend storages, in Global and Action Policies we introduce additional feature - default TypeInstance injection configuration:

```yaml
rules: [...] # rules for Interfaces
common: # properties applied to all rules above
inject:
requiredTypeInstances:
- id: "3ef2e4ac-9070-4093-a3ce-142139fd4a16"
description: "Helm storage (cap.type.helm.storage:0.1.0)"
# it works globally, not only for storage backends:
- id: "c4f66896-c2a1-4031-b847-b55ae6a26c80"
description: "GCP SA (cap.type.gcp.auth.service-account:0.1.0)"
default: # ...
```

Such list of default TypeInstance to inject will be automatically merged with other injection rules for all Interface rules. The required TypeInstances are injected into workflow only if such TypeInstance is truly required ([see source code](https://github.com/capactio/capact/blob/48502d764aaab9fd4133c2ad70ba82501ad7a35b/pkg/hub/client/policy_enforced_client.go#L123)).

1. Of course, System Administrator or System User may override the defaults using current Policy syntax:

```yaml
rules:
- interface:
path: cap.interface.database.postgresql.install
oneOf:
- implementationConstraints:
# constraints to select Bitnami PostgreSQL installation, for example:
path: cap.implementation.bitnami.postgresql.install
inject:
requiredTypeInstances:
- id: b4cf15d2-79b1-45ee-9729-6b83289ecabc # Different TypeInstance of `cap.type.helm.storage` Type - it will be used instead of the one from `common.inject`
description: "Helm Release storage"

common: # properties applied to all rules above
inject:
requiredTypeInstances:
- id: "3ef2e4ac-9070-4093-a3ce-142139fd4a16"
description: "Helm storage (cap.type.helm.storage:0.1.0)"
```
## Uninstalling storage backends
As described in the [Workflow syntax - Create](#workflow-syntax---create) section, every TypeInstance that uses a given storage backend, will use the `uses` property set:
Expand All @@ -575,7 +631,7 @@ According to the accepted [Rollback](./20201209-action-rollback.md) proposal:
- User won't be able to delete TypeInstance manually, but will run Rollback procedure instead.
- A given TypeInstance which contain any `usedBy` reference, cannot be deleted unless all related TypeInstances are deleted.

In that way, we prevent removal of any storage backend that is used.
In other words, we will prevent removal of any storage backend that is used without any additional implementation from our side.

## GraphQL API

Expand Down Expand Up @@ -986,7 +1042,7 @@ Unfortunately, that won't be possible anymore, and instead we should get all the

## Rejected ideas

#### Registering storage backends
### Registering storage backends

1. Enforcing convention of having storage backend defined as Type with `uri` and `additionalParametersSchema`.

Expand Down Expand Up @@ -1019,14 +1075,14 @@ Unfortunately, that won't be possible anymore, and instead we should get all the

1. Dedicated entity of StorageBackend

Such resource could reside in Local Hub, but it wouldn't be an OCF manifest. Cluster Admin should be able to manage them via GraphQL API, CLI and UI.
Such resource could reside in Local Hub, but it wouldn't be an OCF manifest. System Administrator should be able to manage them via GraphQL API, CLI and UI.

**Reasons:**
- We would still need some kind of StorageBackend templates (with `additionalParametersSchema` JSON schema) in public Hub
- How we would be able to output such as a result of an Action? It could be done in a hacky way to output it as a side effect of running Action (not explicitly), but that would be definitely not elegant
- We would need to have additional API

#### Workflow syntax
### Workflow syntax

1. Keep the Argo artifact value as it is, and add additional syntax:

Expand All @@ -1053,12 +1109,22 @@ Unfortunately, that won't be possible anymore, and instead we should get all the

**Reason:** More complex usage in the workflow, and more complex implementation as well

#### Storage backend service implementation
### Storage backend service implementation

1. Using Actions as a way to do CRUD operations (separate Interface/Implementation per Create/Update/Get/Delete operation)

**Reason:** While the idea may seem exciting, that would be really time consuming and ineffective. We are too far from the point at where we can think about such solution.

### Configuring default storage backends

1. Using dedicated Attribute to specify which storage backend TypeInstance should be selected by default

**Reason**: We still need to configure Policy to configure common TypeInstance injection.

1. Using the `cap.*` rule to define common TypeInstance injection

**Reason**: That would be too difficult to understand for System Administrator and System User. Additional property seem as better solution.

## Consequences

Once approved, these are the consequences:
Expand Down

0 comments on commit c7ccf0e

Please sign in to comment.