diff --git a/Makefile b/Makefile index 7026a7f..2b20c91 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ HOSTNAME=local NAMESPACE=badarsebard NAME=xsoar BINARY=terraform-provider-${NAME} -VERSION=0.3.11 +VERSION=0.3.12 OS=${MY_OS} ARCH=${MY_ARCH} diff --git a/xsoar/models.go b/xsoar/models.go index e8211d8..4c09770 100644 --- a/xsoar/models.go +++ b/xsoar/models.go @@ -36,6 +36,7 @@ type Host struct { Name types.String `tfsdk:"name"` Id types.String `tfsdk:"id"` HAGroupName types.String `tfsdk:"ha_group_name"` + NFSMount types.String `tfsdk:"nfs_mount"` ElasticsearchUrl types.String `tfsdk:"elasticsearch_url"` ServerUrl types.String `tfsdk:"server_url"` SSHUser types.String `tfsdk:"ssh_user"` diff --git a/xsoar/provider.go b/xsoar/provider.go index 4acf320..e1a59de 100644 --- a/xsoar/provider.go +++ b/xsoar/provider.go @@ -3,8 +3,10 @@ package xsoar import ( "context" "crypto/tls" + "math/rand" "net/http" "os" + "time" "github.com/badarsebard/xsoar-sdk-go/openapi" "github.com/hashicorp/terraform-plugin-framework/diag" @@ -142,6 +144,7 @@ func (p *provider) Configure(ctx context.Context, req tfsdk.ConfigureProviderReq p.client = c p.configured = true p.data = &config + rand.Seed(time.Now().Unix()) } // GetResources - Defines provider resources diff --git a/xsoar/resource_host.go b/xsoar/resource_host.go index 45b9050..d6a1e86 100644 --- a/xsoar/resource_host.go +++ b/xsoar/resource_host.go @@ -11,6 +11,7 @@ import ( "golang.org/x/crypto/ssh" "io" "log" + "math/rand" "net/http" "strings" "time" @@ -38,6 +39,11 @@ func (r resourceHostType) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagn Optional: true, PlanModifiers: append(planModifiers, tfsdk.RequiresReplace()), }, + "nfs_mount": { + Type: types.StringType, + Optional: true, + PlanModifiers: append(planModifiers, tfsdk.RequiresReplace()), + }, "elasticsearch_url": { Type: types.StringType, Computed: true, @@ -239,7 +245,50 @@ func (r resourceHost) Create(ctx context.Context, req tfsdk.CreateResourceReques return } - // 4) Execute installer + // 4) Check for lock + if !plan.NFSMount.Null { + // wait a random amount of time + randomTimeToWait := rand.Intn(10) + 1 + time.Sleep(time.Duration(randomTimeToWait)) + // wait for a lock file in /tmp + session, err = conn.NewSession() + if err != nil { + resp.Diagnostics.AddError( + "Error creating ssh session", + "Could not create ssh session: "+err.Error(), + ) + return + } + defer session.Close() + err = session.Run(fmt.Sprintf(`while [[ -f "%s/xsoar_host_install.lock" ]]; do sleep %d; done`, plan.NFSMount.Value, randomTimeToWait)) + if err != nil { + resp.Diagnostics.AddError( + "Error waiting for lock file", + "Lock file error: "+err.Error(), + ) + return + } + // create lock file + session, err = conn.NewSession() + if err != nil { + resp.Diagnostics.AddError( + "Error creating ssh session", + "Could not create ssh session: "+err.Error(), + ) + return + } + defer session.Close() + err = session.Run(fmt.Sprintf(`touch %s/xsoar_host_install.lock`, plan.NFSMount.Value)) + if err != nil { + resp.Diagnostics.AddError( + "Error creating lock file", + "Could not create lock file: "+err.Error(), + ) + return + } + } + + // 5) Execute installer log.Println("Executing install") session, err = conn.NewSession() if err != nil { @@ -303,6 +352,26 @@ func (r resourceHost) Create(ctx context.Context, req tfsdk.CreateResourceReques ) return } + // delete lock file + if !plan.NFSMount.Null { + session, err = conn.NewSession() + if err != nil { + resp.Diagnostics.AddError( + "Error creating ssh session", + "Could not create ssh session: "+err.Error(), + ) + return + } + defer session.Close() + err = session.Run(fmt.Sprintf(`rm %s/xsoar_host_install.lock`, plan.NFSMount.Value)) + if err != nil { + resp.Diagnostics.AddError( + "Error creating lock file", + "Could not create lock file: "+err.Error(), + ) + return + } + } // Map response body to resource schema attribute var hostName = host["host"].(string)