Skip to content
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

feat: deployment freezes #822

Merged
merged 40 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
cf62bb2
wip
benPearce1 Nov 20, 2024
fb919c6
fixed casing on project scope
benPearce1 Nov 21, 2024
1ce7c08
refactored state cleanup to support all functions
benPearce1 Nov 21, 2024
63c094b
added date time schema
benPearce1 Nov 21, 2024
9b1ee2f
fixes for deployment freeze resources
benPearce1 Nov 21, 2024
879becd
store the supplied times in state for create and updated
benPearce1 Nov 21, 2024
84b7fe4
updated client library
benPearce1 Nov 22, 2024
a67a0b6
Merge branch 'main' into bp/deployment-freeze
benPearce1 Nov 22, 2024
b2eb8d6
update following merge
benPearce1 Nov 22, 2024
c761241
reverted incorrect change to missing resource handling
benPearce1 Nov 22, 2024
1aa7b68
added update test to project freeze
benPearce1 Nov 24, 2024
e9da4d6
refresh docs
benPearce1 Nov 25, 2024
9b70c40
extracted deployment freeze project scope out to separate resource
benPearce1 Nov 27, 2024
7660848
updated go-octopusdeploy reference
benPearce1 Nov 27, 2024
c22a0c0
updated examples
benPearce1 Nov 27, 2024
70f2a6b
updated build composite id to take params
benPearce1 Nov 28, 2024
f4ac55b
split deployment freeze project scopes to separate resource and added…
benPearce1 Nov 28, 2024
96dc497
updated go-octopusdeploy reference
benPearce1 Nov 28, 2024
e31e4f4
update go.sum
benPearce1 Nov 28, 2024
efd1d83
updated docs
benPearce1 Nov 28, 2024
9e504eb
missed return statement
benPearce1 Nov 28, 2024
b834bc4
missed return statement
benPearce1 Nov 28, 2024
91da299
updated test to perform update
benPearce1 Nov 28, 2024
268cf29
Merge branch 'main' into bp/deployment-freeze
benPearce1 Nov 28, 2024
a82d9d7
fixed up imports
benPearce1 Nov 28, 2024
dfc11c4
chore: fix docs
domenicsim1 Nov 29, 2024
872fc77
fixed formatting string
benPearce1 Nov 29, 2024
7deb89d
Merge remote-tracking branch 'refs/remotes/origin/bp/deployment-freez…
benPearce1 Nov 29, 2024
0b61d02
deleted tests for testing build issue
benPearce1 Nov 29, 2024
5d661ff
update times to support timezones
benPearce1 Dec 2, 2024
7fb99ab
fix support for empty lists
benPearce1 Dec 2, 2024
714ea23
fix support for empty lists
benPearce1 Dec 2, 2024
8549730
fix support for empty lists, again
benPearce1 Dec 2, 2024
d877f8a
test for fixing test
benPearce1 Dec 2, 2024
6420699
test for fixing test
benPearce1 Dec 2, 2024
2806290
test for fixing test
benPearce1 Dec 2, 2024
8ef300d
skip test due to missing functionality
benPearce1 Dec 2, 2024
14ce0fb
don't need to skip test anymore
benPearce1 Dec 3, 2024
7592d7b
validate environment id list is not empty
benPearce1 Dec 4, 2024
c0b7285
Fix test fail
HuyPhanNguyen Dec 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
@@ -1,18 +1,18 @@
package errors

Check warning on line 1 in internal/errors/error.go

View workflow job for this annotation

GitHub Actions / build

should have a package comment

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"
)

func DeleteFromState(ctx context.Context, d *schema.ResourceData, resource string) diag.Diagnostics {

Check warning on line 15 in internal/errors/error.go

View workflow job for this annotation

GitHub Actions / build

parameter 'ctx' seems to be unused, consider removing or renaming it as _
log.Printf("[INFO] %s (%s) not found; deleting from state", resource, d.Id())
d.SetId("")
return nil
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 @@ -125,6 +126,8 @@ func (p *octopusDeployFrameworkProvider) Resources(ctx context.Context) []func()
NewSSHConnectionWorkerResource,
NewScriptModuleResource,
NewUserResource,
NewDeploymentFreezeResource,
NewDeploymentFreezeProjectResource,
NewServiceAccountOIDCIdentity,
}
}
Expand Down
Loading
Loading