From 53dd481b33ef59d4046e550e532bd27fef341e10 Mon Sep 17 00:00:00 2001 From: Bikalpa Dhakal Date: Thu, 9 Jan 2025 07:58:54 +0000 Subject: [PATCH] Add interface: azure --- interfaces/azure/v0/README.md | 65 ++++++++++++++++ interfaces/azure/v0/interface.yaml | 13 ++++ interfaces/azure/v0/schemas/provider.json | 92 +++++++++++++++++++++++ interfaces/azure/v0/schemas/requirer.json | 26 +++++++ 4 files changed, 196 insertions(+) create mode 100644 interfaces/azure/v0/README.md create mode 100644 interfaces/azure/v0/interface.yaml create mode 100644 interfaces/azure/v0/schemas/provider.json create mode 100644 interfaces/azure/v0/schemas/requirer.json diff --git a/interfaces/azure/v0/README.md b/interfaces/azure/v0/README.md new file mode 100644 index 00000000..5c5bd70c --- /dev/null +++ b/interfaces/azure/v0/README.md @@ -0,0 +1,65 @@ +# `azure` + +## Usage + +This relation interface describes the expected behaviour of any charm claiming to be able to interact with Azure Storage protocol. +This relation interface should be used for both Azure Blob Storage and Azure Data Lake Storage (Gen 2). This interface will be accomplished using the provider library, although charm developers are free to provide alternative libraries as long as they fulfil the behavioural and schematic requirements described in this document. + +## Direction + +```mermaid +flowchart TD + Provider -- container, storage-account, secret-key, connection-protocol, endpoint, path --> Requirer +``` + +As with all Juju relations, the `azure` interface consists of two parties: a Provider (object storage charm) and a Requirer (application charm). The Provider will be expected to provide new unique credentials (along with `storage-account`, `container`, `connection-protocol` and other fields), which can be used to access the actual object storage. + +## Behaviour + +Both the Requirer and the Provider must adhere to criteria to be compatible with this interface. + +### Provider +- It is expected to provide `storage-account`, `container` and `secret-key` fields corresponding to a storage account, container and the secret key corresponding to an Azure Storage account when a relation joins. As of now, the container is not automatically created when the relation is joined. +- It is expected to provide the `endpoint` field containing a URL (eg, abfss://containername.accountname.dfs.core.windows.net/). +- It is expected to provide the `connection-protocol` field that may be one of `wasb`, `wasbs`, `abfs` or `abfss`; which signifies which connection protocol should be used to connect to the storage account and the container. +- It is expected to provide the optional `path` field that contains the relative path inside the container which is to be used for storage. + +### Requirer +- Is expected to provide a container name in the `container` field. Field value should be generated on Requirer side if no particular value set in Requirer juju config. +- Is expected to tolerate that the Provider may ignore the `container` field in some cases (e.g. Azure Storage Integrator) and instead use the container name received. +- Is expected to allow multiple different Juju applications to access the same container name. +- Is expected to have unique credentials for each relation. Therefore, different instances of the same Charm (juju applications) will have different relations with different credentials. +- Is expected to have different relations names on Requirer with the same interface name if Requirer needs access to multiple buckets. + +## Relation Data + +### Provider + +[\[JSON Schema\]](./schemas/provider.json) + +The Provider provides credentials, endpoints, TLS info and database-specific fields. It should be placed in the **application** databag. + + +#### Example +```yaml + application-data: + container: test-container + storage-account: test-storage-account + connection-protocol: abfss + secret-key: RANDOM + path: spark-events/ + endpoint: abfss://test-container@test-storage-account.dfs.core.windows.net/ +``` + +### Requirer + +[\[JSON Schema\]](./schemas/requirer.json) + +Requirer provides container name. Should be placed in the **application** databag in the Requirer. + +#### Example + +```yaml + application-data: + container: test-container +``` diff --git a/interfaces/azure/v0/interface.yaml b/interfaces/azure/v0/interface.yaml new file mode 100644 index 00000000..1522c8de --- /dev/null +++ b/interfaces/azure/v0/interface.yaml @@ -0,0 +1,13 @@ +name: azure +version: 0 +status: draft + +providers: + - name: azure-storage-integrator + url: https://github.com/canonical/object-storage-integrators + +requirers: + - name: spark-integration-hub-k8s + url: https://github.com/canonical/spark-integration-hub-k8s-operator + +maintainer: data-platform diff --git a/interfaces/azure/v0/schemas/provider.json b/interfaces/azure/v0/schemas/provider.json new file mode 100644 index 00000000..2bfd738f --- /dev/null +++ b/interfaces/azure/v0/schemas/provider.json @@ -0,0 +1,92 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://canonical.github.io/charm-relation-interfaces/interfaces/azure/schemas/provider.json", + "title": "`azure` provider schema", + "description": "The `azure` root schema comprises the entire provider databag for this interface.", + "type": "object", + "default": {}, + "required": [ + "container", + "connection-protocol", + "storage-account", + "secret-key" + ], + "additionalProperties": true, + "properties": { + "container": { + "title": "Container name", + "description": "The name of the Azure Storage container delivered by the provider.", + "type": "string", + "default": "", + "examples": [ + "test-container" + ] + }, + "storage-account": { + "title": "Storage account name", + "description": "The name of the storage account in Azure Cloud.", + "type": "string", + "default": "", + "examples": [ + "test-storage-account" + ] + }, + "connection-protocol": { + "title": "Connection protocol", + "description": "The connection protocol to use to connect to Azure Storage.", + "type": "string", + "default": "abfss", + "examples": [ + "wasb", + "wasbs", + "abfs", + "abfss" + ] + }, + "secret-key": { + "title": "Secret Key", + "description": "Secret ID (password) corresponding to the storage account for connecting to the object storage.", + "type": "string", + "default": "", + "examples": [ + "random-secret-key" + ] + }, + "path": { + "title": "Path", + "description": "The path inside the container to store objects.", + "type": "string", + "default": "", + "examples": [ + "foo/bar" + ] + }, + "endpoint": { + "title": "Endpoint URL", + "description": "The endpoint corresponding to the specific container and storage account.", + "type": "string", + "default": "", + "examples": [ + "abfss://test-container@test-account.dfs.core.windows.net/" + ] + } + }, + "examples": [ + { + "container": "test-container", + "storage-account": "test-storage-account", + "path": "spark-events/", + "connection-protocol": "abfss", + "secret-key": "DUMMY+ACCESS+KEY+FOR+EXAMPLE+1234567890abcdefghijklmnopqrstuvwxyz==", + "endpoint": "abfss://test-container@test-storage-account.dfs.core.windows.net/" + }, + { + "container": "my-container", + "storage-account": "my-storageacc", + "path": "foo/bar/", + "connection-protocol": "wasb", + "secret-key": "EXAMPLE-KEY+1234567890abcdefghijklmnopqrstuvwxyz==", + "endpoint": "wasb://my-container@my-storageacc.blob.core.windows.net/" + } + ] +} diff --git a/interfaces/azure/v0/schemas/requirer.json b/interfaces/azure/v0/schemas/requirer.json new file mode 100644 index 00000000..f349a8f8 --- /dev/null +++ b/interfaces/azure/v0/schemas/requirer.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://canonical.github.io/charm-relation-interfaces/interfaces/azure/schemas/requirer.json", + "title": "`azure` requirer schema", + "description": "The `azure` root schema comprises the entire requirer databag for this interface.", + "type": "object", + "default": {}, + "required": [ + "container" + ], + "additionalProperties": true, + "properties": { + "container": { + "title": "Container Name", + "description": "The name of the container requested by the requirer", + "type": "string", + "default": "", + "examples": [ + "test-container" + ] + } + }, + "examples": [{ + "container": "myapp" + }] +}