From c54f1cd0e5b17c36e91d288265f18a67705883d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=91=A8=F0=9F=8F=BC=E2=80=8D=F0=9F=92=BB=20Romain=20M?= =?UTF-8?q?arcadier-Muller?= Date: Mon, 17 Sep 2018 16:19:25 +0200 Subject: [PATCH 1/2] chore: Documentation for plugins Added basic documentation for the Plugins mechanism and surface it offers in the `Tools` section of the documentation. Fixes #717 --- docs/src/tools.rst | 235 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) diff --git a/docs/src/tools.rst b/docs/src/tools.rst index 68a565dc1b97c..0a95af85b47d4 100644 --- a/docs/src/tools.rst +++ b/docs/src/tools.rst @@ -139,3 +139,238 @@ To out-out, use one of the following methods: "versionReporting": false } +Plugins +======= + +The |cdk| toolkit provides extension points that enable users to augment the features provided by +the toolkit. There is currently only one extension point, allowing users to define custom AWS +credential providers, but other extension points may be added in the future as the needs arise. + +Loading Plugins +--------------- + +Plugins can be loaded by providing the Node module name (or path) to the CDK toolkit: + +1. Using the ``--plugin`` command line option (which can be specified multiple times): + + .. code-block:: console + + $ cdk list --plugin=module + $ cdk deploy --plugin=module_1 --plugin=module_2 + +2. Adding entries to the ``~/.cdk.json`` or ``cdk.json`` file: + + .. code-block:: js + + { + // ... + "plugin": [ + "module_1", + "module_2" + ], + // ... + } + +Authoring Plugins +----------------- + +Plugins must be authored in TypeScript, and are defined by implementing a Node module that implements +the following protocol, and using :js:class:`~aws-cdk.PluginHost` methods: + +.. tabs:: + .. code-tab:: typescript + + import cdk = require('aws-cdk'); + + export = { + version: '1', // Version of the plugin infrastructure (currently always '1') + init(host: cdk.PluginHost): void { + // Your plugin initialization hook. + // Use methods of ``host`` to register custom code with the CDK toolkit + } + }; + + .. code-tab:: javascript + + export = { + version: '1', // Version of the plugin infrastructure (currently always '1') + init(host) { + // Your plugin initialization hook. + // Use methods of ``host`` to register custom code with the CDK toolkit + } + }; + +Credential Provider Plugins +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Custom credential providers are classes implementing the +:js:class:`~aws-cdk.CredentialProviderSource` interface, and registered to the toolkit using +the :js:func:`~aws-cdk.PluginHost.registerCredentialProviderSource` method. + +.. tabs:: + .. code-tab:: typescript + + import cdk = require('aws-cdk'); + import aws = require('aws-sdk'); + + class CustomCredentialProviderSource implements cdk.CredentialProviderSource { + public async isAvailable(): Promise { + // Return ``false`` if the plugin could determine it cannot be used (for example, + // if it depends on files that are not present on this host). + return true; + } + + public async canProvideCredentials(accountId: string): Promise { + // Return ``false`` if the plugin is unable to provide credentials for the + // requested account (for example if it's not managed by the credentials + // system that this plugin adds support for). + return true; + } + + public async getProvider(accountId: string, mode: cdk.Mode): Promise { + let credentials: aws.Credentials; + // Somehow obtain credentials in ``credentials``, and return those. + return credentials; + } + } + + export = { + version = '1', + init(host: cdk.PluginHost): void { + // Register the credential provider to the PluginHost. + host.registerCredentialProviderSource(new CustomCredentialProviderSource()); + } + }; + + .. code-tab:: javascript + + class CustomCredentialProviderSource { + async isAvailable() { + // Return ``false`` if the plugin could determine it cannot be used (for example, + // if it depends on files that are not present on this host). + return true; + } + + async canProvideCredentials(accountId) { + // Return ``false`` if the plugin is unable to provide credentials for the + // requested account (for example if it's not managed by the credentials + // system that this plugin adds support for). + return true; + } + + async getProvider(accountId, mode) { + let credentials; + // Somehow obtain credentials in ``credentials``, and return those. + return credentials; + } + } + + export = { + version = '1', + init(host) { + // Register the credential provider to the PluginHost. + host.registerCredentialProviderSource(new CustomCredentialProviderSource()); + } + }; + +Note that the credentials obtained from the providers for a given account and mode will be cached, +and as a consequence it is strongly advised that the credentials objects returned are self-refreshing, +as descibed in the `AWS SDK for Javascript documentation `_. + +Reference +--------- + +.. js:module:: aws-cdk + +CredentialProviderSource *(interface)* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. js:class:: CredentialProviderSource + + .. js:attribute:: name + + A friendly name for the provider, which will be used in error messages, for example. + + :type: ``string`` + + .. js:method:: isAvailable() + + Whether the credential provider is even online. Guaranteed to be called before any of the other functions are called. + + :returns: ``Promise`` + + .. js:method:: canProvideCredentials(accountId) + + Whether the credential provider can provide credentials for the given account. + + :param string accountId: the account ID for which credentials are needed. + :returns: ``Promise`` + + .. js:method:: getProvider(accountId, mode) + + Construct a credential provider for the given account and the given access mode. + Guaranteed to be called only if canProvideCredentails() returned true at some point. + + :param string accountId: the account ID for which credentials are needed. + :param aws-cdk.Mode mode: the kind of operations the credentials are intended to perform. + :returns: ``Promise`` + +Mode *(enum)* +^^^^^^^^^^^^^ + +.. js:class:: Mode + + .. js:data:: ForReading + + Credentials are inteded to be used for read-only scenarios. + + .. js:data:: ForWriting + + Credentials are intended to be used for read-write scenarios. + +Plugin *(interface)* +^^^^^^^^^^^^^^^^^^^^ + +.. js:class:: Plugin() + + .. js:attribute:: version + + The version of the plug-in interface used by the plug-in. This will be used by + the plug-in host to handle version changes. Currently, the only valid value for + this attribute is ``'1'``. + + :type: ``string`` + + .. js:method:: init(host) + + When defined, this function is invoked right after the plug-in has been loaded, + so that the plug-in is able to initialize itself. It may call methods of the + :js:class:`~aws-cdk.PluginHost` instance it receives to register new + :js:class:`~aws-cdk.CredentialProviderSource` instances. + + :param aws-cdk.PluginHost host: The |cdk| plugin host + :returns: ``void`` + +PluginHost +^^^^^^^^^^ + +.. js:class:: PluginHost() + + .. js:data:: instance + + :type: :js:class:`~aws-cdk.PluginHost` + + .. js:method:: load(moduleSpec) + + Loads a plug-in into this PluginHost. + + :param string moduleSpec: the specification (path or name) of the plug-in module to be loaded. + :throws Error: if the provided ``moduleSpec`` cannot be loaded or is not a valid :js:class:`~aws-cdk.Plugin`. + :returns: ``void`` + + .. js:method:: registerCredentialProviderSource(source) + + Allows plug-ins to register new :js:class:`~aws-cdk.CredentialProviderSources`. + + :param aws-cdk.CredentialProviderSources source: a new CredentialProviderSource to register. + :returns: ``void`` From e329a55a27cbc59e1e74a3164bcd5476a0f788cc Mon Sep 17 00:00:00 2001 From: Romain Marcadier-Muller Date: Mon, 17 Sep 2018 19:00:02 +0200 Subject: [PATCH 2/2] Update tools.rst --- docs/src/tools.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/tools.rst b/docs/src/tools.rst index 0a95af85b47d4..9f30239193e9c 100644 --- a/docs/src/tools.rst +++ b/docs/src/tools.rst @@ -174,8 +174,8 @@ Plugins can be loaded by providing the Node module name (or path) to the CDK too Authoring Plugins ----------------- -Plugins must be authored in TypeScript, and are defined by implementing a Node module that implements -the following protocol, and using :js:class:`~aws-cdk.PluginHost` methods: +Plugins must be authored in TypeScript or Javascript, and are defined by implementing a Node module +that implements the following protocol, and using :js:class:`~aws-cdk.PluginHost` methods: .. tabs:: .. code-tab:: typescript