Add autoupdate version and config support to TF provider (#53007)

This commit adds two new singular resources to the Terraform provider:
teleport_version and telpeort-config.
Both got added using the resource 153 pattern (new protoc-X.yaml file)
and it went pretty seamless.

The only specific is that I had to add a provider feature to
automatically set singular resource names as we don't run
CheckAndSetDefaults() locally anymore. This got merged in a separate PR.
This commit is contained in:
Hugo Shaka
2025-03-19 17:55:33 +00:00
committed by GitHub
parent f6dccd8da0
commit 5e73eaf342
26 changed files with 3904 additions and 1 deletions
@@ -0,0 +1,77 @@
---
title: Reference for the teleport_autoupdate_config Terraform data-source
sidebar_label: autoupdate_config
description: This page describes the supported values of the teleport_autoupdate_config data-source of the Teleport Terraform provider.
---
{/*Auto-generated file. Do not edit.*/}
{/*To regenerate, navigate to integrations/terraform and run `make docs`.*/}
{/* schema generated by tfplugindocs */}
## Schema
### Required
- `spec` (Attributes) (see [below for nested schema](#nested-schema-for-spec))
- `version` (String)
### Optional
- `metadata` (Attributes) (see [below for nested schema](#nested-schema-for-metadata))
- `sub_kind` (String)
### Nested Schema for `spec`
Optional:
- `agents` (Attributes) (see [below for nested schema](#nested-schema-for-specagents))
- `tools` (Attributes) (see [below for nested schema](#nested-schema-for-spectools))
### Nested Schema for `spec.agents`
Optional:
- `maintenance_window_duration` (String) maintenance_window_duration is the maintenance window duration. This can only be set if `strategy` is "time-based". Once the window is over, the group transitions to the done state. Existing agents won't be updated until the next maintenance window.
- `mode` (String) mode specifies whether agent autoupdates are enabled, disabled, or paused.
- `schedules` (Attributes) schedules specifies schedules for updates of grouped agents. (see [below for nested schema](#nested-schema-for-specagentsschedules))
- `strategy` (String) strategy to use for updating the agents.
### Nested Schema for `spec.agents.schedules`
Optional:
- `regular` (Attributes List) regular schedules for non-critical versions. (see [below for nested schema](#nested-schema-for-specagentsschedulesregular))
### Nested Schema for `spec.agents.schedules.regular`
Optional:
- `days` (List of String) days when the update can run. Supported values are "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" and "*"
- `name` (String) name of the group
- `start_hour` (Number) start_hour to initiate update
- `wait_hours` (Number) wait_hours after last group succeeds before this group can run. This can only be used when the strategy is "halt-on-failure". This field must be positive.
### Nested Schema for `spec.tools`
Optional:
- `mode` (String) Mode defines state of the client tools auto update.
### Nested Schema for `metadata`
Optional:
- `description` (String) description is object description.
- `expires` (String) expires is a global expiry time header can be set on any resource in the system.
- `labels` (Map of String) labels is a set of labels.
- `name` (String) name is an object name.
@@ -0,0 +1,60 @@
---
title: Reference for the teleport_autoupdate_version Terraform data-source
sidebar_label: autoupdate_version
description: This page describes the supported values of the teleport_autoupdate_version data-source of the Teleport Terraform provider.
---
{/*Auto-generated file. Do not edit.*/}
{/*To regenerate, navigate to integrations/terraform and run `make docs`.*/}
{/* schema generated by tfplugindocs */}
## Schema
### Required
- `spec` (Attributes) (see [below for nested schema](#nested-schema-for-spec))
- `version` (String)
### Optional
- `metadata` (Attributes) (see [below for nested schema](#nested-schema-for-metadata))
- `sub_kind` (String)
### Nested Schema for `spec`
Optional:
- `agents` (Attributes) (see [below for nested schema](#nested-schema-for-specagents))
- `tools` (Attributes) (see [below for nested schema](#nested-schema-for-spectools))
### Nested Schema for `spec.agents`
Optional:
- `mode` (String) autoupdate_mode to use for the rollout
- `schedule` (String) schedule to use for the rollout
- `start_version` (String) start_version is the version to update from.
- `target_version` (String) target_version is the version to update to.
### Nested Schema for `spec.tools`
Optional:
- `target_version` (String) TargetVersion specifies the semantic version required for tools to establish a connection with the cluster. Client tools after connection to the cluster going to be updated to this version automatically.
### Nested Schema for `metadata`
Optional:
- `description` (String) description is object description.
- `expires` (String) expires is a global expiry time header can be set on any resource in the system.
- `labels` (Map of String) labels is a set of labels.
- `name` (String) name is an object name.
@@ -17,6 +17,8 @@ The Teleport Terraform provider supports the following data-sources:
- [`teleport_access_monitoring_rule`](./access_monitoring_rule.mdx)
- [`teleport_app`](./app.mdx)
- [`teleport_auth_preference`](./auth_preference.mdx)
- [`teleport_autoupdate_config`](./autoupdate_config.mdx)
- [`teleport_autoupdate_version`](./autoupdate_version.mdx)
- [`teleport_cluster_maintenance_config`](./cluster_maintenance_config.mdx)
- [`teleport_cluster_networking_config`](./cluster_networking_config.mdx)
- [`teleport_database`](./database.mdx)
@@ -0,0 +1,112 @@
---
title: Reference for the teleport_autoupdate_config Terraform resource
sidebar_label: autoupdate_config
description: This page describes the supported values of the teleport_autoupdate_config resource of the Teleport Terraform provider.
---
{/*Auto-generated file. Do not edit.*/}
{/*To regenerate, navigate to integrations/terraform and run `make docs`.*/}
## Example Usage
```hcl
resource "teleport_autoupdate_config" "test" {
version = "v1"
spec = {
tools = {
mode = "enabled"
}
agents = {
mode = "enabled"
strategy = "halt-on-error"
schedules = {
regular = [
{
name = "dev"
days = ["Mon", "Tue", "Wed", "Thu"]
start_hour : 4
},
{
name = "staging"
days = ["Mon", "Tue", "Wed", "Thu"]
start_hour : 14
},
{
name = "prod"
days = ["Mon", "Tue", "Wed", "Thu"]
start_hour : 14
wait_hours : 24
},
]
}
}
}
}
```
{/* schema generated by tfplugindocs */}
## Schema
### Required
- `spec` (Attributes) (see [below for nested schema](#nested-schema-for-spec))
- `version` (String)
### Optional
- `metadata` (Attributes) (see [below for nested schema](#nested-schema-for-metadata))
- `sub_kind` (String)
### Nested Schema for `spec`
Optional:
- `agents` (Attributes) (see [below for nested schema](#nested-schema-for-specagents))
- `tools` (Attributes) (see [below for nested schema](#nested-schema-for-spectools))
### Nested Schema for `spec.agents`
Optional:
- `maintenance_window_duration` (String) maintenance_window_duration is the maintenance window duration. This can only be set if `strategy` is "time-based". Once the window is over, the group transitions to the done state. Existing agents won't be updated until the next maintenance window.
- `mode` (String) mode specifies whether agent autoupdates are enabled, disabled, or paused.
- `schedules` (Attributes) schedules specifies schedules for updates of grouped agents. (see [below for nested schema](#nested-schema-for-specagentsschedules))
- `strategy` (String) strategy to use for updating the agents.
### Nested Schema for `spec.agents.schedules`
Optional:
- `regular` (Attributes List) regular schedules for non-critical versions. (see [below for nested schema](#nested-schema-for-specagentsschedulesregular))
### Nested Schema for `spec.agents.schedules.regular`
Optional:
- `days` (List of String) days when the update can run. Supported values are "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" and "*"
- `name` (String) name of the group
- `start_hour` (Number) start_hour to initiate update
- `wait_hours` (Number) wait_hours after last group succeeds before this group can run. This can only be used when the strategy is "halt-on-failure". This field must be positive.
### Nested Schema for `spec.tools`
Optional:
- `mode` (String) Mode defines state of the client tools auto update.
### Nested Schema for `metadata`
Optional:
- `description` (String) description is object description.
- `expires` (String) expires is a global expiry time header can be set on any resource in the system.
- `labels` (Map of String) labels is a set of labels.
- `name` (String) name is an object name.
@@ -0,0 +1,77 @@
---
title: Reference for the teleport_autoupdate_version Terraform resource
sidebar_label: autoupdate_version
description: This page describes the supported values of the teleport_autoupdate_version resource of the Teleport Terraform provider.
---
{/*Auto-generated file. Do not edit.*/}
{/*To regenerate, navigate to integrations/terraform and run `make docs`.*/}
## Example Usage
```hcl
resource "teleport_autoupdate_version" "test" {
version = "v1"
spec = {
tools = {
target_version = "1.2.3"
}
agents = {
start_version = "1.2.3"
target_version = "1.2.4"
schedule = "regular"
mode = "enabled"
}
}
}
```
{/* schema generated by tfplugindocs */}
## Schema
### Required
- `spec` (Attributes) (see [below for nested schema](#nested-schema-for-spec))
- `version` (String)
### Optional
- `metadata` (Attributes) (see [below for nested schema](#nested-schema-for-metadata))
- `sub_kind` (String)
### Nested Schema for `spec`
Optional:
- `agents` (Attributes) (see [below for nested schema](#nested-schema-for-specagents))
- `tools` (Attributes) (see [below for nested schema](#nested-schema-for-spectools))
### Nested Schema for `spec.agents`
Optional:
- `mode` (String) autoupdate_mode to use for the rollout
- `schedule` (String) schedule to use for the rollout
- `start_version` (String) start_version is the version to update from.
- `target_version` (String) target_version is the version to update to.
### Nested Schema for `spec.tools`
Optional:
- `target_version` (String) TargetVersion specifies the semantic version required for tools to establish a connection with the cluster. Client tools after connection to the cluster going to be updated to this version automatically.
### Nested Schema for `metadata`
Optional:
- `description` (String) description is object description.
- `expires` (String) expires is a global expiry time header can be set on any resource in the system.
- `labels` (Map of String) labels is a set of labels.
- `name` (String) name is an object name.
@@ -17,6 +17,8 @@ The Teleport Terraform provider supports the following resources:
- [`teleport_access_monitoring_rule`](./access_monitoring_rule.mdx)
- [`teleport_app`](./app.mdx)
- [`teleport_auth_preference`](./auth_preference.mdx)
- [`teleport_autoupdate_config`](./autoupdate_config.mdx)
- [`teleport_autoupdate_version`](./autoupdate_version.mdx)
- [`teleport_bot`](./bot.mdx)
- [`teleport_cluster_maintenance_config`](./cluster_maintenance_config.mdx)
- [`teleport_cluster_networking_config`](./cluster_networking_config.mdx)
+13 -1
View File
@@ -122,11 +122,19 @@ endif
--terraform_out=config=protoc-gen-terraform-workloadidentity.yaml:./tfschema \
teleport/workloadidentity/v1/resource.proto
@protoc \
-I=../../api/proto \
-I=$(PROTOBUF_MOD_PATH) \
--plugin=$(PROTOC_GEN_TERRAFORM) \
--terraform_out=config=protoc-gen-terraform-autoupdate.yaml:./tfschema \
teleport/autoupdate/v1/autoupdate.proto
mv ./tfschema/github.com/gravitational/teleport/api/gen/proto/go/teleport/loginrule/v1/loginrule_terraform.go ./tfschema/loginrule/v1/
mv ./tfschema/github.com/gravitational/teleport/api/gen/proto/go/teleport/accesslist/v1/accesslist_terraform.go ./tfschema/accesslist/v1/
mv ./tfschema/github.com/gravitational/teleport/api/gen/proto/go/teleport/accessmonitoringrules/v1/access_monitoring_rules_terraform.go ./tfschema/accessmonitoringrules/v1/
mv ./tfschema/github.com/gravitational/teleport/api/gen/proto/go/teleport/userprovisioning/v2/statichostuser_terraform.go ./tfschema/userprovisioning/v2/
mv ./tfschema/github.com/gravitational/teleport/api/gen/proto/go/teleport/workloadidentity/v1/resource_terraform.go ./tfschema/workloadidentity/v1/
mv ./tfschema/github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1/autoupdate_terraform.go ./tfschema/autoupdate/v1/
mv ./tfschema/github.com/gravitational/teleport/api/types/device_terraform.go ./tfschema/devicetrust/v1/
rm -r ./tfschema/github.com/
@go run ./gen/main.go
@@ -193,6 +201,10 @@ destroy:
lint:
golangci-lint run -c ../../.golangci.yml
.PHONY: fmt
fmt:
terraform fmt -no-color -recursive
.PHONY: docs
docs: gen-tfschema install
docs: gen-tfschema install fmt
./gen/docs.sh $(VERSION)
@@ -0,0 +1,32 @@
resource "teleport_autoupdate_config" "test" {
version = "v1"
spec = {
tools = {
mode = "enabled"
}
agents = {
mode = "enabled"
strategy = "halt-on-error"
schedules = {
regular = [
{
name = "dev"
days = ["Mon", "Tue", "Wed", "Thu"]
start_hour : 4
},
{
name = "staging"
days = ["Mon", "Tue", "Wed", "Thu"]
start_hour : 14
},
{
name = "prod"
days = ["Mon", "Tue", "Wed", "Thu"]
start_hour : 14
wait_hours : 24
},
]
}
}
}
}
@@ -0,0 +1,14 @@
resource "teleport_autoupdate_version" "test" {
version = "v1"
spec = {
tools = {
target_version = "1.2.3"
}
agents = {
start_version = "1.2.3"
target_version = "1.2.4"
schedule = "regular"
mode = "enabled"
}
}
}
+58
View File
@@ -546,6 +546,60 @@ var (
// We import the package containing kinds, then use ForceSetKind.
ForceSetKind: `"workload_identity"`,
}
autoUpdateVersion = payload{
Name: "AutoUpdateVersion",
TypeName: "AutoUpdateVersion",
VarName: "autoUpdateVersion",
GetMethod: "GetAutoUpdateVersion",
CreateMethod: "CreateAutoUpdateVersion",
UpsertMethodArity: 2,
UpdateMethod: "UpdateAutoUpdateVersion",
DeleteMethod: "DeleteAutoUpdateVersion",
ID: "autoUpdateVersion.Metadata.Name",
Kind: "autoupdate_version",
HasStaticID: false,
ProtoPackage: "autoupdatev1",
ProtoPackagePath: "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1",
SchemaPackage: "schemav1",
SchemaPackagePath: "github.com/gravitational/teleport/integrations/terraform/tfschema/autoupdate/v1",
TerraformResourceType: "teleport_autoupdate_version",
// Since [RFD 153](https://github.com/gravitational/teleport/blob/master/rfd/0153-resource-guidelines.md)
// resources are plain structs
IsPlainStruct: true,
// As 153-style resources don't have CheckAndSetDefaults, we must set the Kind manually.
// We import the package containing kinds, then use ForceSetKind.
ExtraImports: []string{"apitypes \"github.com/gravitational/teleport/api/types\""},
ForceSetKind: "apitypes.KindAutoUpdateVersion",
DefaultName: "apitypes.MetaNameAutoUpdateVersion",
}
autoUpdateConfig = payload{
Name: "AutoUpdateConfig",
TypeName: "AutoUpdateConfig",
VarName: "autoUpdateConfig",
GetMethod: "GetAutoUpdateConfig",
CreateMethod: "CreateAutoUpdateConfig",
UpsertMethodArity: 2,
UpdateMethod: "UpdateAutoUpdateConfig",
DeleteMethod: "DeleteAutoUpdateConfig",
ID: "autoUpdateConfig.Metadata.Name",
Kind: "autoupdate_config",
HasStaticID: false,
ProtoPackage: "autoupdatev1",
ProtoPackagePath: "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1",
SchemaPackage: "schemav1",
SchemaPackagePath: "github.com/gravitational/teleport/integrations/terraform/tfschema/autoupdate/v1",
TerraformResourceType: "teleport_autoupdate_config",
// Since [RFD 153](https://github.com/gravitational/teleport/blob/master/rfd/0153-resource-guidelines.md)
// resources are plain structs
IsPlainStruct: true,
// As 153-style resources don't have CheckAndSetDefaults, we must set the Kind manually.
// We import the package containing kinds, then use ForceSetKind.
ExtraImports: []string{"apitypes \"github.com/gravitational/teleport/api/types\""},
ForceSetKind: "apitypes.KindAutoUpdateConfig",
DefaultName: "apitypes.MetaNameAutoUpdateConfig",
}
)
func main() {
@@ -599,6 +653,10 @@ func genTFSchema() {
generateDataSource(staticHostUser, pluralDataSource)
generateResource(workloadIdentity, pluralResource)
generateDataSource(workloadIdentity, pluralDataSource)
generateResource(autoUpdateVersion, singularResource)
generateDataSource(autoUpdateVersion, singularDataSource)
generateResource(autoUpdateConfig, singularResource)
generateDataSource(autoUpdateConfig, singularDataSource)
}
func generateResource(p payload, tpl string) {
@@ -0,0 +1,86 @@
---
target_package_name: "v1"
default_package_name: "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1"
duration_custom_type: Duration
use_state_for_unknown_by_default: true
# Top-level type names to export
types:
- "AutoUpdateVersion"
- "AutoUpdateConfig"
# These import paths were not being automatically picked up by
# protoc-gen-terraform without these overrides
import_path_overrides:
"types": "github.com/gravitational/teleport/api/types"
"wrappers": "github.com/gravitational/teleport/api/types/wrappers"
"durationpb": "google.golang.org/protobuf/types/known/durationpb"
"timestamppb": "google.golang.org/protobuf/types/known/timestamppb"
"v1": "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1"
"github_com_gravitational_teleport_integrations_terraform_tfschema": "github.com/gravitational/teleport/integrations/terraform/tfschema"
# id field is required for integration tests. It is not used by provider.
# We have to add it manually (might be removed in the future versions).
injected_fields:
AutoUpdateConfig:
-
name: id
type: github.com/hashicorp/terraform-plugin-framework/types.StringType
computed: true
plan_modifiers:
- "github.com/hashicorp/terraform-plugin-framework/tfsdk.UseStateForUnknown()"
AutoUpdateVersion:
-
name: id
type: github.com/hashicorp/terraform-plugin-framework/types.StringType
computed: true
plan_modifiers:
- "github.com/hashicorp/terraform-plugin-framework/tfsdk.UseStateForUnknown()"
# These fields will be excluded
exclude_fields:
# Metadata (we id resources by name on our side)
- "AutoUpdateConfig.metadata.id"
- "AutoUpdateVersion.metadata.id"
# These fields will be marked as Computed: true
computed_fields:
# Metadata
- "AutoUpdateVersion.metadata"
- "AutoUpdateVersion.metadata.name"
- "AutoUpdateVersion.metadata.namespace"
- "AutoUpdateVersion.kind"
- "AutoUpdateConfig.metadata"
- "AutoUpdateConfig.metadata.name"
- "AutoUpdateConfig.metadata.namespace"
- "AutoUpdateConfig.kind"
# These fields will be marked as Required: true
required_fields:
- "AutoUpdateVersion.version"
- "AutoUpdateVersion.spec"
- "AutoUpdateConfig.version"
- "AutoUpdateConfig.spec"
plan_modifiers:
# Force to recreate resource if it's name changes
Metadata.name:
- "github.com/hashicorp/terraform-plugin-framework/tfsdk.RequiresReplace()"
# This must be defined for the generator to be happy, but in reality all time
# fields are overridden (because the protobuf timestamps contain locks and the
# linter gets mad if we use raw structs instead of pointers).
time_type:
type: "PlaceholderType"
duration_type:
type: "PlaceholderType"
validators:
# Expires must be in the future
Metadata.expires:
- github_com_gravitational_teleport_integrations_terraform_tfschema.MustTimeBeInFuture()
custom_types:
"AutoUpdateVersion.metadata.expires": Timestamp
"AutoUpdateConfig.metadata.expires": Timestamp
"AutoUpdateConfig.spec.agents.maintenance_window_duration": Duration
@@ -0,0 +1,88 @@
// Code generated by _gen/main.go DO NOT EDIT
/*
Copyright 2015-2024 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package provider
import (
"context"
"github.com/gravitational/trace"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
schemav1 "github.com/gravitational/teleport/integrations/terraform/tfschema/autoupdate/v1"
)
// dataSourceTeleportAutoUpdateConfigType is the data source metadata type
type dataSourceTeleportAutoUpdateConfigType struct{}
// dataSourceTeleportAutoUpdateConfig is the resource
type dataSourceTeleportAutoUpdateConfig struct {
p Provider
}
// GetSchema returns the data source schema
func (r dataSourceTeleportAutoUpdateConfigType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) {
return schemav1.GenSchemaAutoUpdateConfig(ctx)
}
// NewDataSource creates the empty data source
func (r dataSourceTeleportAutoUpdateConfigType) NewDataSource(_ context.Context, p tfsdk.Provider) (tfsdk.DataSource, diag.Diagnostics) {
return dataSourceTeleportAutoUpdateConfig{
p: *(p.(*Provider)),
}, nil
}
// Read reads teleport AutoUpdateConfig
func (r dataSourceTeleportAutoUpdateConfig) Read(ctx context.Context, req tfsdk.ReadDataSourceRequest, resp *tfsdk.ReadDataSourceResponse) {
autoUpdateConfigI, err := r.p.Client.GetAutoUpdateConfig(ctx)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateConfig", trace.Wrap(err), "autoupdate_config"))
return
}
var state types.Object
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}
autoUpdateConfig := autoUpdateConfigI
diags := schemav1.CopyAutoUpdateConfigToTerraform(ctx, autoUpdateConfig, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
// Todo: Remove after updating terraform-plugin to >=v1.5.0.
// terraform-plugin-testing version <1.5.0 requires data resources to
// implement the 'id' attribute.
// https://developer.hashicorp.com/terraform/plugin/framework/acctests#no-id-found-in-attributes
v, ok := state.Attrs["id"]
if !ok || v.IsNull() {
id := autoUpdateConfig.Metadata.Name
state.Attrs["id"] = types.String{Value: id}
}
diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
@@ -0,0 +1,88 @@
// Code generated by _gen/main.go DO NOT EDIT
/*
Copyright 2015-2024 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package provider
import (
"context"
"github.com/gravitational/trace"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
schemav1 "github.com/gravitational/teleport/integrations/terraform/tfschema/autoupdate/v1"
)
// dataSourceTeleportAutoUpdateVersionType is the data source metadata type
type dataSourceTeleportAutoUpdateVersionType struct{}
// dataSourceTeleportAutoUpdateVersion is the resource
type dataSourceTeleportAutoUpdateVersion struct {
p Provider
}
// GetSchema returns the data source schema
func (r dataSourceTeleportAutoUpdateVersionType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) {
return schemav1.GenSchemaAutoUpdateVersion(ctx)
}
// NewDataSource creates the empty data source
func (r dataSourceTeleportAutoUpdateVersionType) NewDataSource(_ context.Context, p tfsdk.Provider) (tfsdk.DataSource, diag.Diagnostics) {
return dataSourceTeleportAutoUpdateVersion{
p: *(p.(*Provider)),
}, nil
}
// Read reads teleport AutoUpdateVersion
func (r dataSourceTeleportAutoUpdateVersion) Read(ctx context.Context, req tfsdk.ReadDataSourceRequest, resp *tfsdk.ReadDataSourceResponse) {
autoUpdateVersionI, err := r.p.Client.GetAutoUpdateVersion(ctx)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateVersion", trace.Wrap(err), "autoupdate_version"))
return
}
var state types.Object
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}
autoUpdateVersion := autoUpdateVersionI
diags := schemav1.CopyAutoUpdateVersionToTerraform(ctx, autoUpdateVersion, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
// Todo: Remove after updating terraform-plugin to >=v1.5.0.
// terraform-plugin-testing version <1.5.0 requires data resources to
// implement the 'id' attribute.
// https://developer.hashicorp.com/terraform/plugin/framework/acctests#no-id-found-in-attributes
v, ok := state.Attrs["id"]
if !ok || v.IsNull() {
id := autoUpdateVersion.Metadata.Name
state.Attrs["id"] = types.String{Value: id}
}
diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
@@ -518,6 +518,8 @@ func (p *Provider) GetResources(_ context.Context) (map[string]tfsdk.ResourceTyp
"teleport_access_monitoring_rule": resourceTeleportAccessMonitoringRuleType{},
"teleport_static_host_user": resourceTeleportStaticHostUserType{},
"teleport_workload_identity": resourceTeleportWorkloadIdentityType{},
"teleport_autoupdate_version": resourceTeleportAutoUpdateVersionType{},
"teleport_autoupdate_config": resourceTeleportAutoUpdateConfigType{},
}, nil
}
@@ -546,6 +548,8 @@ func (p *Provider) GetDataSources(_ context.Context) (map[string]tfsdk.DataSourc
"teleport_access_monitoring_rule": dataSourceTeleportAccessMonitoringRuleType{},
"teleport_static_host_user": dataSourceTeleportStaticHostUserType{},
"teleport_workload_identity": dataSourceTeleportWorkloadIdentityType{},
"teleport_autoupdate_version": dataSourceTeleportAutoUpdateVersionType{},
"teleport_autoupdate_config": dataSourceTeleportAutoUpdateConfigType{},
}, nil
}
@@ -0,0 +1,291 @@
// Code generated by _gen/main.go DO NOT EDIT
/*
Copyright 2015-2024 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package provider
import (
"context"
"fmt"
apitypes "github.com/gravitational/teleport/api/types"
autoupdatev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1"
headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1"
"github.com/gravitational/teleport/integrations/lib/backoff"
"github.com/gravitational/trace"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/jonboulle/clockwork"
schemav1 "github.com/gravitational/teleport/integrations/terraform/tfschema/autoupdate/v1"
)
// resourceTeleportAutoUpdateConfigType is the resource metadata type
type resourceTeleportAutoUpdateConfigType struct{}
// resourceTeleportAutoUpdateConfig is the resource
type resourceTeleportAutoUpdateConfig struct {
p Provider
}
// GetSchema returns the resource schema
func (r resourceTeleportAutoUpdateConfigType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) {
return schemav1.GenSchemaAutoUpdateConfig(ctx)
}
// NewResource creates the empty resource
func (r resourceTeleportAutoUpdateConfigType) NewResource(_ context.Context, p tfsdk.Provider) (tfsdk.Resource, diag.Diagnostics) {
return resourceTeleportAutoUpdateConfig{
p: *(p.(*Provider)),
}, nil
}
// Create creates the AutoUpdateConfig
func (r resourceTeleportAutoUpdateConfig) Create(ctx context.Context, req tfsdk.CreateResourceRequest, resp *tfsdk.CreateResourceResponse) {
if !r.p.IsConfigured(resp.Diagnostics) {
return
}
var plan types.Object
diags := req.Plan.Get(ctx, &plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
autoUpdateConfig := &autoupdatev1.AutoUpdateConfig{}
diags = schemav1.CopyAutoUpdateConfigFromTerraform(ctx, plan, autoUpdateConfig)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
autoUpdateConfig.Kind = apitypes.KindAutoUpdateConfig
if autoUpdateConfig.GetMetadata() == nil {
autoUpdateConfig.Metadata = &headerv1.Metadata{}
}
if autoUpdateConfig.GetMetadata().GetName() == "" {
autoUpdateConfig.Metadata.Name = apitypes.MetaNameAutoUpdateConfig
}
autoUpdateConfigBefore, err := r.p.Client.GetAutoUpdateConfig(ctx)
if err != nil && !trace.IsNotFound(err) {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateConfig", trace.Wrap(err), "autoupdate_config"))
return
}
_, err = r.p.Client.CreateAutoUpdateConfig(ctx, autoUpdateConfig)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error creating AutoUpdateConfig", trace.Wrap(err), "autoupdate_config"))
return
}
// Not really an inferface, just using the same name for easier templating.
var autoUpdateConfigI *autoupdatev1.AutoUpdateConfig
tries := 0
backoff := backoff.NewDecorr(r.p.RetryConfig.Base, r.p.RetryConfig.Cap, clockwork.NewRealClock())
for {
tries = tries + 1
autoUpdateConfigI, err = r.p.Client.GetAutoUpdateConfig(ctx)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateConfig", trace.Wrap(err), "autoupdate_config"))
return
}
previousMetadata := autoUpdateConfigBefore.GetMetadata()
currentMetadata := autoUpdateConfigI.GetMetadata()
if previousMetadata.GetRevision() != currentMetadata.GetRevision() || false {
break
}
if bErr := backoff.Do(ctx); bErr != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateConfig", trace.Wrap(bErr), "autoupdate_config"))
return
}
if tries >= r.p.RetryConfig.MaxTries {
diagMessage := fmt.Sprintf("Error reading AutoUpdateConfig (tried %d times) - state outdated, please import resource", tries)
resp.Diagnostics.AddError(diagMessage, "autoupdate_config")
return
}
}
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateConfig", trace.Wrap(err), "autoupdate_config"))
return
}
autoUpdateConfig = autoUpdateConfigI
diags = schemav1.CopyAutoUpdateConfigToTerraform(ctx, autoUpdateConfig, &plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
plan.Attrs["id"] = types.String{Value: autoUpdateConfig.Metadata.Name}
diags = resp.State.Set(ctx, &plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
// Read reads teleport AutoUpdateConfig
func (r resourceTeleportAutoUpdateConfig) Read(ctx context.Context, req tfsdk.ReadResourceRequest, resp *tfsdk.ReadResourceResponse) {
var state types.Object
diags := req.State.Get(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
autoUpdateConfigI, err := r.p.Client.GetAutoUpdateConfig(ctx)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateConfig", trace.Wrap(err), "autoupdate_config"))
return
}
autoUpdateConfig := autoUpdateConfigI
diags = schemav1.CopyAutoUpdateConfigToTerraform(ctx, autoUpdateConfig, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
// Update updates teleport AutoUpdateConfig
func (r resourceTeleportAutoUpdateConfig) Update(ctx context.Context, req tfsdk.UpdateResourceRequest, resp *tfsdk.UpdateResourceResponse) {
if !r.p.IsConfigured(resp.Diagnostics) {
return
}
var plan types.Object
diags := req.Plan.Get(ctx, &plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
autoUpdateConfig := &autoupdatev1.AutoUpdateConfig{}
diags = schemav1.CopyAutoUpdateConfigFromTerraform(ctx, plan, autoUpdateConfig)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
autoUpdateConfigBefore, err := r.p.Client.GetAutoUpdateConfig(ctx)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateConfig", trace.Wrap(err), "autoupdate_config"))
return
}
_, err = r.p.Client.UpdateAutoUpdateConfig(ctx, autoUpdateConfig)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error updating AutoUpdateConfig", trace.Wrap(err), "autoupdate_config"))
return
}
var autoUpdateConfigI *autoupdatev1.AutoUpdateConfig
tries := 0
backoff := backoff.NewDecorr(r.p.RetryConfig.Base, r.p.RetryConfig.Cap, clockwork.NewRealClock())
for {
tries = tries + 1
autoUpdateConfigI, err = r.p.Client.GetAutoUpdateConfig(ctx)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateConfig", trace.Wrap(err), "autoupdate_config"))
return
}
if autoUpdateConfigBefore.GetMetadata().Revision != autoUpdateConfigI.GetMetadata().Revision || false {
break
}
if bErr := backoff.Do(ctx); bErr != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateConfig", trace.Wrap(bErr), "autoupdate_config"))
return
}
if tries >= r.p.RetryConfig.MaxTries {
diagMessage := fmt.Sprintf("Error reading AutoUpdateConfig (tried %d times) - state outdated, please import resource", tries)
resp.Diagnostics.AddError(diagMessage, "autoupdate_config")
return
}
}
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateConfig", trace.Wrap(err), "autoupdate_config"))
return
}
autoUpdateConfig = autoUpdateConfigI
diags = resp.State.Set(ctx, plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
// Delete deletes Teleport AutoUpdateConfig
func (r resourceTeleportAutoUpdateConfig) Delete(ctx context.Context, req tfsdk.DeleteResourceRequest, resp *tfsdk.DeleteResourceResponse) {
err := r.p.Client.DeleteAutoUpdateConfig(ctx)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error deleting AutoUpdateConfig", trace.Wrap(err), "autoupdate_config"))
return
}
resp.State.RemoveResource(ctx)
}
// ImportState imports AutoUpdateConfig state
func (r resourceTeleportAutoUpdateConfig) ImportState(ctx context.Context, req tfsdk.ImportResourceStateRequest, resp *tfsdk.ImportResourceStateResponse) {
autoUpdateConfigI, err := r.p.Client.GetAutoUpdateConfig(ctx)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error updating AutoUpdateConfig", trace.Wrap(err), "autoupdate_config"))
return
}
autoUpdateConfig := autoUpdateConfigI
var state types.Object
diags := resp.State.Get(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
diags = schemav1.CopyAutoUpdateConfigToTerraform(ctx, autoUpdateConfig, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
id := autoUpdateConfig.Metadata.Name
state.Attrs["id"] = types.String{Value: id}
diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
@@ -0,0 +1,291 @@
// Code generated by _gen/main.go DO NOT EDIT
/*
Copyright 2015-2024 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package provider
import (
"context"
"fmt"
apitypes "github.com/gravitational/teleport/api/types"
autoupdatev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1"
headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1"
"github.com/gravitational/teleport/integrations/lib/backoff"
"github.com/gravitational/trace"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/jonboulle/clockwork"
schemav1 "github.com/gravitational/teleport/integrations/terraform/tfschema/autoupdate/v1"
)
// resourceTeleportAutoUpdateVersionType is the resource metadata type
type resourceTeleportAutoUpdateVersionType struct{}
// resourceTeleportAutoUpdateVersion is the resource
type resourceTeleportAutoUpdateVersion struct {
p Provider
}
// GetSchema returns the resource schema
func (r resourceTeleportAutoUpdateVersionType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) {
return schemav1.GenSchemaAutoUpdateVersion(ctx)
}
// NewResource creates the empty resource
func (r resourceTeleportAutoUpdateVersionType) NewResource(_ context.Context, p tfsdk.Provider) (tfsdk.Resource, diag.Diagnostics) {
return resourceTeleportAutoUpdateVersion{
p: *(p.(*Provider)),
}, nil
}
// Create creates the AutoUpdateVersion
func (r resourceTeleportAutoUpdateVersion) Create(ctx context.Context, req tfsdk.CreateResourceRequest, resp *tfsdk.CreateResourceResponse) {
if !r.p.IsConfigured(resp.Diagnostics) {
return
}
var plan types.Object
diags := req.Plan.Get(ctx, &plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
autoUpdateVersion := &autoupdatev1.AutoUpdateVersion{}
diags = schemav1.CopyAutoUpdateVersionFromTerraform(ctx, plan, autoUpdateVersion)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
autoUpdateVersion.Kind = apitypes.KindAutoUpdateVersion
if autoUpdateVersion.GetMetadata() == nil {
autoUpdateVersion.Metadata = &headerv1.Metadata{}
}
if autoUpdateVersion.GetMetadata().GetName() == "" {
autoUpdateVersion.Metadata.Name = apitypes.MetaNameAutoUpdateVersion
}
autoUpdateVersionBefore, err := r.p.Client.GetAutoUpdateVersion(ctx)
if err != nil && !trace.IsNotFound(err) {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateVersion", trace.Wrap(err), "autoupdate_version"))
return
}
_, err = r.p.Client.CreateAutoUpdateVersion(ctx, autoUpdateVersion)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error creating AutoUpdateVersion", trace.Wrap(err), "autoupdate_version"))
return
}
// Not really an inferface, just using the same name for easier templating.
var autoUpdateVersionI *autoupdatev1.AutoUpdateVersion
tries := 0
backoff := backoff.NewDecorr(r.p.RetryConfig.Base, r.p.RetryConfig.Cap, clockwork.NewRealClock())
for {
tries = tries + 1
autoUpdateVersionI, err = r.p.Client.GetAutoUpdateVersion(ctx)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateVersion", trace.Wrap(err), "autoupdate_version"))
return
}
previousMetadata := autoUpdateVersionBefore.GetMetadata()
currentMetadata := autoUpdateVersionI.GetMetadata()
if previousMetadata.GetRevision() != currentMetadata.GetRevision() || false {
break
}
if bErr := backoff.Do(ctx); bErr != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateVersion", trace.Wrap(bErr), "autoupdate_version"))
return
}
if tries >= r.p.RetryConfig.MaxTries {
diagMessage := fmt.Sprintf("Error reading AutoUpdateVersion (tried %d times) - state outdated, please import resource", tries)
resp.Diagnostics.AddError(diagMessage, "autoupdate_version")
return
}
}
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateVersion", trace.Wrap(err), "autoupdate_version"))
return
}
autoUpdateVersion = autoUpdateVersionI
diags = schemav1.CopyAutoUpdateVersionToTerraform(ctx, autoUpdateVersion, &plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
plan.Attrs["id"] = types.String{Value: autoUpdateVersion.Metadata.Name}
diags = resp.State.Set(ctx, &plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
// Read reads teleport AutoUpdateVersion
func (r resourceTeleportAutoUpdateVersion) Read(ctx context.Context, req tfsdk.ReadResourceRequest, resp *tfsdk.ReadResourceResponse) {
var state types.Object
diags := req.State.Get(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
autoUpdateVersionI, err := r.p.Client.GetAutoUpdateVersion(ctx)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateVersion", trace.Wrap(err), "autoupdate_version"))
return
}
autoUpdateVersion := autoUpdateVersionI
diags = schemav1.CopyAutoUpdateVersionToTerraform(ctx, autoUpdateVersion, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
// Update updates teleport AutoUpdateVersion
func (r resourceTeleportAutoUpdateVersion) Update(ctx context.Context, req tfsdk.UpdateResourceRequest, resp *tfsdk.UpdateResourceResponse) {
if !r.p.IsConfigured(resp.Diagnostics) {
return
}
var plan types.Object
diags := req.Plan.Get(ctx, &plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
autoUpdateVersion := &autoupdatev1.AutoUpdateVersion{}
diags = schemav1.CopyAutoUpdateVersionFromTerraform(ctx, plan, autoUpdateVersion)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
autoUpdateVersionBefore, err := r.p.Client.GetAutoUpdateVersion(ctx)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateVersion", trace.Wrap(err), "autoupdate_version"))
return
}
_, err = r.p.Client.UpdateAutoUpdateVersion(ctx, autoUpdateVersion)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error updating AutoUpdateVersion", trace.Wrap(err), "autoupdate_version"))
return
}
var autoUpdateVersionI *autoupdatev1.AutoUpdateVersion
tries := 0
backoff := backoff.NewDecorr(r.p.RetryConfig.Base, r.p.RetryConfig.Cap, clockwork.NewRealClock())
for {
tries = tries + 1
autoUpdateVersionI, err = r.p.Client.GetAutoUpdateVersion(ctx)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateVersion", trace.Wrap(err), "autoupdate_version"))
return
}
if autoUpdateVersionBefore.GetMetadata().Revision != autoUpdateVersionI.GetMetadata().Revision || false {
break
}
if bErr := backoff.Do(ctx); bErr != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateVersion", trace.Wrap(bErr), "autoupdate_version"))
return
}
if tries >= r.p.RetryConfig.MaxTries {
diagMessage := fmt.Sprintf("Error reading AutoUpdateVersion (tried %d times) - state outdated, please import resource", tries)
resp.Diagnostics.AddError(diagMessage, "autoupdate_version")
return
}
}
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error reading AutoUpdateVersion", trace.Wrap(err), "autoupdate_version"))
return
}
autoUpdateVersion = autoUpdateVersionI
diags = resp.State.Set(ctx, plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
// Delete deletes Teleport AutoUpdateVersion
func (r resourceTeleportAutoUpdateVersion) Delete(ctx context.Context, req tfsdk.DeleteResourceRequest, resp *tfsdk.DeleteResourceResponse) {
err := r.p.Client.DeleteAutoUpdateVersion(ctx)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error deleting AutoUpdateVersion", trace.Wrap(err), "autoupdate_version"))
return
}
resp.State.RemoveResource(ctx)
}
// ImportState imports AutoUpdateVersion state
func (r resourceTeleportAutoUpdateVersion) ImportState(ctx context.Context, req tfsdk.ImportResourceStateRequest, resp *tfsdk.ImportResourceStateResponse) {
autoUpdateVersionI, err := r.p.Client.GetAutoUpdateVersion(ctx)
if err != nil {
resp.Diagnostics.Append(diagFromWrappedErr("Error updating AutoUpdateVersion", trace.Wrap(err), "autoupdate_version"))
return
}
autoUpdateVersion := autoUpdateVersionI
var state types.Object
diags := resp.State.Get(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
diags = schemav1.CopyAutoUpdateVersionToTerraform(ctx, autoUpdateVersion, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
id := autoUpdateVersion.Metadata.Name
state.Attrs["id"] = types.String{Value: id}
diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
@@ -0,0 +1,144 @@
/*
Copyright 2025 Gravitational, Inc.
Licensed under the Apache License, Config 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package testlib
import (
"context"
"time"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/stretchr/testify/require"
autoupdatev1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1"
"github.com/gravitational/teleport/api/types/autoupdate"
)
func (s *TerraformSuiteOSS) TestAutoUpdateConfig() {
name := "teleport_autoupdate_config.test"
resource.Test(s.T(), resource.TestCase{
ProtoV6ProviderFactories: s.terraformProviders,
PreventPostDestroyRefresh: true,
IsUnitTest: true,
Steps: []resource.TestStep{
{
Config: s.getFixture("autoupdate_config_0_create.tf"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(name, "kind", "autoupdate_config"),
resource.TestCheckResourceAttr(name, "spec.tools.mode", "enabled"),
resource.TestCheckResourceAttr(name, "spec.agents.mode", "enabled"),
resource.TestCheckResourceAttr(name, "spec.agents.strategy", "halt-on-error"),
resource.TestCheckResourceAttr(name, "spec.agents.schedules.regular.0.name", "dev"),
),
},
{
Config: s.getFixture("autoupdate_config_0_create.tf"),
PlanOnly: true,
},
{
Config: s.getFixture("autoupdate_config_1_update.tf"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(name, "kind", "autoupdate_config"),
resource.TestCheckResourceAttr(name, "spec.tools.mode", "enabled"),
resource.TestCheckResourceAttr(name, "spec.agents.mode", "suspended"),
resource.TestCheckResourceAttr(name, "spec.agents.strategy", "time-based"),
resource.TestCheckResourceAttr(name, "spec.agents.maintenance_window_duration", "45m"),
),
},
{
Config: s.getFixture("autoupdate_config_1_update.tf"),
PlanOnly: true,
},
},
})
}
func (s *TerraformSuiteOSS) TestImportAutoUpdateConfig() {
ctx, cancel := context.WithCancel(context.Background())
s.T().Cleanup(cancel)
r := "teleport_autoupdate_config"
id := "test_import"
name := r + "." + id
testMode := "enabled"
testStrategy := "halt-on-error"
autoUpdateConfig, err := autoupdate.NewAutoUpdateConfig(
&autoupdatev1pb.AutoUpdateConfigSpec{
// We intentionally don't set tools to test a partial resource
Tools: nil,
Agents: &autoupdatev1pb.AutoUpdateConfigSpecAgents{
Mode: testMode,
Strategy: testStrategy,
Schedules: &autoupdatev1pb.AgentAutoUpdateSchedules{
Regular: []*autoupdatev1pb.AgentAutoUpdateGroup{
{
Name: "dev",
Days: []string{"Mon", "Tue", "Wed", "Thu"},
StartHour: 4,
},
{
Name: "staging",
Days: []string{"Mon", "Tue", "Wed", "Thu"},
StartHour: 14,
},
{
Name: "production",
Days: []string{"Mon", "Tue", "Wed", "Thu"},
StartHour: 14,
WaitHours: 24,
},
},
},
},
},
)
require.NoError(s.T(), err)
autoUpdateConfig, err = s.client.CreateAutoUpdateConfig(ctx, autoUpdateConfig)
require.NoError(s.T(), err)
require.Eventually(s.T(), func() bool {
autoUpdateConfigCurrent, err := s.client.GetAutoUpdateConfig(ctx)
require.NoError(s.T(), err)
return autoUpdateConfig.GetMetadata().GetRevision() != autoUpdateConfigCurrent.GetMetadata().GetName()
}, 5*time.Second, 200*time.Millisecond)
resource.Test(s.T(), resource.TestCase{
ProtoV6ProviderFactories: s.terraformProviders,
IsUnitTest: true,
Steps: []resource.TestStep{
{
Config: s.terraformConfig + "\n" + `resource "` + r + `" "` + id + `" { }`,
ResourceName: name,
ImportState: true,
ImportStateId: id,
ImportStateCheck: func(state []*terraform.InstanceState) error {
require.Equal(s.T(), "autoupdate_config", state[0].Attributes["kind"])
require.Equal(s.T(), testMode, state[0].Attributes["spec.agents.mode"])
require.Equal(s.T(), testStrategy, state[0].Attributes["spec.agents.strategy"])
require.Equal(s.T(), "dev", state[0].Attributes["spec.agents.schedules.regular.0.name"])
return nil
},
},
},
})
}
@@ -0,0 +1,131 @@
/*
Copyright 2025 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package testlib
import (
"context"
"time"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/stretchr/testify/require"
autoupdatev1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1"
"github.com/gravitational/teleport/api/types/autoupdate"
)
func (s *TerraformSuiteOSS) TestAutoUpdateVersion() {
name := "teleport_autoupdate_version.test"
resource.Test(s.T(), resource.TestCase{
ProtoV6ProviderFactories: s.terraformProviders,
PreventPostDestroyRefresh: true,
IsUnitTest: true,
Steps: []resource.TestStep{
{
Config: s.getFixture("autoupdate_version_0_create.tf"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(name, "kind", "autoupdate_version"),
resource.TestCheckResourceAttr(name, "spec.tools.target_version", "1.2.3"),
resource.TestCheckResourceAttr(name, "spec.agents.schedule", "regular"),
resource.TestCheckResourceAttr(name, "spec.agents.mode", "enabled"),
resource.TestCheckResourceAttr(name, "spec.agents.start_version", "1.2.3"),
resource.TestCheckResourceAttr(name, "spec.agents.target_version", "1.2.4"),
),
},
{
Config: s.getFixture("autoupdate_version_0_create.tf"),
PlanOnly: true,
},
{
Config: s.getFixture("autoupdate_version_1_update.tf"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(name, "kind", "autoupdate_version"),
resource.TestCheckResourceAttr(name, "spec.tools.target_version", "1.2.4"),
resource.TestCheckResourceAttr(name, "spec.agents.schedule", "regular"),
resource.TestCheckResourceAttr(name, "spec.agents.mode", "enabled"),
resource.TestCheckResourceAttr(name, "spec.agents.start_version", "1.2.3"),
resource.TestCheckResourceAttr(name, "spec.agents.target_version", "1.2.5"),
),
},
{
Config: s.getFixture("autoupdate_version_1_update.tf"),
PlanOnly: true,
},
},
})
}
func (s *TerraformSuiteOSS) TestImportAutoUpdateVersion() {
ctx, cancel := context.WithCancel(context.Background())
s.T().Cleanup(cancel)
r := "teleport_autoupdate_version"
id := "test_import"
name := r + "." + id
testStartVersion := "1.2.3"
testTargetVersion := "1.2.4"
testSchedule := "regular"
testMode := "enabled"
autoUpdateVersion, err := autoupdate.NewAutoUpdateVersion(
&autoupdatev1pb.AutoUpdateVersionSpec{
// We intentionally don't set tools to test a partial resource
Tools: nil,
Agents: &autoupdatev1pb.AutoUpdateVersionSpecAgents{
StartVersion: testStartVersion,
TargetVersion: testTargetVersion,
Schedule: testSchedule,
Mode: testMode,
},
},
)
require.NoError(s.T(), err)
autoUpdateVersion, err = s.client.CreateAutoUpdateVersion(ctx, autoUpdateVersion)
require.NoError(s.T(), err)
require.Eventually(s.T(), func() bool {
autoUpdateVersionCurrent, err := s.client.GetAutoUpdateVersion(ctx)
require.NoError(s.T(), err)
return autoUpdateVersion.GetMetadata().GetRevision() != autoUpdateVersionCurrent.GetMetadata().GetName()
}, 5*time.Second, time.Second)
resource.Test(s.T(), resource.TestCase{
ProtoV6ProviderFactories: s.terraformProviders,
IsUnitTest: true,
Steps: []resource.TestStep{
{
Config: s.terraformConfig + "\n" + `resource "` + r + `" "` + id + `" { }`,
ResourceName: name,
ImportState: true,
ImportStateId: id,
ImportStateCheck: func(state []*terraform.InstanceState) error {
require.Equal(s.T(), "autoupdate_version", state[0].Attributes["kind"])
require.Equal(s.T(), testStartVersion, state[0].Attributes["spec.agents.start_version"])
require.Equal(s.T(), testTargetVersion, state[0].Attributes["spec.agents.target_version"])
require.Equal(s.T(), testSchedule, state[0].Attributes["spec.agents.schedule"])
require.Equal(s.T(), testMode, state[0].Attributes["spec.agents.mode"])
return nil
},
},
},
})
}
@@ -0,0 +1,22 @@
resource "teleport_autoupdate_config" "test" {
version = "v1"
spec = {
tools = {
mode = "enabled"
}
agents = {
mode = "enabled"
strategy = "halt-on-error"
schedules = {
regular = [
# dev is updated at 4:00 UTC
{ name = "dev", days = ["Mon", "Tue", "Wed", "Thu"], start_hour : 4 },
# staging is updated at 14:00 UTC
{ name = "staging", days = ["Mon", "Tue", "Wed", "Thu"], start_hour : 14 },
# prod is updated at 14:00 UTC the next day
{ name = "prod", days = ["Mon", "Tue", "Wed", "Thu"], start_hour : 14, wait_hours : 24 },
]
}
}
}
}
@@ -0,0 +1,23 @@
resource "teleport_autoupdate_config" "test" {
version = "v1"
spec = {
tools = {
mode = "enabled"
}
agents = {
mode = "suspended"
strategy = "time-based"
maintenance_window_duration = "45m"
schedules = {
regular = [
# dev is updated at 4:00 UTC
{ name = "dev", days = ["Mon", "Tue", "Wed", "Thu"], start_hour : 4 },
# staging is updated at 08:00 UTC
{ name = "staging", days = ["Mon", "Tue", "Wed", "Thu"], start_hour : 8 },
# prod is updated at 14:00 UTC
{ name = "prod", days = ["Mon", "Tue", "Wed", "Thu"], start_hour : 14, },
]
}
}
}
}
@@ -0,0 +1,14 @@
resource "teleport_autoupdate_version" "test" {
version = "v1"
spec = {
tools = {
target_version = "1.2.3"
}
agents = {
start_version = "1.2.3"
target_version = "1.2.4"
schedule = "regular"
mode = "enabled"
}
}
}
@@ -0,0 +1,14 @@
resource "teleport_autoupdate_version" "test" {
version = "v1"
spec = {
tools = {
target_version = "1.2.4"
}
agents = {
start_version = "1.2.3"
target_version = "1.2.5"
schedule = "regular"
mode = "enabled"
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,28 @@
/*
Copyright 2025 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import "github.com/gravitational/teleport/integrations/terraform/tfschema/resource153"
var (
GenSchemaTimestamp = resource153.GenSchemaTimestamp
CopyToTimestamp = resource153.CopyToTimestamp
CopyFromTimestamp = resource153.CopyFromTimestamp
GenSchemaDuration = resource153.GenSchemaDuration
CopyToDuration = resource153.CopyToDuration
CopyFromDuration = resource153.CopyFromDuration
)
+2
View File
@@ -731,6 +731,8 @@ func NewPresetTerraformProviderRole() types.Role {
types.NewRule(types.KindStaticHostUser, RW()),
types.NewRule(types.KindWorkloadIdentity, RW()),
types.NewRule(types.KindGitServer, RW()),
types.NewRule(types.KindAutoUpdateConfig, RW()),
types.NewRule(types.KindAutoUpdateVersion, RW()),
},
},
},
+2
View File
@@ -750,6 +750,8 @@ func TestAddRoleDefaults(t *testing.T) {
types.NewRule(types.KindStaticHostUser, RW()),
types.NewRule(types.KindWorkloadIdentity, RW()),
types.NewRule(types.KindGitServer, RW()),
types.NewRule(types.KindAutoUpdateConfig, RW()),
types.NewRule(types.KindAutoUpdateVersion, RW()),
},
},
},