Skip to content

Commit

Permalink
feat: deployment freezes (#822)
Browse files Browse the repository at this point in the history
Co-authored-by: domenicsim1 <[email protected]>
Co-authored-by: Huy Nguyen <[email protected]>
  • Loading branch information
3 people authored Dec 4, 2024
1 parent 1566f96 commit eede862
Show file tree
Hide file tree
Showing 19 changed files with 1,044 additions and 23 deletions.
45 changes: 45 additions & 0 deletions docs/data-sources/deployment_freezes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "octopusdeploy_deployment_freezes Data Source - terraform-provider-octopusdeploy"
subcategory: ""
description: |-
Provides information about deployment freezes
---

# octopusdeploy_deployment_freezes (Data Source)

Provides information about deployment freezes



<!-- schema generated by tfplugindocs -->
## Schema

### Optional

- `environment_ids` (List of String) A filter to search by a list of environment IDs
- `ids` (List of String) A filter to search by a list of IDs.
- `include_complete` (Boolean) Include deployment freezes that completed, default is true
- `partial_name` (String) A filter to search by a partial name.
- `project_ids` (List of String) A filter to search by a list of project IDs
- `skip` (Number) A filter to specify the number of items to skip in the response.
- `status` (String) Filter by the status of the deployment freeze, value values are Expired, Active, Scheduled (case-insensitive)
- `take` (Number) A filter to specify the number of items to take (or return) in the response.

### Read-Only

- `deployment_freezes` (Attributes List) (see [below for nested schema](#nestedatt--deployment_freezes))
- `id` (String) The unique ID for this resource.

<a id="nestedatt--deployment_freezes"></a>
### Nested Schema for `deployment_freezes`

Read-Only:

- `end` (String) The end time of the freeze
- `id` (String) The unique ID for this resource.
- `name` (String) The name of this resource.
- `project_environment_scope` (Map of List of String) The project environment scope of the deployment freeze
- `start` (String) The start time of the freeze


69 changes: 69 additions & 0 deletions docs/resources/deployment_freeze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "octopusdeploy_deployment_freeze Resource - terraform-provider-octopusdeploy"
subcategory: ""
description: |-
---

# octopusdeploy_deployment_freeze (Resource)



## Example Usage

```terraform
# basic freeze with no project scopes
resource "octopusdeploy_deployment_freeze" "freeze" {
name = "Xmas"
start = "2024-12-25T00:00:00+10:00"
end = "2024-12-27T00:00:00+08:00"
}
# Freeze with different timezones and single project/environment scope
resource "octopusdeploy_deployment_freeze" "freeze" {
name = "Xmas"
start = "2024-12-25T00:00:00+10:00"
end = "2024-12-27T00:00:00+08:00"
}
resource "octopusdeploy_deployment_freeze_project" "project_freeze" {
deploymentfreeze_id= octopusdeploy_deployment_freeze.freeze.id
project_id = "Projects-123"
environment_ids = [ "Environments-123", "Environments-456" ]
}
# Freeze with ids sourced from resources and datasources. Projects can be sourced from different spaces, a single scope can only reference projects and environments from the same space.
resource "octopusdeploy_deployment_freeze" "freeze" {
name = "End of financial year shutdown"
start = "2025-06-30T00:00:00+10:00"
end = "2025-07-02T00:00:00+10:00"
}
resource "octopusdeploy_deployment_freeze_project" "project_freeze" {
deploymentfreeze_id = octopusdeploy_deployment_freeze.freeze.id
project_id = resource.octopusdeploy_project.project1.id
environment_ids = [resource.octopusdeploy_environment.production.id]
}
resource "octopusdeploy_deployment_freeze_project" "project_freeze" {
deploymentfreeze_id = octopusdeploy_deployment_freeze.freeze.id
project_id = data.octopusdeploy_projects.second_project.projects[0].id
environment_ids = [ data.octopusdeploy_environments.default_environment.environments[0].id ]
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `end` (String) The end time of the freeze, must be RFC3339 format
- `name` (String) The name of this resource.
- `start` (String) The start time of the freeze, must be RFC3339 format

### Read-Only

- `id` (String) The unique ID for this resource.


31 changes: 31 additions & 0 deletions docs/resources/deployment_freeze_project.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "octopusdeploy_deployment_freeze_project Resource - terraform-provider-octopusdeploy"
subcategory: ""
description: |-
---

# octopusdeploy_deployment_freeze_project (Resource)





<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `deploymentfreeze_id` (String) The deployment freeze ID associated with this freeze scope.
- `project_id` (String) The project ID associated with this freeze scope.

### Optional

- `environment_ids` (List of String) The environment IDs associated with this project deployment freeze scope.

### Read-Only

- `id` (String) The unique ID for this resource.


38 changes: 38 additions & 0 deletions examples/resources/octopusdeploy_deployment_freeze/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# basic freeze with no project scopes
resource "octopusdeploy_deployment_freeze" "freeze" {
name = "Xmas"
start = "2024-12-25T00:00:00+10:00"
end = "2024-12-27T00:00:00+08:00"
}

# Freeze with different timezones and single project/environment scope
resource "octopusdeploy_deployment_freeze" "freeze" {
name = "Xmas"
start = "2024-12-25T00:00:00+10:00"
end = "2024-12-27T00:00:00+08:00"
}

resource "octopusdeploy_deployment_freeze_project" "project_freeze" {
deploymentfreeze_id= octopusdeploy_deployment_freeze.freeze.id
project_id = "Projects-123"
environment_ids = [ "Environments-123", "Environments-456" ]
}

# Freeze with ids sourced from resources and datasources. Projects can be sourced from different spaces, a single scope can only reference projects and environments from the same space.
resource "octopusdeploy_deployment_freeze" "freeze" {
name = "End of financial year shutdown"
start = "2025-06-30T00:00:00+10:00"
end = "2025-07-02T00:00:00+10:00"
}

resource "octopusdeploy_deployment_freeze_project" "project_freeze" {
deploymentfreeze_id = octopusdeploy_deployment_freeze.freeze.id
project_id = resource.octopusdeploy_project.project1.id
environment_ids = [resource.octopusdeploy_environment.production.id]
}

resource "octopusdeploy_deployment_freeze_project" "project_freeze" {
deploymentfreeze_id = octopusdeploy_deployment_freeze.freeze.id
project_id = data.octopusdeploy_projects.second_project.projects[0].id
environment_ids = [ data.octopusdeploy_environments.default_environment.environments[0].id ]
}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/OctopusDeploy/terraform-provider-octopusdeploy
go 1.21

require (
github.com/OctopusDeploy/go-octopusdeploy/v2 v2.60.0
github.com/OctopusDeploy/go-octopusdeploy/v2 v2.62.2
github.com/OctopusSolutionsEngineering/OctopusTerraformTestFramework v0.0.0-20240729041805-46db6fb717b4
github.com/google/uuid v1.6.0
github.com/hashicorp/go-cty v1.4.1-0.20200723130312-85980079f637
Expand Down Expand Up @@ -77,6 +77,7 @@ require (
github.com/hashicorp/logutils v1.0.0 // indirect
github.com/hashicorp/terraform-exec v0.21.0 // indirect
github.com/hashicorp/terraform-json v0.22.1 // indirect
github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0 // indirect
github.com/hashicorp/terraform-registry-address v0.2.3 // indirect
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ github.com/Microsoft/hcsshim v0.12.4 h1:Ev7YUMHAHoWNm+aDSPzc5W9s6E2jyL1szpVDJeZ/
github.com/Microsoft/hcsshim v0.12.4/go.mod h1:Iyl1WVpZzr+UkzjekHZbV8o5Z9ZkxNGx6CtY2Qg/JVQ=
github.com/OctopusDeploy/go-octodiff v1.0.0 h1:U+ORg6azniwwYo+O44giOw6TiD5USk8S4VDhOQ0Ven0=
github.com/OctopusDeploy/go-octodiff v1.0.0/go.mod h1:Mze0+EkOWTgTmi8++fyUc6r0aLZT7qD9gX+31t8MmIU=
github.com/OctopusDeploy/go-octopusdeploy/v2 v2.60.0 h1:9j4IQ1UcAuaTytlBzQ7Mmoy/dLtofYfSGNiM22+sLXs=
github.com/OctopusDeploy/go-octopusdeploy/v2 v2.60.0/go.mod h1:ggvOXzMnq+w0pLg6C9zdjz6YBaHfO3B3tqmmB7JQdaw=
github.com/OctopusDeploy/go-octopusdeploy/v2 v2.62.2 h1:8CexD1Jnf8ng4S6bHilG7s3+iQOraXZY31Dn0SAxjEM=
github.com/OctopusDeploy/go-octopusdeploy/v2 v2.62.2/go.mod h1:ggvOXzMnq+w0pLg6C9zdjz6YBaHfO3B3tqmmB7JQdaw=
github.com/OctopusSolutionsEngineering/OctopusTerraformTestFramework v0.0.0-20240729041805-46db6fb717b4 h1:QfbVf0bOIRMp/WHAWsuVDB7KHoWnRsGbvDuOf2ua7k4=
github.com/OctopusSolutionsEngineering/OctopusTerraformTestFramework v0.0.0-20240729041805-46db6fb717b4/go.mod h1:Oq9KbiRNDBB5jFmrwnrgLX0urIqR/1ptY18TzkqXm7M=
github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg=
Expand Down Expand Up @@ -166,6 +166,8 @@ github.com/hashicorp/terraform-plugin-docs v0.13.0 h1:6e+VIWsVGb6jYJewfzq2ok2smP
github.com/hashicorp/terraform-plugin-docs v0.13.0/go.mod h1:W0oCmHAjIlTHBbvtppWHe8fLfZ2BznQbuv8+UD8OucQ=
github.com/hashicorp/terraform-plugin-framework v1.11.0 h1:M7+9zBArexHFXDx/pKTxjE6n/2UCXY6b8FIq9ZYhwfE=
github.com/hashicorp/terraform-plugin-framework v1.11.0/go.mod h1:qBXLDn69kM97NNVi/MQ9qgd1uWWsVftGSnygYG1tImM=
github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0 h1:v3DapR8gsp3EM8fKMh6up9cJUFQ2iRaFsYLP8UJnCco=
github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0/go.mod h1:c3PnGE9pHBDfdEVG9t1S1C9ia5LW+gkFR0CygXlM8ak=
github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 h1:HOjBuMbOEzl7snOdOoUfE2Jgeto6JOjLVQ39Ls2nksc=
github.com/hashicorp/terraform-plugin-framework-validators v0.12.0/go.mod h1:jfHGE/gzjxYz6XoUwi/aYiiKrJDeutQNUtGQXkaHklg=
github.com/hashicorp/terraform-plugin-go v0.23.0 h1:AALVuU1gD1kPb48aPQUjug9Ir/125t+AAurhqphJ2Co=
Expand Down
2 changes: 1 addition & 1 deletion internal/errors/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package errors

import (
"context"
"github.com/hashicorp/terraform-plugin-framework/resource"
"log"
"net/http"

"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/core"
"github.com/OctopusDeploy/terraform-provider-octopusdeploy/octopusdeploy_framework/schemas"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
Expand Down
122 changes: 122 additions & 0 deletions octopusdeploy_framework/datasource_deployment_freeze.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package octopusdeploy_framework

import (
"context"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/deploymentfreezes"
"github.com/OctopusDeploy/terraform-provider-octopusdeploy/octopusdeploy_framework/schemas"
"github.com/OctopusDeploy/terraform-provider-octopusdeploy/octopusdeploy_framework/util"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"time"
)

const deploymentFreezeDatasourceName = "deployment_freezes"

type deploymentFreezesModel struct {
ID types.String `tfsdk:"id"`
IDs types.List `tfsdk:"ids"`
PartialName types.String `tfsdk:"partial_name"`
ProjectIDs types.List `tfsdk:"project_ids"`
EnvironmentIDs types.List `tfsdk:"environment_ids"`
IncludeComplete types.Bool `tfsdk:"include_complete"`
Status types.String `tfsdk:"status"`
Skip types.Int64 `tfsdk:"skip"`
Take types.Int64 `tfsdk:"take"`
DeploymentFreezes types.List `tfsdk:"deployment_freezes"`
}

type deploymentFreezeDataSource struct {
*Config
}

func (d *deploymentFreezeDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
d.Config = DataSourceConfiguration(req, resp)
}

func NewDeploymentFreezeDataSource() datasource.DataSource {
return &deploymentFreezeDataSource{}
}

func (d *deploymentFreezeDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = util.GetTypeName(deploymentFreezeDatasourceName)
}

func (d *deploymentFreezeDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schemas.DeploymentFreezeSchema{}.GetDatasourceSchema()
}

func (d *deploymentFreezeDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data deploymentFreezesModel
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}

query := deploymentfreezes.DeploymentFreezeQuery{
IDs: util.Ternary(data.IDs.IsNull(), []string{}, util.ExpandStringList(data.IDs)),
PartialName: data.PartialName.ValueString(),
ProjectIds: util.Ternary(data.ProjectIDs.IsNull(), []string{}, util.ExpandStringList(data.ProjectIDs)),
EnvironmentIds: util.Ternary(data.EnvironmentIDs.IsNull(), []string{}, util.ExpandStringList(data.EnvironmentIDs)),
IncludeComplete: data.IncludeComplete.ValueBool(),
Status: data.Status.ValueString(),
Skip: int(data.Skip.ValueInt64()),
Take: int(data.Take.ValueInt64()),
}

util.DatasourceReading(ctx, "deployment freezes", query)

existingFreezes, err := deploymentfreezes.Get(d.Client, query)
if err != nil {
resp.Diagnostics.AddError("unable to load deployment freezes", err.Error())
return
}

flattenedFreezes := []interface{}{}
for _, freeze := range existingFreezes.DeploymentFreezes {
flattenedFreeze, diags := mapFreezeToAttribute(ctx, freeze)
if diags.HasError() {
resp.Diagnostics.Append(diags...)
return
}
flattenedFreezes = append(flattenedFreezes, flattenedFreeze)
}

data.ID = types.StringValue("Deployment Freezes " + time.Now().UTC().String())
data.DeploymentFreezes, _ = types.ListValueFrom(ctx, types.ObjectType{AttrTypes: freezeObjectType()}, flattenedFreezes)
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

var _ datasource.DataSource = &deploymentFreezeDataSource{}
var _ datasource.DataSourceWithConfigure = &deploymentFreezeDataSource{}

func mapFreezeToAttribute(ctx context.Context, freeze deploymentfreezes.DeploymentFreeze) (attr.Value, diag.Diagnostics) {
projectScopes := make(map[string]attr.Value)
for projectId, environmentScopes := range freeze.ProjectEnvironmentScope {
projectScopes[projectId] = util.FlattenStringList(environmentScopes)
}

scopeType, diags := types.MapValueFrom(ctx, types.ListType{ElemType: types.StringType}, projectScopes)
if diags.HasError() {
return nil, diags
}

return types.ObjectValueMust(freezeObjectType(), map[string]attr.Value{
"id": types.StringValue(freeze.ID),
"name": types.StringValue(freeze.Name),
"start": types.StringValue(freeze.Start.Format(time.RFC3339)),
"end": types.StringValue(freeze.End.Format(time.RFC3339)),
"project_environment_scope": scopeType,
}), diags
}

func freezeObjectType() map[string]attr.Type {
return map[string]attr.Type{
"id": types.StringType,
"name": types.StringType,
"start": types.StringType,
"end": types.StringType,
"project_environment_scope": types.MapType{ElemType: types.ListType{ElemType: types.StringType}},
}
}
3 changes: 3 additions & 0 deletions octopusdeploy_framework/framework_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ func (p *octopusDeployFrameworkProvider) DataSources(ctx context.Context) []func
NewUsersDataSource,
NewServiceAccountOIDCIdentityDataSource,
NewWorkersDataSource,
NewDeploymentFreezeDataSource,
}
}

Expand Down Expand Up @@ -126,6 +127,8 @@ func (p *octopusDeployFrameworkProvider) Resources(ctx context.Context) []func()
NewSSHConnectionWorkerResource,
NewScriptModuleResource,
NewUserResource,
NewDeploymentFreezeResource,
NewDeploymentFreezeProjectResource,
NewServiceAccountOIDCIdentity,
}
}
Expand Down
Loading

0 comments on commit eede862

Please sign in to comment.