@squiz/dxp-cli-next 5.9.0 → 5.10.0-develop.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/__tests__/integration/main.spec.js +1 -0
- package/lib/datastore/blueprint/add/add.d.ts +3 -0
- package/lib/datastore/blueprint/add/add.js +109 -0
- package/lib/datastore/blueprint/add/add.spec.d.ts +1 -0
- package/lib/datastore/blueprint/add/add.spec.js +82 -0
- package/lib/datastore/blueprint/blueprintCommand.d.ts +3 -0
- package/lib/datastore/blueprint/blueprintCommand.js +21 -0
- package/lib/datastore/blueprint/list/list.d.ts +3 -0
- package/lib/datastore/blueprint/list/list.js +74 -0
- package/lib/datastore/blueprint/list/list.spec.d.ts +1 -0
- package/lib/datastore/blueprint/list/list.spec.js +50 -0
- package/lib/datastore/blueprint/rename/rename.d.ts +3 -0
- package/lib/datastore/blueprint/rename/rename.js +83 -0
- package/lib/datastore/blueprint/rename/rename.spec.d.ts +1 -0
- package/lib/datastore/blueprint/rename/rename.spec.js +92 -0
- package/lib/datastore/blueprint/update/update.d.ts +3 -0
- package/lib/datastore/blueprint/update/update.js +87 -0
- package/lib/datastore/blueprint/update/update.spec.d.ts +1 -0
- package/lib/datastore/blueprint/update/update.spec.js +99 -0
- package/lib/datastore/bundle/bundle.d.ts +3 -0
- package/lib/datastore/bundle/bundle.js +174 -0
- package/lib/datastore/bundle/bundle.spec.d.ts +1 -0
- package/lib/datastore/bundle/bundle.spec.js +93 -0
- package/lib/datastore/index.d.ts +3 -0
- package/lib/datastore/index.js +16 -0
- package/lib/datastore/simulator/add/add.d.ts +3 -0
- package/lib/datastore/simulator/add/add.js +138 -0
- package/lib/datastore/simulator/add/add.spec.d.ts +1 -0
- package/lib/datastore/simulator/add/add.spec.js +123 -0
- package/lib/datastore/simulator/remove/remove.d.ts +3 -0
- package/lib/datastore/simulator/remove/remove.js +68 -0
- package/lib/datastore/simulator/remove/remove.spec.d.ts +1 -0
- package/lib/datastore/simulator/remove/remove.spec.js +224 -0
- package/lib/datastore/simulator/simulatorCommand.d.ts +3 -0
- package/lib/datastore/simulator/simulatorCommand.js +17 -0
- package/lib/datastore/simulator/utils.d.ts +22 -0
- package/lib/datastore/simulator/utils.js +197 -0
- package/lib/datastore/simulator/utils.spec.d.ts +1 -0
- package/lib/datastore/simulator/utils.spec.js +165 -0
- package/lib/datastore/utils.d.ts +18 -0
- package/lib/datastore/utils.js +229 -0
- package/lib/datastore/utils.spec.d.ts +1 -0
- package/lib/datastore/utils.spec.js +92 -0
- package/lib/dxp.js +2 -0
- package/package.json +6 -4
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const commander_1 = require("commander");
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const ora_1 = __importDefault(require("ora"));
|
|
18
|
+
const ApiService_1 = require("../../../ApiService");
|
|
19
|
+
const utils_1 = require("../../utils");
|
|
20
|
+
const createAddCommand = () => {
|
|
21
|
+
const addCommand = new commander_1.Command('add')
|
|
22
|
+
.name('add')
|
|
23
|
+
.description('Adds a new blueprint')
|
|
24
|
+
.addOption(new commander_1.Option('-t, --tenant <string>', 'Tenant ID to run against. If not provided will use configured tenant from login'))
|
|
25
|
+
.addOption(new commander_1.Option('-p, --path <string>', 'Path to your blueprint API yaml file e.g. documents/inputs/blueprint.yaml').makeOptionMandatory())
|
|
26
|
+
.addOption(new commander_1.Option('-n, --name <string>', 'Name for your blueprint e.g. MyFirstBlueprint').makeOptionMandatory())
|
|
27
|
+
.addOption(new commander_1.Option('-r, --region <string>', 'Region for your blueprint to be deployed yo e.g. au')
|
|
28
|
+
.choices(['au', 'uk', 'us'])
|
|
29
|
+
.makeOptionMandatory())
|
|
30
|
+
.configureOutput({
|
|
31
|
+
outputError(str, write) {
|
|
32
|
+
write(chalk_1.default.red(str));
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
|
+
yield (0, utils_1.throwErrorIfNotLoggedIn)(addCommand);
|
|
37
|
+
console.log('');
|
|
38
|
+
const spinner = (0, ora_1.default)('Please wait (5 minutes) while our cloud builds this for you.').start();
|
|
39
|
+
let input;
|
|
40
|
+
try {
|
|
41
|
+
const apiService = new ApiService_1.ApiService(utils_1.validateAxiosStatus);
|
|
42
|
+
(0, utils_1.logDebug)('Checking blueprint limit');
|
|
43
|
+
// Check if we are at the blueprint limit.
|
|
44
|
+
const dxpTenantResp = yield apiService.client.get(yield (0, utils_1.buildOrganisationUrl)(options.tenant, options.overrideUrl));
|
|
45
|
+
(0, utils_1.logDebug)(`Blueprint limit response: ${JSON.stringify(dxpTenantResp.data)}`);
|
|
46
|
+
if (dxpTenantResp.data.numberOfDatastoreInstances &&
|
|
47
|
+
dxpTenantResp.data.numberOfDatastoreInstances + 1 >
|
|
48
|
+
dxpTenantResp.data.maximumDatastoreInstances) {
|
|
49
|
+
let limitError = 'Sorry. You are currently limited to ';
|
|
50
|
+
limitError += `${dxpTenantResp.data.maximumDatastoreInstances} blueprint for this customer.`;
|
|
51
|
+
limitError += ' Please speak to your account owner to enable more';
|
|
52
|
+
if (dxpTenantResp.data.maximumDatastoreInstances > 1) {
|
|
53
|
+
limitError = 'Sorry. You are currently limited to ';
|
|
54
|
+
limitError += `${dxpTenantResp.data.maximumDatastoreInstances} blueprints for this customer.`;
|
|
55
|
+
limitError += ' Please speak to your account owner to enable more.';
|
|
56
|
+
}
|
|
57
|
+
throw new Error(limitError);
|
|
58
|
+
}
|
|
59
|
+
// Bundle the blueprint.
|
|
60
|
+
input = yield (0, utils_1.bundleBlueprint)(options.path, true);
|
|
61
|
+
const blueprintFile = Buffer.from(input).toString('base64');
|
|
62
|
+
// Create the instance in the DXP console.
|
|
63
|
+
const datastoreInstanceReq = {
|
|
64
|
+
blueprintFile,
|
|
65
|
+
name: options.name,
|
|
66
|
+
region: options.region,
|
|
67
|
+
type: 'datastore',
|
|
68
|
+
};
|
|
69
|
+
(0, utils_1.logDebug)('Creating new blueprint');
|
|
70
|
+
const datastoreInstanceResp = yield apiService.client.post(yield (0, utils_1.buildInstanceUrl)(options.tenant, undefined, options.overrideUrl, false), datastoreInstanceReq);
|
|
71
|
+
(0, utils_1.logDebug)(`Creating blueprint instance: ${JSON.stringify(datastoreInstanceResp.data)}`);
|
|
72
|
+
if (datastoreInstanceResp.data.message) {
|
|
73
|
+
let errorMsg = '';
|
|
74
|
+
if (datastoreInstanceResp.data.message.startsWith('Error') &&
|
|
75
|
+
datastoreInstanceResp.data.message.toLowerCase() ===
|
|
76
|
+
'error: name is not unique') {
|
|
77
|
+
errorMsg =
|
|
78
|
+
'That blueprint name is already taken. Try renaming to something else.';
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
errorMsg = `Failed to add blueprint for "${options.name}" - "${options.path}".`;
|
|
82
|
+
}
|
|
83
|
+
throw new Error(errorMsg);
|
|
84
|
+
}
|
|
85
|
+
// Deploy the instance.
|
|
86
|
+
(0, utils_1.logDebug)('Starting deploy');
|
|
87
|
+
const deployResp = yield apiService.client.post(yield (0, utils_1.buildInstanceUrl)(options.tenant, datastoreInstanceResp.data.instanceId, options.overrideUrl, true));
|
|
88
|
+
(0, utils_1.logDebug)(`Deploying blueprint: ${JSON.stringify(deployResp.data)}`);
|
|
89
|
+
const createdInstance = yield (0, utils_1.checkDeploymentStatus)(apiService, options.tenant, datastoreInstanceResp.data.instanceId, options.overrideUrl);
|
|
90
|
+
spinner.succeed('Done! Use these details for production querying:');
|
|
91
|
+
console.log('');
|
|
92
|
+
console.log(` URL: ${createdInstance.deploymentUrl}`);
|
|
93
|
+
console.log(` Secret Key: ${createdInstance.secretKey}`);
|
|
94
|
+
console.log(` Region: ${createdInstance.region}`);
|
|
95
|
+
console.log('');
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
(0, utils_1.logDebug)(`ERROR: ${JSON.stringify(error)}`);
|
|
100
|
+
spinner.fail();
|
|
101
|
+
(0, utils_1.handleCommandError)(addCommand, error);
|
|
102
|
+
}
|
|
103
|
+
}));
|
|
104
|
+
if (process.env.ENABLE_OVERRIDE_DATASTORE_URL === 'true') {
|
|
105
|
+
addCommand.addOption(new commander_1.Option('-ou, --overrideUrl <string>', 'Developer option to override the entire DXP url with a custom value'));
|
|
106
|
+
}
|
|
107
|
+
return addCommand;
|
|
108
|
+
};
|
|
109
|
+
exports.default = createAddCommand;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const nock_1 = __importDefault(require("nock"));
|
|
16
|
+
const add_1 = __importDefault(require("./add"));
|
|
17
|
+
const utils_1 = require("../../utils");
|
|
18
|
+
const logSpy = jest.spyOn(global.console, 'log');
|
|
19
|
+
describe('datastoreBlueprintAdd', () => {
|
|
20
|
+
process.env.ENABLE_OVERRIDE_DATASTORE_URL = 'true';
|
|
21
|
+
it('correctly adds a blueprint', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
+
(0, nock_1.default)('http://localhost:9999')
|
|
23
|
+
.get('/__dxp/au/dxp/tenants/myTenant')
|
|
24
|
+
.reply(200, {
|
|
25
|
+
numberOfDatastoreInstances: 1,
|
|
26
|
+
maximumDatastoreInstances: 2,
|
|
27
|
+
});
|
|
28
|
+
(0, nock_1.default)('http://localhost:9999')
|
|
29
|
+
.post('/__dxp/au/dxp/tenants/myTenant/instances', {
|
|
30
|
+
blueprintFile: /.+/i,
|
|
31
|
+
name: 'myBlueprint',
|
|
32
|
+
region: 'au',
|
|
33
|
+
type: 'datastore',
|
|
34
|
+
})
|
|
35
|
+
.reply(200, {
|
|
36
|
+
instanceId: 'mock-instance-id',
|
|
37
|
+
});
|
|
38
|
+
(0, nock_1.default)('http://localhost:9999')
|
|
39
|
+
.post('/__dxp/au/dxp/tenants/myTenant/instances/mock-instance-id/_deploy')
|
|
40
|
+
.reply(200, {
|
|
41
|
+
instanceId: 'mock-instance-id',
|
|
42
|
+
});
|
|
43
|
+
(0, nock_1.default)('http://localhost:9999')
|
|
44
|
+
.get('/__dxp/au/dxp/tenants/myTenant/instances/mock-instance-id')
|
|
45
|
+
.reply(200, {
|
|
46
|
+
status: {
|
|
47
|
+
code: utils_1.CONSOLE_STATUS_CODE_LIVE,
|
|
48
|
+
},
|
|
49
|
+
deploymentUrl: 'https://au-12345678.datastore.squiz.cloud',
|
|
50
|
+
secretKey: 'secretKey',
|
|
51
|
+
region: 'au',
|
|
52
|
+
});
|
|
53
|
+
const program = (0, add_1.default)();
|
|
54
|
+
yield program.parseAsync([
|
|
55
|
+
'node',
|
|
56
|
+
'dxp-cli',
|
|
57
|
+
'datastore',
|
|
58
|
+
'blueprint',
|
|
59
|
+
'add',
|
|
60
|
+
'-t',
|
|
61
|
+
'myTenant',
|
|
62
|
+
'-p',
|
|
63
|
+
'./src/__tests__/datastore/blueprints/blueprint.yaml',
|
|
64
|
+
'-n',
|
|
65
|
+
'myBlueprint',
|
|
66
|
+
'-r',
|
|
67
|
+
'au',
|
|
68
|
+
'-ou',
|
|
69
|
+
'http://localhost:9999',
|
|
70
|
+
]);
|
|
71
|
+
const opts = program.opts();
|
|
72
|
+
expect(opts.tenant).toEqual('myTenant');
|
|
73
|
+
expect(opts.overrideUrl).toEqual('http://localhost:9999');
|
|
74
|
+
expect(logSpy).toHaveBeenCalledTimes(6);
|
|
75
|
+
expect(logSpy).toHaveBeenCalledWith('');
|
|
76
|
+
expect(logSpy).toHaveBeenCalledWith('');
|
|
77
|
+
expect(logSpy).toHaveBeenCalledWith(' URL: https://au-12345678.datastore.squiz.cloud');
|
|
78
|
+
expect(logSpy).toHaveBeenCalledWith(' Secret Key: secretKey');
|
|
79
|
+
expect(logSpy).toHaveBeenCalledWith(' Region: au');
|
|
80
|
+
expect(logSpy).toHaveBeenCalledWith('');
|
|
81
|
+
}));
|
|
82
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const commander_1 = require("commander");
|
|
7
|
+
const add_1 = __importDefault(require("./add/add"));
|
|
8
|
+
const update_1 = __importDefault(require("./update/update"));
|
|
9
|
+
const list_1 = __importDefault(require("./list/list"));
|
|
10
|
+
const rename_1 = __importDefault(require("./rename/rename"));
|
|
11
|
+
const createBlueprintCommand = () => {
|
|
12
|
+
const datastoreBlueprintCommand = new commander_1.Command('blueprint');
|
|
13
|
+
datastoreBlueprintCommand
|
|
14
|
+
.description('Datastore Blueprint Commands')
|
|
15
|
+
.addCommand((0, add_1.default)())
|
|
16
|
+
.addCommand((0, update_1.default)())
|
|
17
|
+
.addCommand((0, list_1.default)())
|
|
18
|
+
.addCommand((0, rename_1.default)());
|
|
19
|
+
return datastoreBlueprintCommand;
|
|
20
|
+
};
|
|
21
|
+
exports.default = createBlueprintCommand;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const commander_1 = require("commander");
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const ora_1 = __importDefault(require("ora"));
|
|
18
|
+
const ApiService_1 = require("../../../ApiService");
|
|
19
|
+
const utils_1 = require("../../utils");
|
|
20
|
+
const createListCommand = () => {
|
|
21
|
+
const listCommand = new commander_1.Command('list')
|
|
22
|
+
.name('list')
|
|
23
|
+
.description('lists the blueprint')
|
|
24
|
+
.addOption(new commander_1.Option('-t, --tenant <string>', 'Tenant ID to run against. If not provided will use configured tenant from login'))
|
|
25
|
+
.configureOutput({
|
|
26
|
+
outputError(str, write) {
|
|
27
|
+
write(chalk_1.default.red(str));
|
|
28
|
+
},
|
|
29
|
+
})
|
|
30
|
+
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
31
|
+
yield (0, utils_1.throwErrorIfNotLoggedIn)(listCommand);
|
|
32
|
+
console.log('');
|
|
33
|
+
const spinner = (0, ora_1.default)('Gathering details for all cloud blueprints.').start();
|
|
34
|
+
let input;
|
|
35
|
+
try {
|
|
36
|
+
const apiService = new ApiService_1.ApiService(utils_1.validateAxiosStatus);
|
|
37
|
+
(0, utils_1.logDebug)('Checking blueprint limit');
|
|
38
|
+
const datastoreInstanceResp = yield apiService.client.get(yield (0, utils_1.buildDatastoreInstancesUrl)(options.tenant, options.overrideUrl));
|
|
39
|
+
(0, utils_1.logDebug)(`Listing blueprint instance: ${JSON.stringify(datastoreInstanceResp.data)}`);
|
|
40
|
+
if (datastoreInstanceResp.data.length == 0) {
|
|
41
|
+
spinner.succeed('No cloud blueprints found. Try adding a blueprint first.');
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
spinner.succeed('Done! Listing cloud blueprints:');
|
|
45
|
+
datastoreInstanceResp.data.map((instance, index) => {
|
|
46
|
+
console.log('');
|
|
47
|
+
console.log(` Name: ${instance.name}`);
|
|
48
|
+
console.log(` URL: ${instance.deploymentUrl}`);
|
|
49
|
+
console.log(` Secret Key: ${instance.secretKey}`);
|
|
50
|
+
console.log(` Region: ${instance.region}`);
|
|
51
|
+
console.log('');
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (datastoreInstanceResp.data.message) {
|
|
55
|
+
let errorMsg = '';
|
|
56
|
+
if (datastoreInstanceResp.data.message.startsWith('Error')) {
|
|
57
|
+
errorMsg = 'Failed to list blueprint';
|
|
58
|
+
}
|
|
59
|
+
throw new Error(errorMsg);
|
|
60
|
+
}
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
(0, utils_1.logDebug)(`ERROR: ${JSON.stringify(error)}`);
|
|
65
|
+
spinner.fail();
|
|
66
|
+
(0, utils_1.handleCommandError)(listCommand, error);
|
|
67
|
+
}
|
|
68
|
+
}));
|
|
69
|
+
if (process.env.ENABLE_OVERRIDE_DATASTORE_URL === 'true') {
|
|
70
|
+
listCommand.addOption(new commander_1.Option('-ou, --overrideUrl <string>', 'Developer option to override the entire DXP url with a custom value'));
|
|
71
|
+
}
|
|
72
|
+
return listCommand;
|
|
73
|
+
};
|
|
74
|
+
exports.default = createListCommand;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const nock_1 = __importDefault(require("nock"));
|
|
16
|
+
const list_1 = __importDefault(require("./list"));
|
|
17
|
+
const logSpy = jest.spyOn(global.console, 'log');
|
|
18
|
+
describe('datastoreBlueprintList', () => {
|
|
19
|
+
process.env.ENABLE_OVERRIDE_DATASTORE_URL = 'true';
|
|
20
|
+
it('correctly lists all the blueprint', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
|
+
(0, nock_1.default)('http://localhost:9999')
|
|
22
|
+
.get('/__dxp/au/dxp/tenants/myTenant/instances?type=datastore')
|
|
23
|
+
.reply(200, [
|
|
24
|
+
{
|
|
25
|
+
name: 'name',
|
|
26
|
+
deploymentUrl: 'https://au-12345678.datastore.squiz.cloud',
|
|
27
|
+
secretKey: 'secretKey',
|
|
28
|
+
region: 'au',
|
|
29
|
+
},
|
|
30
|
+
]);
|
|
31
|
+
const program = (0, list_1.default)();
|
|
32
|
+
yield program.parseAsync([
|
|
33
|
+
'node',
|
|
34
|
+
'dxp-cli',
|
|
35
|
+
'datastore',
|
|
36
|
+
'blueprint',
|
|
37
|
+
'list',
|
|
38
|
+
'-t',
|
|
39
|
+
'myTenant',
|
|
40
|
+
'-ou',
|
|
41
|
+
'http://localhost:9999',
|
|
42
|
+
]);
|
|
43
|
+
const opts = program.opts();
|
|
44
|
+
expect(opts.tenant).toEqual('myTenant');
|
|
45
|
+
expect(opts.overrideUrl).toEqual('http://localhost:9999');
|
|
46
|
+
expect(logSpy).toHaveBeenCalledTimes(7);
|
|
47
|
+
expect(logSpy).toHaveBeenCalledWith('');
|
|
48
|
+
expect(logSpy).toHaveBeenCalledWith('');
|
|
49
|
+
}));
|
|
50
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const commander_1 = require("commander");
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const ora_1 = __importDefault(require("ora"));
|
|
18
|
+
const ApiService_1 = require("../../../ApiService");
|
|
19
|
+
const utils_1 = require("../../utils");
|
|
20
|
+
const createRenameCommand = () => {
|
|
21
|
+
const renameCommand = new commander_1.Command('rename')
|
|
22
|
+
.name('rename')
|
|
23
|
+
.description('Renames an existing blueprint')
|
|
24
|
+
.addOption(new commander_1.Option('-t, --tenant <string>', 'Tenant ID to run against. If not provided will use configured tenant from login'))
|
|
25
|
+
.addOption(new commander_1.Option('-on, --oldName <string>', 'Old Name for your blueprint e.g. MyFirstBlueprint').makeOptionMandatory())
|
|
26
|
+
.addOption(new commander_1.Option('-nn, --newName <string>', 'New Name for your blueprint e.g. MyFirstBlueprint').makeOptionMandatory())
|
|
27
|
+
.configureOutput({
|
|
28
|
+
outputError(str, write) {
|
|
29
|
+
write(chalk_1.default.red(str));
|
|
30
|
+
},
|
|
31
|
+
})
|
|
32
|
+
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
|
+
yield (0, utils_1.throwErrorIfNotLoggedIn)(renameCommand);
|
|
34
|
+
console.log('');
|
|
35
|
+
const spinner = (0, ora_1.default)('Please wait while we rename your cloud blueprint.').start();
|
|
36
|
+
let input;
|
|
37
|
+
const organisationId = null;
|
|
38
|
+
try {
|
|
39
|
+
const apiService = new ApiService_1.ApiService(utils_1.validateAxiosStatus);
|
|
40
|
+
(0, utils_1.logDebug)('Checking current blueprints');
|
|
41
|
+
// Check if we are at the blueprint limit.
|
|
42
|
+
const datastoreInstancesResp = yield apiService.client.get(yield (0, utils_1.buildDatastoreInstancesUrl)(options.tenant, options.overrideUrl));
|
|
43
|
+
(0, utils_1.logDebug)(`Finding blueprint with name: ${options.oldName}`);
|
|
44
|
+
const datastoreInstances = datastoreInstancesResp.data.filter((instance) => {
|
|
45
|
+
return instance.name === options.oldName;
|
|
46
|
+
});
|
|
47
|
+
if (datastoreInstances.length !== 1) {
|
|
48
|
+
throw new Error('Unexpected error. Ask for help in our support forums.');
|
|
49
|
+
}
|
|
50
|
+
const datastoreInstance = datastoreInstances[0];
|
|
51
|
+
const datastoreInstanceReq = {
|
|
52
|
+
name: options.newName,
|
|
53
|
+
};
|
|
54
|
+
(0, utils_1.logDebug)(`Renaming blueprint: ${options.name}`);
|
|
55
|
+
const datastoreInstanceResp = yield apiService.client.patch(yield (0, utils_1.buildInstanceUrl)(options.tenant, datastoreInstance.instanceId, options.overrideUrl, false), datastoreInstanceReq);
|
|
56
|
+
(0, utils_1.logDebug)(`Renaming blueprint instance: ${JSON.stringify(datastoreInstanceResp.data)}`);
|
|
57
|
+
if (datastoreInstanceResp.data.message) {
|
|
58
|
+
const errorMsg = '';
|
|
59
|
+
if (datastoreInstanceResp.data.message.startsWith('Error')) {
|
|
60
|
+
if (datastoreInstanceResp.data.message.toLowerCase() ===
|
|
61
|
+
'error: name is not unique') {
|
|
62
|
+
throw new Error('That blueprint name is already taken. Try renaming to something else.');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (datastoreInstanceResp.data.instance.name !== options.newName) {
|
|
66
|
+
throw new Error('Unexpected error. Ask for help in our support forums.');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
spinner.succeed('Done! Try running the list command to confirm.');
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
(0, utils_1.logDebug)(`ERROR: ${JSON.stringify(error)}`);
|
|
74
|
+
spinner.fail();
|
|
75
|
+
(0, utils_1.handleCommandError)(renameCommand, error);
|
|
76
|
+
}
|
|
77
|
+
}));
|
|
78
|
+
if (process.env.ENABLE_OVERRIDE_DATASTORE_URL === 'true') {
|
|
79
|
+
renameCommand.addOption(new commander_1.Option('-ou, --overrideUrl <string>', 'Developer option to override the entire DXP url with a custom value'));
|
|
80
|
+
}
|
|
81
|
+
return renameCommand;
|
|
82
|
+
};
|
|
83
|
+
exports.default = createRenameCommand;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const nock_1 = __importDefault(require("nock"));
|
|
16
|
+
const rename_1 = __importDefault(require("./rename"));
|
|
17
|
+
const utils_1 = require("../../utils");
|
|
18
|
+
const logSpy = jest.spyOn(global.console, 'log');
|
|
19
|
+
describe('datastoreBlueprintRename', () => {
|
|
20
|
+
process.env.ENABLE_OVERRIDE_DATASTORE_URL = 'true';
|
|
21
|
+
it('correctly renames a blueprint', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
+
(0, nock_1.default)('http://localhost:9999')
|
|
23
|
+
.get('/__dxp/au/dxp/tenants/myTenant/instances?type=datastore')
|
|
24
|
+
.reply(200, [
|
|
25
|
+
{
|
|
26
|
+
status: {
|
|
27
|
+
code: utils_1.CONSOLE_STATUS_CODE_LIVE,
|
|
28
|
+
},
|
|
29
|
+
deploymentUrl: 'https://au-asdfghj.datastore.squiz.cloud',
|
|
30
|
+
secretKey: 'secretKey',
|
|
31
|
+
region: 'au',
|
|
32
|
+
name: 'secondBlueprint',
|
|
33
|
+
instanceId: '1234',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
status: {
|
|
37
|
+
code: utils_1.CONSOLE_STATUS_CODE_LIVE,
|
|
38
|
+
},
|
|
39
|
+
deploymentUrl: 'https://au-12345678.datastore.squiz.cloud',
|
|
40
|
+
secretKey: 'secretKey',
|
|
41
|
+
region: 'au',
|
|
42
|
+
name: 'myBlueprint',
|
|
43
|
+
instanceId: 'mock-instance-id',
|
|
44
|
+
},
|
|
45
|
+
]);
|
|
46
|
+
(0, nock_1.default)('http://localhost:9999')
|
|
47
|
+
.patch('/__dxp/au/dxp/tenants/myTenant/instances/mock-instance-id', {
|
|
48
|
+
name: 'myRenamedBlueprint',
|
|
49
|
+
})
|
|
50
|
+
.reply(200, {
|
|
51
|
+
instanceId: 'mock-instance-id',
|
|
52
|
+
});
|
|
53
|
+
(0, nock_1.default)('http://localhost:9999')
|
|
54
|
+
.post('/__dxp/au/dxp/tenants/myTenant/instances/mock-instance-id/_deploy')
|
|
55
|
+
.reply(200, {
|
|
56
|
+
instanceId: 'mock-instance-id',
|
|
57
|
+
});
|
|
58
|
+
(0, nock_1.default)('http://localhost:9999')
|
|
59
|
+
.get('/__dxp/au/dxp/tenants/myTenant/instances/mock-instance-id')
|
|
60
|
+
.reply(200, {
|
|
61
|
+
status: {
|
|
62
|
+
code: utils_1.CONSOLE_STATUS_CODE_LIVE,
|
|
63
|
+
},
|
|
64
|
+
deploymentUrl: 'https://au-12345678.datastore.squiz.cloud',
|
|
65
|
+
secretKey: 'secretKey',
|
|
66
|
+
region: 'au',
|
|
67
|
+
});
|
|
68
|
+
const program = (0, rename_1.default)();
|
|
69
|
+
yield program.parseAsync([
|
|
70
|
+
'node',
|
|
71
|
+
'dxp-cli',
|
|
72
|
+
'datastore',
|
|
73
|
+
'blueprint',
|
|
74
|
+
'rename',
|
|
75
|
+
'-t',
|
|
76
|
+
'myTenant',
|
|
77
|
+
'-on',
|
|
78
|
+
'myBlueprint',
|
|
79
|
+
'-nn',
|
|
80
|
+
'myRenamedBlueprint',
|
|
81
|
+
'-ou',
|
|
82
|
+
'http://localhost:9999',
|
|
83
|
+
]);
|
|
84
|
+
const opts = program.opts();
|
|
85
|
+
expect(opts.tenant).toEqual('myTenant');
|
|
86
|
+
expect(opts.overrideUrl).toEqual('http://localhost:9999');
|
|
87
|
+
expect(logSpy).toHaveBeenCalledTimes(1);
|
|
88
|
+
expect(logSpy).toHaveBeenCalledWith('');
|
|
89
|
+
expect(logSpy).toHaveBeenCalledWith('');
|
|
90
|
+
expect(logSpy).toHaveBeenCalledWith('');
|
|
91
|
+
}));
|
|
92
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const commander_1 = require("commander");
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const ora_1 = __importDefault(require("ora"));
|
|
18
|
+
const ApiService_1 = require("../../../ApiService");
|
|
19
|
+
const utils_1 = require("../../utils");
|
|
20
|
+
const createUpdateCommand = () => {
|
|
21
|
+
const updateCommand = new commander_1.Command('update')
|
|
22
|
+
.name('update')
|
|
23
|
+
.description('Updates an existing blueprint')
|
|
24
|
+
.addOption(new commander_1.Option('-t, --tenant <string>', 'Tenant ID to run against. If not provided will use configured tenant from login'))
|
|
25
|
+
.addOption(new commander_1.Option('-p, --path <string>', 'Path to your blueprint API yaml file e.g. documents/inputs/blueprint.yaml').makeOptionMandatory())
|
|
26
|
+
.addOption(new commander_1.Option('-n, --name <string>', 'Name for your blueprint e.g. MyFirstBlueprint').makeOptionMandatory())
|
|
27
|
+
.configureOutput({
|
|
28
|
+
outputError(str, write) {
|
|
29
|
+
write(chalk_1.default.red(str));
|
|
30
|
+
},
|
|
31
|
+
})
|
|
32
|
+
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
|
+
yield (0, utils_1.throwErrorIfNotLoggedIn)(updateCommand);
|
|
34
|
+
console.log('');
|
|
35
|
+
const spinner = (0, ora_1.default)('Please wait (5 minutes) while our cloud builds this for you.').start();
|
|
36
|
+
let input;
|
|
37
|
+
try {
|
|
38
|
+
const apiService = new ApiService_1.ApiService(utils_1.validateAxiosStatus);
|
|
39
|
+
(0, utils_1.logDebug)('Checking current blueprints');
|
|
40
|
+
// Check if we are at the blueprint limit.
|
|
41
|
+
const datastoreInstancesResp = yield apiService.client.get(yield (0, utils_1.buildDatastoreInstancesUrl)(options.tenant, options.overrideUrl));
|
|
42
|
+
(0, utils_1.logDebug)(`Finding blueprint with name: ${options.name}`);
|
|
43
|
+
const datastoreInstances = datastoreInstancesResp.data.filter((instance) => {
|
|
44
|
+
return instance.name === options.name;
|
|
45
|
+
});
|
|
46
|
+
if (datastoreInstances.length !== 1) {
|
|
47
|
+
throw new Error('Unexpected error. Ask for help in our support forums.');
|
|
48
|
+
}
|
|
49
|
+
const datastoreInstance = datastoreInstances[0];
|
|
50
|
+
// Bundle the blueprint.
|
|
51
|
+
input = yield (0, utils_1.bundleBlueprint)(options.path, true);
|
|
52
|
+
const blueprintFile = Buffer.from(input).toString('base64');
|
|
53
|
+
const datastoreInstanceReq = {
|
|
54
|
+
blueprintFile,
|
|
55
|
+
status: {
|
|
56
|
+
code: 'Deploying',
|
|
57
|
+
message: 'Instance is deploying',
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
(0, utils_1.logDebug)(`Updating blueprint: ${options.name}`);
|
|
61
|
+
const datastoreInstanceResp = yield apiService.client.patch(yield (0, utils_1.buildInstanceUrl)(options.tenant, datastoreInstance.instanceId, options.overrideUrl, false), datastoreInstanceReq);
|
|
62
|
+
(0, utils_1.logDebug)(`Updating blueprint instance: ${JSON.stringify(datastoreInstanceResp.data)}`);
|
|
63
|
+
// Deploy the instance.
|
|
64
|
+
(0, utils_1.logDebug)('Starting deploy');
|
|
65
|
+
const deployResp = yield apiService.client.post(yield (0, utils_1.buildInstanceUrl)(options.tenant, datastoreInstance.instanceId, options.overrideUrl, true), datastoreInstanceReq);
|
|
66
|
+
(0, utils_1.logDebug)(`Deploying blueprint: ${JSON.stringify(deployResp.data)}`);
|
|
67
|
+
const updatedInstance = yield (0, utils_1.checkDeploymentStatus)(apiService, options.tenant, datastoreInstance.instanceId, options.overrideUrl);
|
|
68
|
+
spinner.succeed('Done! Use these details for production querying:');
|
|
69
|
+
console.log('');
|
|
70
|
+
console.log(` URL: ${updatedInstance.deploymentUrl}`);
|
|
71
|
+
console.log(` Secret Key: ${updatedInstance.secretKey}`);
|
|
72
|
+
console.log(` Region: ${updatedInstance.region}`);
|
|
73
|
+
console.log('');
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
(0, utils_1.logDebug)(`ERROR: ${JSON.stringify(error)}`);
|
|
78
|
+
spinner.fail();
|
|
79
|
+
(0, utils_1.handleCommandError)(updateCommand, error);
|
|
80
|
+
}
|
|
81
|
+
}));
|
|
82
|
+
if (process.env.ENABLE_OVERRIDE_DATASTORE_URL === 'true') {
|
|
83
|
+
updateCommand.addOption(new commander_1.Option('-ou, --overrideUrl <string>', 'Developer option to override the entire DXP url with a custom value'));
|
|
84
|
+
}
|
|
85
|
+
return updateCommand;
|
|
86
|
+
};
|
|
87
|
+
exports.default = createUpdateCommand;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|