Class: ForemanOpentofu::OpentofuExecuter

Inherits:
Object
  • Object
show all
Defined in:
app/services/foreman_opentofu/opentofu_executer.rb

Constant Summary collapse

DRY_RUN_MODES =

‘destroy’ works with TfState rather than the actual tf-file also it might not receive all the necessary data to create a valid tf-file

%w[destroy test].freeze

Instance Method Summary collapse

Constructor Details

#initialize(compute_resource, args = {}) ⇒ OpentofuExecuter

Returns a new instance of OpentofuExecuter.



7
8
9
10
11
12
13
# File 'app/services/foreman_opentofu/opentofu_executer.rb', line 7

def initialize(compute_resource, args = {})
  @compute_resource = compute_resource
  @cr_attrs = args.to_h.with_indifferent_access
  @resource = @cr_attrs['resource']
  @host_name = @cr_attrs['name'] || 'test'
  @key_pair = @compute_resource.key_pair
end

Instance Method Details

#create_token(host_name) ⇒ Object

creates a new authentication token for the TfState API-controller needed for tofu command to send it’s state-file to the database. returns the created token



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'app/services/foreman_opentofu/opentofu_executer.rb', line 47

def create_token(host_name)
  new_token = nil
  # This construct makes sure the token is created outside of the current transaction
  # which is necessary for the API-controller to check the token, while the current transaction still runs
  # see https://stackoverflow.com/a/11675647
  Thread.new do
    ActiveRecord::Base.connection_pool.with_connection do
      token = ForemanOpentofu::Token.find_or_create_by(name: host_name)
      new_token = if token.expired?
                    token.generate
                  else
                    token.token
                  end
    end
  end.join
  new_token
end

#key_pairsObject



90
91
92
# File 'app/services/foreman_opentofu/opentofu_executer.rb', line 90

def key_pairs
  KeyPairs.new self, @compute_resource.available_ssh_keys
end

#run(mode = '') ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'app/services/foreman_opentofu/opentofu_executer.rb', line 15

def run(mode = '')
  Dir.mktmpdir('opentofu_', ForemanOpentofu::OPENTOFU_TMP_PATH) do |dir|
    # FIXME: integrate the user_data-file into AppWrapper!
    if @cr_attrs['user_data']
      @user_data_filename = File.join(dir, 'userdata')
      File.open(@user_data_filename, 'w') do |f|
        f.write(@cr_attrs['user_data'])
      end
    end
    tofu = AppWrapper.new(dir, variables: {
      username: @compute_resource.user,
      password: @compute_resource.password,
      endpoint: @compute_resource.url,
    })
    @use_backend = %w[create destroy output keygen].include?(mode)
    @token = create_token(@host_name) if @use_backend
    tofu.main_configuration = render_template(mode)
    tofu.init
    yield(tofu)
  end
end

#run_create(raise_if_recreate: false) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'app/services/foreman_opentofu/opentofu_executer.rb', line 76

def run_create(raise_if_recreate: false)
  run('create') do |tofu|
    if raise_if_recreate
      # check the plan in advance to verify we do not replace the VM
      tofu.plan
      raise 'OpenTofu planned to re-create a resource; action aborted (check logs for details)!' if plan_wants_recreate? tofu.show_plan
    end
    tofu.apply
    attrs = tofu.output('vm_attrs')
    ForemanOpentofu::TfState.find_by(name: @cr_attrs['name'])&.update(uuid: attrs['identity'])
    attrs
  end
end

#run_create_key(key_pair) ⇒ Object



94
95
96
# File 'app/services/foreman_opentofu/opentofu_executer.rb', line 94

def run_create_key(key_pair)
  run_key(key_pair, &:apply)
end

#run_destroyObject



108
109
110
# File 'app/services/foreman_opentofu/opentofu_executer.rb', line 108

def run_destroy
  run('destroy', &:destroy)
end

#run_destroy_key(key_pair) ⇒ Object



98
99
100
# File 'app/services/foreman_opentofu/opentofu_executer.rb', line 98

def run_destroy_key(key_pair)
  run_key(key_pair, &:destroy)
end

#run_fetchObject



112
113
114
115
116
117
# File 'app/services/foreman_opentofu/opentofu_executer.rb', line 112

def run_fetch
  run do |tofu|
    tofu.apply
    return tofu.output('resources')
  end
end

#run_key(key_pair, &block) ⇒ Object



37
38
39
40
41
42
# File 'app/services/foreman_opentofu/opentofu_executer.rb', line 37

def run_key(key_pair, &block)
  @host_name = key_pair.name
  @key_pair = key_pair
  run('keygen', &block)
  @compute_resource.reset_cached_ssh_keys
end

#run_newObject



65
66
67
68
69
70
# File 'app/services/foreman_opentofu/opentofu_executer.rb', line 65

def run_new
  run('new') do |tofu|
    tofu.plan
    return tofu.show_plan
  end
end

#run_outputObject



102
103
104
105
106
# File 'app/services/foreman_opentofu/opentofu_executer.rb', line 102

def run_output
  run('output') do |tofu|
    tofu.output('vm_attrs')
  end
end

#run_test_connectionObject



72
73
74
# File 'app/services/foreman_opentofu/opentofu_executer.rb', line 72

def run_test_connection
  run('test', &:plan)
end