indraq_cli 2.1.0 → 2.2.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.
Files changed (82) hide show
  1. package/CHANGELOG_v2.1.0.md +27 -27
  2. package/CHANGELOG_v2.2.0.md +52 -0
  3. package/LICENSE +21 -21
  4. package/README.md +27 -14
  5. package/RELEASE_CHECKS_v2.2.0.md +27 -0
  6. package/UPGRADE_v2.0_to_v2.1.md +68 -68
  7. package/UPGRADE_v2.1_to_v2.2.md +62 -0
  8. package/cloud-api/.dockerignore +18 -18
  9. package/cloud-api/.env.example +14 -14
  10. package/cloud-api/Dockerfile +19 -19
  11. package/cloud-api/README.md +93 -93
  12. package/cloud-api/dist/index.js +265 -27
  13. package/cloud-api/node_modules/.package-lock.json +1 -1
  14. package/cloud-api/package-lock.json +2 -2
  15. package/cloud-api/package.json +1 -1
  16. package/cloud-api/sql/001_init.sql +8 -8
  17. package/cloud-api/sql/002_user_providers_and_project_resources.sql +40 -40
  18. package/cloud-api/sql/003_environment_infrastructure.sql +19 -19
  19. package/cloud-api/sql/004_managed_aws_credentials.sql +20 -20
  20. package/cloud-api/sql/005_project_members_and_resource_grants.sql +22 -22
  21. package/cloud-api/sql/006_catalog_identity_password_security.sql +96 -96
  22. package/cloud-api/sql/007_aws_access_key_rotation.sql +16 -16
  23. package/cloud-api/sql/008_provider_scopes.sql +91 -91
  24. package/cloud-api/sql/009_scope_user_secrets_and_project_lifecycle.sql +13 -0
  25. package/cloud-api/src/index.ts +164 -27
  26. package/cloud-api/tsconfig.json +18 -18
  27. package/dist/cli/help-content.d.ts.map +1 -1
  28. package/dist/cli/help-content.js +11 -5
  29. package/dist/cli/help-content.js.map +1 -1
  30. package/dist/modules/access/commands/access.command.js +30 -30
  31. package/dist/modules/aws/services/route53-lookup.service.js.map +1 -1
  32. package/dist/modules/cloud/commands/cloud.command.d.ts +4 -0
  33. package/dist/modules/cloud/commands/cloud.command.d.ts.map +1 -1
  34. package/dist/modules/cloud/commands/cloud.command.js +52 -1
  35. package/dist/modules/cloud/commands/cloud.command.js.map +1 -1
  36. package/dist/modules/cloud/index.d.ts.map +1 -1
  37. package/dist/modules/cloud/index.js +4 -1
  38. package/dist/modules/cloud/index.js.map +1 -1
  39. package/dist/modules/cloud/services/cloud-jenkins.service.js +71 -71
  40. package/dist/modules/cloud/services/user-provider.service.d.ts +2 -8
  41. package/dist/modules/cloud/services/user-provider.service.d.ts.map +1 -1
  42. package/dist/modules/cloud/services/user-provider.service.js +7 -35
  43. package/dist/modules/cloud/services/user-provider.service.js.map +1 -1
  44. package/dist/modules/deploy/commands/build.command.d.ts +1 -0
  45. package/dist/modules/deploy/commands/build.command.d.ts.map +1 -1
  46. package/dist/modules/deploy/commands/build.command.js +12 -5
  47. package/dist/modules/deploy/commands/build.command.js.map +1 -1
  48. package/dist/modules/deploy/index.d.ts.map +1 -1
  49. package/dist/modules/deploy/index.js +11 -4
  50. package/dist/modules/deploy/index.js.map +1 -1
  51. package/dist/modules/prebuild/commands/prebuild.command.d.ts +0 -4
  52. package/dist/modules/prebuild/commands/prebuild.command.d.ts.map +1 -1
  53. package/dist/modules/prebuild/commands/prebuild.command.js +34 -38
  54. package/dist/modules/prebuild/commands/prebuild.command.js.map +1 -1
  55. package/dist/modules/prebuild/index.d.ts.map +1 -1
  56. package/dist/modules/prebuild/index.js +4 -8
  57. package/dist/modules/prebuild/index.js.map +1 -1
  58. package/dist/modules/scaffold/services/docker-template.service.js +95 -95
  59. package/dist/modules/scopes/commands/scope.command.d.ts.map +1 -1
  60. package/dist/modules/scopes/commands/scope.command.js +3 -47
  61. package/dist/modules/scopes/commands/scope.command.js.map +1 -1
  62. package/dist/modules/scopes/services/scope-native.service.js +2 -2
  63. package/dist/modules/scopes/services/scope-native.service.js.map +1 -1
  64. package/dist/modules/users/commands/user.command.d.ts +1 -0
  65. package/dist/modules/users/commands/user.command.d.ts.map +1 -1
  66. package/dist/modules/users/commands/user.command.js +15 -1
  67. package/dist/modules/users/commands/user.command.js.map +1 -1
  68. package/dist/modules/users/index.d.ts.map +1 -1
  69. package/dist/modules/users/index.js +1 -0
  70. package/dist/modules/users/index.js.map +1 -1
  71. package/dist/modules/users/providers/jenkins-user.provider.js +95 -95
  72. package/dist/shared/config/config-files.js +7 -7
  73. package/dist/shared/jenkins/jenkins.service.d.ts.map +1 -1
  74. package/dist/shared/jenkins/jenkins.service.js +13 -8
  75. package/dist/shared/jenkins/jenkins.service.js.map +1 -1
  76. package/dist/shared/jenkins/role-strategy-groovy.js +84 -84
  77. package/docs/ARCHITECTURE.md +29 -29
  78. package/docs/CREATE-DEPLOYMENT-reference.groovy +1105 -1105
  79. package/package.json +9 -5
  80. package/templates/jenkins/CREATE-DEPLOYMENT.groovy +1105 -1105
  81. package/templates/jenkins/Jenkinsfile-Mobile-App +759 -759
  82. package/cloud-api/dist/index.js.map +0 -1
