diff --git a/API.md b/API.md
index 4aa620e..7ae00d6 100644
--- a/API.md
+++ b/API.md
@@ -271,6 +271,11 @@ The environment variables to export into the outgoing event once the BashJobRunn
### BillingProvider
+Represents a Billing Provider that handles billing-related operations.
+
+This construct sets up event targets for various billing-related events
+and optionally creates an API Gateway resource for a webhook function.
+
#### Initializers
```typescript
@@ -281,9 +286,9 @@ new BillingProvider(scope: Construct, id: string, props: BillingProviderProps)
| **Name** | **Type** | **Description** |
| --- | --- | --- |
-| scope
| constructs.Construct
| *No description.* |
-| id
| string
| *No description.* |
-| props
| BillingProviderProps
| *No description.* |
+| scope
| constructs.Construct
| The scope in which to define this construct. |
+| id
| string
| The unique ID of this construct. |
+| props
| BillingProviderProps
| The properties for the BillingProvider. |
---
@@ -291,18 +296,24 @@ new BillingProvider(scope: Construct, id: string, props: BillingProviderProps)
- *Type:* constructs.Construct
+The scope in which to define this construct.
+
---
##### `id`Required
- *Type:* string
+The unique ID of this construct.
+
---
##### `props`Required
- *Type:* BillingProviderProps
+The properties for the BillingProvider.
+
---
#### Methods
@@ -387,6 +398,8 @@ Only set when the IBilling webhookFunction is defined.
- *Implements:* IAuth
+Constructs for setting up Cognito authentication and user management.
+
#### Initializers
```typescript
@@ -468,18 +481,18 @@ Any object.
| **Name** | **Type** | **Description** |
| --- | --- | --- |
| node
| constructs.Node
| The tree node. |
-| authorizationServer
| string
| Authorization server Url. |
-| authorizer
| aws-cdk-lib.aws_apigateway.IAuthorizer
| Authorizer referenced by the ControlPlaneAPI. |
-| clientId
| string
| The OAuth clientId for the identity provider. |
-| controlPlaneIdpDetails
| any
| Contains any information relevant to the IDP implementation required by the Authorizer and User Function implementations. |
-| createUserFunction
| aws-cdk-lib.aws_lambda.IFunction
| Function referenced by the ControlPlaneAPI -- POST /users. |
-| deleteUserFunction
| aws-cdk-lib.aws_lambda.IFunction
| Function referenced by the ControlPlaneAPI -- DELETE /user/{username}. |
-| disableUserFunction
| aws-cdk-lib.aws_lambda.IFunction
| Function referenced by the ControlPlaneAPI -- PUT /user/{username}/disable. |
-| enableUserFunction
| aws-cdk-lib.aws_lambda.IFunction
| Function referenced by the ControlPlaneAPI -- PUT /user/{username}/enable. |
-| fetchAllUsersFunction
| aws-cdk-lib.aws_lambda.IFunction
| Function referenced by the ControlPlaneAPI -- GET /users. |
-| fetchUserFunction
| aws-cdk-lib.aws_lambda.IFunction
| Function referenced by the ControlPlaneAPI -- GET /user/{username}. |
-| updateUserFunction
| aws-cdk-lib.aws_lambda.IFunction
| Function referenced by the ControlPlaneAPI -- PUT /user/{username}. |
-| wellKnownEndpointUrl
| string
| OpenID configuration Url. |
+| authorizationServer
| string
| The authorization server for the control plane IdP. |
+| authorizer
| aws-cdk-lib.aws_apigateway.IAuthorizer
| The API Gateway authorizer for authenticating requests. |
+| clientId
| string
| The client ID for the control plane IdP. |
+| controlPlaneIdpDetails
| any
| The details of the control plane Identity Provider (IdP). |
+| createUserFunction
| aws-cdk-lib.aws_lambda.IFunction
| The Lambda function for creating a user. |
+| deleteUserFunction
| aws-cdk-lib.aws_lambda.IFunction
| The Lambda function for deleting a user. |
+| disableUserFunction
| aws-cdk-lib.aws_lambda.IFunction
| The Lambda function for disabling a user. |
+| enableUserFunction
| aws-cdk-lib.aws_lambda.IFunction
| The Lambda function for enabling a user. |
+| fetchAllUsersFunction
| aws-cdk-lib.aws_lambda.IFunction
| The Lambda function for fetching all users. |
+| fetchUserFunction
| aws-cdk-lib.aws_lambda.IFunction
| The Lambda function for fetching a user. |
+| updateUserFunction
| aws-cdk-lib.aws_lambda.IFunction
| The Lambda function for updating a user. |
+| wellKnownEndpointUrl
| string
| The well-known endpoint URL for the control plane IdP. |
---
@@ -503,7 +516,7 @@ public readonly authorizationServer: string;
- *Type:* string
-Authorization server Url.
+The authorization server for the control plane IdP.
---
@@ -515,7 +528,7 @@ public readonly authorizer: IAuthorizer;
- *Type:* aws-cdk-lib.aws_apigateway.IAuthorizer
-Authorizer referenced by the ControlPlaneAPI.
+The API Gateway authorizer for authenticating requests.
---
@@ -527,7 +540,7 @@ public readonly clientId: string;
- *Type:* string
-The OAuth clientId for the identity provider.
+The client ID for the control plane IdP.
---
@@ -539,7 +552,7 @@ public readonly controlPlaneIdpDetails: any;
- *Type:* any
-Contains any information relevant to the IDP implementation required by the Authorizer and User Function implementations.
+The details of the control plane Identity Provider (IdP).
---
@@ -551,7 +564,7 @@ public readonly createUserFunction: IFunction;
- *Type:* aws-cdk-lib.aws_lambda.IFunction
-Function referenced by the ControlPlaneAPI -- POST /users.
+The Lambda function for creating a user.
---
@@ -563,7 +576,7 @@ public readonly deleteUserFunction: IFunction;
- *Type:* aws-cdk-lib.aws_lambda.IFunction
-Function referenced by the ControlPlaneAPI -- DELETE /user/{username}.
+The Lambda function for deleting a user.
---
@@ -575,7 +588,7 @@ public readonly disableUserFunction: IFunction;
- *Type:* aws-cdk-lib.aws_lambda.IFunction
-Function referenced by the ControlPlaneAPI -- PUT /user/{username}/disable.
+The Lambda function for disabling a user.
---
@@ -587,7 +600,7 @@ public readonly enableUserFunction: IFunction;
- *Type:* aws-cdk-lib.aws_lambda.IFunction
-Function referenced by the ControlPlaneAPI -- PUT /user/{username}/enable.
+The Lambda function for enabling a user.
---
@@ -599,7 +612,7 @@ public readonly fetchAllUsersFunction: IFunction;
- *Type:* aws-cdk-lib.aws_lambda.IFunction
-Function referenced by the ControlPlaneAPI -- GET /users.
+The Lambda function for fetching all users.
---
@@ -611,7 +624,7 @@ public readonly fetchUserFunction: IFunction;
- *Type:* aws-cdk-lib.aws_lambda.IFunction
-Function referenced by the ControlPlaneAPI -- GET /user/{username}.
+The Lambda function for fetching a user.
---
@@ -623,7 +636,7 @@ public readonly updateUserFunction: IFunction;
- *Type:* aws-cdk-lib.aws_lambda.IFunction
-Function referenced by the ControlPlaneAPI -- PUT /user/{username}.
+The Lambda function for updating a user.
---
@@ -635,7 +648,7 @@ public readonly wellKnownEndpointUrl: string;
- *Type:* string
-OpenID configuration Url.
+The well-known endpoint URL for the control plane IdP.
---
@@ -1033,7 +1046,7 @@ public readonly eventManager: EventManager;
### EventManager
-Provides an EventManager to help interact with the EventBus shared with the SBT control plane.
+Provides an EventManager to interact with the EventBus shared with the SBT control plane.
#### Initializers
@@ -1098,7 +1111,7 @@ Adds an IRuleTarget to an event.
- *Type:* DetailType
-The name of the event to add a target to.
+The detail type of the event to add a target to.
---
@@ -1141,10 +1154,10 @@ Any object.
| **Name** | **Type** | **Description** |
| --- | --- | --- |
| node
| constructs.Node
| The tree node. |
-| applicationPlaneEventSource
| string
| *No description.* |
-| controlPlaneEventSource
| string
| *No description.* |
+| applicationPlaneEventSource
| string
| The event source used for events emitted by the application plane. |
+| controlPlaneEventSource
| string
| The event source used for events emitted by the control plane. |
| eventBus
| aws-cdk-lib.aws_events.IEventBus
| The event bus to register new rules with. |
-| supportedEvents
| {[ key: string ]: string}
| *No description.* |
+| supportedEvents
| {[ key: string ]: string}
| List of recognized events that are available as triggers. |
---
@@ -1168,6 +1181,8 @@ public readonly applicationPlaneEventSource: string;
- *Type:* string
+The event source used for events emitted by the application plane.
+
---
##### `controlPlaneEventSource`Required
@@ -1178,6 +1193,8 @@ public readonly controlPlaneEventSource: string;
- *Type:* string
+The event source used for events emitted by the control plane.
+
---
##### `eventBus`Required
@@ -1200,6 +1217,8 @@ public readonly supportedEvents: {[ key: string ]: string};
- *Type:* {[ key: string ]: string}
+List of recognized events that are available as triggers.
+
---
@@ -2335,6 +2354,8 @@ An EventManager object to help coordinate events.
### CognitoAuthProps
+Properties for the CognitoAuth construct.
+
#### Initializer
```typescript
@@ -2347,10 +2368,10 @@ const cognitoAuthProps: CognitoAuthProps = { ... }
| **Name** | **Type** | **Description** |
| --- | --- | --- |
-| idpName
| string
| *No description.* |
-| systemAdminEmail
| string
| *No description.* |
-| systemAdminRoleName
| string
| *No description.* |
-| controlPlaneCallbackURL
| string
| *No description.* |
+| idpName
| string
| The name of the Identity Provider (IdP) for the control plane. |
+| systemAdminEmail
| string
| The email address of the system admin. |
+| systemAdminRoleName
| string
| The name of the system admin role. |
+| controlPlaneCallbackURL
| string
| The callback URL for the control plane. |
---
@@ -2362,6 +2383,8 @@ public readonly idpName: string;
- *Type:* string
+The name of the Identity Provider (IdP) for the control plane.
+
---
##### `systemAdminEmail`Required
@@ -2372,6 +2395,8 @@ public readonly systemAdminEmail: string;
- *Type:* string
+The email address of the system admin.
+
---
##### `systemAdminRoleName`Required
@@ -2382,6 +2407,8 @@ public readonly systemAdminRoleName: string;
- *Type:* string
+The name of the system admin role.
+
---
##### `controlPlaneCallbackURL`Optional
@@ -2391,6 +2418,11 @@ public readonly controlPlaneCallbackURL: string;
```
- *Type:* string
+- *Default:* 'http://localhost'
+
+The callback URL for the control plane.
+
+If not provided, defaults to 'http://localhost'.
---
@@ -2770,7 +2802,7 @@ The list of JobRunner definitions to create.
### EventManagerProps
-Encapsulates the list of properties for an eventManager.
+Encapsulates the properties for an EventManager.
#### Initializer
@@ -3501,40 +3533,74 @@ Encapsulates the list of properties for an IBilling construct.
| **Name** | **Type** | **Description** |
| --- | --- | --- |
-| createUserFunction
| aws-cdk-lib.aws_lambda.IFunction
| The function to trigger when creating a new billing user. |
-| deleteUserFunction
| aws-cdk-lib.aws_lambda.IFunction
| The function to trigger when deleting a billing user. |
+| createCustomerFunction
| aws-cdk-lib.aws_lambda.IFunction \| IFunctionTrigger
| The function to trigger to create a new customer. |
+| deleteCustomerFunction
| aws-cdk-lib.aws_lambda.IFunction \| IFunctionTrigger
| The function to trigger to delete a customer. |
+| createUserFunction
| aws-cdk-lib.aws_lambda.IFunction \| IFunctionTrigger
| The function to trigger to create a new user. |
+| deleteUserFunction
| aws-cdk-lib.aws_lambda.IFunction \| IFunctionTrigger
| The function to trigger to delete a user. |
| ingestor
| IDataIngestorAggregator
| The IDataIngestorAggregator responsible for accepting and aggregating the raw billing data. |
-| putUsageFunction
| aws-cdk-lib.aws_lambda.IFunction
| The function responsible for taking the aggregated data and pushing that to the billing provider. |
+| putUsageFunction
| aws-cdk-lib.aws_lambda.IFunction \| IFunctionSchedule
| The function responsible for taking the aggregated data and pushing that to the billing provider. |
| webhookFunction
| aws-cdk-lib.aws_lambda.IFunction
| The function to trigger when a webhook request is received. |
| webhookPath
| string
| The path to the webhook resource. |
---
-##### `createUserFunction`Required
+##### `createCustomerFunction`Required
```typescript
-public readonly createUserFunction: IFunction;
+public readonly createCustomerFunction: IFunction | IFunctionTrigger;
```
-- *Type:* aws-cdk-lib.aws_lambda.IFunction
+- *Type:* aws-cdk-lib.aws_lambda.IFunction | IFunctionTrigger
-The function to trigger when creating a new billing user.
+The function to trigger to create a new customer.
+
+(Customer in this context is an entity that has zero or more Users.)
---
-##### `deleteUserFunction`Required
+##### `deleteCustomerFunction`Required
```typescript
-public readonly deleteUserFunction: IFunction;
+public readonly deleteCustomerFunction: IFunction | IFunctionTrigger;
```
-- *Type:* aws-cdk-lib.aws_lambda.IFunction
+- *Type:* aws-cdk-lib.aws_lambda.IFunction | IFunctionTrigger
+
+The function to trigger to delete a customer.
+
+(Customer in this context is an entity that has zero or more Users.)
+
+---
+
+##### `createUserFunction`Optional
+
+```typescript
+public readonly createUserFunction: IFunction | IFunctionTrigger;
+```
+
+- *Type:* aws-cdk-lib.aws_lambda.IFunction | IFunctionTrigger
+
+The function to trigger to create a new user.
+
+(User in this context is an entity that belongs to a Customer.)
+
+---
+
+##### `deleteUserFunction`Optional
+
+```typescript
+public readonly deleteUserFunction: IFunction | IFunctionTrigger;
+```
-The function to trigger when deleting a billing user.
+- *Type:* aws-cdk-lib.aws_lambda.IFunction | IFunctionTrigger
+
+The function to trigger to delete a user.
+
+(User in this context is an entity that belongs to a Customer.)
---
-##### `ingestor`Required
+##### `ingestor`Optional
```typescript
public readonly ingestor: IDataIngestorAggregator;
@@ -3546,13 +3612,13 @@ The IDataIngestorAggregator responsible for accepting and aggregating the raw bi
---
-##### `putUsageFunction`Required
+##### `putUsageFunction`Optional
```typescript
-public readonly putUsageFunction: IFunction;
+public readonly putUsageFunction: IFunction | IFunctionSchedule;
```
-- *Type:* aws-cdk-lib.aws_lambda.IFunction
+- *Type:* aws-cdk-lib.aws_lambda.IFunction | IFunctionSchedule
The function responsible for taking the aggregated data and pushing that to the billing provider.
@@ -3635,126 +3701,264 @@ The table containing the aggregated data.
---
+### IFunctionSchedule
+
+- *Implemented By:* IFunctionSchedule
+
+Optional interface that allows specifying both the function to trigger and the schedule by which to trigger it.
+
+
+#### Properties
+
+| **Name** | **Type** | **Description** |
+| --- | --- | --- |
+| handler
| aws-cdk-lib.aws_lambda.IFunction
| The function definition. |
+| schedule
| aws-cdk-lib.aws_events.Schedule
| The schedule that will trigger the handler function. |
+
+---
+
+##### `handler`Required
+
+```typescript
+public readonly handler: IFunction;
+```
+
+- *Type:* aws-cdk-lib.aws_lambda.IFunction
+
+The function definition.
+
+---
+
+##### `schedule`Required
+
+```typescript
+public readonly schedule: Schedule;
+```
+
+- *Type:* aws-cdk-lib.aws_events.Schedule
+
+The schedule that will trigger the handler function.
+
+---
+
+### IFunctionTrigger
+
+- *Implemented By:* IFunctionTrigger
+
+Optional interface that allows specifying both the function to trigger and the event that will trigger it.
+
+
+#### Properties
+
+| **Name** | **Type** | **Description** |
+| --- | --- | --- |
+| handler
| aws-cdk-lib.aws_lambda.IFunction
| The function definition. |
+| trigger
| DetailType
| The detail-type that will trigger the handler function. |
+
+---
+
+##### `handler`Required
+
+```typescript
+public readonly handler: IFunction;
+```
+
+- *Type:* aws-cdk-lib.aws_lambda.IFunction
+
+The function definition.
+
+---
+
+##### `trigger`Required
+
+```typescript
+public readonly trigger: DetailType;
+```
+
+- *Type:* DetailType
+
+The detail-type that will trigger the handler function.
+
+---
+
## Enums
### DetailType
-Provides an easy way of accessing event DetailTypes.
+Provides an easy way of accessing event detail types.
-Note that the string represents the detailTypes used in
+The string values represent the "detail-type" used in
events sent across the EventBus.
#### Members
| **Name** | **Description** |
| --- | --- |
-| ONBOARDING_REQUEST
| *No description.* |
-| ONBOARDING_SUCCESS
| *No description.* |
-| ONBOARDING_FAILURE
| *No description.* |
-| OFFBOARDING_REQUEST
| *No description.* |
-| OFFBOARDING_SUCCESS
| *No description.* |
-| OFFBOARDING_FAILURE
| *No description.* |
-| PROVISION_SUCCESS
| *No description.* |
-| PROVISION_FAILURE
| *No description.* |
-| DEPROVISION_SUCCESS
| *No description.* |
-| DEPROVISION_FAILURE
| *No description.* |
-| BILLING_SUCCESS
| *No description.* |
-| BILLING_FAILURE
| *No description.* |
-| ACTIVATE_REQUEST
| *No description.* |
-| ACTIVATE_SUCCESS
| *No description.* |
-| ACTIVATE_FAILURE
| *No description.* |
-| DEACTIVATE_REQUEST
| *No description.* |
-| DEACTIVATE_SUCCESS
| *No description.* |
-| DEACTIVATE_FAILURE
| *No description.* |
+| ONBOARDING_REQUEST
| Event detail type for onboarding request. |
+| ONBOARDING_SUCCESS
| Event detail type for successful onboarding. |
+| ONBOARDING_FAILURE
| Event detail type for failed onboarding. |
+| OFFBOARDING_REQUEST
| Event detail type for offboarding request. |
+| OFFBOARDING_SUCCESS
| Event detail type for successful offboarding. |
+| OFFBOARDING_FAILURE
| Event detail type for failed offboarding. |
+| PROVISION_SUCCESS
| Event detail type for successful provisioning. |
+| PROVISION_FAILURE
| Event detail type for failed provisioning. |
+| DEPROVISION_SUCCESS
| Event detail type for successful deprovisioning. |
+| DEPROVISION_FAILURE
| Event detail type for failed deprovisioning. |
+| BILLING_SUCCESS
| Event detail type for successful billing configuration. |
+| BILLING_FAILURE
| Event detail type for failure to configure billing. |
+| ACTIVATE_REQUEST
| Event detail type for activation request. |
+| ACTIVATE_SUCCESS
| Event detail type for successful activation. |
+| ACTIVATE_FAILURE
| Event detail type for failed activation. |
+| DEACTIVATE_REQUEST
| Event detail type for deactivation request. |
+| DEACTIVATE_SUCCESS
| Event detail type for successful deactivation. |
+| DEACTIVATE_FAILURE
| Event detail type for failed deactivation. |
+| TENANT_USER_CREATED
| Event detail type for user creation on the app-plane side. |
+| TENANT_USER_DELETED
| Event detail type for user deletion on the app-plane side. |
---
##### `ONBOARDING_REQUEST`
+Event detail type for onboarding request.
+
---
##### `ONBOARDING_SUCCESS`
+Event detail type for successful onboarding.
+
---
##### `ONBOARDING_FAILURE`
+Event detail type for failed onboarding.
+
---
##### `OFFBOARDING_REQUEST`
+Event detail type for offboarding request.
+
---
##### `OFFBOARDING_SUCCESS`
+Event detail type for successful offboarding.
+
---
##### `OFFBOARDING_FAILURE`
+Event detail type for failed offboarding.
+
---
##### `PROVISION_SUCCESS`
+Event detail type for successful provisioning.
+
---
##### `PROVISION_FAILURE`
+Event detail type for failed provisioning.
+
---
##### `DEPROVISION_SUCCESS`
+Event detail type for successful deprovisioning.
+
---
##### `DEPROVISION_FAILURE`
+Event detail type for failed deprovisioning.
+
---
##### `BILLING_SUCCESS`
+Event detail type for successful billing configuration.
+
---
##### `BILLING_FAILURE`
+Event detail type for failure to configure billing.
+
---
##### `ACTIVATE_REQUEST`
+Event detail type for activation request.
+
---
##### `ACTIVATE_SUCCESS`
+Event detail type for successful activation.
+
---
##### `ACTIVATE_FAILURE`
+Event detail type for failed activation.
+
---
##### `DEACTIVATE_REQUEST`
+Event detail type for deactivation request.
+
---
##### `DEACTIVATE_SUCCESS`
+Event detail type for successful deactivation.
+
---
##### `DEACTIVATE_FAILURE`
+Event detail type for failed deactivation.
+
+---
+
+
+##### `TENANT_USER_CREATED`
+
+Event detail type for user creation on the app-plane side.
+
+Note that sbt-aws components do not emit this event. This event
+should be emitted by the application plane.
+
+---
+
+
+##### `TENANT_USER_DELETED`
+
+Event detail type for user deletion on the app-plane side.
+
+Note that sbt-aws components do not emit this event. This event
+should be emitted by the application plane.
+
---
diff --git a/docs/public/README.md b/docs/public/README.md
index 7749d83..4039d14 100644
--- a/docs/public/README.md
+++ b/docs/public/README.md
@@ -551,16 +551,15 @@ The control plane emits this event any time it onboards a new tenant. This event
```json
{
- "Source": "sbt-control-plane-api",
- "DetailType": "Onboarding",
- "Detail": {
+ "source": "sbt-control-plane-api",
+ "detail-type": "Onboarding",
+ "detail": {
"tenantId": "guid string",
"tenantStatus": "see notes",
"tenantName": "tenant name",
"email": "admin@saas.com",
"isActive": "boolean"
- },
- "EventBusName": "sbt-event-bus"
+ }
}
```
@@ -576,13 +575,12 @@ Upon successful tenant provisioning, the Serverless SaaS reference architecture
```json
{
- "Source": "sbt-application-plane-api",
- "DetailType": "Onboarding",
- "Detail": {
+ "source": "sbt-application-plane-api",
+ "detail-type": "Onboarding",
+ "detail": {
"tenantConfig": "json string - see notes",
"tenantStatus": "Complete",
- },
- "EventBusName": "sbt-event-bus"
+ }
}
```
@@ -594,13 +592,12 @@ The control plane emits this event any time it offboards a tenant. At a minimum
```json
{
- "Source": "sbt-control-plane-api",
- "DetailType": "Offboarding",
- "Detail": {
+ "source": "sbt-control-plane-api",
+ "detail-type": "Offboarding",
+ "detail": {
"tenantId": "string",
"tier": "string",
- },
- "EventBusName": "sbt-event-bus"
+ }
}
```
@@ -612,12 +609,11 @@ The application plane emits this event upon completion of offboarding. Similar t
```json
{
- "Source": "sbt-application-plane-api",
- "DetailType": "Offboarding",
- "Detail": {
+ "source": "sbt-application-plane-api",
+ "detail-type": "Offboarding",
+ "detail": {
"tenantStatus": "Deleted",
- },
- "EventBusName": "sbt-event-bus"
+ }
}
```
diff --git a/resources/functions/tenant-management/index.py b/resources/functions/tenant-management/index.py
index e21a027..4119566 100644
--- a/resources/functions/tenant-management/index.py
+++ b/resources/functions/tenant-management/index.py
@@ -13,7 +13,6 @@
CORSConfig)
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools.event_handler.exceptions import (
- BadRequestError,
InternalServerError,
NotFoundError,
)
diff --git a/src/control-plane/auth/auth-interface.ts b/src/control-plane/auth/auth-interface.ts
index e91372f..030e82a 100644
--- a/src/control-plane/auth/auth-interface.ts
+++ b/src/control-plane/auth/auth-interface.ts
@@ -11,60 +11,60 @@ export interface IAuth {
/**
* Authorizer referenced by the ControlPlaneAPI
*/
- authorizer: IAuthorizer;
+ readonly authorizer: IAuthorizer;
/**
* Contains any information relevant to the IDP implementation required by the Authorizer and User Function implementations
*/
- controlPlaneIdpDetails: any;
+ readonly controlPlaneIdpDetails: any;
/**
* Authorization server Url
*/
- authorizationServer: string;
+ readonly authorizationServer: string;
/**
* The OAuth clientId for the identity provider
*/
- clientId: string;
+ readonly clientId: string;
/**
* OpenID configuration Url
*/
- wellKnownEndpointUrl: string;
+ readonly wellKnownEndpointUrl: string;
/**
* Function referenced by the ControlPlaneAPI -- POST /users
*/
- createUserFunction: IFunction;
+ readonly createUserFunction: IFunction;
/**
* Function referenced by the ControlPlaneAPI -- GET /users
*/
- fetchAllUsersFunction: IFunction; // use 'fetch*' instead of 'get*' to avoid error JSII5000
+ readonly fetchAllUsersFunction: IFunction; // use 'fetch*' instead of 'get*' to avoid error JSII5000
/**
* Function referenced by the ControlPlaneAPI -- GET /user/{username}
*/
- fetchUserFunction: IFunction; // use 'fetch*' instead of 'get*' to avoid error JSII5000
+ readonly fetchUserFunction: IFunction; // use 'fetch*' instead of 'get*' to avoid error JSII5000
/**
* Function referenced by the ControlPlaneAPI -- PUT /user/{username}
*/
- updateUserFunction: IFunction;
+ readonly updateUserFunction: IFunction;
/**
* Function referenced by the ControlPlaneAPI -- DELETE /user/{username}
*/
- deleteUserFunction: IFunction;
+ readonly deleteUserFunction: IFunction;
/**
* Function referenced by the ControlPlaneAPI -- PUT /user/{username}/disable
*/
- disableUserFunction: IFunction;
+ readonly disableUserFunction: IFunction;
/**
* Function referenced by the ControlPlaneAPI -- PUT /user/{username}/enable
*/
- enableUserFunction: IFunction;
+ readonly enableUserFunction: IFunction;
}
diff --git a/src/control-plane/auth/cognito-auth.ts b/src/control-plane/auth/cognito-auth.ts
index cb9dfcb..a07178d 100644
--- a/src/control-plane/auth/cognito-auth.ts
+++ b/src/control-plane/auth/cognito-auth.ts
@@ -17,29 +17,99 @@ import { NagSuppressions } from 'cdk-nag';
import { Construct } from 'constructs';
import { IAuth } from './auth-interface';
+/**
+ * Properties for the CognitoAuth construct.
+ */
export interface CognitoAuthProps {
+ /**
+ * The name of the Identity Provider (IdP) for the control plane.
+ */
readonly idpName: string;
+
+ /**
+ * The callback URL for the control plane. If not provided, defaults to 'http://localhost'.
+ * @default - 'http://localhost'
+ */
readonly controlPlaneCallbackURL?: string;
+
+ /**
+ * The name of the system admin role.
+ */
readonly systemAdminRoleName: string;
+
+ /**
+ * The email address of the system admin.
+ */
readonly systemAdminEmail: string;
}
+/**
+ * Constructs for setting up Cognito authentication and user management.
+ */
export class CognitoAuth extends Construct implements IAuth {
- authorizer: IAuthorizer;
- controlPlaneIdpDetails: any;
- authorizationServer: string;
- clientId: string;
- wellKnownEndpointUrl: string;
- createUserFunction: IFunction;
- fetchAllUsersFunction: IFunction;
- fetchUserFunction: IFunction;
- updateUserFunction: IFunction;
- deleteUserFunction: IFunction;
- disableUserFunction: IFunction;
- enableUserFunction: IFunction;
+ /**
+ * The API Gateway authorizer for authenticating requests.
+ */
+ public readonly authorizer: IAuthorizer;
+
+ /**
+ * The details of the control plane Identity Provider (IdP).
+ */
+ public readonly controlPlaneIdpDetails: any;
+
+ /**
+ * The authorization server for the control plane IdP.
+ */
+ public readonly authorizationServer: string;
+
+ /**
+ * The client ID for the control plane IdP.
+ */
+ public readonly clientId: string;
+
+ /**
+ * The well-known endpoint URL for the control plane IdP.
+ */
+ public readonly wellKnownEndpointUrl: string;
+
+ /**
+ * The Lambda function for creating a user.
+ */
+ public readonly createUserFunction: IFunction;
+
+ /**
+ * The Lambda function for fetching all users.
+ */
+ public readonly fetchAllUsersFunction: IFunction;
+
+ /**
+ * The Lambda function for fetching a user.
+ */
+ public readonly fetchUserFunction: IFunction;
+
+ /**
+ * The Lambda function for updating a user.
+ */
+ public readonly updateUserFunction: IFunction;
+
+ /**
+ * The Lambda function for deleting a user.
+ */
+ public readonly deleteUserFunction: IFunction;
+
+ /**
+ * The Lambda function for disabling a user.
+ */
+ public readonly disableUserFunction: IFunction;
+
+ /**
+ * The Lambda function for enabling a user.
+ */
+ public readonly enableUserFunction: IFunction;
constructor(scope: Construct, id: string, props: CognitoAuthProps) {
super(scope, id);
+
const defaultControlPlaneCallbackURL = 'http://localhost';
// https://docs.powertools.aws.dev/lambda/python/2.31.0/#lambda-layer
@@ -145,6 +215,7 @@ export class CognitoAuth extends Construct implements IAuth {
value: this.controlPlaneIdpDetails,
key: 'ControlPlaneIdpDetails',
});
+
const customAuthorizerFunction = new PythonFunction(this, 'CustomAuthorizerFunction', {
entry: path.join(__dirname, '../../../resources/functions/authorizer'),
runtime: Runtime.PYTHON_3_12,
diff --git a/src/control-plane/billing/billing-interface.ts b/src/control-plane/billing/billing-interface.ts
index bda4b03..de16705 100644
--- a/src/control-plane/billing/billing-interface.ts
+++ b/src/control-plane/billing/billing-interface.ts
@@ -1,34 +1,82 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
+import { Schedule } from 'aws-cdk-lib/aws-events';
import { IFunction } from 'aws-cdk-lib/aws-lambda';
+import { DetailType } from '../../utils';
import { IDataIngestorAggregator } from '../ingestor-aggregator/ingestor-aggregator-interface';
+/**
+ * Optional interface that allows specifying both
+ * the function to trigger and the event that will trigger it.
+ */
+export interface IFunctionTrigger {
+ /**
+ * The function definition.
+ */
+ readonly handler: IFunction;
+
+ /**
+ * The detail-type that will trigger the handler function.
+ */
+ readonly trigger: DetailType;
+}
+
+/**
+ * Optional interface that allows specifying both
+ * the function to trigger and the schedule by which to trigger it.
+ */
+export interface IFunctionSchedule {
+ /**
+ * The function definition.
+ */
+ readonly handler: IFunction;
+
+ /**
+ * The schedule that will trigger the handler function.
+ */
+ readonly schedule: Schedule;
+}
+
/**
* Encapsulates the list of properties for an IBilling construct.
*/
export interface IBilling {
/**
- * The function to trigger when creating a new billing user.
+ * The function to trigger to create a new customer.
+ * (Customer in this context is an entity that has zero or more Users.)
+ */
+ createCustomerFunction: IFunction | IFunctionTrigger;
+
+ /**
+ * The function to trigger to delete a customer.
+ * (Customer in this context is an entity that has zero or more Users.)
+ */
+ deleteCustomerFunction: IFunction | IFunctionTrigger;
+
+ /**
+ * The function to trigger to create a new user.
+ * (User in this context is an entity that belongs to a Customer.)
*/
- createUserFunction: IFunction;
+ createUserFunction?: IFunction | IFunctionTrigger;
/**
- * The function to trigger when deleting a billing user.
+ * The function to trigger to delete a user.
+ * (User in this context is an entity that belongs to a Customer.)
*/
- deleteUserFunction: IFunction;
+ deleteUserFunction?: IFunction | IFunctionTrigger;
/**
* The IDataIngestorAggregator responsible for accepting and aggregating
* the raw billing data.
*/
- ingestor: IDataIngestorAggregator;
+ ingestor?: IDataIngestorAggregator;
/**
* The function responsible for taking the aggregated data and pushing
* that to the billing provider.
*/
- putUsageFunction: IFunction;
+ putUsageFunction?: IFunction | IFunctionSchedule;
/**
* The function to trigger when a webhook request is received.
diff --git a/src/control-plane/billing/billing-provider.ts b/src/control-plane/billing/billing-provider.ts
index 48f08b0..a6520b0 100644
--- a/src/control-plane/billing/billing-provider.ts
+++ b/src/control-plane/billing/billing-provider.ts
@@ -5,9 +5,10 @@ import * as cdk from 'aws-cdk-lib';
import { IResource, Resource } from 'aws-cdk-lib/aws-apigateway';
import * as aws_events from 'aws-cdk-lib/aws-events';
import * as event_targets from 'aws-cdk-lib/aws-events-targets';
+import { IFunction } from 'aws-cdk-lib/aws-lambda';
import { NagSuppressions } from 'cdk-nag';
import { Construct } from 'constructs';
-import { IBilling } from './billing-interface';
+import { IBilling, IFunctionTrigger } from './billing-interface';
import { EventManager, DetailType } from '../../utils';
/**
@@ -31,29 +32,76 @@ export interface BillingProviderProps {
readonly controlPlaneAPIBillingResource: Resource;
}
+/**
+ * Represents a Billing Provider that handles billing-related operations.
+ *
+ * This construct sets up event targets for various billing-related events
+ * and optionally creates an API Gateway resource for a webhook function.
+ */
export class BillingProvider extends Construct {
/**
* The API Gateway resource containing the billing webhook resource.
* Only set when the IBilling webhookFunction is defined.
*/
public readonly controlPlaneAPIBillingWebhookResource?: IResource;
+
+ /**
+ * Creates a new instance of the BillingProvider construct.
+ *
+ * @param scope The scope in which to define this construct.
+ * @param id The unique ID of this construct.
+ * @param props The properties for the BillingProvider.
+ */
constructor(scope: Construct, id: string, props: BillingProviderProps) {
super(scope, id);
- props.eventManager.addTargetToEvent(
- DetailType.PROVISION_SUCCESS,
- new event_targets.LambdaFunction(props.billing.createUserFunction)
+ this.createEventTarget(
+ props.eventManager,
+ DetailType.ONBOARDING_REQUEST,
+ props.billing.createCustomerFunction
);
- props.eventManager.addTargetToEvent(
- DetailType.DEPROVISION_SUCCESS,
- new event_targets.LambdaFunction(props.billing.deleteUserFunction)
+ this.createEventTarget(
+ props.eventManager,
+ DetailType.OFFBOARDING_REQUEST,
+ props.billing.deleteCustomerFunction
);
- new aws_events.Rule(this, 'BillingPutUsageRule', {
- schedule: aws_events.Schedule.rate(cdk.Duration.hours(24)),
- targets: [new event_targets.LambdaFunction(props.billing.putUsageFunction)],
- });
+ this.createEventTarget(
+ props.eventManager,
+ DetailType.TENANT_USER_CREATED,
+ props.billing.createUserFunction
+ );
+
+ this.createEventTarget(
+ props.eventManager,
+ DetailType.TENANT_USER_DELETED,
+ props.billing.deleteUserFunction
+ );
+
+ if (props.billing.putUsageFunction) {
+ const schedule =
+ 'handler' in props.billing.putUsageFunction
+ ? props.billing.putUsageFunction.schedule
+ : aws_events.Schedule.rate(cdk.Duration.hours(24));
+
+ const handler =
+ 'handler' in props.billing.putUsageFunction
+ ? props.billing.putUsageFunction.handler
+ : props.billing.putUsageFunction;
+
+ new aws_events.Rule(this, 'BillingPutUsageRule', {
+ schedule: schedule,
+ targets: [new event_targets.LambdaFunction(handler)],
+ });
+ }
+
+ if (props.billing.ingestor) {
+ new cdk.CfnOutput(this, 'DataIngestorName', {
+ value: props.billing.ingestor.dataIngestorName,
+ key: 'dataIngestorName',
+ });
+ }
if (props.billing.webhookFunction && props.billing.webhookPath) {
this.controlPlaneAPIBillingWebhookResource = props.controlPlaneAPIBillingResource.addResource(
@@ -84,4 +132,26 @@ export class BillingProvider extends Construct {
);
}
}
+
+ private getFunctionProps(
+ fn: IFunction | IFunctionTrigger,
+ defaultTrigger: DetailType
+ ): IFunctionTrigger {
+ return 'handler' in fn
+ ? { handler: fn.handler, trigger: fn.trigger }
+ : { handler: fn, trigger: defaultTrigger };
+ }
+
+ private createEventTarget(
+ eventManager: EventManager,
+ defaultEvent: DetailType,
+ fn?: IFunction | IFunctionTrigger
+ ) {
+ if (!fn) {
+ return;
+ }
+
+ const { handler, trigger } = this.getFunctionProps(fn, defaultEvent);
+ eventManager.addTargetToEvent(trigger, new event_targets.LambdaFunction(handler));
+ }
}
diff --git a/src/utils/event-manager.ts b/src/utils/event-manager.ts
index 256a443..338ba8b 100644
--- a/src/utils/event-manager.ts
+++ b/src/utils/event-manager.ts
@@ -5,43 +5,115 @@ import { IEventBus, Rule, IRuleTarget } from 'aws-cdk-lib/aws-events';
import { Construct } from 'constructs';
/**
- * Provides an easy way of accessing event DetailTypes.
- * Note that the string represents the detailTypes used in
+ * Provides an easy way of accessing event detail types.
+ * The string values represent the "detail-type" used in
* events sent across the EventBus.
*/
export enum DetailType {
+ /**
+ * Event detail type for onboarding request.
+ */
ONBOARDING_REQUEST = 'onboardingRequest',
+ /**
+ * Event detail type for successful onboarding.
+ */
ONBOARDING_SUCCESS = 'onboardingSuccess',
+ /**
+ * Event detail type for failed onboarding.
+ */
ONBOARDING_FAILURE = 'onboardingFailure',
+
+ /**
+ * Event detail type for offboarding request.
+ */
OFFBOARDING_REQUEST = 'offboardingRequest',
+ /**
+ * Event detail type for successful offboarding.
+ */
OFFBOARDING_SUCCESS = 'offboardingSuccess',
+ /**
+ * Event detail type for failed offboarding.
+ */
OFFBOARDING_FAILURE = 'offboardingFailure',
+
+ /**
+ * Event detail type for successful provisioning.
+ */
PROVISION_SUCCESS = 'provisionSuccess',
+ /**
+ * Event detail type for failed provisioning.
+ */
PROVISION_FAILURE = 'provisionFailure',
+
+ /**
+ * Event detail type for successful deprovisioning.
+ */
DEPROVISION_SUCCESS = 'deprovisionSuccess',
+ /**
+ * Event detail type for failed deprovisioning.
+ */
DEPROVISION_FAILURE = 'deprovisionFailure',
+
+ /**
+ * Event detail type for successful billing configuration.
+ */
BILLING_SUCCESS = 'billingSuccess',
+ /**
+ * Event detail type for failure to configure billing.
+ */
BILLING_FAILURE = 'billingFailure',
+
+ /**
+ * Event detail type for activation request.
+ */
ACTIVATE_REQUEST = 'activateRequest',
+ /**
+ * Event detail type for successful activation.
+ */
ACTIVATE_SUCCESS = 'activateSuccess',
+ /**
+ * Event detail type for failed activation.
+ */
ACTIVATE_FAILURE = 'activateFailure',
+
+ /**
+ * Event detail type for deactivation request.
+ */
DEACTIVATE_REQUEST = 'deactivateRequest',
+ /**
+ * Event detail type for successful deactivation.
+ */
DEACTIVATE_SUCCESS = 'deactivateSuccess',
+ /**
+ * Event detail type for failed deactivation.
+ */
DEACTIVATE_FAILURE = 'deactivateFailure',
+
+ /**
+ * Event detail type for user creation on the app-plane side.
+ * Note that sbt-aws components do not emit this event. This event
+ * should be emitted by the application plane.
+ */
+ TENANT_USER_CREATED = 'tenantUserCreated',
+ /**
+ * Event detail type for user deletion on the app-plane side.
+ * Note that sbt-aws components do not emit this event. This event
+ * should be emitted by the application plane.
+ */
+ TENANT_USER_DELETED = 'tenantUserDeleted',
}
/**
- * Represents mapping between 'detailType' as key,
- * and 'source' as value.
+ * Represents a mapping between 'detailType' as the key and 'source' as the value.
*/
export type EventMetadata = {
- // key: Event 'detailType' -> val: Event 'source'
+ // key: Event 'detailType' -> value: Event 'source'
[key: string]: string;
// [key in DetailType]: string; // Causes this error: Only string-indexed map types are supported
};
/**
- * Encapsulates the list of properties for an eventManager.
+ * Encapsulates the properties for an EventManager.
*/
export interface EventManagerProps {
/**
@@ -66,37 +138,28 @@ export interface EventManagerProps {
}
/**
- * Provides an EventManager to help interact with the EventBus shared with the SBT control plane.
+ * Provides an EventManager to interact with the EventBus shared with the SBT control plane.
*/
export class EventManager extends Construct {
+ /**
+ * The event source used for events emitted by the application plane.
+ * @default
+ */
public readonly applicationPlaneEventSource: string = 'applicationPlaneEventSource';
+
+ /**
+ * The event source used for events emitted by the control plane.
+ * @default
+ */
public readonly controlPlaneEventSource: string = 'controlPlaneEventSource';
- // sensible defaults so they are not required when instantiating control plane
-
- public readonly supportedEvents: EventMetadata = {
- onboardingRequest: this.controlPlaneEventSource,
- onboardingSuccess: this.applicationPlaneEventSource,
- onboardingFailure: this.applicationPlaneEventSource,
- offboardingRequest: this.controlPlaneEventSource,
- offboardingSuccess: this.applicationPlaneEventSource,
- offboardingFailure: this.applicationPlaneEventSource,
- provisionSuccess: this.applicationPlaneEventSource,
- provisionFailure: this.applicationPlaneEventSource,
- deprovisionSuccess: this.applicationPlaneEventSource,
- deprovisionFailure: this.applicationPlaneEventSource,
- billingSuccess: this.controlPlaneEventSource,
- billingFailure: this.controlPlaneEventSource,
- activateRequest: this.controlPlaneEventSource,
- activateSuccess: this.applicationPlaneEventSource,
- activateFailure: this.applicationPlaneEventSource,
- deactivateRequest: this.controlPlaneEventSource,
- deactivateSuccess: this.applicationPlaneEventSource,
- deactivateFailure: this.applicationPlaneEventSource,
- };
+
+ /**
+ * List of recognized events that are available as triggers.
+ */
+ public readonly supportedEvents: EventMetadata;
/**
* The event bus to register new rules with.
- * @attribute
*/
public readonly eventBus: IEventBus;
@@ -110,6 +173,27 @@ export class EventManager extends Construct {
props.applicationPlaneEventSource || this.applicationPlaneEventSource;
this.controlPlaneEventSource = props.controlPlaneEventSource || this.controlPlaneEventSource;
+ this.supportedEvents = {
+ onboardingRequest: this.controlPlaneEventSource,
+ onboardingSuccess: this.applicationPlaneEventSource,
+ onboardingFailure: this.applicationPlaneEventSource,
+ offboardingRequest: this.controlPlaneEventSource,
+ offboardingSuccess: this.applicationPlaneEventSource,
+ offboardingFailure: this.applicationPlaneEventSource,
+ provisionSuccess: this.applicationPlaneEventSource,
+ provisionFailure: this.applicationPlaneEventSource,
+ deprovisionSuccess: this.applicationPlaneEventSource,
+ deprovisionFailure: this.applicationPlaneEventSource,
+ billingSuccess: this.controlPlaneEventSource,
+ billingFailure: this.controlPlaneEventSource,
+ activateRequest: this.controlPlaneEventSource,
+ activateSuccess: this.applicationPlaneEventSource,
+ activateFailure: this.applicationPlaneEventSource,
+ deactivateRequest: this.controlPlaneEventSource,
+ deactivateSuccess: this.applicationPlaneEventSource,
+ deactivateFailure: this.applicationPlaneEventSource,
+ };
+
for (const key in this.supportedEvents) {
// update this.eventMetadata with any values passed in via props
if (props.eventMetadata && props.eventMetadata[key]) {
@@ -121,7 +205,7 @@ export class EventManager extends Construct {
/**
* Adds an IRuleTarget to an event.
*
- * @param eventType The name of the event to add a target to.
+ * @param eventType The detail type of the event to add a target to.
* @param target The target that will be added to the event.
*/
public addTargetToEvent(eventType: DetailType, target: IRuleTarget): void {