mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-12 02:15:01 +00:00
Terraform: convert installer to generic provider (#69403)
Contributes to https://github.com/gravitational/teleport/issues/69301.
This commit is contained in:
@@ -526,21 +526,6 @@ var (
|
||||
ForceSetKind: "apitypes.KindNode",
|
||||
}
|
||||
|
||||
installer = payload{
|
||||
Name: "Installer",
|
||||
TypeName: "InstallerV1",
|
||||
VarName: "installer",
|
||||
GetMethod: "GetInstaller",
|
||||
CreateMethod: "SetInstaller",
|
||||
UpdateMethod: "SetInstaller",
|
||||
DeleteMethod: "DeleteInstaller",
|
||||
ID: `"installer"`,
|
||||
Kind: "installer",
|
||||
HasStaticID: false,
|
||||
TerraformResourceType: "teleport_installer",
|
||||
HasCheckAndSetDefaults: true,
|
||||
}
|
||||
|
||||
accessMonitoringRule = payload{
|
||||
Name: "AccessMonitoringRule",
|
||||
TypeName: "AccessMonitoringRule",
|
||||
@@ -1062,8 +1047,6 @@ func genTFSchema() {
|
||||
generateDataSource(oktaImportRule, pluralDataSource)
|
||||
generateResource(server, pluralResource)
|
||||
generateDataSource(server, pluralDataSource)
|
||||
generateResource(installer, pluralResource)
|
||||
generateDataSource(installer, pluralDataSource)
|
||||
generateResource(accessMonitoringRule, pluralResource)
|
||||
generateDataSource(accessMonitoringRule, pluralDataSource)
|
||||
generateResource(workloadIdentity, pluralResource)
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
// 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 legacy
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
apitypes "github.com/gravitational/teleport/api/types"
|
||||
"github.com/gravitational/trace"
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
"github.com/gravitational/teleport/integrations/terraform/tfschema"
|
||||
"github.com/gravitational/teleport/integrations/terraform/provider/internal/tfdiag"
|
||||
)
|
||||
|
||||
// dataSourceTeleportInstallerType is the data source metadata type
|
||||
type dataSourceTeleportInstallerType struct{}
|
||||
|
||||
// dataSourceTeleportInstaller is the resource
|
||||
type dataSourceTeleportInstaller struct {
|
||||
p Provider
|
||||
}
|
||||
|
||||
// GetSchema returns the data source schema
|
||||
func (r dataSourceTeleportInstallerType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) {
|
||||
return tfschema.GenSchemaInstallerV1(ctx)
|
||||
}
|
||||
|
||||
// NewDataSource creates the empty data source
|
||||
func (r dataSourceTeleportInstallerType) NewDataSource(_ context.Context, p tfsdk.Provider) (tfsdk.DataSource, diag.Diagnostics) {
|
||||
return dataSourceTeleportInstaller{
|
||||
p: p.(Provider),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Read reads teleport Installer
|
||||
func (r dataSourceTeleportInstaller) Read(ctx context.Context, req tfsdk.ReadDataSourceRequest, resp *tfsdk.ReadDataSourceResponse) {
|
||||
var id types.String
|
||||
diags := req.Config.GetAttribute(ctx, path.Root("metadata").AtName("name"), &id)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
installerI, err := r.p.Client().GetInstaller(ctx, id.Value)
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading Installer", trace.Wrap(err), "installer"))
|
||||
return
|
||||
}
|
||||
|
||||
var state types.Object
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
|
||||
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() {
|
||||
state.Attrs["id"] = id
|
||||
}
|
||||
|
||||
|
||||
installer := installerI.(*apitypes.InstallerV1)
|
||||
diags = tfschema.CopyInstallerV1ToTerraform(ctx, installer, &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
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,6 @@ func DataSourceTypes() map[string]tfsdk.DataSourceType {
|
||||
"teleport_login_rule": dataSourceTeleportLoginRuleType{},
|
||||
"teleport_trusted_device": dataSourceTeleportDeviceV1Type{},
|
||||
"teleport_okta_import_rule": dataSourceTeleportOktaImportRuleType{},
|
||||
"teleport_installer": dataSourceTeleportInstallerType{},
|
||||
"teleport_access_monitoring_rule": dataSourceTeleportAccessMonitoringRuleType{},
|
||||
"teleport_workload_identity": dataSourceTeleportWorkloadIdentityType{},
|
||||
"teleport_autoupdate_version": dataSourceTeleportAutoUpdateVersionType{},
|
||||
@@ -80,7 +79,6 @@ func ResourceTypes() map[string]tfsdk.ResourceType {
|
||||
"teleport_trusted_device": resourceTeleportDeviceV1Type{},
|
||||
"teleport_okta_import_rule": resourceTeleportOktaImportRuleType{},
|
||||
"teleport_server": resourceTeleportServerType{},
|
||||
"teleport_installer": resourceTeleportInstallerType{},
|
||||
"teleport_access_monitoring_rule": resourceTeleportAccessMonitoringRuleType{},
|
||||
"teleport_workload_identity": resourceTeleportWorkloadIdentityType{},
|
||||
"teleport_autoupdate_version": resourceTeleportAutoUpdateVersionType{},
|
||||
|
||||
@@ -1,397 +0,0 @@
|
||||
// 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 legacy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
apitypes "github.com/gravitational/teleport/api/types"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
"github.com/gravitational/teleport/integrations/terraform/tfschema"
|
||||
"github.com/gravitational/teleport/integrations/terraform/provider/internal/tfdiag"
|
||||
)
|
||||
|
||||
// resourceTeleportInstallerType is the resource metadata type
|
||||
type resourceTeleportInstallerType struct{}
|
||||
|
||||
// resourceTeleportInstaller is the resource
|
||||
type resourceTeleportInstaller struct {
|
||||
p Provider
|
||||
}
|
||||
|
||||
// GetSchema returns the resource schema
|
||||
func (r resourceTeleportInstallerType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) {
|
||||
return tfschema.GenSchemaInstallerV1(ctx)
|
||||
}
|
||||
|
||||
// NewResource creates the empty resource
|
||||
func (r resourceTeleportInstallerType) NewResource(_ context.Context, p tfsdk.Provider) (tfsdk.Resource, diag.Diagnostics) {
|
||||
return resourceTeleportInstaller{
|
||||
p: p.(Provider),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Create creates the Installer
|
||||
func (r resourceTeleportInstaller) Create(ctx context.Context, req tfsdk.CreateResourceRequest, resp *tfsdk.CreateResourceResponse) {
|
||||
var err error
|
||||
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
|
||||
}
|
||||
|
||||
installer := &apitypes.InstallerV1{}
|
||||
diags = tfschema.CopyInstallerV1FromTerraform(ctx, plan, installer)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
installerResource := installer
|
||||
|
||||
err = installerResource.CheckAndSetDefaults()
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error setting Installer defaults", trace.Wrap(err), "installer"))
|
||||
return
|
||||
}
|
||||
|
||||
id := installerResource.Metadata.Name
|
||||
|
||||
_, err = r.p.Client().GetInstaller(ctx, id)
|
||||
if !trace.IsNotFound(err) {
|
||||
if err == nil {
|
||||
existErr := fmt.Sprintf("Installer exists in Teleport. Either remove it (tctl rm installer/%v)"+
|
||||
" or import it to the existing state (terraform import teleport_installer.%v %v)", id, id, id)
|
||||
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromErr("Installer exists in Teleport", trace.Errorf(existErr)))
|
||||
return
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading Installer", trace.Wrap(err), "installer"))
|
||||
return
|
||||
}
|
||||
|
||||
err = r.p.Client().SetInstaller(ctx, installerResource)
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error creating Installer", trace.Wrap(err), "installer"))
|
||||
return
|
||||
}
|
||||
|
||||
// Not really an inferface, just using the same name for easier templating.
|
||||
var installerI apitypes.Installer
|
||||
// Try getting the resource until it exists.
|
||||
tries := 0
|
||||
retry, err := r.p.Retry()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for {
|
||||
tries = tries + 1
|
||||
installerI, err = r.p.Client().GetInstaller(ctx, id)
|
||||
if trace.IsNotFound(err) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading Installer", trace.Wrap(ctx.Err()), "installer"))
|
||||
return
|
||||
case <-retry.After():
|
||||
}
|
||||
if tries >= r.p.MaxRetries() {
|
||||
diagMessage := fmt.Sprintf("Error reading Installer (tried %d times) - state outdated, please import resource", tries)
|
||||
resp.Diagnostics.AddError(diagMessage, "installer")
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading Installer", trace.Wrap(err), "installer"))
|
||||
return
|
||||
}
|
||||
|
||||
installerResource, ok := installerI.(*apitypes.InstallerV1)
|
||||
if !ok {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading Installer", trace.Errorf("Can not convert %T to InstallerV1", installerI), "installer"))
|
||||
return
|
||||
}
|
||||
installer = installerResource
|
||||
|
||||
diags = tfschema.CopyInstallerV1ToTerraform(ctx, installer, &plan)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
plan.Attrs["id"] = types.String{Value: "installer"}
|
||||
|
||||
diags = resp.State.Set(ctx, &plan)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Read reads teleport Installer
|
||||
func (r resourceTeleportInstaller) 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
|
||||
}
|
||||
|
||||
var id types.String
|
||||
diags = req.State.GetAttribute(ctx, path.Root("metadata").AtName("name"), &id)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
installerI, err := r.p.Client().GetInstaller(ctx, id.Value)
|
||||
if trace.IsNotFound(err) {
|
||||
resp.State.RemoveResource(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading Installer", trace.Wrap(err), "installer"))
|
||||
return
|
||||
}
|
||||
|
||||
installer := installerI.(*apitypes.InstallerV1)
|
||||
diags = tfschema.CopyInstallerV1ToTerraform(ctx, installer, &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 Installer
|
||||
func (r resourceTeleportInstaller) 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
|
||||
}
|
||||
|
||||
installer := &apitypes.InstallerV1{}
|
||||
diags = tfschema.CopyInstallerV1FromTerraform(ctx, plan, installer)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
installerResource := installer
|
||||
|
||||
|
||||
if err := installerResource.CheckAndSetDefaults(); err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error updating Installer", err, "installer"))
|
||||
return
|
||||
}
|
||||
name := installerResource.Metadata.Name
|
||||
|
||||
installerBefore, err := r.p.Client().GetInstaller(ctx, name)
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading Installer", err, "installer"))
|
||||
return
|
||||
}
|
||||
|
||||
err = r.p.Client().SetInstaller(ctx, installerResource)
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error updating Installer", err, "installer"))
|
||||
return
|
||||
}
|
||||
|
||||
// Not really an inferface, just using the same name for easier templating.
|
||||
var installerI apitypes.Installer
|
||||
|
||||
tries := 0
|
||||
retry, err := r.p.Retry()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for {
|
||||
tries = tries + 1
|
||||
installerI, err = r.p.Client().GetInstaller(ctx, name)
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading Installer", err, "installer"))
|
||||
return
|
||||
}
|
||||
if installerBefore.GetMetadata().Revision != installerI.GetMetadata().Revision || false {
|
||||
break
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading Installer", trace.Wrap(ctx.Err()), "installer"))
|
||||
return
|
||||
case <-retry.After():
|
||||
}
|
||||
if tries >= r.p.MaxRetries() {
|
||||
diagMessage := fmt.Sprintf("Error reading Installer (tried %d times) - state outdated, please import resource", tries)
|
||||
resp.Diagnostics.AddError(diagMessage, "installer")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
installerResource, ok := installerI.(*apitypes.InstallerV1)
|
||||
if !ok {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading Installer", trace.Errorf("Can not convert %T to InstallerV1", installerI), "installer"))
|
||||
return
|
||||
}
|
||||
installer = installerResource
|
||||
|
||||
diags = tfschema.CopyInstallerV1ToTerraform(ctx, installer, &plan)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
diags = resp.State.Set(ctx, plan)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Delete deletes Teleport Installer
|
||||
func (r resourceTeleportInstaller) Delete(ctx context.Context, req tfsdk.DeleteResourceRequest, resp *tfsdk.DeleteResourceResponse) {
|
||||
var id types.String
|
||||
diags := req.State.GetAttribute(ctx, path.Root("metadata").AtName("name"), &id)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
err := r.p.Client().DeleteInstaller(ctx, id.Value)
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error deleting InstallerV1", trace.Wrap(err), "installer"))
|
||||
return
|
||||
}
|
||||
|
||||
resp.State.RemoveResource(ctx)
|
||||
}
|
||||
|
||||
// ImportState imports Installer state
|
||||
func (r resourceTeleportInstaller) ImportState(ctx context.Context, req tfsdk.ImportResourceStateRequest, resp *tfsdk.ImportResourceStateResponse) {
|
||||
installer, err := r.p.Client().GetInstaller(ctx, req.ID)
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading Installer", trace.Wrap(err), "installer"))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
installerResource := installer.(*apitypes.InstallerV1)
|
||||
|
||||
var state types.Object
|
||||
|
||||
diags := resp.State.Get(ctx, &state)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
diags = tfschema.CopyInstallerV1ToTerraform(ctx, installerResource, &state)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
id := installerResource.GetName()
|
||||
|
||||
state.Attrs["id"] = types.String{Value: id}
|
||||
|
||||
diags = resp.State.Set(ctx, &state)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// ModifyPlan modifies the planned value, normalizing null values.
|
||||
func (r resourceTeleportInstaller) ModifyPlan(ctx context.Context, req tfsdk.ModifyResourcePlanRequest, resp *tfsdk.ModifyResourcePlanResponse) {
|
||||
// If the entire plan is null, the resource is planned for destruction.
|
||||
if req.Plan.Raw.IsNull() {
|
||||
return
|
||||
}
|
||||
|
||||
// If the state is null, the resource is being created. No need to modify plan.
|
||||
if req.State.Raw.IsNull() {
|
||||
return
|
||||
}
|
||||
|
||||
var config types.Object
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
installer := &apitypes.InstallerV1{}
|
||||
resp.Diagnostics.Append(tfschema.CopyInstallerV1FromTerraform(ctx, config, installer)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
installerResource := installer
|
||||
|
||||
if err := installerResource.CheckAndSetDefaults(); err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error setting Installer defaults", trace.Wrap(err), "installer"))
|
||||
return
|
||||
}
|
||||
|
||||
installer = installerResource
|
||||
|
||||
const preserveUnknown = true
|
||||
resp.Diagnostics.Append(tfschema.CopyInstallerV1ToTerraformPreserveUnknown(ctx, installer, &config, preserveUnknown)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
var plan types.Object
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
plan.Attrs["spec"] = config.Attrs["spec"]
|
||||
|
||||
resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...)
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// Teleport
|
||||
// Copyright (C) 2026 Gravitational, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package resources
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
|
||||
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
|
||||
"github.com/gravitational/teleport/integrations/terraform/provider/internal/teleport"
|
||||
"github.com/gravitational/teleport/integrations/terraform/provider/internal/tfdriver"
|
||||
"github.com/gravitational/teleport/integrations/terraform/tfschema"
|
||||
)
|
||||
|
||||
// NewInstallerDataSourceType returns the installer data source type.
|
||||
func NewInstallerDataSourceType() tfdriver.DataSourceType[types.InstallerV1, tfdriver.NameIdentifier] {
|
||||
return tfdriver.DataSourceType[types.InstallerV1, tfdriver.NameIdentifier]{
|
||||
NewDataSourceClient: func(p tfsdk.Provider) tfdriver.DataSourceClient[types.InstallerV1, tfdriver.NameIdentifier] {
|
||||
return teleport.NewInstallerClient(clientFromProvider(p))
|
||||
},
|
||||
Kind: types.KindInstaller,
|
||||
Codec: tfdriver.DataSourceCodecFuncs[types.InstallerV1]{
|
||||
SchemaFunc: tfschema.GenSchemaInstallerV1,
|
||||
ToStateFunc: tfschema.CopyInstallerV1ToTerraform,
|
||||
},
|
||||
Identifier: tfdriver.NameIdentifierFromPath(path.Root("metadata").AtName("name")),
|
||||
}
|
||||
}
|
||||
|
||||
// NewInstallerResourceType returns the installer resource type.
|
||||
func NewInstallerResourceType() tfdriver.ResourceType[types.InstallerV1, tfdriver.NameIdentifier] {
|
||||
return tfdriver.ResourceType[types.InstallerV1, tfdriver.NameIdentifier]{
|
||||
NewResourceClient: func(p tfsdk.Provider) tfdriver.ResourceClient[types.InstallerV1, tfdriver.NameIdentifier] {
|
||||
return teleport.NewInstallerClient(clientFromProvider(p))
|
||||
},
|
||||
Kind: types.KindInstaller,
|
||||
Codec: tfdriver.ResourceCodecFuncs[types.InstallerV1]{
|
||||
SchemaFunc: tfschema.GenSchemaInstallerV1,
|
||||
ToStateFunc: tfschema.CopyInstallerV1ToTerraform,
|
||||
FromPlanFunc: tfschema.CopyInstallerV1FromTerraform,
|
||||
},
|
||||
Normalizer: tfdriver.CheckAndSetDefaults[types.InstallerV1](),
|
||||
Identifier: tfdriver.NameIdentifierPolicy(path.Root("metadata").AtName("name"), func(installer *types.InstallerV1) string {
|
||||
return installer.GetMetadata().Name
|
||||
}),
|
||||
ResourceRevision: func(st *types.InstallerV1) string {
|
||||
return st.GetMetadata().Revision
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// Teleport
|
||||
// Copyright (C) 2026 Gravitational, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package teleport
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
|
||||
"github.com/gravitational/teleport/api/client"
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
|
||||
"github.com/gravitational/teleport/integrations/terraform/provider/internal/tfdriver"
|
||||
)
|
||||
|
||||
// NewInstallerClient returns an installer client.
|
||||
func NewInstallerClient(c *client.Client) InstallerClient {
|
||||
return InstallerClient{client: c}
|
||||
}
|
||||
|
||||
// InstallerClient manages installer resources.
|
||||
type InstallerClient struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
// Get reads an installer by name.
|
||||
func (r InstallerClient) Get(ctx context.Context, id tfdriver.NameIdentifier) (*types.InstallerV1, error) {
|
||||
installer, err := r.client.GetInstaller(ctx, id.Name)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
installerv1, ok := installer.(*types.InstallerV1)
|
||||
if !ok {
|
||||
return nil, trace.BadParameter("unexpected installer type: %T", installer)
|
||||
}
|
||||
|
||||
return installerv1, nil
|
||||
}
|
||||
|
||||
// Create creates an installer.
|
||||
func (r InstallerClient) Create(ctx context.Context, installer *types.InstallerV1) error {
|
||||
if err := r.client.SetInstaller(ctx, installer); err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Upsert updates an installer.
|
||||
func (r InstallerClient) Upsert(ctx context.Context, installer *types.InstallerV1) error {
|
||||
if err := r.client.SetInstaller(ctx, installer); err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete deletes an installer by name.
|
||||
func (r InstallerClient) Delete(ctx context.Context, id tfdriver.NameIdentifier) error {
|
||||
return trace.Wrap(r.client.DeleteInstaller(ctx, id.Name))
|
||||
}
|
||||
@@ -569,6 +569,7 @@ func (p *Provider) GetResources(_ context.Context) (map[string]tfsdk.ResourceTyp
|
||||
"teleport_app": resources.NewAppResourceType(),
|
||||
"teleport_auth_preference": resources.NewAuthPreferenceResourceType(),
|
||||
"teleport_database": resources.NewDatabaseResourceType(),
|
||||
"teleport_installer": resources.NewInstallerResourceType(),
|
||||
"teleport_kube_cluster": resources.NewKubernetesClusterResourceType(),
|
||||
"teleport_lock": resources.NewLockResourceType(),
|
||||
"teleport_saml_connector": resources.NewSAMLConnectorResourceType(),
|
||||
@@ -594,6 +595,7 @@ func (p *Provider) GetDataSources(_ context.Context) (map[string]tfsdk.DataSourc
|
||||
"teleport_app": resources.NewAppDataSourceType(),
|
||||
"teleport_auth_preference": resources.NewAuthPreferenceDataSourceType(),
|
||||
"teleport_database": resources.NewDatabaseDataSourceType(),
|
||||
"teleport_installer": resources.NewInstallerDataSourceType(),
|
||||
"teleport_kube_cluster": resources.NewKubernetesClusterDataSourceType(),
|
||||
"teleport_lock": resources.NewLockDataSourceType(),
|
||||
"teleport_saml_connector": resources.NewSAMLConnectorDataSourceType(),
|
||||
|
||||
Reference in New Issue
Block a user