From 5e73eaf3421401619c72fff491eed0407850ef4e Mon Sep 17 00:00:00 2001 From: Hugo Shaka Date: Wed, 19 Mar 2025 18:55:33 +0100 Subject: [PATCH] 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. --- .../data-sources/autoupdate_config.mdx | 77 + .../data-sources/autoupdate_version.mdx | 60 + .../data-sources/data-sources.mdx | 2 + .../resources/autoupdate_config.mdx | 112 + .../resources/autoupdate_version.mdx | 77 + .../resources/resources.mdx | 2 + integrations/terraform/Makefile | 14 +- .../teleport_autoupdate_config/resource.tf | 32 + .../teleport_autoupdate_version/resource.tf | 14 + integrations/terraform/gen/main.go | 58 + .../protoc-gen-terraform-autoupdate.yaml | 86 + .../data_source_teleport_autoupdate_config.go | 88 + ...data_source_teleport_autoupdate_version.go | 88 + integrations/terraform/provider/provider.go | 4 + .../resource_teleport_autoupdate_config.go | 291 +++ .../resource_teleport_autoupdate_version.go | 291 +++ .../testlib/autoupdate_config_test.go | 144 ++ .../testlib/autoupdate_version_test.go | 131 + .../fixtures/autoupdate_config_0_create.tf | 22 + .../fixtures/autoupdate_config_1_update.tf | 23 + .../fixtures/autoupdate_version_0_create.tf | 14 + .../fixtures/autoupdate_version_1_update.tf | 14 + .../autoupdate/v1/autoupdate_terraform.go | 2229 +++++++++++++++++ .../tfschema/autoupdate/v1/custom_types.go | 28 + lib/services/presets.go | 2 + lib/services/presets_test.go | 2 + 26 files changed, 3904 insertions(+), 1 deletion(-) create mode 100644 docs/pages/reference/terraform-provider/data-sources/autoupdate_config.mdx create mode 100644 docs/pages/reference/terraform-provider/data-sources/autoupdate_version.mdx create mode 100644 docs/pages/reference/terraform-provider/resources/autoupdate_config.mdx create mode 100644 docs/pages/reference/terraform-provider/resources/autoupdate_version.mdx create mode 100644 integrations/terraform/examples/resources/teleport_autoupdate_config/resource.tf create mode 100644 integrations/terraform/examples/resources/teleport_autoupdate_version/resource.tf create mode 100644 integrations/terraform/protoc-gen-terraform-autoupdate.yaml create mode 100755 integrations/terraform/provider/data_source_teleport_autoupdate_config.go create mode 100755 integrations/terraform/provider/data_source_teleport_autoupdate_version.go create mode 100755 integrations/terraform/provider/resource_teleport_autoupdate_config.go create mode 100755 integrations/terraform/provider/resource_teleport_autoupdate_version.go create mode 100644 integrations/terraform/testlib/autoupdate_config_test.go create mode 100644 integrations/terraform/testlib/autoupdate_version_test.go create mode 100644 integrations/terraform/testlib/fixtures/autoupdate_config_0_create.tf create mode 100644 integrations/terraform/testlib/fixtures/autoupdate_config_1_update.tf create mode 100644 integrations/terraform/testlib/fixtures/autoupdate_version_0_create.tf create mode 100644 integrations/terraform/testlib/fixtures/autoupdate_version_1_update.tf create mode 100644 integrations/terraform/tfschema/autoupdate/v1/autoupdate_terraform.go create mode 100644 integrations/terraform/tfschema/autoupdate/v1/custom_types.go diff --git a/docs/pages/reference/terraform-provider/data-sources/autoupdate_config.mdx b/docs/pages/reference/terraform-provider/data-sources/autoupdate_config.mdx new file mode 100644 index 00000000000..7d8feb1e83c --- /dev/null +++ b/docs/pages/reference/terraform-provider/data-sources/autoupdate_config.mdx @@ -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. + diff --git a/docs/pages/reference/terraform-provider/data-sources/autoupdate_version.mdx b/docs/pages/reference/terraform-provider/data-sources/autoupdate_version.mdx new file mode 100644 index 00000000000..4737c8dbb4f --- /dev/null +++ b/docs/pages/reference/terraform-provider/data-sources/autoupdate_version.mdx @@ -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. + diff --git a/docs/pages/reference/terraform-provider/data-sources/data-sources.mdx b/docs/pages/reference/terraform-provider/data-sources/data-sources.mdx index 0e6dfabb1b4..dda3fd3d5e4 100644 --- a/docs/pages/reference/terraform-provider/data-sources/data-sources.mdx +++ b/docs/pages/reference/terraform-provider/data-sources/data-sources.mdx @@ -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) diff --git a/docs/pages/reference/terraform-provider/resources/autoupdate_config.mdx b/docs/pages/reference/terraform-provider/resources/autoupdate_config.mdx new file mode 100644 index 00000000000..7e10a3c465a --- /dev/null +++ b/docs/pages/reference/terraform-provider/resources/autoupdate_config.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. + diff --git a/docs/pages/reference/terraform-provider/resources/autoupdate_version.mdx b/docs/pages/reference/terraform-provider/resources/autoupdate_version.mdx new file mode 100644 index 00000000000..fe1cc7a106a --- /dev/null +++ b/docs/pages/reference/terraform-provider/resources/autoupdate_version.mdx @@ -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. + diff --git a/docs/pages/reference/terraform-provider/resources/resources.mdx b/docs/pages/reference/terraform-provider/resources/resources.mdx index e962f85c38a..6d9e57352df 100644 --- a/docs/pages/reference/terraform-provider/resources/resources.mdx +++ b/docs/pages/reference/terraform-provider/resources/resources.mdx @@ -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) diff --git a/integrations/terraform/Makefile b/integrations/terraform/Makefile index fbdf60b66c2..9832f680a83 100644 --- a/integrations/terraform/Makefile +++ b/integrations/terraform/Makefile @@ -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) diff --git a/integrations/terraform/examples/resources/teleport_autoupdate_config/resource.tf b/integrations/terraform/examples/resources/teleport_autoupdate_config/resource.tf new file mode 100644 index 00000000000..1527ade6af7 --- /dev/null +++ b/integrations/terraform/examples/resources/teleport_autoupdate_config/resource.tf @@ -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 + }, + ] + } + } + } +} diff --git a/integrations/terraform/examples/resources/teleport_autoupdate_version/resource.tf b/integrations/terraform/examples/resources/teleport_autoupdate_version/resource.tf new file mode 100644 index 00000000000..cf736ba6d92 --- /dev/null +++ b/integrations/terraform/examples/resources/teleport_autoupdate_version/resource.tf @@ -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" + } + } +} diff --git a/integrations/terraform/gen/main.go b/integrations/terraform/gen/main.go index fa2a196c19b..feb38c3776c 100644 --- a/integrations/terraform/gen/main.go +++ b/integrations/terraform/gen/main.go @@ -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) { diff --git a/integrations/terraform/protoc-gen-terraform-autoupdate.yaml b/integrations/terraform/protoc-gen-terraform-autoupdate.yaml new file mode 100644 index 00000000000..57dbbc65c4a --- /dev/null +++ b/integrations/terraform/protoc-gen-terraform-autoupdate.yaml @@ -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 diff --git a/integrations/terraform/provider/data_source_teleport_autoupdate_config.go b/integrations/terraform/provider/data_source_teleport_autoupdate_config.go new file mode 100755 index 00000000000..c6678341062 --- /dev/null +++ b/integrations/terraform/provider/data_source_teleport_autoupdate_config.go @@ -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 + } +} diff --git a/integrations/terraform/provider/data_source_teleport_autoupdate_version.go b/integrations/terraform/provider/data_source_teleport_autoupdate_version.go new file mode 100755 index 00000000000..185fb96cf55 --- /dev/null +++ b/integrations/terraform/provider/data_source_teleport_autoupdate_version.go @@ -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 + } +} diff --git a/integrations/terraform/provider/provider.go b/integrations/terraform/provider/provider.go index 99d460a49f8..7cd4da7c12a 100644 --- a/integrations/terraform/provider/provider.go +++ b/integrations/terraform/provider/provider.go @@ -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 } diff --git a/integrations/terraform/provider/resource_teleport_autoupdate_config.go b/integrations/terraform/provider/resource_teleport_autoupdate_config.go new file mode 100755 index 00000000000..8e2cd244a74 --- /dev/null +++ b/integrations/terraform/provider/resource_teleport_autoupdate_config.go @@ -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 + } +} diff --git a/integrations/terraform/provider/resource_teleport_autoupdate_version.go b/integrations/terraform/provider/resource_teleport_autoupdate_version.go new file mode 100755 index 00000000000..14bdead291d --- /dev/null +++ b/integrations/terraform/provider/resource_teleport_autoupdate_version.go @@ -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 + } +} diff --git a/integrations/terraform/testlib/autoupdate_config_test.go b/integrations/terraform/testlib/autoupdate_config_test.go new file mode 100644 index 00000000000..d505402cd22 --- /dev/null +++ b/integrations/terraform/testlib/autoupdate_config_test.go @@ -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 + }, + }, + }, + }) +} diff --git a/integrations/terraform/testlib/autoupdate_version_test.go b/integrations/terraform/testlib/autoupdate_version_test.go new file mode 100644 index 00000000000..161d16f06fe --- /dev/null +++ b/integrations/terraform/testlib/autoupdate_version_test.go @@ -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 + }, + }, + }, + }) +} diff --git a/integrations/terraform/testlib/fixtures/autoupdate_config_0_create.tf b/integrations/terraform/testlib/fixtures/autoupdate_config_0_create.tf new file mode 100644 index 00000000000..0b8780500d0 --- /dev/null +++ b/integrations/terraform/testlib/fixtures/autoupdate_config_0_create.tf @@ -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 }, + ] + } + } + } +} diff --git a/integrations/terraform/testlib/fixtures/autoupdate_config_1_update.tf b/integrations/terraform/testlib/fixtures/autoupdate_config_1_update.tf new file mode 100644 index 00000000000..aa61a189ab4 --- /dev/null +++ b/integrations/terraform/testlib/fixtures/autoupdate_config_1_update.tf @@ -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, }, + ] + } + } + } +} diff --git a/integrations/terraform/testlib/fixtures/autoupdate_version_0_create.tf b/integrations/terraform/testlib/fixtures/autoupdate_version_0_create.tf new file mode 100644 index 00000000000..cf736ba6d92 --- /dev/null +++ b/integrations/terraform/testlib/fixtures/autoupdate_version_0_create.tf @@ -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" + } + } +} diff --git a/integrations/terraform/testlib/fixtures/autoupdate_version_1_update.tf b/integrations/terraform/testlib/fixtures/autoupdate_version_1_update.tf new file mode 100644 index 00000000000..034d0354b4a --- /dev/null +++ b/integrations/terraform/testlib/fixtures/autoupdate_version_1_update.tf @@ -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" + } + } +} diff --git a/integrations/terraform/tfschema/autoupdate/v1/autoupdate_terraform.go b/integrations/terraform/tfschema/autoupdate/v1/autoupdate_terraform.go new file mode 100644 index 00000000000..fe0cbc478dd --- /dev/null +++ b/integrations/terraform/tfschema/autoupdate/v1/autoupdate_terraform.go @@ -0,0 +1,2229 @@ +/* +Copyright 2015-2022 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. +*/ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: teleport/autoupdate/v1/autoupdate.proto + +package v1 + +import ( + context "context" + fmt "fmt" + math "math" + + proto "github.com/gogo/protobuf/proto" + github_com_gravitational_teleport_api_gen_proto_go_teleport_autoupdate_v1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1" + _ "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + github_com_gravitational_teleport_api_gen_proto_go_teleport_header_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" + github_com_hashicorp_terraform_plugin_framework_attr "github.com/hashicorp/terraform-plugin-framework/attr" + github_com_hashicorp_terraform_plugin_framework_diag "github.com/hashicorp/terraform-plugin-framework/diag" + github_com_hashicorp_terraform_plugin_framework_tfsdk "github.com/hashicorp/terraform-plugin-framework/tfsdk" + github_com_hashicorp_terraform_plugin_framework_types "github.com/hashicorp/terraform-plugin-framework/types" + github_com_hashicorp_terraform_plugin_go_tftypes "github.com/hashicorp/terraform-plugin-go/tftypes" + _ "google.golang.org/protobuf/types/known/durationpb" + _ "google.golang.org/protobuf/types/known/timestamppb" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// GenSchemaAutoUpdateConfig returns tfsdk.Schema definition for AutoUpdateConfig +func GenSchemaAutoUpdateConfig(ctx context.Context) (github_com_hashicorp_terraform_plugin_framework_tfsdk.Schema, github_com_hashicorp_terraform_plugin_framework_diag.Diagnostics) { + return github_com_hashicorp_terraform_plugin_framework_tfsdk.Schema{Attributes: map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + "id": { + Computed: true, + Optional: false, + PlanModifiers: []github_com_hashicorp_terraform_plugin_framework_tfsdk.AttributePlanModifier{github_com_hashicorp_terraform_plugin_framework_tfsdk.UseStateForUnknown()}, + Required: false, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "kind": { + Computed: true, + Description: "", + Optional: true, + PlanModifiers: []github_com_hashicorp_terraform_plugin_framework_tfsdk.AttributePlanModifier{github_com_hashicorp_terraform_plugin_framework_tfsdk.UseStateForUnknown()}, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "metadata": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.SingleNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + "description": { + Description: "description is object description.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "expires": GenSchemaTimestamp(ctx, github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + Description: "expires is a global expiry time header can be set on any resource in the system.", + Optional: true, + Validators: []github_com_hashicorp_terraform_plugin_framework_tfsdk.AttributeValidator{github_com_gravitational_teleport_integrations_terraform_tfschema.MustTimeBeInFuture()}, + }), + "labels": { + Description: "labels is a set of labels.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.MapType{ElemType: github_com_hashicorp_terraform_plugin_framework_types.StringType}, + }, + "name": { + Computed: true, + Description: "name is an object name.", + Optional: true, + PlanModifiers: []github_com_hashicorp_terraform_plugin_framework_tfsdk.AttributePlanModifier{github_com_hashicorp_terraform_plugin_framework_tfsdk.RequiresReplace()}, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "namespace": { + Computed: true, + Description: "namespace is object namespace. The field should be called \"namespace\" when it returns in Teleport 2.4.", + Optional: true, + PlanModifiers: []github_com_hashicorp_terraform_plugin_framework_tfsdk.AttributePlanModifier{github_com_hashicorp_terraform_plugin_framework_tfsdk.UseStateForUnknown()}, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "revision": { + Description: "revision is an opaque identifier which tracks the versions of a resource over time. Clients should ignore and not alter its value but must return the revision in any updates of a resource.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + }), + Computed: true, + Description: "", + Optional: true, + PlanModifiers: []github_com_hashicorp_terraform_plugin_framework_tfsdk.AttributePlanModifier{github_com_hashicorp_terraform_plugin_framework_tfsdk.UseStateForUnknown()}, + }, + "spec": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.SingleNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + "agents": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.SingleNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + "maintenance_window_duration": GenSchemaDuration(ctx, github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + Description: "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.", + Optional: true, + }), + "mode": { + Description: "mode specifies whether agent autoupdates are enabled, disabled, or paused.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "schedules": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.SingleNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{"regular": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.ListNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + "days": { + Description: "days when the update can run. Supported values are \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\" and \"*\"", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.ListType{ElemType: github_com_hashicorp_terraform_plugin_framework_types.StringType}, + }, + "name": { + Description: "name of the group", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "start_hour": { + Description: "start_hour to initiate update", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.Int64Type, + }, + "wait_hours": { + Description: "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.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.Int64Type, + }, + }), + Description: "regular schedules for non-critical versions.", + Optional: true, + }}), + Description: "schedules specifies schedules for updates of grouped agents.", + Optional: true, + }, + "strategy": { + Description: "strategy to use for updating the agents.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + }), + Description: "", + Optional: true, + }, + "tools": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.SingleNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{"mode": { + Description: "Mode defines state of the client tools auto update.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }}), + Description: "", + Optional: true, + }, + }), + Description: "", + Required: true, + }, + "sub_kind": { + Description: "", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "version": { + Description: "", + Required: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + }}, nil +} + +// GenSchemaAutoUpdateVersion returns tfsdk.Schema definition for AutoUpdateVersion +func GenSchemaAutoUpdateVersion(ctx context.Context) (github_com_hashicorp_terraform_plugin_framework_tfsdk.Schema, github_com_hashicorp_terraform_plugin_framework_diag.Diagnostics) { + return github_com_hashicorp_terraform_plugin_framework_tfsdk.Schema{Attributes: map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + "id": { + Computed: true, + Optional: false, + PlanModifiers: []github_com_hashicorp_terraform_plugin_framework_tfsdk.AttributePlanModifier{github_com_hashicorp_terraform_plugin_framework_tfsdk.UseStateForUnknown()}, + Required: false, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "kind": { + Computed: true, + Description: "", + Optional: true, + PlanModifiers: []github_com_hashicorp_terraform_plugin_framework_tfsdk.AttributePlanModifier{github_com_hashicorp_terraform_plugin_framework_tfsdk.UseStateForUnknown()}, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "metadata": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.SingleNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + "description": { + Description: "description is object description.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "expires": GenSchemaTimestamp(ctx, github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + Description: "expires is a global expiry time header can be set on any resource in the system.", + Optional: true, + Validators: []github_com_hashicorp_terraform_plugin_framework_tfsdk.AttributeValidator{github_com_gravitational_teleport_integrations_terraform_tfschema.MustTimeBeInFuture()}, + }), + "labels": { + Description: "labels is a set of labels.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.MapType{ElemType: github_com_hashicorp_terraform_plugin_framework_types.StringType}, + }, + "name": { + Computed: true, + Description: "name is an object name.", + Optional: true, + PlanModifiers: []github_com_hashicorp_terraform_plugin_framework_tfsdk.AttributePlanModifier{github_com_hashicorp_terraform_plugin_framework_tfsdk.RequiresReplace()}, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "namespace": { + Computed: true, + Description: "namespace is object namespace. The field should be called \"namespace\" when it returns in Teleport 2.4.", + Optional: true, + PlanModifiers: []github_com_hashicorp_terraform_plugin_framework_tfsdk.AttributePlanModifier{github_com_hashicorp_terraform_plugin_framework_tfsdk.UseStateForUnknown()}, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "revision": { + Description: "revision is an opaque identifier which tracks the versions of a resource over time. Clients should ignore and not alter its value but must return the revision in any updates of a resource.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + }), + Computed: true, + Description: "", + Optional: true, + PlanModifiers: []github_com_hashicorp_terraform_plugin_framework_tfsdk.AttributePlanModifier{github_com_hashicorp_terraform_plugin_framework_tfsdk.UseStateForUnknown()}, + }, + "spec": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.SingleNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + "agents": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.SingleNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + "mode": { + Description: "autoupdate_mode to use for the rollout", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "schedule": { + Description: "schedule to use for the rollout", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "start_version": { + Description: "start_version is the version to update from.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "target_version": { + Description: "target_version is the version to update to.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + }), + Description: "", + Optional: true, + }, + "tools": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.SingleNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{"target_version": { + Description: "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.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }}), + Description: "", + Optional: true, + }, + }), + Description: "", + Required: true, + }, + "sub_kind": { + Description: "", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "version": { + Description: "", + Required: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + }}, nil +} + +// CopyAutoUpdateConfigFromTerraform copies contents of the source Terraform object into a target struct +func CopyAutoUpdateConfigFromTerraform(_ context.Context, tf github_com_hashicorp_terraform_plugin_framework_types.Object, obj *github_com_gravitational_teleport_api_gen_proto_go_teleport_autoupdate_v1.AutoUpdateConfig) github_com_hashicorp_terraform_plugin_framework_diag.Diagnostics { + var diags github_com_hashicorp_terraform_plugin_framework_diag.Diagnostics + { + a, ok := tf.Attrs["kind"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.kind"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.kind", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Kind = t + } + } + } + { + a, ok := tf.Attrs["sub_kind"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.sub_kind"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.sub_kind", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.SubKind = t + } + } + } + { + a, ok := tf.Attrs["version"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.version"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.version", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Version = t + } + } + } + { + a, ok := tf.Attrs["metadata"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.metadata"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.metadata", "github.com/hashicorp/terraform-plugin-framework/types.Object"}) + } else { + obj.Metadata = nil + if !v.Null && !v.Unknown { + tf := v + obj.Metadata = &github_com_gravitational_teleport_api_gen_proto_go_teleport_header_v1.Metadata{} + obj := obj.Metadata + { + a, ok := tf.Attrs["name"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.metadata.name"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.metadata.name", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Name = t + } + } + } + { + a, ok := tf.Attrs["namespace"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.metadata.namespace"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.metadata.namespace", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Namespace = t + } + } + } + { + a, ok := tf.Attrs["description"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.metadata.description"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.metadata.description", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Description = t + } + } + } + { + a, ok := tf.Attrs["labels"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.metadata.labels"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Map) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.metadata.labels", "github.com/hashicorp/terraform-plugin-framework/types.Map"}) + } else { + obj.Labels = make(map[string]string, len(v.Elems)) + if !v.Null && !v.Unknown { + for k, a := range v.Elems { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.metadata.labels", "github_com_hashicorp_terraform_plugin_framework_types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Labels[k] = t + } + } + } + } + } + } + { + a, ok := tf.Attrs["expires"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.metadata.expires"}) + } + CopyFromTimestamp(diags, a, &obj.Expires) + } + { + a, ok := tf.Attrs["revision"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.metadata.revision"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.metadata.revision", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Revision = t + } + } + } + } + } + } + } + { + a, ok := tf.Attrs["spec"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.spec"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.spec", "github.com/hashicorp/terraform-plugin-framework/types.Object"}) + } else { + obj.Spec = nil + if !v.Null && !v.Unknown { + tf := v + obj.Spec = &github_com_gravitational_teleport_api_gen_proto_go_teleport_autoupdate_v1.AutoUpdateConfigSpec{} + obj := obj.Spec + { + a, ok := tf.Attrs["tools"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.spec.tools"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.spec.tools", "github.com/hashicorp/terraform-plugin-framework/types.Object"}) + } else { + obj.Tools = nil + if !v.Null && !v.Unknown { + tf := v + obj.Tools = &github_com_gravitational_teleport_api_gen_proto_go_teleport_autoupdate_v1.AutoUpdateConfigSpecTools{} + obj := obj.Tools + { + a, ok := tf.Attrs["mode"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.spec.tools.mode"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.spec.tools.mode", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Mode = t + } + } + } + } + } + } + } + { + a, ok := tf.Attrs["agents"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.spec.agents"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.spec.agents", "github.com/hashicorp/terraform-plugin-framework/types.Object"}) + } else { + obj.Agents = nil + if !v.Null && !v.Unknown { + tf := v + obj.Agents = &github_com_gravitational_teleport_api_gen_proto_go_teleport_autoupdate_v1.AutoUpdateConfigSpecAgents{} + obj := obj.Agents + { + a, ok := tf.Attrs["mode"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.spec.agents.mode"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.spec.agents.mode", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Mode = t + } + } + } + { + a, ok := tf.Attrs["strategy"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.spec.agents.strategy"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.spec.agents.strategy", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Strategy = t + } + } + } + { + a, ok := tf.Attrs["maintenance_window_duration"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.spec.agents.maintenance_window_duration"}) + } + CopyFromDuration(diags, a, &obj.MaintenanceWindowDuration) + } + { + a, ok := tf.Attrs["schedules"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.spec.agents.schedules"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.spec.agents.schedules", "github.com/hashicorp/terraform-plugin-framework/types.Object"}) + } else { + obj.Schedules = nil + if !v.Null && !v.Unknown { + tf := v + obj.Schedules = &github_com_gravitational_teleport_api_gen_proto_go_teleport_autoupdate_v1.AgentAutoUpdateSchedules{} + obj := obj.Schedules + { + a, ok := tf.Attrs["regular"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.spec.agents.schedules.regular"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.List) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.spec.agents.schedules.regular", "github.com/hashicorp/terraform-plugin-framework/types.List"}) + } else { + obj.Regular = make([]*github_com_gravitational_teleport_api_gen_proto_go_teleport_autoupdate_v1.AgentAutoUpdateGroup, len(v.Elems)) + if !v.Null && !v.Unknown { + for k, a := range v.Elems { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.spec.agents.schedules.regular", "github_com_hashicorp_terraform_plugin_framework_types.Object"}) + } else { + var t *github_com_gravitational_teleport_api_gen_proto_go_teleport_autoupdate_v1.AgentAutoUpdateGroup + if !v.Null && !v.Unknown { + tf := v + t = &github_com_gravitational_teleport_api_gen_proto_go_teleport_autoupdate_v1.AgentAutoUpdateGroup{} + obj := t + { + a, ok := tf.Attrs["name"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.spec.agents.schedules.regular.name"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.spec.agents.schedules.regular.name", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Name = t + } + } + } + { + a, ok := tf.Attrs["days"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.spec.agents.schedules.regular.days"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.List) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.spec.agents.schedules.regular.days", "github.com/hashicorp/terraform-plugin-framework/types.List"}) + } else { + obj.Days = make([]string, len(v.Elems)) + if !v.Null && !v.Unknown { + for k, a := range v.Elems { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.spec.agents.schedules.regular.days", "github_com_hashicorp_terraform_plugin_framework_types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Days[k] = t + } + } + } + } + } + } + { + a, ok := tf.Attrs["start_hour"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.spec.agents.schedules.regular.start_hour"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Int64) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.spec.agents.schedules.regular.start_hour", "github.com/hashicorp/terraform-plugin-framework/types.Int64"}) + } else { + var t int32 + if !v.Null && !v.Unknown { + t = int32(v.Value) + } + obj.StartHour = t + } + } + } + { + a, ok := tf.Attrs["wait_hours"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateConfig.spec.agents.schedules.regular.wait_hours"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Int64) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateConfig.spec.agents.schedules.regular.wait_hours", "github.com/hashicorp/terraform-plugin-framework/types.Int64"}) + } else { + var t int32 + if !v.Null && !v.Unknown { + t = int32(v.Value) + } + obj.WaitHours = t + } + } + } + } + obj.Regular[k] = t + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + return diags +} + +// CopyAutoUpdateConfigToTerraform copies contents of the source Terraform object into a target struct +func CopyAutoUpdateConfigToTerraform(ctx context.Context, obj *github_com_gravitational_teleport_api_gen_proto_go_teleport_autoupdate_v1.AutoUpdateConfig, tf *github_com_hashicorp_terraform_plugin_framework_types.Object) github_com_hashicorp_terraform_plugin_framework_diag.Diagnostics { + var diags github_com_hashicorp_terraform_plugin_framework_diag.Diagnostics + tf.Null = false + tf.Unknown = false + if tf.Attrs == nil { + tf.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value) + } + { + t, ok := tf.AttrTypes["kind"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.kind"}) + } else { + v, ok := tf.Attrs["kind"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateConfig.kind", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.kind", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Kind) == "" + } + v.Value = string(obj.Kind) + v.Unknown = false + tf.Attrs["kind"] = v + } + } + { + t, ok := tf.AttrTypes["sub_kind"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.sub_kind"}) + } else { + v, ok := tf.Attrs["sub_kind"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateConfig.sub_kind", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.sub_kind", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.SubKind) == "" + } + v.Value = string(obj.SubKind) + v.Unknown = false + tf.Attrs["sub_kind"] = v + } + } + { + t, ok := tf.AttrTypes["version"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.version"}) + } else { + v, ok := tf.Attrs["version"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateConfig.version", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.version", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Version) == "" + } + v.Value = string(obj.Version) + v.Unknown = false + tf.Attrs["version"] = v + } + } + { + a, ok := tf.AttrTypes["metadata"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.metadata"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.metadata", "github.com/hashicorp/terraform-plugin-framework/types.ObjectType"}) + } else { + v, ok := tf.Attrs["metadata"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if obj.Metadata == nil { + v.Null = true + } else { + obj := obj.Metadata + tf := &v + { + t, ok := tf.AttrTypes["name"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.metadata.name"}) + } else { + v, ok := tf.Attrs["name"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateConfig.metadata.name", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.metadata.name", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Name) == "" + } + v.Value = string(obj.Name) + v.Unknown = false + tf.Attrs["name"] = v + } + } + { + t, ok := tf.AttrTypes["namespace"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.metadata.namespace"}) + } else { + v, ok := tf.Attrs["namespace"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateConfig.metadata.namespace", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.metadata.namespace", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Namespace) == "" + } + v.Value = string(obj.Namespace) + v.Unknown = false + tf.Attrs["namespace"] = v + } + } + { + t, ok := tf.AttrTypes["description"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.metadata.description"}) + } else { + v, ok := tf.Attrs["description"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateConfig.metadata.description", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.metadata.description", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Description) == "" + } + v.Value = string(obj.Description) + v.Unknown = false + tf.Attrs["description"] = v + } + } + { + a, ok := tf.AttrTypes["labels"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.metadata.labels"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.MapType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.metadata.labels", "github.com/hashicorp/terraform-plugin-framework/types.MapType"}) + } else { + c, ok := tf.Attrs["labels"].(github_com_hashicorp_terraform_plugin_framework_types.Map) + if !ok { + c = github_com_hashicorp_terraform_plugin_framework_types.Map{ + + ElemType: o.ElemType, + Elems: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.Labels)), + Null: true, + } + } else { + if c.Elems == nil { + c.Elems = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.Labels)) + } + } + if obj.Labels != nil { + t := o.ElemType + for k, a := range obj.Labels { + v, ok := tf.Attrs["labels"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateConfig.metadata.labels", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.metadata.labels", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = false + } + v.Value = string(a) + v.Unknown = false + c.Elems[k] = v + } + if len(obj.Labels) > 0 { + c.Null = false + } + } + c.Unknown = false + tf.Attrs["labels"] = c + } + } + } + { + t, ok := tf.AttrTypes["expires"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.metadata.expires"}) + } else { + v := CopyToTimestamp(diags, obj.Expires, t, tf.Attrs["expires"]) + tf.Attrs["expires"] = v + } + } + { + t, ok := tf.AttrTypes["revision"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.metadata.revision"}) + } else { + v, ok := tf.Attrs["revision"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateConfig.metadata.revision", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.metadata.revision", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Revision) == "" + } + v.Value = string(obj.Revision) + v.Unknown = false + tf.Attrs["revision"] = v + } + } + } + v.Unknown = false + tf.Attrs["metadata"] = v + } + } + } + { + a, ok := tf.AttrTypes["spec"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.spec"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.spec", "github.com/hashicorp/terraform-plugin-framework/types.ObjectType"}) + } else { + v, ok := tf.Attrs["spec"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if obj.Spec == nil { + v.Null = true + } else { + obj := obj.Spec + tf := &v + { + a, ok := tf.AttrTypes["tools"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.spec.tools"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.spec.tools", "github.com/hashicorp/terraform-plugin-framework/types.ObjectType"}) + } else { + v, ok := tf.Attrs["tools"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if obj.Tools == nil { + v.Null = true + } else { + obj := obj.Tools + tf := &v + { + t, ok := tf.AttrTypes["mode"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.spec.tools.mode"}) + } else { + v, ok := tf.Attrs["mode"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateConfig.spec.tools.mode", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.spec.tools.mode", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Mode) == "" + } + v.Value = string(obj.Mode) + v.Unknown = false + tf.Attrs["mode"] = v + } + } + } + v.Unknown = false + tf.Attrs["tools"] = v + } + } + } + { + a, ok := tf.AttrTypes["agents"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.spec.agents"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.spec.agents", "github.com/hashicorp/terraform-plugin-framework/types.ObjectType"}) + } else { + v, ok := tf.Attrs["agents"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if obj.Agents == nil { + v.Null = true + } else { + obj := obj.Agents + tf := &v + { + t, ok := tf.AttrTypes["mode"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.spec.agents.mode"}) + } else { + v, ok := tf.Attrs["mode"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateConfig.spec.agents.mode", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.spec.agents.mode", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Mode) == "" + } + v.Value = string(obj.Mode) + v.Unknown = false + tf.Attrs["mode"] = v + } + } + { + t, ok := tf.AttrTypes["strategy"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.spec.agents.strategy"}) + } else { + v, ok := tf.Attrs["strategy"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateConfig.spec.agents.strategy", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.spec.agents.strategy", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Strategy) == "" + } + v.Value = string(obj.Strategy) + v.Unknown = false + tf.Attrs["strategy"] = v + } + } + { + t, ok := tf.AttrTypes["maintenance_window_duration"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.spec.agents.maintenance_window_duration"}) + } else { + v := CopyToDuration(diags, obj.MaintenanceWindowDuration, t, tf.Attrs["maintenance_window_duration"]) + tf.Attrs["maintenance_window_duration"] = v + } + } + { + a, ok := tf.AttrTypes["schedules"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.spec.agents.schedules"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.spec.agents.schedules", "github.com/hashicorp/terraform-plugin-framework/types.ObjectType"}) + } else { + v, ok := tf.Attrs["schedules"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if obj.Schedules == nil { + v.Null = true + } else { + obj := obj.Schedules + tf := &v + { + a, ok := tf.AttrTypes["regular"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.spec.agents.schedules.regular"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ListType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.spec.agents.schedules.regular", "github.com/hashicorp/terraform-plugin-framework/types.ListType"}) + } else { + c, ok := tf.Attrs["regular"].(github_com_hashicorp_terraform_plugin_framework_types.List) + if !ok { + c = github_com_hashicorp_terraform_plugin_framework_types.List{ + + ElemType: o.ElemType, + Elems: make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.Regular)), + Null: true, + } + } else { + if c.Elems == nil { + c.Elems = make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.Regular)) + } + } + if obj.Regular != nil { + o := o.ElemType.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if len(obj.Regular) != len(c.Elems) { + c.Elems = make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.Regular)) + } + for k, a := range obj.Regular { + v, ok := tf.Attrs["regular"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if a == nil { + v.Null = true + } else { + obj := a + tf := &v + { + t, ok := tf.AttrTypes["name"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.spec.agents.schedules.regular.name"}) + } else { + v, ok := tf.Attrs["name"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateConfig.spec.agents.schedules.regular.name", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.spec.agents.schedules.regular.name", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Name) == "" + } + v.Value = string(obj.Name) + v.Unknown = false + tf.Attrs["name"] = v + } + } + { + a, ok := tf.AttrTypes["days"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.spec.agents.schedules.regular.days"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ListType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.spec.agents.schedules.regular.days", "github.com/hashicorp/terraform-plugin-framework/types.ListType"}) + } else { + c, ok := tf.Attrs["days"].(github_com_hashicorp_terraform_plugin_framework_types.List) + if !ok { + c = github_com_hashicorp_terraform_plugin_framework_types.List{ + + ElemType: o.ElemType, + Elems: make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.Days)), + Null: true, + } + } else { + if c.Elems == nil { + c.Elems = make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.Days)) + } + } + if obj.Days != nil { + t := o.ElemType + if len(obj.Days) != len(c.Elems) { + c.Elems = make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.Days)) + } + for k, a := range obj.Days { + v, ok := tf.Attrs["days"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateConfig.spec.agents.schedules.regular.days", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.spec.agents.schedules.regular.days", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(a) == "" + } + v.Value = string(a) + v.Unknown = false + c.Elems[k] = v + } + if len(obj.Days) > 0 { + c.Null = false + } + } + c.Unknown = false + tf.Attrs["days"] = c + } + } + } + { + t, ok := tf.AttrTypes["start_hour"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.spec.agents.schedules.regular.start_hour"}) + } else { + v, ok := tf.Attrs["start_hour"].(github_com_hashicorp_terraform_plugin_framework_types.Int64) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateConfig.spec.agents.schedules.regular.start_hour", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.Int64) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.spec.agents.schedules.regular.start_hour", "github.com/hashicorp/terraform-plugin-framework/types.Int64"}) + } + v.Null = int64(obj.StartHour) == 0 + } + v.Value = int64(obj.StartHour) + v.Unknown = false + tf.Attrs["start_hour"] = v + } + } + { + t, ok := tf.AttrTypes["wait_hours"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateConfig.spec.agents.schedules.regular.wait_hours"}) + } else { + v, ok := tf.Attrs["wait_hours"].(github_com_hashicorp_terraform_plugin_framework_types.Int64) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateConfig.spec.agents.schedules.regular.wait_hours", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.Int64) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateConfig.spec.agents.schedules.regular.wait_hours", "github.com/hashicorp/terraform-plugin-framework/types.Int64"}) + } + v.Null = int64(obj.WaitHours) == 0 + } + v.Value = int64(obj.WaitHours) + v.Unknown = false + tf.Attrs["wait_hours"] = v + } + } + } + v.Unknown = false + c.Elems[k] = v + } + if len(obj.Regular) > 0 { + c.Null = false + } + } + c.Unknown = false + tf.Attrs["regular"] = c + } + } + } + } + v.Unknown = false + tf.Attrs["schedules"] = v + } + } + } + } + v.Unknown = false + tf.Attrs["agents"] = v + } + } + } + } + v.Unknown = false + tf.Attrs["spec"] = v + } + } + } + return diags +} + +// CopyAutoUpdateVersionFromTerraform copies contents of the source Terraform object into a target struct +func CopyAutoUpdateVersionFromTerraform(_ context.Context, tf github_com_hashicorp_terraform_plugin_framework_types.Object, obj *github_com_gravitational_teleport_api_gen_proto_go_teleport_autoupdate_v1.AutoUpdateVersion) github_com_hashicorp_terraform_plugin_framework_diag.Diagnostics { + var diags github_com_hashicorp_terraform_plugin_framework_diag.Diagnostics + { + a, ok := tf.Attrs["kind"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.kind"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.kind", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Kind = t + } + } + } + { + a, ok := tf.Attrs["sub_kind"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.sub_kind"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.sub_kind", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.SubKind = t + } + } + } + { + a, ok := tf.Attrs["version"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.version"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.version", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Version = t + } + } + } + { + a, ok := tf.Attrs["metadata"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.metadata"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.metadata", "github.com/hashicorp/terraform-plugin-framework/types.Object"}) + } else { + obj.Metadata = nil + if !v.Null && !v.Unknown { + tf := v + obj.Metadata = &github_com_gravitational_teleport_api_gen_proto_go_teleport_header_v1.Metadata{} + obj := obj.Metadata + { + a, ok := tf.Attrs["name"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.metadata.name"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.metadata.name", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Name = t + } + } + } + { + a, ok := tf.Attrs["namespace"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.metadata.namespace"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.metadata.namespace", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Namespace = t + } + } + } + { + a, ok := tf.Attrs["description"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.metadata.description"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.metadata.description", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Description = t + } + } + } + { + a, ok := tf.Attrs["labels"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.metadata.labels"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Map) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.metadata.labels", "github.com/hashicorp/terraform-plugin-framework/types.Map"}) + } else { + obj.Labels = make(map[string]string, len(v.Elems)) + if !v.Null && !v.Unknown { + for k, a := range v.Elems { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.metadata.labels", "github_com_hashicorp_terraform_plugin_framework_types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Labels[k] = t + } + } + } + } + } + } + { + a, ok := tf.Attrs["expires"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.metadata.expires"}) + } + CopyFromTimestamp(diags, a, &obj.Expires) + } + { + a, ok := tf.Attrs["revision"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.metadata.revision"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.metadata.revision", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Revision = t + } + } + } + } + } + } + } + { + a, ok := tf.Attrs["spec"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.spec"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.spec", "github.com/hashicorp/terraform-plugin-framework/types.Object"}) + } else { + obj.Spec = nil + if !v.Null && !v.Unknown { + tf := v + obj.Spec = &github_com_gravitational_teleport_api_gen_proto_go_teleport_autoupdate_v1.AutoUpdateVersionSpec{} + obj := obj.Spec + { + a, ok := tf.Attrs["tools"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.spec.tools"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.spec.tools", "github.com/hashicorp/terraform-plugin-framework/types.Object"}) + } else { + obj.Tools = nil + if !v.Null && !v.Unknown { + tf := v + obj.Tools = &github_com_gravitational_teleport_api_gen_proto_go_teleport_autoupdate_v1.AutoUpdateVersionSpecTools{} + obj := obj.Tools + { + a, ok := tf.Attrs["target_version"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.spec.tools.target_version"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.spec.tools.target_version", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.TargetVersion = t + } + } + } + } + } + } + } + { + a, ok := tf.Attrs["agents"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.spec.agents"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.spec.agents", "github.com/hashicorp/terraform-plugin-framework/types.Object"}) + } else { + obj.Agents = nil + if !v.Null && !v.Unknown { + tf := v + obj.Agents = &github_com_gravitational_teleport_api_gen_proto_go_teleport_autoupdate_v1.AutoUpdateVersionSpecAgents{} + obj := obj.Agents + { + a, ok := tf.Attrs["start_version"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.spec.agents.start_version"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.spec.agents.start_version", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.StartVersion = t + } + } + } + { + a, ok := tf.Attrs["target_version"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.spec.agents.target_version"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.spec.agents.target_version", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.TargetVersion = t + } + } + } + { + a, ok := tf.Attrs["schedule"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.spec.agents.schedule"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.spec.agents.schedule", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Schedule = t + } + } + } + { + a, ok := tf.Attrs["mode"] + if !ok { + diags.Append(attrReadMissingDiag{"AutoUpdateVersion.spec.agents.mode"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"AutoUpdateVersion.spec.agents.mode", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Mode = t + } + } + } + } + } + } + } + } + } + } + } + return diags +} + +// CopyAutoUpdateVersionToTerraform copies contents of the source Terraform object into a target struct +func CopyAutoUpdateVersionToTerraform(ctx context.Context, obj *github_com_gravitational_teleport_api_gen_proto_go_teleport_autoupdate_v1.AutoUpdateVersion, tf *github_com_hashicorp_terraform_plugin_framework_types.Object) github_com_hashicorp_terraform_plugin_framework_diag.Diagnostics { + var diags github_com_hashicorp_terraform_plugin_framework_diag.Diagnostics + tf.Null = false + tf.Unknown = false + if tf.Attrs == nil { + tf.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value) + } + { + t, ok := tf.AttrTypes["kind"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.kind"}) + } else { + v, ok := tf.Attrs["kind"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateVersion.kind", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.kind", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Kind) == "" + } + v.Value = string(obj.Kind) + v.Unknown = false + tf.Attrs["kind"] = v + } + } + { + t, ok := tf.AttrTypes["sub_kind"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.sub_kind"}) + } else { + v, ok := tf.Attrs["sub_kind"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateVersion.sub_kind", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.sub_kind", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.SubKind) == "" + } + v.Value = string(obj.SubKind) + v.Unknown = false + tf.Attrs["sub_kind"] = v + } + } + { + t, ok := tf.AttrTypes["version"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.version"}) + } else { + v, ok := tf.Attrs["version"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateVersion.version", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.version", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Version) == "" + } + v.Value = string(obj.Version) + v.Unknown = false + tf.Attrs["version"] = v + } + } + { + a, ok := tf.AttrTypes["metadata"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.metadata"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.metadata", "github.com/hashicorp/terraform-plugin-framework/types.ObjectType"}) + } else { + v, ok := tf.Attrs["metadata"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if obj.Metadata == nil { + v.Null = true + } else { + obj := obj.Metadata + tf := &v + { + t, ok := tf.AttrTypes["name"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.metadata.name"}) + } else { + v, ok := tf.Attrs["name"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateVersion.metadata.name", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.metadata.name", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Name) == "" + } + v.Value = string(obj.Name) + v.Unknown = false + tf.Attrs["name"] = v + } + } + { + t, ok := tf.AttrTypes["namespace"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.metadata.namespace"}) + } else { + v, ok := tf.Attrs["namespace"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateVersion.metadata.namespace", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.metadata.namespace", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Namespace) == "" + } + v.Value = string(obj.Namespace) + v.Unknown = false + tf.Attrs["namespace"] = v + } + } + { + t, ok := tf.AttrTypes["description"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.metadata.description"}) + } else { + v, ok := tf.Attrs["description"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateVersion.metadata.description", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.metadata.description", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Description) == "" + } + v.Value = string(obj.Description) + v.Unknown = false + tf.Attrs["description"] = v + } + } + { + a, ok := tf.AttrTypes["labels"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.metadata.labels"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.MapType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.metadata.labels", "github.com/hashicorp/terraform-plugin-framework/types.MapType"}) + } else { + c, ok := tf.Attrs["labels"].(github_com_hashicorp_terraform_plugin_framework_types.Map) + if !ok { + c = github_com_hashicorp_terraform_plugin_framework_types.Map{ + + ElemType: o.ElemType, + Elems: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.Labels)), + Null: true, + } + } else { + if c.Elems == nil { + c.Elems = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.Labels)) + } + } + if obj.Labels != nil { + t := o.ElemType + for k, a := range obj.Labels { + v, ok := tf.Attrs["labels"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateVersion.metadata.labels", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.metadata.labels", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = false + } + v.Value = string(a) + v.Unknown = false + c.Elems[k] = v + } + if len(obj.Labels) > 0 { + c.Null = false + } + } + c.Unknown = false + tf.Attrs["labels"] = c + } + } + } + { + t, ok := tf.AttrTypes["expires"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.metadata.expires"}) + } else { + v := CopyToTimestamp(diags, obj.Expires, t, tf.Attrs["expires"]) + tf.Attrs["expires"] = v + } + } + { + t, ok := tf.AttrTypes["revision"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.metadata.revision"}) + } else { + v, ok := tf.Attrs["revision"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateVersion.metadata.revision", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.metadata.revision", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Revision) == "" + } + v.Value = string(obj.Revision) + v.Unknown = false + tf.Attrs["revision"] = v + } + } + } + v.Unknown = false + tf.Attrs["metadata"] = v + } + } + } + { + a, ok := tf.AttrTypes["spec"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.spec"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.spec", "github.com/hashicorp/terraform-plugin-framework/types.ObjectType"}) + } else { + v, ok := tf.Attrs["spec"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if obj.Spec == nil { + v.Null = true + } else { + obj := obj.Spec + tf := &v + { + a, ok := tf.AttrTypes["tools"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.spec.tools"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.spec.tools", "github.com/hashicorp/terraform-plugin-framework/types.ObjectType"}) + } else { + v, ok := tf.Attrs["tools"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if obj.Tools == nil { + v.Null = true + } else { + obj := obj.Tools + tf := &v + { + t, ok := tf.AttrTypes["target_version"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.spec.tools.target_version"}) + } else { + v, ok := tf.Attrs["target_version"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateVersion.spec.tools.target_version", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.spec.tools.target_version", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.TargetVersion) == "" + } + v.Value = string(obj.TargetVersion) + v.Unknown = false + tf.Attrs["target_version"] = v + } + } + } + v.Unknown = false + tf.Attrs["tools"] = v + } + } + } + { + a, ok := tf.AttrTypes["agents"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.spec.agents"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.spec.agents", "github.com/hashicorp/terraform-plugin-framework/types.ObjectType"}) + } else { + v, ok := tf.Attrs["agents"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if obj.Agents == nil { + v.Null = true + } else { + obj := obj.Agents + tf := &v + { + t, ok := tf.AttrTypes["start_version"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.spec.agents.start_version"}) + } else { + v, ok := tf.Attrs["start_version"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateVersion.spec.agents.start_version", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.spec.agents.start_version", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.StartVersion) == "" + } + v.Value = string(obj.StartVersion) + v.Unknown = false + tf.Attrs["start_version"] = v + } + } + { + t, ok := tf.AttrTypes["target_version"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.spec.agents.target_version"}) + } else { + v, ok := tf.Attrs["target_version"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateVersion.spec.agents.target_version", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.spec.agents.target_version", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.TargetVersion) == "" + } + v.Value = string(obj.TargetVersion) + v.Unknown = false + tf.Attrs["target_version"] = v + } + } + { + t, ok := tf.AttrTypes["schedule"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.spec.agents.schedule"}) + } else { + v, ok := tf.Attrs["schedule"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateVersion.spec.agents.schedule", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.spec.agents.schedule", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Schedule) == "" + } + v.Value = string(obj.Schedule) + v.Unknown = false + tf.Attrs["schedule"] = v + } + } + { + t, ok := tf.AttrTypes["mode"] + if !ok { + diags.Append(attrWriteMissingDiag{"AutoUpdateVersion.spec.agents.mode"}) + } else { + v, ok := tf.Attrs["mode"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"AutoUpdateVersion.spec.agents.mode", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"AutoUpdateVersion.spec.agents.mode", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Mode) == "" + } + v.Value = string(obj.Mode) + v.Unknown = false + tf.Attrs["mode"] = v + } + } + } + v.Unknown = false + tf.Attrs["agents"] = v + } + } + } + } + v.Unknown = false + tf.Attrs["spec"] = v + } + } + } + return diags +} + +// attrReadMissingDiag represents diagnostic message on an attribute missing in the source object +type attrReadMissingDiag struct { + Path string +} + +func (d attrReadMissingDiag) Severity() github_com_hashicorp_terraform_plugin_framework_diag.Severity { + return github_com_hashicorp_terraform_plugin_framework_diag.SeverityError +} + +func (d attrReadMissingDiag) Summary() string { + return "Error reading from Terraform object" +} + +func (d attrReadMissingDiag) Detail() string { + return fmt.Sprintf("A value for %v is missing in the source Terraform object Attrs", d.Path) +} + +func (d attrReadMissingDiag) Equal(o github_com_hashicorp_terraform_plugin_framework_diag.Diagnostic) bool { + return (d.Severity() == o.Severity()) && (d.Summary() == o.Summary()) && (d.Detail() == o.Detail()) +} + +// attrReadConversionFailureDiag represents diagnostic message on a failed type conversion on read +type attrReadConversionFailureDiag struct { + Path string + Type string +} + +func (d attrReadConversionFailureDiag) Severity() github_com_hashicorp_terraform_plugin_framework_diag.Severity { + return github_com_hashicorp_terraform_plugin_framework_diag.SeverityError +} + +func (d attrReadConversionFailureDiag) Summary() string { + return "Error reading from Terraform object" +} + +func (d attrReadConversionFailureDiag) Detail() string { + return fmt.Sprintf("A value for %v can not be converted to %v", d.Path, d.Type) +} + +func (d attrReadConversionFailureDiag) Equal(o github_com_hashicorp_terraform_plugin_framework_diag.Diagnostic) bool { + return (d.Severity() == o.Severity()) && (d.Summary() == o.Summary()) && (d.Detail() == o.Detail()) +} + +// attrWriteMissingDiag represents diagnostic message on an attribute missing in the target object +type attrWriteMissingDiag struct { + Path string +} + +func (d attrWriteMissingDiag) Severity() github_com_hashicorp_terraform_plugin_framework_diag.Severity { + return github_com_hashicorp_terraform_plugin_framework_diag.SeverityError +} + +func (d attrWriteMissingDiag) Summary() string { + return "Error writing to Terraform object" +} + +func (d attrWriteMissingDiag) Detail() string { + return fmt.Sprintf("A value for %v is missing in the source Terraform object AttrTypes", d.Path) +} + +func (d attrWriteMissingDiag) Equal(o github_com_hashicorp_terraform_plugin_framework_diag.Diagnostic) bool { + return (d.Severity() == o.Severity()) && (d.Summary() == o.Summary()) && (d.Detail() == o.Detail()) +} + +// attrWriteConversionFailureDiag represents diagnostic message on a failed type conversion on write +type attrWriteConversionFailureDiag struct { + Path string + Type string +} + +func (d attrWriteConversionFailureDiag) Severity() github_com_hashicorp_terraform_plugin_framework_diag.Severity { + return github_com_hashicorp_terraform_plugin_framework_diag.SeverityError +} + +func (d attrWriteConversionFailureDiag) Summary() string { + return "Error writing to Terraform object" +} + +func (d attrWriteConversionFailureDiag) Detail() string { + return fmt.Sprintf("A value for %v can not be converted to %v", d.Path, d.Type) +} + +func (d attrWriteConversionFailureDiag) Equal(o github_com_hashicorp_terraform_plugin_framework_diag.Diagnostic) bool { + return (d.Severity() == o.Severity()) && (d.Summary() == o.Summary()) && (d.Detail() == o.Detail()) +} + +// attrWriteGeneralError represents diagnostic message on a generic error on write +type attrWriteGeneralError struct { + Path string + Err error +} + +func (d attrWriteGeneralError) Severity() github_com_hashicorp_terraform_plugin_framework_diag.Severity { + return github_com_hashicorp_terraform_plugin_framework_diag.SeverityError +} + +func (d attrWriteGeneralError) Summary() string { + return "Error writing to Terraform object" +} + +func (d attrWriteGeneralError) Detail() string { + return fmt.Sprintf("%s: %s", d.Path, d.Err.Error()) +} + +func (d attrWriteGeneralError) Equal(o github_com_hashicorp_terraform_plugin_framework_diag.Diagnostic) bool { + return (d.Severity() == o.Severity()) && (d.Summary() == o.Summary()) && (d.Detail() == o.Detail()) +} diff --git a/integrations/terraform/tfschema/autoupdate/v1/custom_types.go b/integrations/terraform/tfschema/autoupdate/v1/custom_types.go new file mode 100644 index 00000000000..ce1b7b32427 --- /dev/null +++ b/integrations/terraform/tfschema/autoupdate/v1/custom_types.go @@ -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 +) diff --git a/lib/services/presets.go b/lib/services/presets.go index 4a74e4bf609..f1dbcac84ea 100644 --- a/lib/services/presets.go +++ b/lib/services/presets.go @@ -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()), }, }, }, diff --git a/lib/services/presets_test.go b/lib/services/presets_test.go index ef1e60b4aa1..d7de20a546e 100644 --- a/lib/services/presets_test.go +++ b/lib/services/presets_test.go @@ -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()), }, }, },