indraq_cli 1.9.1 → 2.0.0
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/LICENSE +21 -21
- package/README.md +1043 -1517
- package/cloud-api/.env +6 -0
- package/cloud-api/.env.example +14 -14
- package/cloud-api/README.md +145 -141
- package/cloud-api/package.json +29 -29
- package/cloud-api/sql/001_init.sql +8 -8
- package/cloud-api/sql/002_user_providers_and_project_resources.sql +40 -40
- package/cloud-api/sql/003_environment_infrastructure.sql +19 -19
- package/cloud-api/sql/004_managed_aws_credentials.sql +20 -20
- package/cloud-api/sql/005_project_members_and_resource_grants.sql +22 -22
- package/cloud-api/sql/006_catalog_identity_password_security.sql +96 -96
- package/cloud-api/sql/007_aws_access_key_rotation.sql +16 -16
- package/cloud-api/src/index.ts +1329 -1254
- package/cloud-api/tsconfig.json +18 -18
- package/dist/cli/help-content.d.ts.map +1 -1
- package/dist/cli/help-content.js +254 -251
- package/dist/cli/help-content.js.map +1 -1
- package/dist/modules/access/commands/access.command.d.ts +19 -0
- package/dist/modules/access/commands/access.command.d.ts.map +1 -1
- package/dist/modules/access/commands/access.command.js +57 -46
- package/dist/modules/access/commands/access.command.js.map +1 -1
- package/dist/modules/cloud/commands/cloud.command.d.ts.map +1 -1
- package/dist/modules/cloud/commands/cloud.command.js +18 -2
- package/dist/modules/cloud/commands/cloud.command.js.map +1 -1
- package/dist/modules/cloud/config/cloud-config.d.ts +1 -1
- package/dist/modules/cloud/config/cloud-config.js +1 -1
- package/dist/modules/cloud/services/cloud-jenkins.service.d.ts +13 -1
- package/dist/modules/cloud/services/cloud-jenkins.service.d.ts.map +1 -1
- package/dist/modules/cloud/services/cloud-jenkins.service.js +173 -77
- package/dist/modules/cloud/services/cloud-jenkins.service.js.map +1 -1
- package/dist/modules/cloud/services/managed-aws-credential.service.d.ts.map +1 -1
- package/dist/modules/cloud/services/managed-aws-credential.service.js +11 -4
- package/dist/modules/cloud/services/managed-aws-credential.service.js.map +1 -1
- package/dist/modules/jenkins/commands/admin.command.d.ts +3 -0
- package/dist/modules/jenkins/commands/admin.command.d.ts.map +1 -1
- package/dist/modules/jenkins/commands/admin.command.js +91 -1
- package/dist/modules/jenkins/commands/admin.command.js.map +1 -1
- package/dist/modules/jenkins/index.d.ts.map +1 -1
- package/dist/modules/jenkins/index.js +3 -0
- package/dist/modules/jenkins/index.js.map +1 -1
- package/dist/modules/scaffold/services/docker-template.service.js +95 -95
- package/dist/modules/users/commands/user.command.d.ts.map +1 -1
- package/dist/modules/users/commands/user.command.js +290 -44
- package/dist/modules/users/commands/user.command.js.map +1 -1
- package/dist/modules/users/providers/aws-user.provider.d.ts.map +1 -1
- package/dist/modules/users/providers/aws-user.provider.js +9 -2
- package/dist/modules/users/providers/aws-user.provider.js.map +1 -1
- package/dist/modules/users/providers/jenkins-user.provider.d.ts +11 -4
- package/dist/modules/users/providers/jenkins-user.provider.d.ts.map +1 -1
- package/dist/modules/users/providers/jenkins-user.provider.js +174 -72
- package/dist/modules/users/providers/jenkins-user.provider.js.map +1 -1
- package/dist/modules/users/providers/npm-user.provider.d.ts.map +1 -1
- package/dist/modules/users/providers/npm-user.provider.js +3 -1
- package/dist/modules/users/providers/npm-user.provider.js.map +1 -1
- package/dist/shared/config/config-files.js +7 -7
- package/docs/ARCHITECTURE.md +29 -29
- package/docs/CREATE-DEPLOYMENT-reference.groovy +1105 -1105
- package/package.json +77 -76
- package/templates/jenkins/CREATE-DEPLOYMENT.groovy +1105 -1105
- package/templates/jenkins/Jenkinsfile-Mobile-App +759 -759
- package/cloud-api/.dockerignore +0 -18
- package/cloud-api/Dockerfile +0 -19
- package/cloud-api/package-lock.json +0 -2250
|
@@ -1,96 +1,96 @@
|
|
|
1
|
-
-- Organization-wide catalog constraints, project access levels, first-login
|
|
2
|
-
-- password changes, self-service OTP resets, and managed external identities.
|
|
3
|
-
|
|
4
|
-
ALTER TABLE users
|
|
5
|
-
ADD COLUMN IF NOT EXISTS must_change_password boolean NOT NULL DEFAULT false,
|
|
6
|
-
ADD COLUMN IF NOT EXISTS password_changed_at timestamptz,
|
|
7
|
-
ADD COLUMN IF NOT EXISTS last_login_at timestamptz;
|
|
8
|
-
|
|
9
|
-
ALTER TABLE project_members
|
|
10
|
-
ADD COLUMN IF NOT EXISTS access_level text NOT NULL DEFAULT 'write';
|
|
11
|
-
|
|
12
|
-
DO $$
|
|
13
|
-
BEGIN
|
|
14
|
-
IF NOT EXISTS (
|
|
15
|
-
SELECT 1 FROM pg_constraint WHERE conname = 'project_members_access_level_check'
|
|
16
|
-
) THEN
|
|
17
|
-
ALTER TABLE project_members
|
|
18
|
-
ADD CONSTRAINT project_members_access_level_check
|
|
19
|
-
CHECK (access_level IN ('view','write'));
|
|
20
|
-
END IF;
|
|
21
|
-
END $$;
|
|
22
|
-
|
|
23
|
-
UPDATE project_members SET access_level='write' WHERE role='owner';
|
|
24
|
-
|
|
25
|
-
-- Resolve historical duplicate project names before enforcing organization-wide
|
|
26
|
-
-- case-insensitive uniqueness. The oldest row keeps the original display name.
|
|
27
|
-
WITH ranked AS (
|
|
28
|
-
SELECT id, name,
|
|
29
|
-
row_number() OVER (PARTITION BY lower(name) ORDER BY created_at, id) AS rn
|
|
30
|
-
FROM projects
|
|
31
|
-
)
|
|
32
|
-
UPDATE projects p
|
|
33
|
-
SET name = p.name || '-legacy-' || left(p.id::text, 8), updated_at=now()
|
|
34
|
-
FROM ranked r
|
|
35
|
-
WHERE p.id=r.id AND r.rn > 1;
|
|
36
|
-
|
|
37
|
-
CREATE UNIQUE INDEX IF NOT EXISTS projects_name_lower_unique_idx
|
|
38
|
-
ON projects (lower(name));
|
|
39
|
-
|
|
40
|
-
-- GHCR image names are organization-wide claims. Resolve historical duplicate
|
|
41
|
-
-- DB claims before adding the unique index; this does not mutate any registry.
|
|
42
|
-
WITH ranked AS (
|
|
43
|
-
SELECT id,
|
|
44
|
-
row_number() OVER (
|
|
45
|
-
PARTITION BY lower(config->>'fullImage')
|
|
46
|
-
ORDER BY created_at, id
|
|
47
|
-
) AS rn
|
|
48
|
-
FROM project_resources
|
|
49
|
-
WHERE provider='ghcr'
|
|
50
|
-
AND config ? 'fullImage'
|
|
51
|
-
AND coalesce(config->>'fullImage','') <> ''
|
|
52
|
-
)
|
|
53
|
-
UPDATE project_resources pr
|
|
54
|
-
SET config = jsonb_set(
|
|
55
|
-
jsonb_set(pr.config, '{fullImage}', to_jsonb((pr.config->>'fullImage') || '-legacy-' || left(pr.id::text,8)), true),
|
|
56
|
-
'{imageName}', to_jsonb(coalesce(pr.config->>'imageName','image') || '-legacy-' || left(pr.id::text,8)), true
|
|
57
|
-
),
|
|
58
|
-
updated_at=now()
|
|
59
|
-
FROM ranked r
|
|
60
|
-
WHERE pr.id=r.id AND r.rn > 1;
|
|
61
|
-
|
|
62
|
-
CREATE UNIQUE INDEX IF NOT EXISTS project_resources_ghcr_full_image_unique_idx
|
|
63
|
-
ON project_resources ((lower(config->>'fullImage')))
|
|
64
|
-
WHERE provider='ghcr'
|
|
65
|
-
AND config ? 'fullImage'
|
|
66
|
-
AND coalesce(config->>'fullImage','') <> '';
|
|
67
|
-
|
|
68
|
-
CREATE TABLE IF NOT EXISTS managed_external_accounts (
|
|
69
|
-
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
70
|
-
cloud_user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
71
|
-
provider text NOT NULL CHECK (provider IN ('npm','jenkins-dev','jenkins-prod')),
|
|
72
|
-
external_username text NOT NULL,
|
|
73
|
-
external_email text,
|
|
74
|
-
managed_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
75
|
-
config jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
76
|
-
created_at timestamptz NOT NULL DEFAULT now(),
|
|
77
|
-
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
78
|
-
UNIQUE(cloud_user_id, provider)
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
CREATE INDEX IF NOT EXISTS managed_external_accounts_manager_idx
|
|
82
|
-
ON managed_external_accounts(managed_by_user_id, provider);
|
|
83
|
-
|
|
84
|
-
CREATE TABLE IF NOT EXISTS password_reset_otps (
|
|
85
|
-
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
86
|
-
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
87
|
-
otp_hash text NOT NULL,
|
|
88
|
-
expires_at timestamptz NOT NULL,
|
|
89
|
-
attempts integer NOT NULL DEFAULT 0,
|
|
90
|
-
max_attempts integer NOT NULL DEFAULT 5,
|
|
91
|
-
used_at timestamptz,
|
|
92
|
-
created_at timestamptz NOT NULL DEFAULT now()
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
CREATE INDEX IF NOT EXISTS password_reset_otps_user_idx
|
|
96
|
-
ON password_reset_otps(user_id, created_at DESC);
|
|
1
|
+
-- Organization-wide catalog constraints, project access levels, first-login
|
|
2
|
+
-- password changes, self-service OTP resets, and managed external identities.
|
|
3
|
+
|
|
4
|
+
ALTER TABLE users
|
|
5
|
+
ADD COLUMN IF NOT EXISTS must_change_password boolean NOT NULL DEFAULT false,
|
|
6
|
+
ADD COLUMN IF NOT EXISTS password_changed_at timestamptz,
|
|
7
|
+
ADD COLUMN IF NOT EXISTS last_login_at timestamptz;
|
|
8
|
+
|
|
9
|
+
ALTER TABLE project_members
|
|
10
|
+
ADD COLUMN IF NOT EXISTS access_level text NOT NULL DEFAULT 'write';
|
|
11
|
+
|
|
12
|
+
DO $$
|
|
13
|
+
BEGIN
|
|
14
|
+
IF NOT EXISTS (
|
|
15
|
+
SELECT 1 FROM pg_constraint WHERE conname = 'project_members_access_level_check'
|
|
16
|
+
) THEN
|
|
17
|
+
ALTER TABLE project_members
|
|
18
|
+
ADD CONSTRAINT project_members_access_level_check
|
|
19
|
+
CHECK (access_level IN ('view','write'));
|
|
20
|
+
END IF;
|
|
21
|
+
END $$;
|
|
22
|
+
|
|
23
|
+
UPDATE project_members SET access_level='write' WHERE role='owner';
|
|
24
|
+
|
|
25
|
+
-- Resolve historical duplicate project names before enforcing organization-wide
|
|
26
|
+
-- case-insensitive uniqueness. The oldest row keeps the original display name.
|
|
27
|
+
WITH ranked AS (
|
|
28
|
+
SELECT id, name,
|
|
29
|
+
row_number() OVER (PARTITION BY lower(name) ORDER BY created_at, id) AS rn
|
|
30
|
+
FROM projects
|
|
31
|
+
)
|
|
32
|
+
UPDATE projects p
|
|
33
|
+
SET name = p.name || '-legacy-' || left(p.id::text, 8), updated_at=now()
|
|
34
|
+
FROM ranked r
|
|
35
|
+
WHERE p.id=r.id AND r.rn > 1;
|
|
36
|
+
|
|
37
|
+
CREATE UNIQUE INDEX IF NOT EXISTS projects_name_lower_unique_idx
|
|
38
|
+
ON projects (lower(name));
|
|
39
|
+
|
|
40
|
+
-- GHCR image names are organization-wide claims. Resolve historical duplicate
|
|
41
|
+
-- DB claims before adding the unique index; this does not mutate any registry.
|
|
42
|
+
WITH ranked AS (
|
|
43
|
+
SELECT id,
|
|
44
|
+
row_number() OVER (
|
|
45
|
+
PARTITION BY lower(config->>'fullImage')
|
|
46
|
+
ORDER BY created_at, id
|
|
47
|
+
) AS rn
|
|
48
|
+
FROM project_resources
|
|
49
|
+
WHERE provider='ghcr'
|
|
50
|
+
AND config ? 'fullImage'
|
|
51
|
+
AND coalesce(config->>'fullImage','') <> ''
|
|
52
|
+
)
|
|
53
|
+
UPDATE project_resources pr
|
|
54
|
+
SET config = jsonb_set(
|
|
55
|
+
jsonb_set(pr.config, '{fullImage}', to_jsonb((pr.config->>'fullImage') || '-legacy-' || left(pr.id::text,8)), true),
|
|
56
|
+
'{imageName}', to_jsonb(coalesce(pr.config->>'imageName','image') || '-legacy-' || left(pr.id::text,8)), true
|
|
57
|
+
),
|
|
58
|
+
updated_at=now()
|
|
59
|
+
FROM ranked r
|
|
60
|
+
WHERE pr.id=r.id AND r.rn > 1;
|
|
61
|
+
|
|
62
|
+
CREATE UNIQUE INDEX IF NOT EXISTS project_resources_ghcr_full_image_unique_idx
|
|
63
|
+
ON project_resources ((lower(config->>'fullImage')))
|
|
64
|
+
WHERE provider='ghcr'
|
|
65
|
+
AND config ? 'fullImage'
|
|
66
|
+
AND coalesce(config->>'fullImage','') <> '';
|
|
67
|
+
|
|
68
|
+
CREATE TABLE IF NOT EXISTS managed_external_accounts (
|
|
69
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
70
|
+
cloud_user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
71
|
+
provider text NOT NULL CHECK (provider IN ('npm','jenkins-dev','jenkins-prod')),
|
|
72
|
+
external_username text NOT NULL,
|
|
73
|
+
external_email text,
|
|
74
|
+
managed_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
75
|
+
config jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
76
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
77
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
78
|
+
UNIQUE(cloud_user_id, provider)
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
CREATE INDEX IF NOT EXISTS managed_external_accounts_manager_idx
|
|
82
|
+
ON managed_external_accounts(managed_by_user_id, provider);
|
|
83
|
+
|
|
84
|
+
CREATE TABLE IF NOT EXISTS password_reset_otps (
|
|
85
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
86
|
+
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
87
|
+
otp_hash text NOT NULL,
|
|
88
|
+
expires_at timestamptz NOT NULL,
|
|
89
|
+
attempts integer NOT NULL DEFAULT 0,
|
|
90
|
+
max_attempts integer NOT NULL DEFAULT 5,
|
|
91
|
+
used_at timestamptz,
|
|
92
|
+
created_at timestamptz NOT NULL DEFAULT now()
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
CREATE INDEX IF NOT EXISTS password_reset_otps_user_idx
|
|
96
|
+
ON password_reset_otps(user_id, created_at DESC);
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
-- AWS access-key rotation ownership.
|
|
2
|
-
-- The manager/admin provider that manages an IAM user's key is tracked so a
|
|
3
|
-
-- normal user can request self-service rotation without receiving broad IAM
|
|
4
|
-
-- permissions. Managers/admins can rotate keys for users they are allowed to
|
|
5
|
-
-- manage. Secret access keys remain encrypted at rest in IndraQ Cloud.
|
|
6
|
-
|
|
7
|
-
ALTER TABLE managed_aws_credentials
|
|
8
|
-
ADD COLUMN IF NOT EXISTS managed_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL;
|
|
9
|
-
|
|
10
|
-
UPDATE managed_aws_credentials
|
|
11
|
-
SET managed_by_user_id = created_by
|
|
12
|
-
WHERE managed_by_user_id IS NULL
|
|
13
|
-
AND created_by IS NOT NULL;
|
|
14
|
-
|
|
15
|
-
CREATE INDEX IF NOT EXISTS managed_aws_credentials_manager_idx
|
|
16
|
-
ON managed_aws_credentials(managed_by_user_id, cloud_user_id);
|
|
1
|
+
-- AWS access-key rotation ownership.
|
|
2
|
+
-- The manager/admin provider that manages an IAM user's key is tracked so a
|
|
3
|
+
-- normal user can request self-service rotation without receiving broad IAM
|
|
4
|
+
-- permissions. Managers/admins can rotate keys for users they are allowed to
|
|
5
|
+
-- manage. Secret access keys remain encrypted at rest in IndraQ Cloud.
|
|
6
|
+
|
|
7
|
+
ALTER TABLE managed_aws_credentials
|
|
8
|
+
ADD COLUMN IF NOT EXISTS managed_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL;
|
|
9
|
+
|
|
10
|
+
UPDATE managed_aws_credentials
|
|
11
|
+
SET managed_by_user_id = created_by
|
|
12
|
+
WHERE managed_by_user_id IS NULL
|
|
13
|
+
AND created_by IS NOT NULL;
|
|
14
|
+
|
|
15
|
+
CREATE INDEX IF NOT EXISTS managed_aws_credentials_manager_idx
|
|
16
|
+
ON managed_aws_credentials(managed_by_user_id, cloud_user_id);
|