@@ -7,10 +7,35 @@ import {t} from '../../i18n/index.js';
77type SandboxModel = OdsComponents [ 'schemas' ] [ 'SandboxModel' ] ;
88type SandboxResourceProfile = OdsComponents [ 'schemas' ] [ 'SandboxResourceProfile' ] ;
99type SandboxState = OdsComponents [ 'schemas' ] [ 'SandboxState' ] ;
10+ type OcapiSettings = OdsComponents [ 'schemas' ] [ 'OcapiSettings' ] ;
11+ type WebDavSettings = OdsComponents [ 'schemas' ] [ 'WebDavSettings' ] ;
12+ type SandboxSettings = OdsComponents [ 'schemas' ] [ 'SandboxSettings' ] ;
1013
1114/** States that indicate sandbox creation has completed (success or failure) */
1215const TERMINAL_STATES = new Set < SandboxState > ( [ 'deleted' , 'failed' , 'started' ] ) ;
1316
17+ /**
18+ * Default OCAPI resources to grant the client ID access to.
19+ * These enable common CI/CD operations like code deployment and job execution.
20+ */
21+ const DEFAULT_OCAPI_RESOURCES : NonNullable < OcapiSettings [ number ] [ 'resources' ] > = [
22+ { resource_id : '/code_versions' , methods : [ 'get' ] , read_attributes : '(**)' , write_attributes : '(**)' } ,
23+ { resource_id : '/code_versions/*' , methods : [ 'patch' , 'delete' ] , read_attributes : '(**)' , write_attributes : '(**)' } ,
24+ { resource_id : '/jobs/*/executions' , methods : [ 'post' ] , read_attributes : '(**)' , write_attributes : '(**)' } ,
25+ { resource_id : '/jobs/*/executions/*' , methods : [ 'get' ] , read_attributes : '(**)' , write_attributes : '(**)' } ,
26+ { resource_id : '/sites/*/cartridges' , methods : [ 'post' ] , read_attributes : '(**)' , write_attributes : '(**)' } ,
27+ ] ;
28+
29+ /**
30+ * Default WebDAV permissions to grant the client ID.
31+ * These enable common operations like code upload and data import/export.
32+ */
33+ const DEFAULT_WEBDAV_PERMISSIONS : WebDavSettings [ number ] [ 'permissions' ] = [
34+ { path : '/impex' , operations : [ 'read_write' ] } ,
35+ { path : '/cartridges' , operations : [ 'read_write' ] } ,
36+ { path : '/static' , operations : [ 'read_write' ] } ,
37+ ] ;
38+
1439/**
1540 * Command to create a new on-demand sandbox.
1641 */
@@ -63,6 +88,11 @@ export default class OdsCreate extends OdsCommand<typeof OdsCreate> {
6388 default : 600 ,
6489 dependsOn : [ 'wait' ] ,
6590 } ) ,
91+ 'set-permissions' : Flags . boolean ( {
92+ description : 'Automatically set OCAPI and WebDAV permissions for the client ID used to create the sandbox' ,
93+ default : true ,
94+ allowNo : true ,
95+ } ) ,
6696 } ;
6797
6898 async run ( ) : Promise < SandboxModel > {
@@ -73,18 +103,30 @@ export default class OdsCreate extends OdsCommand<typeof OdsCreate> {
73103 const wait = this . flags . wait ;
74104 const pollInterval = this . flags [ 'poll-interval' ] ;
75105 const timeout = this . flags . timeout ;
106+ const setPermissions = this . flags [ 'set-permissions' ] ;
76107
77108 this . log ( t ( 'commands.ods.create.creating' , 'Creating sandbox in realm {{realm}}...' , { realm} ) ) ;
78109 this . log ( t ( 'commands.ods.create.profile' , 'Profile: {{profile}}' , { profile} ) ) ;
79110 this . log ( t ( 'commands.ods.create.ttl' , 'TTL: {{ttl}} hours' , { ttl : ttl === 0 ? 'infinite' : String ( ttl ) } ) ) ;
80111
112+ // Build settings with OCAPI and WebDAV permissions if enabled
113+ const settings = this . buildSettings ( setPermissions ) ;
114+ if ( settings ) {
115+ this . log (
116+ t ( 'commands.ods.create.settingPermissions' , 'Setting OCAPI and WebDAV permissions for client ID: {{clientId}}' , {
117+ clientId : this . resolvedConfig . clientId ! ,
118+ } ) ,
119+ ) ;
120+ }
121+
81122 const result = await this . odsClient . POST ( '/sandboxes' , {
82123 body : {
83124 realm,
84125 ttl,
85126 resourceProfile : profile ,
86127 autoScheduled,
87128 analyticsEnabled : false ,
129+ settings,
88130 } ,
89131 } ) ;
90132
@@ -117,6 +159,37 @@ export default class OdsCreate extends OdsCommand<typeof OdsCreate> {
117159 return sandbox ;
118160 }
119161
162+ /**
163+ * Builds the sandbox settings object with OCAPI and WebDAV permissions.
164+ * @param setPermissions - Whether to set permissions for the client ID
165+ * @returns Settings object or undefined if permissions should not be set
166+ */
167+ private buildSettings ( setPermissions : boolean ) : SandboxSettings | undefined {
168+ if ( ! setPermissions ) {
169+ return undefined ;
170+ }
171+
172+ const clientId = this . resolvedConfig . clientId ;
173+ if ( ! clientId ) {
174+ return undefined ;
175+ }
176+
177+ return {
178+ ocapi : [
179+ {
180+ client_id : clientId ,
181+ resources : DEFAULT_OCAPI_RESOURCES ,
182+ } ,
183+ ] ,
184+ webdav : [
185+ {
186+ client_id : clientId ,
187+ permissions : DEFAULT_WEBDAV_PERMISSIONS ,
188+ } ,
189+ ] ,
190+ } ;
191+ }
192+
120193 private printSandboxSummary ( sandbox : SandboxModel ) : void {
121194 const ui = cliui ( { width : process . stdout . columns || 80 } ) ;
122195
0 commit comments