-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: project versioning strategy resource (#834)
- Loading branch information
1 parent
9361f05
commit d009e07
Showing
7 changed files
with
424 additions
and
2 deletions.
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 |
---|---|---|
@@ -0,0 +1,100 @@ | ||
--- | ||
# generated by https://github.com/hashicorp/terraform-plugin-docs | ||
page_title: "octopusdeploy_project_versioning_strategy Resource - terraform-provider-octopusdeploy" | ||
subcategory: "" | ||
description: |- | ||
--- | ||
|
||
# octopusdeploy_project_versioning_strategy (Resource) | ||
|
||
|
||
|
||
## Example Usage | ||
|
||
```terraform | ||
resource "octopusdeploy_project_group" "tp" { | ||
name = "DevOps Projects" | ||
description = "My DevOps projects group" | ||
} | ||
resource "octopusdeploy_project" "tp" { | ||
name = "My DevOps Project" | ||
description = "test project" | ||
lifecycle_id = "Lifecycles-1" | ||
project_group_id = octopusdeploy_project_group.tp.id | ||
depends_on = [octopusdeploy_project_group.tp] | ||
} | ||
resource "octopusdeploy_deployment_process" "process" { | ||
project_id = octopusdeploy_project.tp.id | ||
step { | ||
name = "Hello World" | ||
target_roles = [ "hello-world" ] | ||
start_trigger = "StartAfterPrevious" | ||
package_requirement = "LetOctopusDecide" | ||
condition = "Success" | ||
run_script_action { | ||
name = "Hello World" | ||
is_disabled = false | ||
is_required = true | ||
script_body = "Write-Host 'hello world'" | ||
script_syntax = "PowerShell" | ||
can_be_used_for_project_versioning = true | ||
sort_order = 1 | ||
package { | ||
name = "Package" | ||
feed_id = "feeds-builtin" | ||
package_id = "myExpressApp" | ||
acquisition_location = "Server" | ||
extract_during_deployment = true | ||
} | ||
} | ||
} | ||
depends_on = [octopusdeploy_project.tp] | ||
} | ||
resource "octopusdeploy_project_versioning_strategy" "tp" { | ||
project_id = octopusdeploy_project.tp.id | ||
space_id = octopusdeploy_project.tp.space_id | ||
donor_package_step_id = octopusdeploy_deployment_process.process.step[0].run_script_action[0].id | ||
donor_package = { | ||
deployment_action = "Hello World" | ||
package_reference = "Package" | ||
} | ||
depends_on = [ | ||
octopusdeploy_project_group.tp, | ||
octopusdeploy_deployment_process.process | ||
] | ||
} | ||
``` | ||
|
||
<!-- schema generated by tfplugindocs --> | ||
## Schema | ||
|
||
### Required | ||
|
||
- `donor_package` (Attributes) Donor Packages. (see [below for nested schema](#nestedatt--donor_package)) | ||
- `project_id` (String) The associated project ID. | ||
- `space_id` (String) Space ID of the associated project. | ||
|
||
### Optional | ||
|
||
- `donor_package_step_id` (String) The associated donor package step ID. | ||
- `template` (String) | ||
|
||
<a id="nestedatt--donor_package"></a> | ||
### Nested Schema for `donor_package` | ||
|
||
Optional: | ||
|
||
- `deployment_action` (String) Deployment action. | ||
- `package_reference` (String) Package reference. | ||
|
||
|
60 changes: 60 additions & 0 deletions
60
examples/resources/octopusdeploy_project_versioning_strategy/resource.tf
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,60 @@ | ||
resource "octopusdeploy_project_group" "tp" { | ||
name = "DevOps Projects" | ||
description = "My DevOps projects group" | ||
} | ||
|
||
resource "octopusdeploy_project" "tp" { | ||
name = "My DevOps Project" | ||
description = "test project" | ||
lifecycle_id = "Lifecycles-1" | ||
project_group_id = octopusdeploy_project_group.tp.id | ||
|
||
depends_on = [octopusdeploy_project_group.tp] | ||
} | ||
|
||
resource "octopusdeploy_deployment_process" "process" { | ||
project_id = octopusdeploy_project.tp.id | ||
|
||
step { | ||
name = "Hello World" | ||
target_roles = [ "hello-world" ] | ||
start_trigger = "StartAfterPrevious" | ||
package_requirement = "LetOctopusDecide" | ||
condition = "Success" | ||
|
||
run_script_action { | ||
name = "Hello World" | ||
is_disabled = false | ||
is_required = true | ||
script_body = "Write-Host 'hello world'" | ||
script_syntax = "PowerShell" | ||
can_be_used_for_project_versioning = true | ||
sort_order = 1 | ||
|
||
|
||
package { | ||
name = "Package" | ||
feed_id = "feeds-builtin" | ||
package_id = "myExpressApp" | ||
acquisition_location = "Server" | ||
extract_during_deployment = true | ||
} | ||
} | ||
} | ||
|
||
depends_on = [octopusdeploy_project.tp] | ||
} | ||
|
||
resource "octopusdeploy_project_versioning_strategy" "tp" { | ||
project_id = octopusdeploy_project.tp.id | ||
space_id = octopusdeploy_project.tp.space_id | ||
donor_package_step_id = octopusdeploy_deployment_process.process.step[0].run_script_action[0].id | ||
donor_package = { | ||
deployment_action = "Hello World" | ||
package_reference = "Package" | ||
} | ||
depends_on = [ | ||
octopusdeploy_project_group.tp, | ||
octopusdeploy_deployment_process.process | ||
] | ||
} |
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
190 changes: 190 additions & 0 deletions
190
octopusdeploy_framework/resource_project_versioning_strategy.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,190 @@ | ||
package octopusdeploy_framework | ||
|
||
import ( | ||
"context" | ||
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/core" | ||
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/packages" | ||
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/projects" | ||
"github.com/OctopusDeploy/terraform-provider-octopusdeploy/octopusdeploy_framework/schemas" | ||
"github.com/OctopusDeploy/terraform-provider-octopusdeploy/octopusdeploy_framework/util" | ||
"github.com/hashicorp/terraform-plugin-framework/resource" | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
"log" | ||
"net/http" | ||
) | ||
|
||
var _ resource.Resource = &projectVersioningStrategyResource{} | ||
|
||
type projectVersioningStrategyResource struct { | ||
*Config | ||
} | ||
|
||
func NewProjectVersioningStrategyResource() resource.Resource { | ||
return &projectVersioningStrategyResource{} | ||
} | ||
|
||
func (r *projectVersioningStrategyResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { | ||
resp.TypeName = util.GetTypeName(schemas.ProjectVersioningStrategyResourceName) | ||
} | ||
|
||
func (r *projectVersioningStrategyResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { | ||
resp.Schema = schemas.ProjectVersioningStrategySchema{}.GetResourceSchema() | ||
} | ||
|
||
func (r *projectVersioningStrategyResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { | ||
r.Config = ResourceConfiguration(req, resp) | ||
} | ||
|
||
func (r *projectVersioningStrategyResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { | ||
var plan schemas.ProjectVersioningStrategyModel | ||
diags := req.Plan.Get(ctx, &plan) | ||
resp.Diagnostics.Append(diags...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
project, err := projects.GetByID(r.Client, plan.SpaceID.ValueString(), plan.ProjectID.ValueString()) | ||
if err != nil { | ||
if apiError, ok := err.(*core.APIError); ok { | ||
if apiError.StatusCode == http.StatusNotFound { | ||
log.Printf("[INFO] associated project (%s) not found; deleting version strategy from state", plan.ProjectID.ValueString()) | ||
resp.State.RemoveResource(ctx) | ||
} | ||
} else { | ||
resp.Diagnostics.AddError("Failed to read associated project", err.Error()) | ||
} | ||
return | ||
} | ||
versioningStrategy := mapStateToProjectVersioningStrategy(&plan) | ||
project.VersioningStrategy = versioningStrategy | ||
|
||
_, err = projects.Update(r.Client, project) | ||
if err != nil { | ||
resp.Diagnostics.AddError("Error updating associated project", err.Error()) | ||
return | ||
} | ||
|
||
updatedProject, err := projects.GetByID(r.Client, plan.SpaceID.ValueString(), plan.ProjectID.ValueString()) | ||
if err != nil { | ||
if apiError, ok := err.(*core.APIError); ok { | ||
if apiError.StatusCode == http.StatusNotFound { | ||
log.Printf("[INFO] associated project (%s) not found; deleting version strategy from state", plan.ProjectID.ValueString()) | ||
resp.State.RemoveResource(ctx) | ||
} | ||
} else { | ||
resp.Diagnostics.AddError("Failed to read associated project", err.Error()) | ||
} | ||
return | ||
} | ||
|
||
mapProjectVersioningStrategyToState(updatedProject.VersioningStrategy, &plan) | ||
resp.Diagnostics.Append(resp.State.Set(ctx, plan)...) | ||
} | ||
|
||
func (r *projectVersioningStrategyResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { | ||
var state schemas.ProjectVersioningStrategyModel | ||
diags := req.State.Get(ctx, &state) | ||
resp.Diagnostics.Append(diags...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
project, err := projects.GetByID(r.Client, state.SpaceID.ValueString(), state.ProjectID.ValueString()) | ||
if err != nil { | ||
if apiError, ok := err.(*core.APIError); ok { | ||
if apiError.StatusCode == http.StatusNotFound { | ||
log.Printf("[INFO] associated project (%s) not found; deleting version strategy from state", state.ProjectID.ValueString()) | ||
resp.State.RemoveResource(ctx) | ||
} | ||
} else { | ||
resp.Diagnostics.AddError("Failed to read associated project", err.Error()) | ||
} | ||
return | ||
} | ||
mapProjectVersioningStrategyToState(project.VersioningStrategy, &state) | ||
|
||
resp.Diagnostics.Append(resp.State.Set(ctx, state)...) | ||
} | ||
|
||
func (r *projectVersioningStrategyResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { | ||
var plan schemas.ProjectVersioningStrategyModel | ||
diags := req.Plan.Get(ctx, &plan) | ||
resp.Diagnostics.Append(diags...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
existingProject, err := projects.GetByID(r.Client, plan.SpaceID.ValueString(), plan.ProjectID.ValueString()) | ||
if err != nil { | ||
resp.Diagnostics.AddError("Error retrieving associated project", err.Error()) | ||
return | ||
} | ||
|
||
versioningStrategy := mapStateToProjectVersioningStrategy(&plan) | ||
existingProject.VersioningStrategy = versioningStrategy | ||
|
||
_, err = projects.Update(r.Client, existingProject) | ||
if err != nil { | ||
resp.Diagnostics.AddError("Error updating associated project", err.Error()) | ||
return | ||
} | ||
|
||
updatedProject, err := projects.GetByID(r.Client, plan.SpaceID.ValueString(), plan.ProjectID.ValueString()) | ||
if err != nil { | ||
resp.Diagnostics.AddError("Error retrieving associated project", err.Error()) | ||
return | ||
} | ||
|
||
mapProjectVersioningStrategyToState(updatedProject.VersioningStrategy, &plan) | ||
resp.Diagnostics.Append(resp.State.Set(ctx, plan)...) | ||
} | ||
|
||
func (r *projectVersioningStrategyResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { | ||
var state schemas.ProjectVersioningStrategyModel | ||
diags := req.State.Get(ctx, &state) | ||
resp.Diagnostics.Append(diags...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
project, err := projects.GetByID(r.Client, state.SpaceID.ValueString(), state.ProjectID.ValueString()) | ||
if err != nil { | ||
resp.Diagnostics.AddError("Error retrieving project", err.Error()) | ||
return | ||
} | ||
|
||
project.VersioningStrategy = &projects.VersioningStrategy{} | ||
_, err = projects.Update(r.Client, project) | ||
if err != nil { | ||
resp.Diagnostics.AddError("Error updating project to remove versioning strategy", err.Error()) | ||
return | ||
} | ||
|
||
resp.State.RemoveResource(ctx) | ||
} | ||
|
||
func mapStateToProjectVersioningStrategy(state *schemas.ProjectVersioningStrategyModel) *projects.VersioningStrategy { | ||
var donorPackageStepID *string | ||
donorPackageStepIDString := state.DonorPackageStepID.ValueString() | ||
if donorPackageStepIDString != "" { | ||
donorPackageStepID = &donorPackageStepIDString | ||
} | ||
|
||
return &projects.VersioningStrategy{ | ||
Template: state.Template.ValueString(), | ||
DonorPackageStepID: donorPackageStepID, | ||
DonorPackage: &packages.DeploymentActionPackage{ | ||
DeploymentAction: state.DonorPackage.DeploymentAction.ValueString(), | ||
PackageReference: state.DonorPackage.PackageReference.ValueString(), | ||
}, | ||
} | ||
} | ||
|
||
func mapProjectVersioningStrategyToState(versioningStrategy *projects.VersioningStrategy, state *schemas.ProjectVersioningStrategyModel) { | ||
if versioningStrategy.DonorPackageStepID != nil { | ||
state.DonorPackageStepID = types.StringValue(*versioningStrategy.DonorPackageStepID) | ||
} | ||
state.Template = types.StringValue(versioningStrategy.Template) | ||
state.DonorPackage.PackageReference = types.StringValue(versioningStrategy.DonorPackage.PackageReference) | ||
state.DonorPackage.DeploymentAction = types.StringValue(versioningStrategy.DonorPackage.DeploymentAction) | ||
} |
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
Oops, something went wrong.