Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to authenticate to secure assets #101

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,15 @@ Below are the available commands:

### Examples

**Backing up All Data from an Environment with Secure Asset Delivery Enabled**

```bash
npx @kontent-ai/data-ops@latest environment backup \
--environmentId <environment-id> \
--apiKey <Management-API-key> \
--secureAssetDeliveryKey=<Secure-Asset-Delivery-API-key>
```

**Creating an Environment Backup including Content Items and Assets**

```bash
Expand Down
44 changes: 28 additions & 16 deletions src/commands/environment/backupRestore/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@ npx @kontent-ai/data-ops@latest environment backup --help

### Parameters

| Parameter | Description |
|-------------------|-----------------------------------------------------------------------------------|
| `--environmentId` | The ID of the environment you want to backup. |
| `--apiKey` | The Management API key for the environment. |
| `--fileName` | (Optional) The name of the output `.zip` file. Default is `backup.zip`. |
| `--include` | (Optional) Specify entities to include in the backup. |
| `--exclude` | (Optional) Specify entities to exclude from the backup. |
| `--configFile` | (Optional) Path to a JSON configuration file containing parameters. |
| Parameter | Description |
| -------------------------- | ----------------------------------------------------------------------- |
| `--environmentId` | The ID of the environment you want to backup. |
| `--apiKey` | The Management API key for the environment. |
| `--secureAssetDeliveryKey` | (Optional) The secure asset delivery API key for the environment.<br />Read more about enabling secure asset delivery in the [Kontent.ai documentation](https://kontent.ai/learn/docs/security/secure-access/javascript#a-retrieve-assets-securely). |
| `--fileName` | (Optional) The name of the output `.zip` file. Default is `backup.zip`. |
| `--include` | (Optional) Specify entities to include in the backup. |
| `--exclude` | (Optional) Specify entities to exclude from the backup. |
| `--configFile` | (Optional) Path to a JSON configuration file containing parameters. |

### Examples

Expand All @@ -77,6 +78,15 @@ npx @kontent-ai/data-ops@latest environment backup \
--exclude roles
```

**Backing up All Data from an Environment with Secure Asset Delivery Enabled**

```bash
npx @kontent-ai/data-ops@latest environment backup \
--environmentId=<environment-id> \
--apiKey=<Management-API-key> \
--secureAssetDeliveryKey=<Secure-Asset-Delivery-API-key>
```

### Backup Programmatically

