@@ -203,7 +203,27 @@ def create(self, organization: str, options: AgentPoolCreateOptions) -> AgentPoo
203203 options .allowed_workspace_policy .value
204204 )
205205
206- payload = {"data" : {"type" : "agent-pools" , "attributes" : attributes }}
206+ relationships : dict [str , Any ] = {}
207+ if options .allowed_workspace_ids :
208+ relationships ["allowed-workspaces" ] = {
209+ "data" : [
210+ {"type" : "workspaces" , "id" : ws_id }
211+ for ws_id in options .allowed_workspace_ids
212+ ]
213+ }
214+ if options .excluded_workspace_ids :
215+ relationships ["excluded-workspaces" ] = {
216+ "data" : [
217+ {"type" : "workspaces" , "id" : ws_id }
218+ for ws_id in options .excluded_workspace_ids
219+ ]
220+ }
221+
222+ payload : dict [str , Any ] = {
223+ "data" : {"type" : "agent-pools" , "attributes" : attributes }
224+ }
225+ if relationships :
226+ payload ["data" ]["relationships" ] = relationships
207227
208228 response = self .t .request ("POST" , path , json_body = payload )
209229 data = response .json ()["data" ]
@@ -320,13 +340,31 @@ def update(self, agent_pool_id: str, options: AgentPoolUpdateOptions) -> AgentPo
320340 options .allowed_workspace_policy .value
321341 )
322342
323- payload = {
343+ relationships : dict [str , Any ] = {}
344+ if options .allowed_workspace_ids :
345+ relationships ["allowed-workspaces" ] = {
346+ "data" : [
347+ {"type" : "workspaces" , "id" : ws_id }
348+ for ws_id in options .allowed_workspace_ids
349+ ]
350+ }
351+ if options .excluded_workspace_ids :
352+ relationships ["excluded-workspaces" ] = {
353+ "data" : [
354+ {"type" : "workspaces" , "id" : ws_id }
355+ for ws_id in options .excluded_workspace_ids
356+ ]
357+ }
358+
359+ payload : dict [str , Any ] = {
324360 "data" : {
325361 "type" : "agent-pools" ,
326362 "id" : agent_pool_id ,
327363 "attributes" : attributes ,
328364 }
329365 }
366+ if relationships :
367+ payload ["data" ]["relationships" ] = relationships
330368
331369 response = self .t .request ("PATCH" , path , json_body = payload )
332370 data = response .json ()["data" ]
@@ -371,13 +409,20 @@ def delete(self, agent_pool_id: str) -> None:
371409
372410 def assign_to_workspaces (
373411 self , agent_pool_id : str , options : AgentPoolAssignToWorkspacesOptions
374- ) -> None :
375- """Assign an agent pool to workspaces.
412+ ) -> AgentPool :
413+ """Assign an agent pool to workspaces by updating the allowed-workspaces
414+ relationship via PATCH /agent-pools/:id.
415+
416+ The provided workspace IDs become the new complete list of allowed
417+ workspaces for this pool (full replacement, not append).
376418
377419 Args:
378420 agent_pool_id: Agent pool ID
379421 options: Assignment options containing workspace IDs
380422
423+ Returns:
424+ Updated AgentPool object
425+
381426 Raises:
382427 ValueError: If parameters are invalid
383428 TFEError: If API request fails
@@ -388,26 +433,67 @@ def assign_to_workspaces(
388433 if not options .workspace_ids :
389434 raise ValueError ("At least one workspace ID is required" )
390435
391- path = f"/api/v2/agent-pools/{ agent_pool_id } /relationships/workspaces"
392-
393- # Create data payload with workspace references
394- workspace_data = []
395436 for workspace_id in options .workspace_ids :
396437 if not valid_string_id (workspace_id ):
397438 raise ValueError (f"Invalid workspace ID: { workspace_id } " )
398- workspace_data .append ({"type" : "workspaces" , "id" : workspace_id })
399439
400- payload = {"data" : workspace_data }
401- self .t .request ("POST" , path , json_body = payload )
440+ path = f"/api/v2/agent-pools/{ agent_pool_id } "
441+ payload : dict [str , Any ] = {
442+ "data" : {
443+ "type" : "agent-pools" ,
444+ "id" : agent_pool_id ,
445+ "attributes" : {},
446+ "relationships" : {
447+ "allowed-workspaces" : {
448+ "data" : [
449+ {"type" : "workspaces" , "id" : ws_id }
450+ for ws_id in options .workspace_ids
451+ ]
452+ }
453+ },
454+ }
455+ }
456+ response = self .t .request ("PATCH" , path , json_body = payload )
457+ data = response .json ()["data" ]
458+
459+ # Extract agent pool data from response
460+ attr = data .get ("attributes" , {}) or {}
461+ agent_pool_data = {
462+ "id" : _safe_str (data .get ("id" )),
463+ "name" : _safe_str (attr .get ("name" )),
464+ "created_at" : attr .get ("created-at" ),
465+ "organization_scoped" : attr .get ("organization-scoped" ),
466+ "allowed_workspace_policy" : attr .get ("allowed-workspace-policy" ),
467+ "agent_count" : attr .get ("agent-count" , 0 ),
468+ }
469+
470+ return AgentPool (
471+ id = _safe_str (agent_pool_data ["id" ]) or "" ,
472+ name = _safe_str (agent_pool_data ["name" ]),
473+ created_at = cast (Any , agent_pool_data ["created_at" ]),
474+ organization_scoped = _safe_bool (agent_pool_data ["organization_scoped" ]),
475+ allowed_workspace_policy = _safe_workspace_policy (
476+ agent_pool_data ["allowed_workspace_policy" ]
477+ ),
478+ agent_count = _safe_int (agent_pool_data ["agent_count" ]),
479+ )
402480
403481 def remove_from_workspaces (
404482 self , agent_pool_id : str , options : AgentPoolRemoveFromWorkspacesOptions
405- ) -> None :
406- """Remove an agent pool from workspaces.
483+ ) -> AgentPool :
484+ """Exclude workspaces from an agent pool by updating the excluded-workspaces
485+ relationship via PATCH /agent-pools/:id.
486+
487+ Use this for organization-scoped pools where most workspaces are allowed
488+ but you want to block specific ones. The provided list becomes the new
489+ complete excluded-workspaces list (full replacement, not append).
407490
408491 Args:
409492 agent_pool_id: Agent pool ID
410- options: Removal options containing workspace IDs
493+ options: Removal options containing workspace IDs to exclude
494+
495+ Returns:
496+ Updated AgentPool object
411497
412498 Raises:
413499 ValueError: If parameters are invalid
@@ -419,14 +505,47 @@ def remove_from_workspaces(
419505 if not options .workspace_ids :
420506 raise ValueError ("At least one workspace ID is required" )
421507
422- path = f"/api/v2/agent-pools/{ agent_pool_id } /relationships/workspaces"
423-
424- # Create data payload with workspace references
425- workspace_data = []
426508 for workspace_id in options .workspace_ids :
427509 if not valid_string_id (workspace_id ):
428510 raise ValueError (f"Invalid workspace ID: { workspace_id } " )
429- workspace_data .append ({"type" : "workspaces" , "id" : workspace_id })
430511
431- payload = {"data" : workspace_data }
432- self .t .request ("DELETE" , path , json_body = payload )
512+ path = f"/api/v2/agent-pools/{ agent_pool_id } "
513+ payload : dict [str , Any ] = {
514+ "data" : {
515+ "type" : "agent-pools" ,
516+ "id" : agent_pool_id ,
517+ "attributes" : {},
518+ "relationships" : {
519+ "excluded-workspaces" : {
520+ "data" : [
521+ {"type" : "workspaces" , "id" : ws_id }
522+ for ws_id in options .workspace_ids
523+ ]
524+ }
525+ },
526+ }
527+ }
528+ response = self .t .request ("PATCH" , path , json_body = payload )
529+ data = response .json ()["data" ]
530+
531+ # Extract agent pool data from response
532+ attr = data .get ("attributes" , {}) or {}
533+ agent_pool_data = {
534+ "id" : _safe_str (data .get ("id" )),
535+ "name" : _safe_str (attr .get ("name" )),
536+ "created_at" : attr .get ("created-at" ),
537+ "organization_scoped" : attr .get ("organization-scoped" ),
538+ "allowed_workspace_policy" : attr .get ("allowed-workspace-policy" ),
539+ "agent_count" : attr .get ("agent-count" , 0 ),
540+ }
541+
542+ return AgentPool (
543+ id = _safe_str (agent_pool_data ["id" ]) or "" ,
544+ name = _safe_str (agent_pool_data ["name" ]),
545+ created_at = cast (Any , agent_pool_data ["created_at" ]),
546+ organization_scoped = _safe_bool (agent_pool_data ["organization_scoped" ]),
547+ allowed_workspace_policy = _safe_workspace_policy (
548+ agent_pool_data ["allowed_workspace_policy" ]
549+ ),
550+ agent_count = _safe_int (agent_pool_data ["agent_count" ]),
551+ )
0 commit comments