@@ -12,89 +12,89 @@ exports.jenkinsRoleStrategyCompatGroovy = void 0;
12
12
  * an older (but still usable) Role Strategy release does not fail during
13
13
  * Groovy compilation before we can print a useful diagnostic.
14
14
  */
15
- exports.jenkinsRoleStrategyCompatGroovy = `
16
- def indraqLoadPluginClass = { String name ->
17
- try { return Jenkins.get().pluginManager.uberClassLoader.loadClass(name) } catch (Throwable ignored) { return null }
18
- }
19
-
20
- def indraqRoleStrategyClass = indraqLoadPluginClass('com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy')
21
- def indraqRoleClass = indraqLoadPluginClass('com.michelin.cio.hudson.plugins.rolestrategy.Role')
22
- def indraqRoleTypeClass = indraqLoadPluginClass('com.synopsys.arc.jenkins.plugins.rolestrategy.RoleType')
23
- def indraqPermissionEntryClass = indraqLoadPluginClass('com.michelin.cio.hudson.plugins.rolestrategy.PermissionEntry')
24
- def indraqAuthorizationTypeClass = indraqLoadPluginClass('com.michelin.cio.hudson.plugins.rolestrategy.AuthorizationType')
25
-
26
- def indraqRequireRoleStrategy = { strategy ->
27
- if (indraqRoleStrategyClass == null || indraqRoleClass == null) {
28
- throw new IllegalStateException('Role Strategy plugin is not installed or its core API is unavailable')
29
- }
30
- if (!indraqRoleStrategyClass.isInstance(strategy)) {
31
- throw new IllegalStateException('Role Strategy plugin must be the active Jenkins authorization strategy; active strategy is ' + strategy.getClass().getName())
32
- }
33
- }
34
-
35
- def indraqRoleType = { String logicalName ->
36
- // Newer Role Strategy releases use RoleType.
37
- if (indraqRoleTypeClass != null) {
38
- try { return indraqRoleTypeClass.getField(logicalName).get(null) } catch (Throwable ignored) {}
39
- try { return java.lang.Enum.valueOf(indraqRoleTypeClass, logicalName) } catch (Throwable ignored) {}
40
- }
41
-
42
- // Older releases use RoleBasedAuthorizationStrategy.GLOBAL/PROJECT/SLAVE
43
- // String keys such as globalRoles/projectRoles.
44
- if (indraqRoleStrategyClass != null) {
45
- def legacyField = logicalName == 'Global' ? 'GLOBAL' : logicalName == 'Project' ? 'PROJECT' : 'SLAVE'
46
- try { return indraqRoleStrategyClass.getField(legacyField).get(null) } catch (Throwable ignored) {}
47
- }
48
-
49
- // Last-resort values used by the plugin's REST/API contract for many years.
50
- if (logicalName == 'Global') return 'globalRoles'
51
- if (logicalName == 'Project') return 'projectRoles'
52
- return 'slaveRoles'
53
- }
54
-
55
- def indraqRoles = { roleMap ->
56
- try { return roleMap.getRoles().toList() } catch (Throwable ignored) {}
57
- try { return roleMap.getGrantedRoles().keySet().toList() } catch (Throwable ignored) {}
58
- return []
59
- }
60
-
61
- def indraqPrincipal = { String sid ->
62
- // Newer releases support typed USER principals.
63
- if (indraqPermissionEntryClass != null && indraqAuthorizationTypeClass != null) {
64
- try {
65
- def userType = indraqAuthorizationTypeClass.getField('USER').get(null)
66
- return indraqPermissionEntryClass.getConstructor(indraqAuthorizationTypeClass, String.class).newInstance(userType, sid)
67
- } catch (Throwable ignored) {}
68
- }
69
- // Older releases accept the String SID directly.
70
- return sid
71
- }
72
-
73
- def indraqAssignRole = { roleMap, role, String sid ->
74
- def principal = indraqPrincipal(sid)
75
- try { roleMap.assignRole(role, principal); return } catch (groovy.lang.MissingMethodException ignored) {}
76
- roleMap.assignRole(role, sid)
77
- }
78
-
79
- def indraqUnassignRole = { roleMap, role, String sid ->
80
- // Remove both newer typed USER assignments and older String/EITHER entries.
81
- // This also cleans identities created by an earlier IndraQ release.
82
- def principal = indraqPrincipal(sid)
83
- try { roleMap.unAssignRole(role, principal) } catch (Throwable ignored) {}
84
- try { roleMap.unAssignRole(role, sid) } catch (Throwable ignored) {}
85
- try { roleMap.deleteRoleSid(principal, role.getName()) } catch (Throwable ignored) {}
86
- try { roleMap.deleteRoleSid(sid, role.getName()) } catch (Throwable ignored) {}
87
- }
88
-
89
- def indraqNewRole = { String name, String pattern, Set permissions ->
90
- if (indraqRoleClass == null) throw new IllegalStateException('Role Strategy Role API is unavailable')
91
- try { return indraqRoleClass.newInstance(name, pattern, permissions) } catch (Throwable first) {
92
- // Global roles in very old versions may expose only Role(String, Set).
93
- if (pattern == '.*') {
94
- try { return indraqRoleClass.newInstance(name, permissions) } catch (Throwable ignored) {}
95
- }
96
- throw first
97
- }
98
- }
15
+ exports.jenkinsRoleStrategyCompatGroovy = `
16
+ def indraqLoadPluginClass = { String name ->
17
+ try { return Jenkins.get().pluginManager.uberClassLoader.loadClass(name) } catch (Throwable ignored) { return null }
18
+ }
19
+
20
+ def indraqRoleStrategyClass = indraqLoadPluginClass('com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy')
21
+ def indraqRoleClass = indraqLoadPluginClass('com.michelin.cio.hudson.plugins.rolestrategy.Role')
22
+ def indraqRoleTypeClass = indraqLoadPluginClass('com.synopsys.arc.jenkins.plugins.rolestrategy.RoleType')
23
+ def indraqPermissionEntryClass = indraqLoadPluginClass('com.michelin.cio.hudson.plugins.rolestrategy.PermissionEntry')
24
+ def indraqAuthorizationTypeClass = indraqLoadPluginClass('com.michelin.cio.hudson.plugins.rolestrategy.AuthorizationType')
25
+
26
+ def indraqRequireRoleStrategy = { strategy ->
27
+ if (indraqRoleStrategyClass == null || indraqRoleClass == null) {
28
+ throw new IllegalStateException('Role Strategy plugin is not installed or its core API is unavailable')
29
+ }
30
+ if (!indraqRoleStrategyClass.isInstance(strategy)) {
31
+ throw new IllegalStateException('Role Strategy plugin must be the active Jenkins authorization strategy; active strategy is ' + strategy.getClass().getName())
32
+ }
33
+ }
34
+
35
+ def indraqRoleType = { String logicalName ->
36
+ // Newer Role Strategy releases use RoleType.
37
+ if (indraqRoleTypeClass != null) {
38
+ try { return indraqRoleTypeClass.getField(logicalName).get(null) } catch (Throwable ignored) {}
39
+ try { return java.lang.Enum.valueOf(indraqRoleTypeClass, logicalName) } catch (Throwable ignored) {}
40
+ }
41
+
42
+ // Older releases use RoleBasedAuthorizationStrategy.GLOBAL/PROJECT/SLAVE
43
+ // String keys such as globalRoles/projectRoles.
44
+ if (indraqRoleStrategyClass != null) {
45
+ def legacyField = logicalName == 'Global' ? 'GLOBAL' : logicalName == 'Project' ? 'PROJECT' : 'SLAVE'
46
+ try { return indraqRoleStrategyClass.getField(legacyField).get(null) } catch (Throwable ignored) {}
47
+ }
48
+
49
+ // Last-resort values used by the plugin's REST/API contract for many years.
50
+ if (logicalName == 'Global') return 'globalRoles'
51
+ if (logicalName == 'Project') return 'projectRoles'
52
+ return 'slaveRoles'
53
+ }
54
+
55
+ def indraqRoles = { roleMap ->
56
+ try { return roleMap.getRoles().toList() } catch (Throwable ignored) {}
57
+ try { return roleMap.getGrantedRoles().keySet().toList() } catch (Throwable ignored) {}
58
+ return []
59
+ }
60
+
61
+ def indraqPrincipal = { String sid ->
62
+ // Newer releases support typed USER principals.
63
+ if (indraqPermissionEntryClass != null && indraqAuthorizationTypeClass != null) {
64
+ try {
65
+ def userType = indraqAuthorizationTypeClass.getField('USER').get(null)
66
+ return indraqPermissionEntryClass.getConstructor(indraqAuthorizationTypeClass, String.class).newInstance(userType, sid)
67
+ } catch (Throwable ignored) {}
68
+ }
69
+ // Older releases accept the String SID directly.
70
+ return sid
71
+ }
72
+
73
+ def indraqAssignRole = { roleMap, role, String sid ->
74
+ def principal = indraqPrincipal(sid)
75
+ try { roleMap.assignRole(role, principal); return } catch (groovy.lang.MissingMethodException ignored) {}
76
+ roleMap.assignRole(role, sid)
77
+ }
78
+
79
+ def indraqUnassignRole = { roleMap, role, String sid ->
80
+ // Remove both newer typed USER assignments and older String/EITHER entries.
81
+ // This also cleans identities created by an earlier IndraQ release.
82
+ def principal = indraqPrincipal(sid)
83
+ try { roleMap.unAssignRole(role, principal) } catch (Throwable ignored) {}
84
+ try { roleMap.unAssignRole(role, sid) } catch (Throwable ignored) {}
85
+ try { roleMap.deleteRoleSid(principal, role.getName()) } catch (Throwable ignored) {}
86
+ try { roleMap.deleteRoleSid(sid, role.getName()) } catch (Throwable ignored) {}
87
+ }
88
+
89
+ def indraqNewRole = { String name, String pattern, Set permissions ->
90
+ if (indraqRoleClass == null) throw new IllegalStateException('Role Strategy Role API is unavailable')
91
+ try { return indraqRoleClass.newInstance(name, pattern, permissions) } catch (Throwable first) {
92
+ // Global roles in very old versions may expose only Role(String, Set).
93
+ if (pattern == '.*') {
94
+ try { return indraqRoleClass.newInstance(name, permissions) } catch (Throwable ignored) {}
95
+ }
96
+ throw first
97
+ }
98
+ }
99
99
  `;
100
100
  //# sourceMappingURL=role-strategy-groovy.js.map
@@ -1,29 +1,29 @@
1
- # IndraQ Architecture
2
-
3
- ## Control plane
4
-
5
- IndraQ CLI communicates with IndraQ Cloud API. PostgreSQL stores identities, roles, projects, shared environments, encrypted user provider credentials, infrastructure associations, managed AWS IAM credentials, and audit logs.
6
-
7
- ## Credential ownership
8
-
9
- AWS, NPM, Jenkins, and GHCR credentials belong to an individual IndraQ user and are reusable across that user's projects.
10
-
11
- They are not organization-wide global secrets and are not copied into each project folder.
12
-
13
- ## Shared environments
14
-
15
- Admins can create any number of shared environments with arbitrary names. An environment is a reusable named target containing an IP and optional region. Health-check protocol, endpoint, port, path, interval, threshold, latency measurement, and SNI are Route53-resource settings selected when DNS is configured.
16
-
17
- PRIMARY/SECONDARY is not an environment property. A FAILOVER DNS resource chooses which environment is PRIMARY and which is SECONDARY for that particular Route53 record.
18
-
19
- ## Project resources
20
-
21
- Projects keep intent and external-resource associations, including GHCR image repositories, Jenkins jobs, Route53 routing/health checks, and NPM proxy hosts. Project membership controls who can discover/re-link a project. Resource grants record access to individual AWS, NPM, and Jenkins resources and are audited.
22
-
23
- ## Prebuild
24
-
25
- Prebuild reconciles rather than blindly creates. It validates user provider configuration, checks existing project associations, asks for the Route53 routing policy first (SIMPLE, FAILOVER, WEIGHTED, or LATENCY), validates Jenkins host ports, configures/repairs Route53 according to that policy, verifies DNS before NPM, and creates/repairs NPM proxy hosts. SIMPLE records never receive a health check; FAILOVER uses PRIMARY/SECONDARY health checks; WEIGHTED/LATENCY may use health checks when requested.
26
-
27
- ## Local state
28
-
29
- The project folder stores the Cloud project ID in `.indraq/project.json`. Reusable provider secrets are resolved from the authenticated user's Cloud account only when required.
1
+ # IndraQ Architecture
2
+
3
+ ## Control plane
4
+
5
+ IndraQ CLI communicates with IndraQ Cloud API. PostgreSQL stores identities, roles, projects, shared environments, encrypted user provider credentials, infrastructure associations, managed AWS IAM credentials, and audit logs.
6
+
7
+ ## Credential ownership
8
+
9
+ AWS, NPM, Jenkins, and GHCR credentials belong to an individual IndraQ user and are reusable across that user's projects.
10
+
11
+ They are not organization-wide global secrets and are not copied into each project folder.
12
+
13
+ ## Shared environments
14
+
15
+ Admins can create any number of shared environments with arbitrary names. An environment is a reusable named target containing an IP and optional region. Health-check protocol, endpoint, port, path, interval, threshold, latency measurement, and SNI are Route53-resource settings selected when DNS is configured.
16
+
17
+ PRIMARY/SECONDARY is not an environment property. A FAILOVER DNS resource chooses which environment is PRIMARY and which is SECONDARY for that particular Route53 record.
18
+
19
+ ## Project resources
20
+
21
+ Projects keep intent and external-resource associations, including GHCR image repositories, Jenkins jobs, Route53 routing/health checks, and NPM proxy hosts. Project membership controls who can discover/re-link a project. Resource grants record access to individual AWS, NPM, and Jenkins resources and are audited.
22
+
23
+ ## Prebuild
24
+
25
+ Prebuild reconciles rather than blindly creates. It validates user provider configuration, checks existing project associations, asks for the Route53 routing policy first (SIMPLE, FAILOVER, WEIGHTED, or LATENCY), validates Jenkins host ports, configures/repairs Route53 according to that policy, verifies DNS before NPM, and creates/repairs NPM proxy hosts. SIMPLE records never receive a health check; FAILOVER uses PRIMARY/SECONDARY health checks; WEIGHTED/LATENCY may use health checks when requested.
26
+
27
+ ## Local state
28
+
29
+ The project folder stores the Cloud project ID in `.indraq/project.json`. Reusable provider secrets are resolved from the authenticated user's Cloud account only when required.