@credibledata/cred-cli 0.0.6
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/.github/workflows/build.yml +23 -0
- package/.mocharc.json +10 -0
- package/.prettierignore +2 -0
- package/.prettierrc +4 -0
- package/README-DEV.md +40 -0
- package/README.md +11 -0
- package/bun.lock +1158 -0
- package/dist/client/api.js +7715 -0
- package/dist/client/api.js.map +1 -0
- package/dist/client/base.js +69 -0
- package/dist/client/base.js.map +1 -0
- package/dist/client/common.js +162 -0
- package/dist/client/common.js.map +1 -0
- package/dist/client/configuration.js +44 -0
- package/dist/client/configuration.js.map +1 -0
- package/dist/client/index.js +32 -0
- package/dist/client/index.js.map +1 -0
- package/dist/clientconfiguration.js +205 -0
- package/dist/clientconfiguration.js.map +1 -0
- package/dist/clientconfiguration.spec.js +381 -0
- package/dist/clientconfiguration.spec.js.map +1 -0
- package/dist/commands/add.js +66 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/connection/createconnections.js +89 -0
- package/dist/commands/connection/createconnections.js.map +1 -0
- package/dist/commands/connection/createconnections.spec.js +219 -0
- package/dist/commands/connection/createconnections.spec.js.map +1 -0
- package/dist/commands/connection/deleteconnection.js +52 -0
- package/dist/commands/connection/deleteconnection.js.map +1 -0
- package/dist/commands/connection/deleteconnection.spec.js +130 -0
- package/dist/commands/connection/deleteconnection.spec.js.map +1 -0
- package/dist/commands/connection/listconnections.js +50 -0
- package/dist/commands/connection/listconnections.js.map +1 -0
- package/dist/commands/connection/listconnections.spec.js +117 -0
- package/dist/commands/connection/listconnections.spec.js.map +1 -0
- package/dist/commands/get.js +28 -0
- package/dist/commands/get.js.map +1 -0
- package/dist/commands/group/addmember.js +75 -0
- package/dist/commands/group/addmember.js.map +1 -0
- package/dist/commands/group/addmember.spec.js +148 -0
- package/dist/commands/group/addmember.spec.js.map +1 -0
- package/dist/commands/group/creategroup.js +55 -0
- package/dist/commands/group/creategroup.js.map +1 -0
- package/dist/commands/group/creategroup.spec.js +122 -0
- package/dist/commands/group/creategroup.spec.js.map +1 -0
- package/dist/commands/group/deletegroup.js +48 -0
- package/dist/commands/group/deletegroup.js.map +1 -0
- package/dist/commands/group/deletegroup.spec.js +104 -0
- package/dist/commands/group/deletegroup.spec.js.map +1 -0
- package/dist/commands/group/getgroup.js +50 -0
- package/dist/commands/group/getgroup.js.map +1 -0
- package/dist/commands/group/getgroup.spec.js +111 -0
- package/dist/commands/group/getgroup.spec.js.map +1 -0
- package/dist/commands/group/listgroups.js +56 -0
- package/dist/commands/group/listgroups.js.map +1 -0
- package/dist/commands/group/listgroups.spec.js +118 -0
- package/dist/commands/group/listgroups.spec.js.map +1 -0
- package/dist/commands/group/removemember.js +69 -0
- package/dist/commands/group/removemember.js.map +1 -0
- package/dist/commands/group/removemember.spec.js +138 -0
- package/dist/commands/group/removemember.spec.js.map +1 -0
- package/dist/commands/groupaccesstoken/createToken.js +53 -0
- package/dist/commands/groupaccesstoken/createToken.js.map +1 -0
- package/dist/commands/groupaccesstoken/createToken.spec.js +127 -0
- package/dist/commands/groupaccesstoken/createToken.spec.js.map +1 -0
- package/dist/commands/groupaccesstoken/deleteToken.js +24 -0
- package/dist/commands/groupaccesstoken/deleteToken.js.map +1 -0
- package/dist/commands/groupaccesstoken/deleteToken.spec.js +103 -0
- package/dist/commands/groupaccesstoken/deleteToken.spec.js.map +1 -0
- package/dist/commands/groupaccesstoken/groupContainer.js +71 -0
- package/dist/commands/groupaccesstoken/groupContainer.js.map +1 -0
- package/dist/commands/groupaccesstoken/listTokens.js +25 -0
- package/dist/commands/groupaccesstoken/listTokens.js.map +1 -0
- package/dist/commands/groupaccesstoken/listTokens.spec.js +115 -0
- package/dist/commands/groupaccesstoken/listTokens.spec.js.map +1 -0
- package/dist/commands/list.js +75 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/misc/login.js +290 -0
- package/dist/commands/misc/login.js.map +1 -0
- package/dist/commands/misc/login.spec.js +243 -0
- package/dist/commands/misc/login.spec.js.map +1 -0
- package/dist/commands/misc/logout.js +11 -0
- package/dist/commands/misc/logout.js.map +1 -0
- package/dist/commands/misc/logout.spec.js +30 -0
- package/dist/commands/misc/logout.spec.js.map +1 -0
- package/dist/commands/misc/loopbackOAuth.js +110 -0
- package/dist/commands/misc/loopbackOAuth.js.map +1 -0
- package/dist/commands/misc/set-access-token.js +27 -0
- package/dist/commands/misc/set-access-token.js.map +1 -0
- package/dist/commands/misc/set-access-token.spec.js +65 -0
- package/dist/commands/misc/set-access-token.spec.js.map +1 -0
- package/dist/commands/package/deletepackage.js +54 -0
- package/dist/commands/package/deletepackage.js.map +1 -0
- package/dist/commands/package/deletepackage.spec.js +136 -0
- package/dist/commands/package/deletepackage.spec.js.map +1 -0
- package/dist/commands/package/listpackages.js +57 -0
- package/dist/commands/package/listpackages.js.map +1 -0
- package/dist/commands/package/listpackages.spec.js +129 -0
- package/dist/commands/package/listpackages.spec.js.map +1 -0
- package/dist/commands/package/publish.js +157 -0
- package/dist/commands/package/publish.js.map +1 -0
- package/dist/commands/package/publish.spec.js +511 -0
- package/dist/commands/package/publish.spec.js.map +1 -0
- package/dist/commands/package/updatepackage.js +75 -0
- package/dist/commands/package/updatepackage.js.map +1 -0
- package/dist/commands/package/updatepackage.spec.js +189 -0
- package/dist/commands/package/updatepackage.spec.js.map +1 -0
- package/dist/commands/project/createproject.js +75 -0
- package/dist/commands/project/createproject.js.map +1 -0
- package/dist/commands/project/createproject.spec.js +154 -0
- package/dist/commands/project/createproject.spec.js.map +1 -0
- package/dist/commands/project/deleteproject.js +49 -0
- package/dist/commands/project/deleteproject.js.map +1 -0
- package/dist/commands/project/deleteproject.spec.js +106 -0
- package/dist/commands/project/deleteproject.spec.js.map +1 -0
- package/dist/commands/project/getproject.js +44 -0
- package/dist/commands/project/getproject.js.map +1 -0
- package/dist/commands/project/getproject.spec.js +99 -0
- package/dist/commands/project/getproject.spec.js.map +1 -0
- package/dist/commands/project/listprojects.js +52 -0
- package/dist/commands/project/listprojects.js.map +1 -0
- package/dist/commands/project/listprojects.spec.js +111 -0
- package/dist/commands/project/listprojects.spec.js.map +1 -0
- package/dist/commands/project/setproject.js +26 -0
- package/dist/commands/project/setproject.js.map +1 -0
- package/dist/commands/project/setproject.spec.js +58 -0
- package/dist/commands/project/setproject.spec.js.map +1 -0
- package/dist/commands/project/updateproject.js +68 -0
- package/dist/commands/project/updateproject.js.map +1 -0
- package/dist/commands/project/updateproject.spec.js +129 -0
- package/dist/commands/project/updateproject.spec.js.map +1 -0
- package/dist/commands/rm.js +68 -0
- package/dist/commands/rm.js.map +1 -0
- package/dist/commands/set.js +17 -0
- package/dist/commands/set.js.map +1 -0
- package/dist/commands/update.js +42 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/version/archive-unarchive-version.js +79 -0
- package/dist/commands/version/archive-unarchive-version.js.map +1 -0
- package/dist/commands/version/archive-unarchive-version.spec.js +244 -0
- package/dist/commands/version/archive-unarchive-version.spec.js.map +1 -0
- package/dist/commands/version/listversions.js +46 -0
- package/dist/commands/version/listversions.js.map +1 -0
- package/dist/commands/version/listversions.spec.js +121 -0
- package/dist/commands/version/listversions.spec.js.map +1 -0
- package/dist/common/UserGroupId.js +112 -0
- package/dist/common/UserGroupId.js.map +1 -0
- package/dist/common/UserGroupId.spec.js +92 -0
- package/dist/common/UserGroupId.spec.js.map +1 -0
- package/dist/constants.js +90 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.js +159 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.js +77 -0
- package/dist/logger.js.map +1 -0
- package/dist/logger.spec.js +125 -0
- package/dist/logger.spec.js.map +1 -0
- package/dist/polyfills/file.polyfill.js +6 -0
- package/dist/polyfills/file.polyfill.js.map +1 -0
- package/dist/utils.js +110 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.spec.js +158 -0
- package/dist/utils.spec.js.map +1 -0
- package/dist/validator.js +53 -0
- package/dist/validator.js.map +1 -0
- package/dist/validator.spec.js +41 -0
- package/dist/validator.spec.js.map +1 -0
- package/docker/Dockerfile.ci +18 -0
- package/docker-compose.yml +18 -0
- package/eslint.config.mjs +45 -0
- package/generate-client.sh +27 -0
- package/mocha.setup.ts +4 -0
- package/openapitools.json +7 -0
- package/package.json +75 -0
- package/src/client/.openapi-generator/FILES +9 -0
- package/src/client/.openapi-generator/VERSION +1 -0
- package/src/client/.openapi-generator-ignore +23 -0
- package/src/client/api.ts +9729 -0
- package/src/client/base.ts +86 -0
- package/src/client/common.ts +150 -0
- package/src/client/configuration.ts +110 -0
- package/src/client/git_push.sh +57 -0
- package/src/client/index.ts +18 -0
- package/src/clientconfiguration.spec.ts +490 -0
- package/src/clientconfiguration.ts +263 -0
- package/src/commands/add.ts +125 -0
- package/src/commands/connection/createconnections.spec.ts +403 -0
- package/src/commands/connection/createconnections.ts +109 -0
- package/src/commands/connection/deleteconnection.spec.ts +189 -0
- package/src/commands/connection/deleteconnection.ts +57 -0
- package/src/commands/connection/listconnections.spec.ts +132 -0
- package/src/commands/connection/listconnections.ts +58 -0
- package/src/commands/get.ts +31 -0
- package/src/commands/group/addmember.spec.ts +257 -0
- package/src/commands/group/addmember.ts +85 -0
- package/src/commands/group/creategroup.spec.ts +146 -0
- package/src/commands/group/creategroup.ts +54 -0
- package/src/commands/group/deletegroup.spec.ts +120 -0
- package/src/commands/group/deletegroup.ts +45 -0
- package/src/commands/group/getgroup.spec.ts +129 -0
- package/src/commands/group/getgroup.ts +47 -0
- package/src/commands/group/listgroups.spec.ts +137 -0
- package/src/commands/group/listgroups.ts +45 -0
- package/src/commands/group/removemember.spec.ts +224 -0
- package/src/commands/group/removemember.ts +75 -0
- package/src/commands/groupaccesstoken/createToken.spec.ts +211 -0
- package/src/commands/groupaccesstoken/createToken.ts +72 -0
- package/src/commands/groupaccesstoken/deleteToken.spec.ts +147 -0
- package/src/commands/groupaccesstoken/deleteToken.ts +29 -0
- package/src/commands/groupaccesstoken/groupContainer.ts +83 -0
- package/src/commands/groupaccesstoken/listTokens.spec.ts +147 -0
- package/src/commands/groupaccesstoken/listTokens.ts +29 -0
- package/src/commands/list.ts +131 -0
- package/src/commands/misc/login.spec.ts +213 -0
- package/src/commands/misc/login.ts +325 -0
- package/src/commands/misc/logout.spec.ts +32 -0
- package/src/commands/misc/logout.ts +9 -0
- package/src/commands/misc/loopbackOAuth.ts +127 -0
- package/src/commands/misc/set-access-token.spec.ts +95 -0
- package/src/commands/misc/set-access-token.ts +32 -0
- package/src/commands/package/deletepackage.spec.ts +164 -0
- package/src/commands/package/deletepackage.ts +58 -0
- package/src/commands/package/listpackages.spec.ts +147 -0
- package/src/commands/package/listpackages.ts +67 -0
- package/src/commands/package/publish.spec.ts +597 -0
- package/src/commands/package/publish.ts +211 -0
- package/src/commands/package/updatepackage.spec.ts +319 -0
- package/src/commands/package/updatepackage.ts +95 -0
- package/src/commands/project/createproject.spec.ts +247 -0
- package/src/commands/project/createproject.ts +70 -0
- package/src/commands/project/deleteproject.spec.ts +123 -0
- package/src/commands/project/deleteproject.ts +48 -0
- package/src/commands/project/getproject.spec.ts +109 -0
- package/src/commands/project/getproject.ts +43 -0
- package/src/commands/project/listprojects.spec.ts +121 -0
- package/src/commands/project/listprojects.ts +62 -0
- package/src/commands/project/setproject.spec.ts +63 -0
- package/src/commands/project/setproject.ts +14 -0
- package/src/commands/project/updateproject.spec.ts +217 -0
- package/src/commands/project/updateproject.ts +82 -0
- package/src/commands/rm.ts +101 -0
- package/src/commands/set.ts +16 -0
- package/src/commands/update.ts +64 -0
- package/src/commands/version/archive-unarchive-version.spec.ts +456 -0
- package/src/commands/version/archive-unarchive-version.ts +111 -0
- package/src/commands/version/listversions.spec.ts +138 -0
- package/src/commands/version/listversions.ts +45 -0
- package/src/common/UserGroupId.spec.ts +117 -0
- package/src/common/UserGroupId.ts +137 -0
- package/src/constants.ts +116 -0
- package/src/index.ts +209 -0
- package/src/logger.spec.ts +158 -0
- package/src/logger.ts +86 -0
- package/src/polyfills/file.polyfill.ts +6 -0
- package/src/utils.spec.ts +135 -0
- package/src/utils.ts +115 -0
- package/src/validator.spec.ts +51 -0
- package/src/validator.ts +44 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import sinon from "sinon";
|
|
3
|
+
import { ProjectsApi } from "../../client/api";
|
|
4
|
+
import { ClientConfiguration } from "../../clientconfiguration";
|
|
5
|
+
import { logger } from "../../logger";
|
|
6
|
+
import { prettifyJson } from "../../utils";
|
|
7
|
+
import { listProjects, printOutProjects } from "./listprojects";
|
|
8
|
+
|
|
9
|
+
describe("list-projects", () => {
|
|
10
|
+
let sandbox: sinon.SinonSandbox;
|
|
11
|
+
let listProjectsStub: sinon.SinonStub;
|
|
12
|
+
let loggerStub: sinon.SinonStubbedInstance<typeof logger>;
|
|
13
|
+
let consoleLogStub: sinon.SinonStub;
|
|
14
|
+
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
sandbox = sinon.createSandbox();
|
|
17
|
+
listProjectsStub = sandbox.stub();
|
|
18
|
+
loggerStub = sandbox.stub(logger);
|
|
19
|
+
consoleLogStub = sandbox.stub(console, "log");
|
|
20
|
+
|
|
21
|
+
sandbox
|
|
22
|
+
.stub(ClientConfiguration.prototype, "getOrganization")
|
|
23
|
+
.returns("test-org");
|
|
24
|
+
sandbox
|
|
25
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
26
|
+
.returns(true);
|
|
27
|
+
sandbox
|
|
28
|
+
.stub(ClientConfiguration.prototype, "getHeaders")
|
|
29
|
+
.returns({ Authorization: "Bearer test-token" });
|
|
30
|
+
|
|
31
|
+
sandbox
|
|
32
|
+
.stub(ProjectsApi.prototype, "listProjects")
|
|
33
|
+
.callsFake(listProjectsStub);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
afterEach(() => {
|
|
37
|
+
sandbox.restore();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should list projects successfully", async () => {
|
|
41
|
+
const mockProjects = [
|
|
42
|
+
{ name: "project1", replicationCount: 2 },
|
|
43
|
+
{ name: "project2", replicationCount: 3 },
|
|
44
|
+
];
|
|
45
|
+
const mockResponse = {
|
|
46
|
+
data: mockProjects,
|
|
47
|
+
headers: {},
|
|
48
|
+
};
|
|
49
|
+
listProjectsStub.resolves(mockResponse);
|
|
50
|
+
|
|
51
|
+
const result = await listProjects("http://test-server", false);
|
|
52
|
+
|
|
53
|
+
expect(listProjectsStub.calledOnce).to.be.true;
|
|
54
|
+
expect(listProjectsStub.firstCall.args[0]).to.equal("test-org");
|
|
55
|
+
expect(listProjectsStub.firstCall.args[1]).to.equal(-1); // limit
|
|
56
|
+
expect(listProjectsStub.firstCall.args[2]).to.equal(0); // offset
|
|
57
|
+
expect(listProjectsStub.firstCall.args[3]).to.deep.include({
|
|
58
|
+
baseURL: "http://test-server",
|
|
59
|
+
headers: { Authorization: "Bearer test-token" },
|
|
60
|
+
});
|
|
61
|
+
expect(result).to.deep.equal({
|
|
62
|
+
projects: mockProjects,
|
|
63
|
+
totalCount: undefined,
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("should return empty array when config doesn't exist", async () => {
|
|
68
|
+
sandbox.restore();
|
|
69
|
+
sandbox = sinon.createSandbox();
|
|
70
|
+
listProjectsStub = sandbox.stub();
|
|
71
|
+
loggerStub = sandbox.stub(logger);
|
|
72
|
+
consoleLogStub = sandbox.stub(console, "log");
|
|
73
|
+
|
|
74
|
+
sandbox
|
|
75
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
76
|
+
.returns(false);
|
|
77
|
+
sandbox
|
|
78
|
+
.stub(ProjectsApi.prototype, "listProjects")
|
|
79
|
+
.callsFake(listProjectsStub);
|
|
80
|
+
|
|
81
|
+
const result = await listProjects("http://test-server", false);
|
|
82
|
+
|
|
83
|
+
expect(listProjectsStub.called).to.be.false;
|
|
84
|
+
expect(result).to.be.undefined;
|
|
85
|
+
expect(
|
|
86
|
+
loggerStub.error.calledWith(
|
|
87
|
+
sinon.match("Please, make sure that you are logged in"),
|
|
88
|
+
),
|
|
89
|
+
).to.be.true;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("should return empty array on API error", async () => {
|
|
93
|
+
const mockError = new Error("API Error");
|
|
94
|
+
listProjectsStub.rejects(mockError);
|
|
95
|
+
|
|
96
|
+
const result = await listProjects("http://test-server", true);
|
|
97
|
+
|
|
98
|
+
expect(listProjectsStub.calledOnce).to.be.true;
|
|
99
|
+
expect(result).to.be.undefined;
|
|
100
|
+
expect(
|
|
101
|
+
loggerStub.error.calledWith(sinon.match("Failed to list projects")),
|
|
102
|
+
).to.be.true;
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("should print projects when using printOutProjects", async () => {
|
|
106
|
+
const mockProjects = [{ name: "project1" }];
|
|
107
|
+
const mockResponse = {
|
|
108
|
+
data: mockProjects,
|
|
109
|
+
headers: {},
|
|
110
|
+
};
|
|
111
|
+
listProjectsStub.resolves(mockResponse);
|
|
112
|
+
|
|
113
|
+
await printOutProjects("http://test-server", false);
|
|
114
|
+
|
|
115
|
+
expect(consoleLogStub.calledOnce).to.be.true;
|
|
116
|
+
const loggedValue = consoleLogStub.firstCall.args[0];
|
|
117
|
+
const parsed = JSON.parse(loggedValue);
|
|
118
|
+
expect(parsed).to.have.property("projects");
|
|
119
|
+
expect(parsed.projects).to.deep.equal(mockProjects);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ProjectsApi } from "../../client/api";
|
|
2
|
+
import { Configuration } from "../../client/configuration";
|
|
3
|
+
import { ClientConfiguration } from "../../clientconfiguration";
|
|
4
|
+
import { logger } from "../../logger";
|
|
5
|
+
import {
|
|
6
|
+
prettifyJson,
|
|
7
|
+
printOutError,
|
|
8
|
+
parsePaginationParams,
|
|
9
|
+
extractTotalCount,
|
|
10
|
+
} from "../../utils";
|
|
11
|
+
|
|
12
|
+
const projectsApi = new ProjectsApi(new Configuration());
|
|
13
|
+
|
|
14
|
+
export async function listProjects(
|
|
15
|
+
controlPlane: string,
|
|
16
|
+
debug: boolean,
|
|
17
|
+
page?: string | number,
|
|
18
|
+
pageSize?: string | number,
|
|
19
|
+
) {
|
|
20
|
+
const clientConfig = new ClientConfiguration();
|
|
21
|
+
|
|
22
|
+
if (!clientConfig.doesConfigExists()) {
|
|
23
|
+
logger.error("Please, make sure that you are logged in");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const { limit, offset } = parsePaginationParams(page, pageSize);
|
|
29
|
+
|
|
30
|
+
const response = await projectsApi.listProjects(
|
|
31
|
+
clientConfig.getOrganization(),
|
|
32
|
+
limit,
|
|
33
|
+
offset,
|
|
34
|
+
{
|
|
35
|
+
baseURL: controlPlane,
|
|
36
|
+
headers: clientConfig.getHeaders(),
|
|
37
|
+
},
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const totalCount = extractTotalCount(response.headers);
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
projects: response.data,
|
|
44
|
+
totalCount,
|
|
45
|
+
};
|
|
46
|
+
} catch (e) {
|
|
47
|
+
logger.error("Failed to list projects");
|
|
48
|
+
printOutError(e, debug);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function printOutProjects(
|
|
54
|
+
controlPlane: string,
|
|
55
|
+
debug: boolean,
|
|
56
|
+
page?: string | number,
|
|
57
|
+
pageSize?: string | number,
|
|
58
|
+
) {
|
|
59
|
+
const projects = await listProjects(controlPlane, debug, page, pageSize);
|
|
60
|
+
|
|
61
|
+
console.log(prettifyJson(projects));
|
|
62
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import sinon from "sinon";
|
|
3
|
+
import { ClientConfiguration } from "../../clientconfiguration";
|
|
4
|
+
import { logger } from "../../logger";
|
|
5
|
+
import { setProject } from "./setproject";
|
|
6
|
+
|
|
7
|
+
describe("set-project", () => {
|
|
8
|
+
let sandbox: sinon.SinonSandbox;
|
|
9
|
+
let setProjectStub: sinon.SinonStub;
|
|
10
|
+
let loggerStub: sinon.SinonStubbedInstance<typeof logger>;
|
|
11
|
+
let consoleLogStub: sinon.SinonStub;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
sandbox = sinon.createSandbox();
|
|
15
|
+
loggerStub = sandbox.stub(logger);
|
|
16
|
+
consoleLogStub = sandbox.stub(console, "log");
|
|
17
|
+
setProjectStub = sandbox.stub(
|
|
18
|
+
ClientConfiguration.prototype,
|
|
19
|
+
"setProject",
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
sandbox
|
|
23
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
24
|
+
.returns(true);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
sandbox.restore();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("should set project successfully", async () => {
|
|
32
|
+
await setProject("test-project");
|
|
33
|
+
|
|
34
|
+
expect(setProjectStub.calledOnce).to.be.true;
|
|
35
|
+
expect(setProjectStub.firstCall.args[0]).to.equal("test-project");
|
|
36
|
+
expect(consoleLogStub.calledWith("Setting project test-project")).to.be
|
|
37
|
+
.true;
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should handle missing config", async () => {
|
|
41
|
+
sandbox.restore();
|
|
42
|
+
sandbox = sinon.createSandbox();
|
|
43
|
+
loggerStub = sandbox.stub(logger);
|
|
44
|
+
consoleLogStub = sandbox.stub(console, "log");
|
|
45
|
+
setProjectStub = sandbox.stub(
|
|
46
|
+
ClientConfiguration.prototype,
|
|
47
|
+
"setProject",
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
sandbox
|
|
51
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
52
|
+
.returns(false);
|
|
53
|
+
|
|
54
|
+
await setProject("test-project");
|
|
55
|
+
|
|
56
|
+
expect(setProjectStub.called).to.be.false;
|
|
57
|
+
expect(
|
|
58
|
+
loggerStub.error.calledWith(
|
|
59
|
+
sinon.match("Please, make sure that you are logged in"),
|
|
60
|
+
),
|
|
61
|
+
).to.be.true;
|
|
62
|
+
});
|
|
63
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ClientConfiguration } from "../../clientconfiguration";
|
|
2
|
+
import { logger } from "../../logger";
|
|
3
|
+
|
|
4
|
+
export async function setProject(projectName: string) {
|
|
5
|
+
console.log("Setting project " + projectName);
|
|
6
|
+
const clientConfig = new ClientConfiguration();
|
|
7
|
+
|
|
8
|
+
if (!clientConfig.doesConfigExists()) {
|
|
9
|
+
logger.error("Please, make sure that you are logged in");
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
clientConfig.setProject(projectName);
|
|
14
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import sinon from "sinon";
|
|
3
|
+
import { ProjectsApi } from "../../client/api";
|
|
4
|
+
import { ClientConfiguration } from "../../clientconfiguration";
|
|
5
|
+
import { logger } from "../../logger";
|
|
6
|
+
import { updateProject } from "./updateproject";
|
|
7
|
+
|
|
8
|
+
describe("update-project", () => {
|
|
9
|
+
let sandbox: sinon.SinonSandbox;
|
|
10
|
+
let updateProjectStub: sinon.SinonStub;
|
|
11
|
+
let loggerStub: sinon.SinonStubbedInstance<typeof logger>;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
sandbox = sinon.createSandbox();
|
|
15
|
+
updateProjectStub = sandbox.stub();
|
|
16
|
+
loggerStub = sandbox.stub(logger);
|
|
17
|
+
|
|
18
|
+
// Mock ClientConfiguration constructor
|
|
19
|
+
sandbox
|
|
20
|
+
.stub(ClientConfiguration.prototype, "getOrganization")
|
|
21
|
+
.returns("test-org");
|
|
22
|
+
sandbox
|
|
23
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
24
|
+
.returns(true);
|
|
25
|
+
sandbox
|
|
26
|
+
.stub(ClientConfiguration.prototype, "getHeaders")
|
|
27
|
+
.returns({ Authorization: "Bearer test-token" });
|
|
28
|
+
|
|
29
|
+
// Mock ProjectsApi constructor and method
|
|
30
|
+
sandbox
|
|
31
|
+
.stub(ProjectsApi.prototype, "updateProject")
|
|
32
|
+
.callsFake(updateProjectStub);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
sandbox.restore();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe("updateProject", () => {
|
|
40
|
+
it("should update project successfully", async () => {
|
|
41
|
+
const mockResponse = { status: 200 };
|
|
42
|
+
updateProjectStub.resolves(mockResponse);
|
|
43
|
+
|
|
44
|
+
await updateProject(
|
|
45
|
+
"http://test-server",
|
|
46
|
+
"test-project",
|
|
47
|
+
{ replicationCount: 3 },
|
|
48
|
+
false,
|
|
49
|
+
true,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
expect(updateProjectStub.calledOnce).to.be.true;
|
|
53
|
+
expect(updateProjectStub.firstCall.args[0]).to.equal("test-org");
|
|
54
|
+
expect(updateProjectStub.firstCall.args[1]).to.equal("test-project");
|
|
55
|
+
expect(updateProjectStub.firstCall.args[2]).to.include({
|
|
56
|
+
replicationCount: 3,
|
|
57
|
+
});
|
|
58
|
+
expect(updateProjectStub.firstCall.args[3]).to.deep.include({
|
|
59
|
+
baseURL: "http://test-server",
|
|
60
|
+
headers: { Authorization: "Bearer test-token" },
|
|
61
|
+
});
|
|
62
|
+
expect(
|
|
63
|
+
loggerStub.info.calledWith(
|
|
64
|
+
sinon.match("Successfully updated project test-project"),
|
|
65
|
+
),
|
|
66
|
+
).to.be.true;
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("should handle missing project name", async () => {
|
|
70
|
+
await updateProject(
|
|
71
|
+
"http://test-server",
|
|
72
|
+
"",
|
|
73
|
+
{ replicationCount: 3 },
|
|
74
|
+
false,
|
|
75
|
+
true,
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
expect(updateProjectStub.called).to.be.false;
|
|
79
|
+
expect(
|
|
80
|
+
loggerStub.error.calledWith(
|
|
81
|
+
sinon.match("Please provide a project name"),
|
|
82
|
+
),
|
|
83
|
+
).to.be.true;
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("should handle API errors", async () => {
|
|
87
|
+
const mockError = new Error("API Error");
|
|
88
|
+
updateProjectStub.rejects(mockError);
|
|
89
|
+
|
|
90
|
+
await updateProject(
|
|
91
|
+
"http://test-server",
|
|
92
|
+
"test-project",
|
|
93
|
+
{ replicationCount: 3 },
|
|
94
|
+
true,
|
|
95
|
+
true,
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
expect(updateProjectStub.calledOnce).to.be.true;
|
|
99
|
+
expect(
|
|
100
|
+
loggerStub.error.calledWith(
|
|
101
|
+
sinon.match("Failed to update project test-project"),
|
|
102
|
+
),
|
|
103
|
+
).to.be.true;
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("should handle non-200 response status", async () => {
|
|
107
|
+
const mockResponse = { status: 400 };
|
|
108
|
+
updateProjectStub.resolves(mockResponse);
|
|
109
|
+
|
|
110
|
+
await updateProject(
|
|
111
|
+
"http://test-server",
|
|
112
|
+
"test-project",
|
|
113
|
+
{ replicationCount: 3 },
|
|
114
|
+
false,
|
|
115
|
+
true,
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
expect(updateProjectStub.calledOnce).to.be.true;
|
|
119
|
+
expect(
|
|
120
|
+
loggerStub.error.calledWith(
|
|
121
|
+
sinon.match("Failed to update project. Status: 400"),
|
|
122
|
+
),
|
|
123
|
+
).to.be.true;
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe("validators", () => {
|
|
128
|
+
describe("authentication validation", () => {
|
|
129
|
+
it("should fail when user is not logged in", async () => {
|
|
130
|
+
sandbox.restore();
|
|
131
|
+
sandbox = sinon.createSandbox();
|
|
132
|
+
updateProjectStub = sandbox.stub();
|
|
133
|
+
loggerStub = sandbox.stub(logger);
|
|
134
|
+
|
|
135
|
+
sandbox
|
|
136
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
137
|
+
.returns(false);
|
|
138
|
+
sandbox
|
|
139
|
+
.stub(ProjectsApi.prototype, "updateProject")
|
|
140
|
+
.callsFake(updateProjectStub);
|
|
141
|
+
|
|
142
|
+
await updateProject(
|
|
143
|
+
"http://test-server",
|
|
144
|
+
"test-project",
|
|
145
|
+
{ replicationCount: 3 },
|
|
146
|
+
false,
|
|
147
|
+
true,
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
expect(updateProjectStub.called).to.be.false;
|
|
151
|
+
expect(
|
|
152
|
+
loggerStub.error.calledWith(
|
|
153
|
+
sinon.match("Please, make sure that you are logged in"),
|
|
154
|
+
),
|
|
155
|
+
).to.be.true;
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
describe("replication count validation", () => {
|
|
160
|
+
it("should accept valid replication counts", async () => {
|
|
161
|
+
const mockResponse = { status: 200 };
|
|
162
|
+
updateProjectStub.resolves(mockResponse);
|
|
163
|
+
|
|
164
|
+
const validCounts = [1, 2, 5, 10, 100];
|
|
165
|
+
|
|
166
|
+
for (const count of validCounts) {
|
|
167
|
+
await updateProject(
|
|
168
|
+
"http://test-server",
|
|
169
|
+
"test-project",
|
|
170
|
+
{ replicationCount: count },
|
|
171
|
+
false,
|
|
172
|
+
true,
|
|
173
|
+
);
|
|
174
|
+
expect(updateProjectStub.called).to.be.true;
|
|
175
|
+
expect(updateProjectStub.firstCall.args[2]).to.include({
|
|
176
|
+
replicationCount: count,
|
|
177
|
+
});
|
|
178
|
+
updateProjectStub.reset();
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it("should reject replication count less than 1", async () => {
|
|
183
|
+
await updateProject(
|
|
184
|
+
"http://test-server",
|
|
185
|
+
"test-project",
|
|
186
|
+
{ replicationCount: 0 },
|
|
187
|
+
false,
|
|
188
|
+
true,
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
expect(updateProjectStub.called).to.be.false;
|
|
192
|
+
expect(
|
|
193
|
+
loggerStub.error.calledWith(
|
|
194
|
+
sinon.match("Replication count must be at least 1"),
|
|
195
|
+
),
|
|
196
|
+
).to.be.true;
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it("should reject negative replication count", async () => {
|
|
200
|
+
await updateProject(
|
|
201
|
+
"http://test-server",
|
|
202
|
+
"test-project",
|
|
203
|
+
{ replicationCount: -1 },
|
|
204
|
+
false,
|
|
205
|
+
true,
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
expect(updateProjectStub.called).to.be.false;
|
|
209
|
+
expect(
|
|
210
|
+
loggerStub.error.calledWith(
|
|
211
|
+
sinon.match("Replication count must be at least 1"),
|
|
212
|
+
),
|
|
213
|
+
).to.be.true;
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Project, ProjectsApi } from "../../client/api";
|
|
2
|
+
import { Configuration } from "../../client/configuration";
|
|
3
|
+
import { ClientConfiguration } from "../../clientconfiguration";
|
|
4
|
+
import { logger } from "../../logger";
|
|
5
|
+
import { getConfirmation, printOutError } from "../../utils";
|
|
6
|
+
|
|
7
|
+
const projectsApi = new ProjectsApi(new Configuration());
|
|
8
|
+
|
|
9
|
+
type UpdateProjectProperties = {
|
|
10
|
+
replicationCount?: number;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export async function updateProject(
|
|
14
|
+
controlPlane: string,
|
|
15
|
+
projectName: string,
|
|
16
|
+
properties: UpdateProjectProperties,
|
|
17
|
+
debug?: boolean,
|
|
18
|
+
skipConfirmation?: boolean,
|
|
19
|
+
) {
|
|
20
|
+
const clientConfig = new ClientConfiguration();
|
|
21
|
+
if (!clientConfig.doesConfigExists()) {
|
|
22
|
+
logger.error("Please, make sure that you are logged in");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!projectName) {
|
|
27
|
+
logger.error("Please provide a project name");
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const organizationName = clientConfig.getOrganization();
|
|
32
|
+
|
|
33
|
+
if (
|
|
34
|
+
properties.replicationCount !== undefined &&
|
|
35
|
+
properties.replicationCount < 1
|
|
36
|
+
) {
|
|
37
|
+
logger.error("Replication count must be at least 1");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
if (!skipConfirmation) {
|
|
43
|
+
const confirmation = await getConfirmation(
|
|
44
|
+
`Are you sure you want to update project ${projectName}?`,
|
|
45
|
+
);
|
|
46
|
+
if (!confirmation) {
|
|
47
|
+
logger.info("Operation cancelled.");
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const projectUpdate: Project = {};
|
|
53
|
+
|
|
54
|
+
if (properties.replicationCount !== undefined) {
|
|
55
|
+
projectUpdate.replicationCount = properties.replicationCount;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const response = await projectsApi.updateProject(
|
|
59
|
+
organizationName,
|
|
60
|
+
projectName,
|
|
61
|
+
projectUpdate,
|
|
62
|
+
{
|
|
63
|
+
baseURL: controlPlane,
|
|
64
|
+
headers: clientConfig.getHeaders(),
|
|
65
|
+
},
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
if (response.status === 200) {
|
|
69
|
+
logger.info(`Successfully updated project ${projectName}`);
|
|
70
|
+
if (properties.replicationCount !== undefined) {
|
|
71
|
+
logger.info(
|
|
72
|
+
`Replication count set to ${properties.replicationCount}`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
logger.error(`Failed to update project. Status: ${response.status}`);
|
|
77
|
+
}
|
|
78
|
+
} catch (e) {
|
|
79
|
+
logger.error(`Failed to update project ${projectName}`);
|
|
80
|
+
printOutError(e, debug);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { controlPlanesByEnv, Environment } from "../constants";
|
|
3
|
+
import { deleteConnection } from "./connection/deleteconnection";
|
|
4
|
+
import { deleteGroup } from "./group/deletegroup";
|
|
5
|
+
import { removeMember } from "./group/removemember";
|
|
6
|
+
import { deleteGroupAccessToken } from "./groupaccesstoken/deleteToken";
|
|
7
|
+
import { deletePackage } from "./package/deletepackage";
|
|
8
|
+
import { deleteProject } from "./project/deleteproject";
|
|
9
|
+
|
|
10
|
+
export const registerRmCommands = (cli: Command, environment: Environment) => {
|
|
11
|
+
const rm = cli
|
|
12
|
+
.command("rm")
|
|
13
|
+
.description("Remove a resource")
|
|
14
|
+
.argument("<resource>", "The resource to remove");
|
|
15
|
+
|
|
16
|
+
rm.command("package")
|
|
17
|
+
.description("Delete a package.")
|
|
18
|
+
.argument("<packageName>", "The name of the package to delete.")
|
|
19
|
+
.option("--debug")
|
|
20
|
+
.option("-y, --yes", "Skip confirmation.")
|
|
21
|
+
.action((packageName, options) => {
|
|
22
|
+
deletePackage(
|
|
23
|
+
controlPlanesByEnv[environment],
|
|
24
|
+
packageName,
|
|
25
|
+
options.debug,
|
|
26
|
+
options.yes,
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
rm.command("project")
|
|
31
|
+
.description("Delete a project.")
|
|
32
|
+
.argument("<projectName>", "The name of the project to delete.")
|
|
33
|
+
.option("--debug")
|
|
34
|
+
.option("-y, --yes", "Skip confirmation.")
|
|
35
|
+
.action((projectName, options) => {
|
|
36
|
+
deleteProject(
|
|
37
|
+
controlPlanesByEnv[environment],
|
|
38
|
+
projectName,
|
|
39
|
+
options.debug,
|
|
40
|
+
options.yes,
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
rm.command("connection")
|
|
45
|
+
.description("Delete a connection.")
|
|
46
|
+
.argument("<connectionName>", "The name of the connection to delete.")
|
|
47
|
+
.option("--debug")
|
|
48
|
+
.option("-y, --yes", "Skip confirmation.")
|
|
49
|
+
.action((connectionName, options) => {
|
|
50
|
+
deleteConnection(
|
|
51
|
+
controlPlanesByEnv[environment],
|
|
52
|
+
connectionName,
|
|
53
|
+
options.debug,
|
|
54
|
+
options.yes,
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
rm.command("group")
|
|
59
|
+
.description("Delete a group.")
|
|
60
|
+
.argument("<groupName>", "The name of the group to delete")
|
|
61
|
+
.option("--debug")
|
|
62
|
+
.option("-y, --yes", "Skip confirmation.")
|
|
63
|
+
.action((groupName, options) => {
|
|
64
|
+
deleteGroup(
|
|
65
|
+
controlPlanesByEnv[environment],
|
|
66
|
+
groupName,
|
|
67
|
+
options.debug || false,
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
rm.command("member")
|
|
72
|
+
.description("Remove a member from a group.")
|
|
73
|
+
.argument("<groupName>", "The name of the group")
|
|
74
|
+
.argument("<memberType>", "The type of member (user or group)")
|
|
75
|
+
.argument("<memberName>", "The name of the member")
|
|
76
|
+
.option("--debug")
|
|
77
|
+
.action((groupName, memberType, memberName, options) => {
|
|
78
|
+
removeMember(
|
|
79
|
+
controlPlanesByEnv[environment],
|
|
80
|
+
groupName,
|
|
81
|
+
memberType,
|
|
82
|
+
memberName,
|
|
83
|
+
options.debug || false,
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
rm.command("group-access-token")
|
|
88
|
+
.description("Delete an access token from a group.")
|
|
89
|
+
.argument("<groupName>", "The name of the group")
|
|
90
|
+
.argument("<tokenName>", "The name of the token to delete")
|
|
91
|
+
.option("--debug")
|
|
92
|
+
.option("-y, --yes", "Skip confirmation.")
|
|
93
|
+
.action((groupName, tokenName, options) => {
|
|
94
|
+
deleteGroupAccessToken(
|
|
95
|
+
controlPlanesByEnv[environment],
|
|
96
|
+
groupName,
|
|
97
|
+
tokenName,
|
|
98
|
+
options.debug || false,
|
|
99
|
+
);
|
|
100
|
+
});
|
|
101
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { setProject } from "./project/setproject";
|
|
3
|
+
|
|
4
|
+
export const registerSetCommands = (cli: Command) => {
|
|
5
|
+
const set = cli
|
|
6
|
+
.command("set")
|
|
7
|
+
.description("Set a resource")
|
|
8
|
+
.argument("<resource>", "The resource to set");
|
|
9
|
+
|
|
10
|
+
set.command("project")
|
|
11
|
+
.description("Set the default project.")
|
|
12
|
+
.argument("<projectName>", "The name of the project to set.")
|
|
13
|
+
.action(setProject);
|
|
14
|
+
|
|
15
|
+
// TODO: It would be nice to `cred set org` and avoid logging again when switching orgs.
|
|
16
|
+
};
|