-
Notifications
You must be signed in to change notification settings - Fork 161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support for organization-level default execution mode and agent pool #1137
Merged
Merged
Changes from 17 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
c819ce6
support org-level default agent pool and execution mode
SwiftEngineer e09d1b9
horrific first attempt at allowing users to set organization default …
SwiftEngineer 1e3c62c
use seperate model to support default execution mode to avoid circula…
SwiftEngineer 7d6056e
merge main
SwiftEngineer 7e14b3a
fix erroneous drift when toggling operations from true to false when …
SwiftEngineer c25d26c
Merge branch 'main' into SwiftEngineer/org-level-agent-pools
SwiftEngineer bd56db5
fix agent_pool_id not being set to null after being unset
SwiftEngineer ca9e73d
fmt
SwiftEngineer 8f432dc
fix validations erroring erroneously when the workspace is being set …
SwiftEngineer 70d8c7e
fix for error thrown when switching from the default agent pool to th…
SwiftEngineer 7f5df02
Merge branch 'main' into SwiftEngineer/org-level-agent-pools
SwiftEngineer f6d3bd9
remove default_execution_mode from organization, it is handled via it…
SwiftEngineer cdd8f1b
add changelog entry and documentation
SwiftEngineer 4d4d4df
remove extra space
SwiftEngineer 938dc89
clean up comments
SwiftEngineer 9c38d83
fix agent pool id not receiving new configuration value due to underl…
SwiftEngineer 37019aa
simplify test helper by removing unnecessary cleanup
SwiftEngineer 9d1b0d4
add import docs
SwiftEngineer ca721a3
add note in changelog about execution_mode default changing
SwiftEngineer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -106,44 +106,45 @@ func Provider() *schema.Provider { | |
}, | ||
|
||
ResourcesMap: map[string]*schema.Resource{ | ||
"tfe_admin_organization_settings": resourceTFEAdminOrganizationSettings(), | ||
"tfe_agent_pool": resourceTFEAgentPool(), | ||
"tfe_agent_pool_allowed_workspaces": resourceTFEAgentPoolAllowedWorkspaces(), | ||
"tfe_agent_token": resourceTFEAgentToken(), | ||
"tfe_notification_configuration": resourceTFENotificationConfiguration(), | ||
"tfe_oauth_client": resourceTFEOAuthClient(), | ||
"tfe_organization": resourceTFEOrganization(), | ||
"tfe_organization_membership": resourceTFEOrganizationMembership(), | ||
"tfe_organization_module_sharing": resourceTFEOrganizationModuleSharing(), | ||
"tfe_organization_run_task": resourceTFEOrganizationRunTask(), | ||
"tfe_organization_token": resourceTFEOrganizationToken(), | ||
"tfe_policy": resourceTFEPolicy(), | ||
"tfe_policy_set": resourceTFEPolicySet(), | ||
"tfe_policy_set_parameter": resourceTFEPolicySetParameter(), | ||
"tfe_project": resourceTFEProject(), | ||
"tfe_project_policy_set": resourceTFEProjectPolicySet(), | ||
"tfe_project_variable_set": resourceTFEProjectVariableSet(), | ||
"tfe_registry_module": resourceTFERegistryModule(), | ||
"tfe_no_code_module": resourceTFENoCodeModule(), | ||
"tfe_run_trigger": resourceTFERunTrigger(), | ||
"tfe_sentinel_policy": resourceTFESentinelPolicy(), | ||
"tfe_ssh_key": resourceTFESSHKey(), | ||
"tfe_team": resourceTFETeam(), | ||
"tfe_team_access": resourceTFETeamAccess(), | ||
"tfe_team_organization_member": resourceTFETeamOrganizationMember(), | ||
"tfe_team_organization_members": resourceTFETeamOrganizationMembers(), | ||
"tfe_team_project_access": resourceTFETeamProjectAccess(), | ||
"tfe_team_member": resourceTFETeamMember(), | ||
"tfe_team_members": resourceTFETeamMembers(), | ||
"tfe_team_token": resourceTFETeamToken(), | ||
"tfe_terraform_version": resourceTFETerraformVersion(), | ||
"tfe_workspace": resourceTFEWorkspace(), | ||
"tfe_workspace_run_task": resourceTFEWorkspaceRunTask(), | ||
"tfe_variable_set": resourceTFEVariableSet(), | ||
"tfe_workspace_policy_set": resourceTFEWorkspacePolicySet(), | ||
"tfe_workspace_policy_set_exclusion": resourceTFEWorkspacePolicySetExclusion(), | ||
"tfe_workspace_run": resourceTFEWorkspaceRun(), | ||
"tfe_workspace_variable_set": resourceTFEWorkspaceVariableSet(), | ||
"tfe_admin_organization_settings": resourceTFEAdminOrganizationSettings(), | ||
"tfe_agent_pool": resourceTFEAgentPool(), | ||
"tfe_agent_pool_allowed_workspaces": resourceTFEAgentPoolAllowedWorkspaces(), | ||
"tfe_agent_token": resourceTFEAgentToken(), | ||
"tfe_notification_configuration": resourceTFENotificationConfiguration(), | ||
"tfe_oauth_client": resourceTFEOAuthClient(), | ||
"tfe_organization": resourceTFEOrganization(), | ||
"tfe_organization_default_execution_mode": resourceTFEOrganizationDefaultExecutionMode(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ^ the only line that really changed |
||
"tfe_organization_membership": resourceTFEOrganizationMembership(), | ||
"tfe_organization_module_sharing": resourceTFEOrganizationModuleSharing(), | ||
"tfe_organization_run_task": resourceTFEOrganizationRunTask(), | ||
"tfe_organization_token": resourceTFEOrganizationToken(), | ||
"tfe_policy": resourceTFEPolicy(), | ||
"tfe_policy_set": resourceTFEPolicySet(), | ||
"tfe_policy_set_parameter": resourceTFEPolicySetParameter(), | ||
"tfe_project": resourceTFEProject(), | ||
"tfe_project_policy_set": resourceTFEProjectPolicySet(), | ||
"tfe_project_variable_set": resourceTFEProjectVariableSet(), | ||
"tfe_registry_module": resourceTFERegistryModule(), | ||
"tfe_no_code_module": resourceTFENoCodeModule(), | ||
"tfe_run_trigger": resourceTFERunTrigger(), | ||
"tfe_sentinel_policy": resourceTFESentinelPolicy(), | ||
"tfe_ssh_key": resourceTFESSHKey(), | ||
"tfe_team": resourceTFETeam(), | ||
"tfe_team_access": resourceTFETeamAccess(), | ||
"tfe_team_organization_member": resourceTFETeamOrganizationMember(), | ||
"tfe_team_organization_members": resourceTFETeamOrganizationMembers(), | ||
"tfe_team_project_access": resourceTFETeamProjectAccess(), | ||
"tfe_team_member": resourceTFETeamMember(), | ||
"tfe_team_members": resourceTFETeamMembers(), | ||
"tfe_team_token": resourceTFETeamToken(), | ||
"tfe_terraform_version": resourceTFETerraformVersion(), | ||
"tfe_workspace": resourceTFEWorkspace(), | ||
"tfe_workspace_run_task": resourceTFEWorkspaceRunTask(), | ||
"tfe_variable_set": resourceTFEVariableSet(), | ||
"tfe_workspace_policy_set": resourceTFEWorkspacePolicySet(), | ||
"tfe_workspace_policy_set_exclusion": resourceTFEWorkspacePolicySetExclusion(), | ||
"tfe_workspace_run": resourceTFEWorkspaceRun(), | ||
"tfe_workspace_variable_set": resourceTFEWorkspaceVariableSet(), | ||
}, | ||
ConfigureContextFunc: configure(), | ||
} | ||
|
162 changes: 162 additions & 0 deletions
162
internal/provider/resource_tfe_organization_default_execution_mode.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
package provider | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
tfe "github.com/hashicorp/go-tfe" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" | ||
"log" | ||
) | ||
|
||
func resourceTFEOrganizationDefaultExecutionMode() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceTFEOrganizationDefaultExecutionModeCreate, | ||
Read: resourceTFEOrganizationDefaultExecutionModeRead, | ||
Delete: resourceTFEOrganizationDefaultExecutionModeDelete, | ||
Importer: &schema.ResourceImporter{ | ||
StateContext: resourceTFEOrganizationDefaultExecutionModeImporter, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"organization": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Computed: true, | ||
ForceNew: true, | ||
}, | ||
|
||
"default_execution_mode": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ValidateFunc: validation.StringInSlice( | ||
[]string{ | ||
"agent", | ||
"local", | ||
"remote", | ||
}, | ||
false, | ||
), | ||
ForceNew: true, | ||
}, | ||
|
||
"default_agent_pool_id": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
ForceNew: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceTFEOrganizationDefaultExecutionModeCreate(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(ConfiguredClient) | ||
|
||
// Get the organization name. | ||
organization, err := config.schemaOrDefaultOrganization(d) | ||
if err != nil { | ||
return fmt.Errorf("error getting organization name: %w", err) | ||
} | ||
|
||
// If the "default_agent_pool_id" was provided, get the agent pool | ||
var agentPool *tfe.AgentPool | ||
if v, ok := d.GetOk("default_agent_pool_id"); ok && v.(string) != "" { | ||
agentPool = &tfe.AgentPool{ | ||
ID: v.(string), | ||
} | ||
} | ||
|
||
defaultExecutionMode := "" | ||
if v, ok := d.GetOk("default_execution_mode"); ok { | ||
defaultExecutionMode = v.(string) | ||
} else { | ||
return fmt.Errorf("default_execution_mode was missing from tfstate, please create an issue to report this error") | ||
} | ||
|
||
// set organization default execution mode | ||
_, err = config.Client.Organizations.Update(context.Background(), organization, tfe.OrganizationUpdateOptions{ | ||
DefaultExecutionMode: tfe.String(defaultExecutionMode), | ||
DefaultAgentPool: agentPool, | ||
}) | ||
if err != nil { | ||
return fmt.Errorf("error setting default execution mode of organization %s: %w", d.Id(), err) | ||
} | ||
|
||
d.SetId(organization) | ||
|
||
return resourceTFEOrganizationDefaultExecutionModeRead(d, meta) | ||
} | ||
|
||
func resourceTFEOrganizationDefaultExecutionModeRead(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(ConfiguredClient) | ||
|
||
log.Printf("[DEBUG] Read the organization: %s", d.Id()) | ||
organization, err := config.Client.Organizations.Read(ctx, d.Id()) | ||
if err != nil { | ||
if errors.Is(err, tfe.ErrResourceNotFound) { | ||
log.Printf("[DEBUG] organization %s no longer exists", d.Id()) | ||
d.SetId("") | ||
return nil | ||
} | ||
return fmt.Errorf("error reading organization %s: %w", d.Id(), err) | ||
} | ||
|
||
defaultExecutionMode := "" | ||
if v, ok := d.GetOk("default_execution_mode"); ok { | ||
defaultExecutionMode = v.(string) | ||
} else { | ||
return fmt.Errorf("default_execution_mode was missing from tfstate, please create an issue to report this error") | ||
} | ||
if organization.DefaultExecutionMode != defaultExecutionMode { | ||
// set id to empty string so that the provider knows it needs to set the default execution mode again | ||
d.SetId("") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceTFEOrganizationDefaultExecutionModeDelete(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(ConfiguredClient) | ||
|
||
// Get the organization name. | ||
organization, err := config.schemaOrDefaultOrganization(d) | ||
if err != nil { | ||
return fmt.Errorf("error getting organization name: %w", err) | ||
} | ||
|
||
log.Printf("[DEBUG] Reseting default execution mode of organization: %s", organization) | ||
// reset organization default execution mode | ||
_, err = config.Client.Organizations.Update(context.Background(), organization, tfe.OrganizationUpdateOptions{ | ||
DefaultExecutionMode: tfe.String("remote"), | ||
DefaultAgentPool: nil, | ||
}) | ||
if err != nil { | ||
return fmt.Errorf("error updating organization default execution mode: %w", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceTFEOrganizationDefaultExecutionModeImporter(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { | ||
config := meta.(ConfiguredClient) | ||
|
||
log.Printf("[DEBUG] Read the organization: %s", d.Id()) | ||
organization, err := config.Client.Organizations.Read(ctx, d.Id()) | ||
if err != nil { | ||
if errors.Is(err, tfe.ErrResourceNotFound) { | ||
log.Printf("[DEBUG] organization %s no longer exists", d.Id()) | ||
d.SetId("") | ||
} | ||
return nil, fmt.Errorf("error reading organization %s: %w", d.Id(), err) | ||
} | ||
|
||
// Set the organization field. | ||
d.Set("organization", d.Id()) | ||
d.Set("default_execution_mode", organization.DefaultExecutionMode) | ||
if organization.DefaultAgentPool != nil { | ||
d.Set("default_agent_pool_id", organization.DefaultAgentPool.ID) | ||
} | ||
|
||
return []*schema.ResourceData{d}, nil | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a breaking change which should be highlighted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this breaks the API of the provider or the platform API itself because it's a purely additive change. If you don't change the default at the org level, everything continues to behave as before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah but what if someone does? 🙂
The provider is still pre-1.0 so everything is allowed. I'm just suggesting to add a specific note about this in the changelog.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a fair point. Previously, I was thinking setting the default
execution_mode
in an admission that you were prepared for that change to affect all the workspaces in your organization, but adding a note here couldn't hurt!