To backup data from an environment in your scripts, use the `backupEnvironment` function:
Expand All @@ -89,6 +99,8 @@ const params: BackupEnvironmentParams = {
apiKey: "<mapi-key>",
// Optional: specify output file name
// fileName: "backup.zip",
// Optional: specify secure asset delivery API key
// secureAssetDeliveryKey: "<secure-asset-delivery-api-key>",
// Optional: include or exclude specific entities
// include: ["contentItems", "assets"],
// exclude: ["roles"],
Expand Down Expand Up @@ -154,14 +166,14 @@ npx @kontent-ai/data-ops@latest environment restore --fileName <file-to-restore>

### Parameters

| Parameter | Description |
|-------------------|----------------------------------------------------------------------------|
| `--fileName` | The path to the `.zip` file containing the data to restore. |
| `--environmentId` | The ID of the target environment where you want to restore data to. |
| `--apiKey` | The Management API key for the target environment. |
| `--include` | (Optional) Specify entities to restore. |
| `--exclude` | (Optional) Specify entities to exclude from the restore. |
| `--configFile` | (Optional) Path to a JSON configuration file containing parameters. |
| Parameter | Description |
| ----------------- | ------------------------------------------------------------------- |
| `--fileName` | The path to the `.zip` file containing the data to restore. |
| `--environmentId` | The ID of the target environment where you want to restore data to. |
| `--apiKey` | The Management API key for the target environment. |
| `--include` | (Optional) Specify entities to restore. |
| `--exclude` | (Optional) Specify entities to exclude from the restore. |
| `--configFile` | (Optional) Path to a JSON configuration file containing parameters. |

### Examples

Expand Down
6 changes: 6 additions & 0 deletions src/commands/environment/backupRestore/backup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ export const register: RegisterCommand = yargs =>
demandOption: "You need to provide a Management API key for the given Kontent.ai environment.",
alias: "k",
})
.option("secureAssetDeliveryKey", {
type: "string",
describe:
"You need to provide a asset delivery key when secure asset delivery is enabled for the given Kontent.ai environment.",
})
.option("include", {
type: "array",
describe: "Only back up specified entities.",
Expand All @@ -62,6 +67,7 @@ type BackupEnvironmentCliParams =
environmentId: string;
fileName: string | undefined;
apiKey: string;
secureAssetDeliveryKey: string | undefined;
include: ReadonlyArray<BackupEntityChoices> | undefined;
exclude: ReadonlyArray<BackupEntityChoices> | undefined;
kontentUrl: string | undefined;
Expand Down
8 changes: 7 additions & 1 deletion src/modules/backupRestore/backup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export type BackupEnvironmentParams = Readonly<
environmentId: string;
fileName?: string;
apiKey: string;
secureAssetDeliveryKey?: string;
kontentUrl?: string;
}
& IncludeExclude<BackupEntityChoices>
Expand Down Expand Up @@ -101,7 +102,12 @@ export const backupEnvironmentInternal = async (

try {
const entities = await def.fetchEntities(client);
await (def as EntityDefinition<unknown>).addOtherFiles?.(entities, archive, params);
await (def as EntityDefinition<unknown>).addOtherFiles?.(
entities,
archive,
params,
params.secureAssetDeliveryKey,
);
const result = def.serializeEntities(entities);

archive.append(result, { name: `${def.name}.json` });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ export const assetsEntity = {
fetchEntities: client =>
client.listAssets().toAllPromise().then(res => res.data.items.map(a => a._raw as AssetWithElements)),
serializeEntities: JSON.stringify,
addOtherFiles: async (assets, archive, logOptions) => {
await serially(assets.map(a => () => saveAsset(archive, logOptions, a)));
addOtherFiles: async (assets, archive, logOptions, secureAssetDeliveryKey) => {
await serially(assets.map(a => () => saveAsset(archive, logOptions, a, secureAssetDeliveryKey)));
},
deserializeEntities: JSON.parse,
importEntities: async (client, fileAssets, context, logOptions, zip) => {
Expand Down Expand Up @@ -69,9 +69,14 @@ const saveAsset = async (
archive: archiver.Archiver,
logOptions: LogOptions,
asset: AssetContracts.IAssetModelContract,
secureAssetDeliveryKey: string | undefined,
) => {
logInfo(logOptions, "verbose", `Exporting: file ${chalk.yellow(asset.file_name)}.`);
const file = await fetch(asset.url).then(res => res.blob()).then(res => res.stream());
const defaultOptions: RequestInit = {
headers: secureAssetDeliveryKey ? { Authorization: `Bearer ${secureAssetDeliveryKey}` } : undefined,
};
const file = await fetch(asset.url, defaultOptions)
.then(res => res.blob()).then(res => res.stream());
archive.append(stream.Readable.fromWeb(file), { name: createFileName(asset) });
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ export type EntityBackupDefinition<T> = Readonly<{
displayName: string;
fetchEntities: (client: ManagementClient) => Promise<T>;
serializeEntities: (entities: T) => string;
addOtherFiles?: (loadedEntities: T, archive: archiver.Archiver, logOptions: LogOptions) => Promise<void>;
addOtherFiles?: (
loadedEntities: T,
archive: archiver.Archiver,
logOptions: LogOptions,
secureAssetDeliveryKey: string | undefined,
) => Promise<void>;
}>;

export type EntityRestoreDefinition<T> = Readonly<{
Expand All @@ -29,11 +34,7 @@ export type EntityRestoreDefinition<T> = Readonly<{

export type EntityCleanDefinition<T> = Readonly<{
name: string;
cleanEntities: (
client: ManagementClient,
entities: T,
logOptions: LogOptions,
) => Promise<void>;
cleanEntities: (client: ManagementClient, entities: T, logOptions: LogOptions) => Promise<void>;
}>;

export type DependentRestoreAction<T> = Readonly<{
Expand Down
Loading