@@ -365,196 +365,6 @@ func (o *teamResourceType) Revoke(ctx context.Context, grant *v2.Grant) (annotat
365365 return nil , nil
366366}
367367
368- // Create creates a new team in a GitHub organization.
369- // The resource must have a parent resource ID that references the organization.
370- // The team name is taken from the resource's DisplayName field.
371- // Optional profile fields:
372- // - description: string - Team description
373- // - privacy: string - "secret" or "closed" (default: "secret")
374- // - parent_team_id: int64 - ID of the parent team for nested teams
375- func (o * teamResourceType ) Create (ctx context.Context , resource * v2.Resource ) (* v2.Resource , annotations.Annotations , error ) {
376- l := ctxzap .Extract (ctx )
377-
378- if resource == nil {
379- return nil , nil , fmt .Errorf ("github-connector: resource cannot be nil" )
380- }
381-
382- if resource .Id == nil || resource .Id .ResourceType != resourceTypeTeam .Id {
383- return nil , nil , fmt .Errorf ("github-connector: invalid resource type for team creation" )
384- }
385-
386- // Get the parent org resource ID
387- parentResourceID := resource .GetParentResourceId ()
388- if parentResourceID == nil {
389- return nil , nil , fmt .Errorf ("github-connector: parent organization resource ID is required to create a team" )
390- }
391-
392- if parentResourceID .ResourceType != resourceTypeOrg .Id {
393- return nil , nil , fmt .Errorf ("github-connector: parent resource must be an organization, got %s" , parentResourceID .ResourceType )
394- }
395-
396- // Get the organization name
397- orgName , err := o .orgCache .GetOrgName (ctx , parentResourceID )
398- if err != nil {
399- return nil , nil , fmt .Errorf ("github-connector: failed to get organization name: %w" , err )
400- }
401-
402- // Get team name from display name
403- teamName := resource .GetDisplayName ()
404- if teamName == "" {
405- return nil , nil , fmt .Errorf ("github-connector: team name (DisplayName) is required" )
406- }
407-
408- l .Info ("github-connector: creating team" ,
409- zap .String ("team_name" , teamName ),
410- zap .String ("org_name" , orgName ),
411- )
412-
413- // Build the NewTeam request
414- newTeam := github.NewTeam {
415- Name : teamName ,
416- }
417-
418- // Extract optional fields from the group trait profile if available
419- groupTrait , err := rType .GetGroupTrait (resource )
420- if err == nil && groupTrait != nil && groupTrait .Profile != nil {
421- // Get description if provided
422- if description , ok := rType .GetProfileStringValue (groupTrait .Profile , "description" ); ok && description != "" {
423- newTeam .Description = github .Ptr (description )
424- }
425-
426- // Get privacy setting if provided ("secret" or "closed")
427- if privacy , ok := rType .GetProfileStringValue (groupTrait .Profile , "privacy" ); ok && privacy != "" {
428- if privacy == "secret" || privacy == "closed" {
429- newTeam .Privacy = github .Ptr (privacy )
430- } else {
431- l .Warn ("github-connector: invalid privacy value, using default" ,
432- zap .String ("provided_privacy" , privacy ),
433- )
434- }
435- }
436-
437- // Get parent team ID if provided (for nested teams)
438- if parentTeamID , ok := rType .GetProfileInt64Value (groupTrait .Profile , "parent_team_id" ); ok && parentTeamID > 0 {
439- newTeam .ParentTeamID = github .Ptr (parentTeamID )
440- }
441- }
442-
443- // Create the team via GitHub API
444- createdTeam , resp , err := o .client .Teams .CreateTeam (ctx , orgName , newTeam )
445- if err != nil {
446- return nil , nil , wrapGitHubError (err , resp , fmt .Sprintf ("github-connector: failed to create team %s in org %s" , teamName , orgName ))
447- }
448-
449- // Extract rate limit data for annotations
450- var annos annotations.Annotations
451- if rateLimitData , err := extractRateLimitData (resp ); err == nil {
452- annos .WithRateLimiting (rateLimitData )
453- }
454-
455- l .Info ("github-connector: team created successfully" ,
456- zap .String ("team_name" , createdTeam .GetName ()),
457- zap .Int64 ("team_id" , createdTeam .GetID ()),
458- zap .String ("team_slug" , createdTeam .GetSlug ()),
459- )
460-
461- // Create the resource representation of the newly created team
462- createdResource , err := teamResource (createdTeam , parentResourceID )
463- if err != nil {
464- return nil , annos , fmt .Errorf ("github-connector: failed to create resource representation for team: %w" , err )
465- }
466-
467- return createdResource , annos , nil
468- }
469-
470- // Delete deletes a team from a GitHub organization.
471- // The team is identified by its resource ID which contains the GitHub team ID.
472- func (o * teamResourceType ) Delete (ctx context.Context , resourceId * v2.ResourceId ) (annotations.Annotations , error ) {
473- l := ctxzap .Extract (ctx )
474-
475- if resourceId == nil {
476- return nil , fmt .Errorf ("github-connector: resource ID cannot be nil" )
477- }
478-
479- if resourceId .ResourceType != resourceTypeTeam .Id {
480- return nil , fmt .Errorf ("github-connector: invalid resource type %s, expected %s" , resourceId .ResourceType , resourceTypeTeam .Id )
481- }
482-
483- // Parse the team ID from the resource
484- teamID , err := strconv .ParseInt (resourceId .GetResource (), 10 , 64 )
485- if err != nil {
486- return nil , fmt .Errorf ("github-connector: invalid team ID %s: %w" , resourceId .GetResource (), err )
487- }
488-
489- l .Info ("github-connector: deleting team" ,
490- zap .Int64 ("team_id" , teamID ),
491- )
492-
493- // We need to find the org that this team belongs to.
494- // We'll iterate through the organizations in the org cache.
495- var annos annotations.Annotations
496- var deleted bool
497- var lastErr error
498- var lastResp * github.Response
499-
500- // Use the org cache to get the list of organizations
501- // We need to iterate through the configured organizations
502- o .orgCache .RLock ()
503- orgIDs := make ([]string , 0 , len (o .orgCache .orgNames ))
504- for orgID := range o .orgCache .orgNames {
505- orgIDs = append (orgIDs , orgID )
506- }
507- o .orgCache .RUnlock ()
508-
509- for _ , orgID := range orgIDs {
510- orgIDInt , err := strconv .ParseInt (orgID , 10 , 64 )
511- if err != nil {
512- continue
513- }
514-
515- // Try to get the team first to verify it exists in this org
516- _ , resp , err := o .client .Teams .GetTeamByID (ctx , orgIDInt , teamID )
517- if err != nil {
518- // Team doesn't exist in this org, continue to next
519- if isNotFoundError (resp ) {
520- continue
521- }
522- lastErr = err
523- lastResp = resp
524- continue
525- }
526-
527- // Team found in this org, delete it
528- resp , err = o .client .Teams .DeleteTeamByID (ctx , orgIDInt , teamID )
529- if err != nil {
530- lastErr = err
531- lastResp = resp
532- continue
533- }
534-
535- // Successfully deleted
536- deleted = true
537- if rateLimitData , err := extractRateLimitData (resp ); err == nil {
538- annos .WithRateLimiting (rateLimitData )
539- }
540-
541- l .Info ("github-connector: team deleted successfully" ,
542- zap .Int64 ("team_id" , teamID ),
543- zap .Int64 ("org_id" , orgIDInt ),
544- )
545- break
546- }
547-
548- if ! deleted {
549- if lastErr != nil {
550- return annos , wrapGitHubError (lastErr , lastResp , fmt .Sprintf ("github-connector: failed to delete team %d" , teamID ))
551- }
552- return annos , fmt .Errorf ("github-connector: team %d not found in any accessible organization" , teamID )
553- }
554-
555- return annos , nil
556- }
557-
558368// ResourceActions registers the resource actions for the team resource type.
559369// This implements the ResourceActionProvider interface.
560370func (o * teamResourceType ) ResourceActions (ctx context.Context , registry actions.ResourceTypeActionRegistry ) error {
0 commit comments