Skip to content

Commit

Permalink
Merge pull request #20 from wttech/connection-imprs
Browse files Browse the repository at this point in the history
Connection improvements
  • Loading branch information
krystian-panek-vmltech authored Nov 14, 2023
2 parents 0d429cd + cf8f8f5 commit ca6a250
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 28 deletions.
16 changes: 10 additions & 6 deletions examples/ssh/aem.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ resource "aem_instance" "single" {
client {
type = "ssh"
settings = {
host = aws_instance.aem_single.public_ip
port = 22
user = local.ssh_user
private_key_file = local.ssh_private_key # cannot be put into state as this is OS-dependent
host = aws_instance.aem_single.public_ip
port = 22
user = local.ssh_user
secure = false
}
credentials = {
private_key = file(local.ssh_private_key)
}
}

system {
data_dir = local.aem_single_compose_dir
data_dir = local.aem_single_compose_dir
bootstrap_script = <<SHELL
#!/bin/sh
(
Expand All @@ -34,7 +37,8 @@ resource "aem_instance" "single" {
SHELL
}

compose {} // TODO must be at least empty; TF plugin framework bug?
compose {}
// must be at least empty
}

locals {
Expand Down
9 changes: 5 additions & 4 deletions internal/client/client_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ func (c ClientManager) connection(typeName string, settings map[string]string) (
switch typeName {
case "ssh":
return &SSHConnection{
host: settings["host"],
user: settings["user"],
privateKeyFile: settings["private_key_file"],
port: cast.ToInt(settings["port"]),
host: settings["host"],
user: settings["user"],
privateKey: settings["private_key"],
port: cast.ToInt(settings["port"]),
secure: cast.ToBool(settings["secure"]),
}, nil
case "aws-ssm":
return &AWSSSMConnection{
Expand Down
37 changes: 28 additions & 9 deletions internal/client/connection_ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,44 @@ import (
type SSHConnection struct {
client *goph.Client

host string
user string
passphrase string
privateKeyFile string
port int
host string
user string
passphrase string
privateKey string
port int
secure bool
}

func (s *SSHConnection) Connect() error {
auth, err := goph.Key(s.privateKeyFile, s.passphrase)
if s.host == "" {
return fmt.Errorf("ssh: host is required")
}
if s.user == "" {
return fmt.Errorf("ssh: user is required")
}
if s.privateKey == "" {
return fmt.Errorf("ssh: private key is required")
}
if s.port == 0 {
s.port = 22
}
signer, err := ssh.ParsePrivateKey([]byte(s.privateKey))
if err != nil {
return fmt.Errorf("ssh: cannot get auth using private key '%s': %w", s.privateKeyFile, err)
return fmt.Errorf("ssh: cannot parse private key: %w", err)
}
var callback ssh.HostKeyCallback
if s.secure {
callback = ssh.FixedHostKey(signer.PublicKey())
} else {
callback = ssh.InsecureIgnoreHostKey()
}
client, err := goph.NewConn(&goph.Config{
User: s.user,
Addr: s.host,
Port: cast.ToUint(s.port),
Auth: auth,
Auth: goph.Auth{ssh.PublicKeys(signer)},
Timeout: goph.DefaultTimeout,
Callback: ssh.InsecureIgnoreHostKey(), // TODO make it secure by default
Callback: callback,
})
if err != nil {
return fmt.Errorf("ssh: cannot connect to host '%s': %w", s.host, err)
Expand Down
4 changes: 2 additions & 2 deletions internal/provider/instance/create.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh

sh aemw instance create && \
sh aemw instance init
sh aemw instance init && \
sh aemw instance create
6 changes: 5 additions & 1 deletion internal/provider/instance_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,13 @@ func (ic *InstanceClient) create() error {

func (ic *InstanceClient) saveProfileScript() error {
envFile := fmt.Sprintf("/etc/profile.d/%s.sh", ServiceName)

var systemEnvMap map[string]string
ic.data.System.Env.ElementsAs(ic.ctx, &systemEnvMap, true)

envMap := map[string]string{}
maps.Copy(envMap, ic.cl.Env)
ic.data.System.Env.ElementsAs(ic.ctx, &envMap, true)
maps.Copy(envMap, systemEnvMap)

ic.cl.Sudo = true
defer func() { ic.cl.Sudo = false }()
Expand Down
29 changes: 23 additions & 6 deletions internal/provider/instance_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/wttech/terraform-provider-aem/internal/client"
"github.com/wttech/terraform-provider-aem/internal/provider/instance"
"golang.org/x/exp/maps"
"time"
)

Expand All @@ -36,8 +37,9 @@ type InstanceResource struct {

type InstanceResourceModel struct {
Client struct {
Type types.String `tfsdk:"type"`
Settings types.Map `tfsdk:"settings"`
Type types.String `tfsdk:"type"`
Settings types.Map `tfsdk:"settings"`
Credentials types.Map `tfsdk:"credentials"`
} `tfsdk:"client"`
Files types.Map `tfsdk:"files"`
System struct {
Expand Down Expand Up @@ -94,6 +96,12 @@ func (r *InstanceResource) Schema(ctx context.Context, req resource.SchemaReques
ElementType: types.StringType,
Required: true,
},
"credentials": schema.MapAttribute{
MarkdownDescription: "Credentials for the connection type",
ElementType: types.StringType,
Optional: true,
Sensitive: true,
},
},
},
"system": schema.SingleNestedBlock{
Expand Down Expand Up @@ -443,10 +451,7 @@ func (r *InstanceResource) client(ctx context.Context, model InstanceResourceMod
typeName := model.Client.Type.ValueString()
tflog.Info(ctx, fmt.Sprintf("Connecting to AEM instance machine using %s", typeName))

var settings map[string]string
model.Client.Settings.ElementsAs(ctx, &settings, true)

cl, err := r.clientManager.Make(typeName, settings)
cl, err := r.clientManager.Make(typeName, r.clientSettings(ctx, model))
if err != nil {
return nil, err
}
Expand All @@ -466,3 +471,15 @@ func (r *InstanceResource) client(ctx context.Context, model InstanceResourceMod
tflog.Info(ctx, fmt.Sprintf("Connected to AEM instance machine using %s", cl.Connection().Info()))
return &InstanceClient{cl, ctx, model}, nil
}

func (r *InstanceResource) clientSettings(ctx context.Context, model InstanceResourceModel) map[string]string {
var settings map[string]string
model.Client.Settings.ElementsAs(ctx, &settings, true)
var credentials map[string]string
model.Client.Credentials.ElementsAs(ctx, &credentials, true)

combined := map[string]string{}
maps.Copy(combined, credentials)
maps.Copy(combined, settings)
return combined
}

0 comments on commit ca6a250

Please sign in to comment.