mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-11 22:49:54 +00:00
Terraform: convert static host user to generic provider (#69404)
Contributes to https://github.com/gravitational/teleport/issues/69301.
This commit is contained in:
@@ -567,32 +567,6 @@ var (
|
||||
ForceSetKind: "apitypes.KindAccessMonitoringRule",
|
||||
}
|
||||
|
||||
staticHostUser = payload{
|
||||
Name: "StaticHostUser",
|
||||
TypeName: "StaticHostUser",
|
||||
VarName: "staticHostUser",
|
||||
GetMethod: "StaticHostUserClient().GetStaticHostUser",
|
||||
CreateMethod: "StaticHostUserClient().CreateStaticHostUser",
|
||||
UpsertMethodArity: 2,
|
||||
UpdateMethod: "StaticHostUserClient().UpsertStaticHostUser",
|
||||
DeleteMethod: "StaticHostUserClient().DeleteStaticHostUser",
|
||||
ID: "staticHostUser.Metadata.Name",
|
||||
Kind: "static_host_user",
|
||||
HasStaticID: false,
|
||||
ProtoPackage: "userprovisioningv2",
|
||||
ProtoPackagePath: "github.com/gravitational/teleport/api/gen/proto/go/teleport/userprovisioning/v2",
|
||||
SchemaPackage: "schemav1",
|
||||
SchemaPackagePath: "github.com/gravitational/teleport/integrations/terraform/tfschema/userprovisioning/v2",
|
||||
TerraformResourceType: "teleport_static_host_user",
|
||||
// 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.KindStaticHostUser",
|
||||
}
|
||||
|
||||
workloadIdentity = payload{
|
||||
Name: "WorkloadIdentity",
|
||||
TypeName: "WorkloadIdentity",
|
||||
@@ -1092,8 +1066,6 @@ func genTFSchema() {
|
||||
generateDataSource(installer, pluralDataSource)
|
||||
generateResource(accessMonitoringRule, pluralResource)
|
||||
generateDataSource(accessMonitoringRule, pluralDataSource)
|
||||
generateResource(staticHostUser, pluralResource)
|
||||
generateDataSource(staticHostUser, pluralDataSource)
|
||||
generateResource(workloadIdentity, pluralResource)
|
||||
generateDataSource(workloadIdentity, pluralDataSource)
|
||||
generateResource(autoUpdateVersion, singularResource)
|
||||
|
||||
-97
@@ -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"
|
||||
|
||||
|
||||
"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"
|
||||
|
||||
schemav1 "github.com/gravitational/teleport/integrations/terraform/tfschema/userprovisioning/v2"
|
||||
"github.com/gravitational/teleport/integrations/terraform/provider/internal/tfdiag"
|
||||
)
|
||||
|
||||
// dataSourceTeleportStaticHostUserType is the data source metadata type
|
||||
type dataSourceTeleportStaticHostUserType struct{}
|
||||
|
||||
// dataSourceTeleportStaticHostUser is the resource
|
||||
type dataSourceTeleportStaticHostUser struct {
|
||||
p Provider
|
||||
}
|
||||
|
||||
// GetSchema returns the data source schema
|
||||
func (r dataSourceTeleportStaticHostUserType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) {
|
||||
return schemav1.GenSchemaStaticHostUser(ctx)
|
||||
}
|
||||
|
||||
// NewDataSource creates the empty data source
|
||||
func (r dataSourceTeleportStaticHostUserType) NewDataSource(_ context.Context, p tfsdk.Provider) (tfsdk.DataSource, diag.Diagnostics) {
|
||||
return dataSourceTeleportStaticHostUser{
|
||||
p: p.(Provider),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Read reads teleport StaticHostUser
|
||||
func (r dataSourceTeleportStaticHostUser) 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
|
||||
}
|
||||
|
||||
staticHostUserI, err := r.p.Client().StaticHostUserClient().GetStaticHostUser(ctx, id.Value)
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading StaticHostUser", trace.Wrap(err), "static_host_user"))
|
||||
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
|
||||
}
|
||||
|
||||
staticHostUser := staticHostUserI
|
||||
|
||||
diags = schemav1.CopyStaticHostUserToTerraform(ctx, staticHostUser, &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
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,6 @@ func DataSourceTypes() map[string]tfsdk.DataSourceType {
|
||||
"teleport_okta_import_rule": dataSourceTeleportOktaImportRuleType{},
|
||||
"teleport_installer": dataSourceTeleportInstallerType{},
|
||||
"teleport_access_monitoring_rule": dataSourceTeleportAccessMonitoringRuleType{},
|
||||
"teleport_static_host_user": dataSourceTeleportStaticHostUserType{},
|
||||
"teleport_workload_identity": dataSourceTeleportWorkloadIdentityType{},
|
||||
"teleport_autoupdate_version": dataSourceTeleportAutoUpdateVersionType{},
|
||||
"teleport_autoupdate_config": dataSourceTeleportAutoUpdateConfigType{},
|
||||
@@ -83,7 +82,6 @@ func ResourceTypes() map[string]tfsdk.ResourceType {
|
||||
"teleport_server": resourceTeleportServerType{},
|
||||
"teleport_installer": resourceTeleportInstallerType{},
|
||||
"teleport_access_monitoring_rule": resourceTeleportAccessMonitoringRuleType{},
|
||||
"teleport_static_host_user": resourceTeleportStaticHostUserType{},
|
||||
"teleport_workload_identity": resourceTeleportWorkloadIdentityType{},
|
||||
"teleport_autoupdate_version": resourceTeleportAutoUpdateVersionType{},
|
||||
"teleport_autoupdate_config": resourceTeleportAutoUpdateConfigType{},
|
||||
|
||||
-377
@@ -1,377 +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"
|
||||
|
||||
userprovisioningv2 "github.com/gravitational/teleport/api/gen/proto/go/teleport/userprovisioning/v2"
|
||||
|
||||
"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"
|
||||
|
||||
schemav1 "github.com/gravitational/teleport/integrations/terraform/tfschema/userprovisioning/v2"
|
||||
"github.com/gravitational/teleport/integrations/terraform/provider/internal/tfdiag"
|
||||
)
|
||||
|
||||
// resourceTeleportStaticHostUserType is the resource metadata type
|
||||
type resourceTeleportStaticHostUserType struct{}
|
||||
|
||||
// resourceTeleportStaticHostUser is the resource
|
||||
type resourceTeleportStaticHostUser struct {
|
||||
p Provider
|
||||
}
|
||||
|
||||
// GetSchema returns the resource schema
|
||||
func (r resourceTeleportStaticHostUserType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) {
|
||||
return schemav1.GenSchemaStaticHostUser(ctx)
|
||||
}
|
||||
|
||||
// NewResource creates the empty resource
|
||||
func (r resourceTeleportStaticHostUserType) NewResource(_ context.Context, p tfsdk.Provider) (tfsdk.Resource, diag.Diagnostics) {
|
||||
return resourceTeleportStaticHostUser{
|
||||
p: p.(Provider),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Create creates the StaticHostUser
|
||||
func (r resourceTeleportStaticHostUser) 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
|
||||
}
|
||||
|
||||
staticHostUser := &userprovisioningv2.StaticHostUser{}
|
||||
diags = schemav1.CopyStaticHostUserFromTerraform(ctx, plan, staticHostUser)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
staticHostUserResource := staticHostUser
|
||||
|
||||
staticHostUserResource.Kind = apitypes.KindStaticHostUser
|
||||
|
||||
id := staticHostUserResource.Metadata.Name
|
||||
|
||||
_, err = r.p.Client().StaticHostUserClient().GetStaticHostUser(ctx, id)
|
||||
if !trace.IsNotFound(err) {
|
||||
if err == nil {
|
||||
existErr := fmt.Sprintf("StaticHostUser exists in Teleport. Either remove it (tctl rm static_host_user/%v)"+
|
||||
" or import it to the existing state (terraform import teleport_static_host_user.%v %v)", id, id, id)
|
||||
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromErr("StaticHostUser exists in Teleport", trace.Errorf(existErr)))
|
||||
return
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading StaticHostUser", trace.Wrap(err), "static_host_user"))
|
||||
return
|
||||
}
|
||||
|
||||
_, err = r.p.Client().StaticHostUserClient().CreateStaticHostUser(ctx, staticHostUserResource)
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error creating StaticHostUser", trace.Wrap(err), "static_host_user"))
|
||||
return
|
||||
}
|
||||
var staticHostUserI *userprovisioningv2.StaticHostUser
|
||||
// Try getting the resource until it exists.
|
||||
tries := 0
|
||||
retry, err := r.p.Retry()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for {
|
||||
tries = tries + 1
|
||||
staticHostUserI, err = r.p.Client().StaticHostUserClient().GetStaticHostUser(ctx, id)
|
||||
if trace.IsNotFound(err) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading StaticHostUser", trace.Wrap(ctx.Err()), "static_host_user"))
|
||||
return
|
||||
case <-retry.After():
|
||||
}
|
||||
if tries >= r.p.MaxRetries() {
|
||||
diagMessage := fmt.Sprintf("Error reading StaticHostUser (tried %d times) - state outdated, please import resource", tries)
|
||||
resp.Diagnostics.AddError(diagMessage, "static_host_user")
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading StaticHostUser", trace.Wrap(err), "static_host_user"))
|
||||
return
|
||||
}
|
||||
|
||||
staticHostUserResource = staticHostUserI
|
||||
|
||||
staticHostUser = staticHostUserResource
|
||||
|
||||
diags = schemav1.CopyStaticHostUserToTerraform(ctx, staticHostUser, &plan)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
plan.Attrs["id"] = types.String{Value: staticHostUser.Metadata.Name}
|
||||
|
||||
diags = resp.State.Set(ctx, &plan)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Read reads teleport StaticHostUser
|
||||
func (r resourceTeleportStaticHostUser) 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
|
||||
}
|
||||
|
||||
staticHostUserI, err := r.p.Client().StaticHostUserClient().GetStaticHostUser(ctx, id.Value)
|
||||
if trace.IsNotFound(err) {
|
||||
resp.State.RemoveResource(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading StaticHostUser", trace.Wrap(err), "static_host_user"))
|
||||
return
|
||||
}
|
||||
staticHostUser := staticHostUserI
|
||||
diags = schemav1.CopyStaticHostUserToTerraform(ctx, staticHostUser, &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 StaticHostUser
|
||||
func (r resourceTeleportStaticHostUser) 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
|
||||
}
|
||||
|
||||
staticHostUser := &userprovisioningv2.StaticHostUser{}
|
||||
diags = schemav1.CopyStaticHostUserFromTerraform(ctx, plan, staticHostUser)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
staticHostUserResource := staticHostUser
|
||||
|
||||
staticHostUserResource.Kind = apitypes.KindStaticHostUser
|
||||
|
||||
|
||||
name := staticHostUserResource.Metadata.Name
|
||||
|
||||
staticHostUserBefore, err := r.p.Client().StaticHostUserClient().GetStaticHostUser(ctx, name)
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading StaticHostUser", err, "static_host_user"))
|
||||
return
|
||||
}
|
||||
|
||||
_, err = r.p.Client().StaticHostUserClient().UpsertStaticHostUser(ctx, staticHostUserResource)
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error updating StaticHostUser", err, "static_host_user"))
|
||||
return
|
||||
}
|
||||
var staticHostUserI *userprovisioningv2.StaticHostUser
|
||||
|
||||
tries := 0
|
||||
retry, err := r.p.Retry()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for {
|
||||
tries = tries + 1
|
||||
staticHostUserI, err = r.p.Client().StaticHostUserClient().GetStaticHostUser(ctx, name)
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading StaticHostUser", err, "static_host_user"))
|
||||
return
|
||||
}
|
||||
if staticHostUserBefore.GetMetadata().Revision != staticHostUserI.GetMetadata().Revision || false {
|
||||
break
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading StaticHostUser", trace.Wrap(ctx.Err()), "static_host_user"))
|
||||
return
|
||||
case <-retry.After():
|
||||
}
|
||||
if tries >= r.p.MaxRetries() {
|
||||
diagMessage := fmt.Sprintf("Error reading StaticHostUser (tried %d times) - state outdated, please import resource", tries)
|
||||
resp.Diagnostics.AddError(diagMessage, "static_host_user")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
staticHostUserResource = staticHostUserI
|
||||
|
||||
staticHostUser = staticHostUserResource
|
||||
|
||||
diags = schemav1.CopyStaticHostUserToTerraform(ctx, staticHostUser, &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 StaticHostUser
|
||||
func (r resourceTeleportStaticHostUser) 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().StaticHostUserClient().DeleteStaticHostUser(ctx, id.Value)
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error deleting StaticHostUser", trace.Wrap(err), "static_host_user"))
|
||||
return
|
||||
}
|
||||
|
||||
resp.State.RemoveResource(ctx)
|
||||
}
|
||||
|
||||
// ImportState imports StaticHostUser state
|
||||
func (r resourceTeleportStaticHostUser) ImportState(ctx context.Context, req tfsdk.ImportResourceStateRequest, resp *tfsdk.ImportResourceStateResponse) {
|
||||
staticHostUser, err := r.p.Client().StaticHostUserClient().GetStaticHostUser(ctx, req.ID)
|
||||
if err != nil {
|
||||
resp.Diagnostics.Append(tfdiag.DiagFromWrappedErr("Error reading StaticHostUser", trace.Wrap(err), "static_host_user"))
|
||||
return
|
||||
}
|
||||
|
||||
staticHostUserResource := staticHostUser
|
||||
|
||||
|
||||
var state types.Object
|
||||
|
||||
diags := resp.State.Get(ctx, &state)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
diags = schemav1.CopyStaticHostUserToTerraform(ctx, staticHostUserResource, &state)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
id := staticHostUser.Metadata.Name
|
||||
|
||||
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 resourceTeleportStaticHostUser) 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
|
||||
}
|
||||
|
||||
staticHostUser := &userprovisioningv2.StaticHostUser{}
|
||||
resp.Diagnostics.Append(schemav1.CopyStaticHostUserFromTerraform(ctx, config, staticHostUser)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
staticHostUserResource := staticHostUser
|
||||
staticHostUserResource.Kind = apitypes.KindStaticHostUser
|
||||
|
||||
staticHostUser = staticHostUserResource
|
||||
|
||||
const preserveUnknown = true
|
||||
resp.Diagnostics.Append(schemav1.CopyStaticHostUserToTerraformPreserveUnknown(ctx, staticHostUser, &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,66 @@
|
||||
// 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"
|
||||
|
||||
userprovisioningv2 "github.com/gravitational/teleport/api/gen/proto/go/teleport/userprovisioning/v2"
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
|
||||
"github.com/gravitational/teleport/integrations/terraform/provider/internal/teleport"
|
||||
"github.com/gravitational/teleport/integrations/terraform/provider/internal/tfdriver"
|
||||
schemav1 "github.com/gravitational/teleport/integrations/terraform/tfschema/userprovisioning/v2"
|
||||
)
|
||||
|
||||
// NewStaticHostUserDataSourceType returns the static host user data source type.
|
||||
func NewStaticHostUserDataSourceType() tfdriver.DataSourceType[userprovisioningv2.StaticHostUser, tfdriver.NameIdentifier] {
|
||||
return tfdriver.DataSourceType[userprovisioningv2.StaticHostUser, tfdriver.NameIdentifier]{
|
||||
NewDataSourceClient: func(p tfsdk.Provider) tfdriver.DataSourceClient[userprovisioningv2.StaticHostUser, tfdriver.NameIdentifier] {
|
||||
return teleport.NewStaticHostUserClient(clientFromProvider(p))
|
||||
},
|
||||
Kind: types.KindStaticHostUser,
|
||||
Codec: tfdriver.DataSourceCodecFuncs[userprovisioningv2.StaticHostUser]{
|
||||
SchemaFunc: schemav1.GenSchemaStaticHostUser,
|
||||
ToStateFunc: schemav1.CopyStaticHostUserToTerraform,
|
||||
},
|
||||
Identifier: tfdriver.NameIdentifierFromPath(path.Root("metadata").AtName("name")),
|
||||
}
|
||||
}
|
||||
|
||||
// NewStaticHostUserResourceType returns the static host user resource type.
|
||||
func NewStaticHostUserResourceType() tfdriver.ResourceType[userprovisioningv2.StaticHostUser, tfdriver.NameIdentifier] {
|
||||
return tfdriver.ResourceType[userprovisioningv2.StaticHostUser, tfdriver.NameIdentifier]{
|
||||
NewResourceClient: func(p tfsdk.Provider) tfdriver.ResourceClient[userprovisioningv2.StaticHostUser, tfdriver.NameIdentifier] {
|
||||
return teleport.NewStaticHostUserClient(clientFromProvider(p))
|
||||
},
|
||||
Kind: types.KindStaticHostUser,
|
||||
Codec: tfdriver.ResourceCodecFuncs[userprovisioningv2.StaticHostUser]{
|
||||
SchemaFunc: schemav1.GenSchemaStaticHostUser,
|
||||
ToStateFunc: schemav1.CopyStaticHostUserToTerraform,
|
||||
FromPlanFunc: schemav1.CopyStaticHostUserFromTerraform,
|
||||
},
|
||||
Normalizer: tfdriver.ForceKind[userprovisioningv2.StaticHostUser](types.KindStaticHostUser),
|
||||
Identifier: tfdriver.NameIdentifierPolicy(path.Root("metadata").AtName("name"), func(staticHostUser *userprovisioningv2.StaticHostUser) string {
|
||||
return staticHostUser.GetMetadata().GetName()
|
||||
}),
|
||||
ResourceRevision: func(st *userprovisioningv2.StaticHostUser) string {
|
||||
return st.GetMetadata().GetRevision()
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// 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"
|
||||
userprovisioningv2 "github.com/gravitational/teleport/api/gen/proto/go/teleport/userprovisioning/v2"
|
||||
|
||||
"github.com/gravitational/teleport/integrations/terraform/provider/internal/tfdriver"
|
||||
)
|
||||
|
||||
// NewStaticHostUserClient returns a static host user client.
|
||||
func NewStaticHostUserClient(c *client.Client) StaticHostUserClient {
|
||||
return StaticHostUserClient{client: c}
|
||||
}
|
||||
|
||||
// StaticHostUserClient manages static host user resources.
|
||||
type StaticHostUserClient struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
// Get reads a static host user by name.
|
||||
func (r StaticHostUserClient) Get(ctx context.Context, id tfdriver.NameIdentifier) (*userprovisioningv2.StaticHostUser, error) {
|
||||
staticHostUser, err := r.client.StaticHostUserClient().GetStaticHostUser(ctx, id.Name)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
return staticHostUser, nil
|
||||
}
|
||||
|
||||
// Create creates a static host user.
|
||||
func (r StaticHostUserClient) Create(ctx context.Context, staticHostUser *userprovisioningv2.StaticHostUser) error {
|
||||
if _, err := r.client.StaticHostUserClient().CreateStaticHostUser(ctx, staticHostUser); err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Upsert updates a static host user.
|
||||
func (r StaticHostUserClient) Upsert(ctx context.Context, staticHostUser *userprovisioningv2.StaticHostUser) error {
|
||||
if _, err := r.client.StaticHostUserClient().UpsertStaticHostUser(ctx, staticHostUser); err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete deletes a static host user by name.
|
||||
func (r StaticHostUserClient) Delete(ctx context.Context, id tfdriver.NameIdentifier) error {
|
||||
return trace.Wrap(r.client.StaticHostUserClient().DeleteStaticHostUser(ctx, id.Name))
|
||||
}
|
||||
@@ -573,6 +573,7 @@ func (p *Provider) GetResources(_ context.Context) (map[string]tfsdk.ResourceTyp
|
||||
"teleport_lock": resources.NewLockResourceType(),
|
||||
"teleport_saml_connector": resources.NewSAMLConnectorResourceType(),
|
||||
"teleport_scoped_role": resources.NewScopedRoleResourceType(),
|
||||
"teleport_static_host_user": resources.NewStaticHostUserResourceType(),
|
||||
"teleport_scoped_role_assignment": resources.NewScopedRoleAssignmentResourceType(),
|
||||
"teleport_scoped_token": resources.NewScopedTokenResourceType(),
|
||||
"teleport_user": resources.NewUserResourceType(),
|
||||
@@ -597,6 +598,7 @@ func (p *Provider) GetDataSources(_ context.Context) (map[string]tfsdk.DataSourc
|
||||
"teleport_lock": resources.NewLockDataSourceType(),
|
||||
"teleport_saml_connector": resources.NewSAMLConnectorDataSourceType(),
|
||||
"teleport_scoped_role": resources.NewScopedRoleDataSourceType(),
|
||||
"teleport_static_host_user": resources.NewStaticHostUserDataSourceType(),
|
||||
"teleport_scoped_role_assignment": resources.NewScopedRoleAssignmentDataSourceType(),
|
||||
"teleport_scoped_token": resources.NewScopedTokenDataSourceType(),
|
||||
"teleport_user": resources.NewUserDataSourceType(),
|
||||
|
||||
Reference in New Issue
Block a user