Skip to content

Commit a9ba166

Browse files
committed
refactor: extract OpenTofu package and reorganize under Provision namespace
- Extract OpenTofu methods (_run_tofu_init, _run_tofu_apply, _get_vm_ip) from provision command - Create new TorrustDeploy::Provision::OpenTofu package with public methods (init, apply, get_vm_ip) - Move package and tests to Provision subdirectory for better organization - Update provision command to use new OpenTofu package - Update all tests to reflect new package structure - Maintain backward compatibility and functionality
1 parent 87ab7dc commit a9ba166

File tree

4 files changed

+154
-53
lines changed

4 files changed

+154
-53
lines changed

lib/TorrustDeploy/App/Command/provision.pm

Lines changed: 7 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use warnings;
55
use v5.20;
66

77
use TorrustDeploy::App -command;
8+
use TorrustDeploy::Provision::OpenTofu;
89
use Path::Tiny qw(path);
910
use File::Spec;
1011
use Time::HiRes qw(sleep);
@@ -43,14 +44,17 @@ sub execute {
4344
# Copy templates to working directory
4445
$self->_copy_templates($templates_dir, $tofu_dir);
4546

47+
# Create OpenTofu instance
48+
my $tofu = TorrustDeploy::Provision::OpenTofu->new();
49+
4650
# Initialize OpenTofu
47-
$self->_run_tofu_init($tofu_dir);
51+
$tofu->init($tofu_dir);
4852

4953
# Apply OpenTofu configuration
50-
$self->_run_tofu_apply($tofu_dir);
54+
$tofu->apply($tofu_dir);
5155

5256
# Get VM IP address
53-
my $vm_ip = $self->_get_vm_ip($tofu_dir);
57+
my $vm_ip = $tofu->get_vm_ip($tofu_dir);
5458

5559
# Wait for cloud-init completion
5660
$self->_wait_for_cloud_init($vm_ip);
@@ -100,54 +104,6 @@ sub _copy_templates {
100104
say "Templates copied successfully.";
101105
}
102106

103-
sub _run_tofu_init {
104-
my ($self, $tofu_dir) = @_;
105-
106-
say "Initializing OpenTofu...";
107-
108-
my $result = system("cd '$tofu_dir' && tofu init");
109-
if ($result != 0) {
110-
die "OpenTofu init failed with exit code: $result";
111-
}
112-
113-
say "OpenTofu initialized successfully.";
114-
}
115-
116-
sub _run_tofu_apply {
117-
my ($self, $tofu_dir) = @_;
118-
119-
say "Applying OpenTofu configuration...";
120-
say "This may take a few minutes to download the base image and create the VM...";
121-
122-
my $result = system("cd '$tofu_dir' && tofu apply -auto-approve");
123-
if ($result != 0) {
124-
die "OpenTofu apply failed with exit code: $result";
125-
}
126-
127-
say "OpenTofu apply completed successfully.";
128-
}
129-
130-
sub _get_vm_ip {
131-
my ($self, $tofu_dir) = @_;
132-
133-
say "Getting VM IP address...";
134-
135-
my $output = `cd '$tofu_dir' && tofu output -json`;
136-
if ($? != 0) {
137-
die "Failed to get OpenTofu outputs";
138-
}
139-
140-
my $outputs = decode_json($output);
141-
my $vm_ip = $outputs->{vm_ip}{value};
142-
143-
unless ($vm_ip) {
144-
die "Could not retrieve VM IP address from OpenTofu outputs";
145-
}
146-
147-
say "VM IP address: $vm_ip";
148-
return $vm_ip;
149-
}
150-
151107
sub _wait_for_cloud_init {
152108
my ($self, $vm_ip) = @_;
153109

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package TorrustDeploy::Provision::OpenTofu;
2+
3+
use strict;
4+
use warnings;
5+
use v5.20;
6+
7+
use JSON;
8+
9+
=head1 NAME
10+
11+
TorrustDeploy::Provision::OpenTofu - OpenTofu command wrapper for Torrust deployment
12+
13+
=head1 DESCRIPTION
14+
15+
This package provides methods to interact with OpenTofu (Terraform fork) for
16+
infrastructure provisioning. It handles initialization, applying configurations,
17+
and extracting outputs.
18+
19+
=head1 METHODS
20+
21+
=cut
22+
23+
=head2 new
24+
25+
Create a new OpenTofu instance.
26+
27+
=cut
28+
29+
sub new {
30+
my ($class) = @_;
31+
return bless {}, $class;
32+
}
33+
34+
=head2 init
35+
36+
Initialize OpenTofu in the specified directory.
37+
38+
$tofu->init($tofu_dir);
39+
40+
=cut
41+
42+
sub init {
43+
my ($self, $tofu_dir) = @_;
44+
45+
say "Initializing OpenTofu...";
46+
47+
my $result = system("cd '$tofu_dir' && tofu init");
48+
if ($result != 0) {
49+
die "OpenTofu init failed with exit code: $result";
50+
}
51+
52+
say "OpenTofu initialized successfully.";
53+
}
54+
55+
=head2 apply
56+
57+
Apply OpenTofu configuration in the specified directory.
58+
59+
$tofu->apply($tofu_dir);
60+
61+
=cut
62+
63+
sub apply {
64+
my ($self, $tofu_dir) = @_;
65+
66+
say "Applying OpenTofu configuration...";
67+
say "This may take a few minutes to download the base image and create the VM...";
68+
69+
my $result = system("cd '$tofu_dir' && tofu apply -auto-approve");
70+
if ($result != 0) {
71+
die "OpenTofu apply failed with exit code: $result";
72+
}
73+
74+
say "OpenTofu apply completed successfully.";
75+
}
76+
77+
=head2 get_vm_ip
78+
79+
Get the VM IP address from OpenTofu outputs.
80+
81+
my $ip = $tofu->get_vm_ip($tofu_dir);
82+
83+
Returns the IP address as a string.
84+
85+
=cut
86+
87+
sub get_vm_ip {
88+
my ($self, $tofu_dir) = @_;
89+
90+
say "Getting VM IP address...";
91+
92+
my $output = `cd '$tofu_dir' && tofu output -json`;
93+
if ($? != 0) {
94+
die "Failed to get OpenTofu outputs";
95+
}
96+
97+
my $outputs = decode_json($output);
98+
my $vm_ip = $outputs->{vm_ip}{value};
99+
100+
unless ($vm_ip) {
101+
die "Could not retrieve VM IP address from OpenTofu outputs";
102+
}
103+
104+
say "VM IP address: $vm_ip";
105+
return $vm_ip;
106+
}
107+
108+
1;
109+
110+
__END__
111+
112+
=head1 AUTHOR
113+
114+
Torrust Team
115+
116+
=head1 LICENSE
117+
118+
This software is licensed under the MIT License.
119+
120+
=cut

t/command/provision.t

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,13 @@ subtest 'Provision command internal methods' => sub {
115115

116116
# Test that the command has the expected private methods
117117
ok($provision_cmd->can('_copy_templates'), 'Provision command has _copy_templates method');
118-
ok($provision_cmd->can('_run_tofu_init'), 'Provision command has _run_tofu_init method');
119-
ok($provision_cmd->can('_run_tofu_apply'), 'Provision command has _run_tofu_apply method');
118+
119+
# Test that OpenTofu functionality is available via the OpenTofu package
120+
require TorrustDeploy::Provision::OpenTofu;
121+
my $tofu = TorrustDeploy::Provision::OpenTofu->new();
122+
ok($tofu->can('init'), 'OpenTofu package has init method');
123+
ok($tofu->can('apply'), 'OpenTofu package has apply method');
124+
ok($tofu->can('get_vm_ip'), 'OpenTofu package has get_vm_ip method');
120125
};
121126

122127
done_testing;

t/provision/opentofu.t

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use Test2::V0;
2+
use FindBin qw($Bin);
3+
use lib "$Bin/../../lib";
4+
5+
use TorrustDeploy::Provision::OpenTofu;
6+
7+
subtest 'OpenTofu module loads correctly' => sub {
8+
ok(TorrustDeploy::Provision::OpenTofu->can('new'), 'OpenTofu has new method');
9+
ok(TorrustDeploy::Provision::OpenTofu->can('init'), 'OpenTofu has init method');
10+
ok(TorrustDeploy::Provision::OpenTofu->can('apply'), 'OpenTofu has apply method');
11+
ok(TorrustDeploy::Provision::OpenTofu->can('get_vm_ip'), 'OpenTofu has get_vm_ip method');
12+
};
13+
14+
subtest 'OpenTofu instance creation' => sub {
15+
my $tofu = TorrustDeploy::Provision::OpenTofu->new();
16+
ok($tofu, 'OpenTofu instance created successfully');
17+
isa_ok($tofu, 'TorrustDeploy::Provision::OpenTofu');
18+
};
19+
20+
done_testing;

0 commit comments

Comments
 (0)