class Object

Public Instance Methods

build_interfaces_attributes(networks) click to toggle source
# File lib/foreman_opentofu/provider_types/hetzner.rb, line 55
def build_interfaces_attributes(networks)
  Array(networks).each_with_index.to_h do |net, idx|
    nic = net.respond_to?(:with_indifferent_access) ? net.with_indifferent_access : net
    [idx.to_s, { network_id: nic[:network_id].to_s }]
  end
end
comparable_agent(values, unknown) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 77
def comparable_agent(values, unknown)
  return values unless unknown['agent']

  agent = values['agent'].to_h
  fields = unknown['agent'].is_a?(Hash) ? unknown['agent'].select { |_key, value| value }.keys : agent.keys
  values['agent'] = agent.except(*fields)
  values
end
comparable_plan(change, direction) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 69
def comparable_plan(change, direction)
  values = change.fetch(direction, {}).dup
  unknown = change.fetch('after_unknown', {})
  ignored = ['desired_status'] + %w[agent created_at launched_at updated_at].select { |key| unknown[key] == true }
  values.except!(*ignored)
  comparable_agent(values, unknown)
end
configured_interfaces(cr_attrs) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 105
def configured_interfaces(cr_attrs)
  cr_attrs['interfaces'].presence || cr_attrs['interfaces_attributes'].presence ||
    [{ 'network_id' => cr_attrs['network_id'].to_s, 'security_group_id' => cr_attrs['security_group_id'].to_s }]
end
default_nic(nics, network_id) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 94
def default_nic(nics, network_id)
  nics.first if network_id.blank? && nics.all? { |entry| entry['identifier'].blank? }
end
deleted_interface?(interface) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 122
def deleted_interface?(interface)
  interface['_delete'].to_i == 1 || interface['_destroy'].to_i == 1
end
desired_status(attributes) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 26
def desired_status(attributes)
  { 'on' => 'active', 'off' => 'inactive' }.fetch(attributes['power_state'].presence || 'on')
end
disk_renderer_collection?() click to toggle source
# File lib/foreman_opentofu/provider_types/hetzner.rb, line 9
def disk_renderer_collection?
  true
end
extract_networks(attrs) click to toggle source
# File lib/foreman_opentofu/provider_types/hetzner.rb, line 48
def extract_networks(attrs)
  attrs.dig(:vm, :network) ||
    attrs.dig('vm', 'network') ||
    attrs[:network] ||
    attrs['network']
end
fallback_interface(interfaces) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 134
def fallback_interface(interfaces)
  security_group_id = interfaces.filter_map { |interface| interface['security_group_id'].presence }.first
  { 'security_group_id' => security_group_id, 'identifier' => interfaces.first&.fetch('identifier', nil) }.compact
end
find_nic_by_identifier(nics, identifier) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 86
def find_nic_by_identifier(nics, identifier)
  nics.find { |entry| identifier.present? && entry['identifier'] == identifier }
end
find_nic_by_network(nics, network_id) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 90
def find_nic_by_network(nics, network_id)
  nics.find { |entry| network_id.present? && entry['network_id'] == network_id }
end
harmless_power_change?(resource, change) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 61
def harmless_power_change?(resource, change)
  change['actions'] == ['no-op'] || resource['mode'] == 'data'
end
indexed_interfaces?(interfaces) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 110
def indexed_interfaces?(interfaces)
  interfaces.is_a?(Hash) && interfaces.keys.all? { |key| key.to_s.match?(/\A\d+\z/) }
end
interfaces_for_template(cr_attrs, context) click to toggle source

Prepare all NICs together so an empty form produces one default network.

# File lib/foreman_opentofu/provider_types/stackit.rb, line 53
def interfaces_for_template(cr_attrs, context)
  interfaces = context.normalize_interfaces(normalized_interfaces(cr_attrs)).filter_map do |interface|
    normalize_interface(interface, context)
  end
  configured = interfaces.select { |interface| interface['network_id'].present? }
  configured.presence || [fallback_interface(interfaces)]
end
nic_renderer_collection?() click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 48
def nic_renderer_collection?
  true
end
normalize_interface(interface, context) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 114
def normalize_interface(interface, context)
  interface = interface.with_indifferent_access
  return if deleted_interface?(interface)

  attributes = (interface['compute_attributes'].presence || interface).with_indifferent_access
  sanitize_interface(attributes, interface, context)
end
normalize_interfaces(vm_attrs) click to toggle source
# File lib/foreman_opentofu/provider_types/hetzner.rb, line 37
def normalize_interfaces(vm_attrs)
  attrs = vm_attrs.with_indifferent_access
  return attrs if attrs[:interfaces_attributes].present?

  networks = extract_networks(attrs)
  return attrs if networks.blank?

  attrs[:interfaces_attributes] = build_interfaces_attributes(networks)
  attrs
end
normalized_interfaces(cr_attrs) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 98
def normalized_interfaces(cr_attrs)
  raw = configured_interfaces(cr_attrs)
  return raw unless indexed_interfaces?(raw)

  raw.sort_by { |key, _value| key.to_i }.map(&:last)
end
power_change_allowed?(resource) click to toggle source

Only a power update is allowed during a start/stop action.

# File lib/foreman_opentofu/provider_types/stackit.rb, line 31
def power_change_allowed?(resource)
  change = resource.fetch('change', {})
  return true if harmless_power_change?(resource, change)

  server_update?(resource, change) && comparable_plan(change, 'before') == comparable_plan(change, 'after')
end
power_state_attributes(state) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 22
def power_state_attributes(state)
  { 'power_state' => state }
end
provided_attributes() click to toggle source
# File lib/foreman_opentofu/provider_types/hetzner.rb, line 13
def provided_attributes
  {
    ip: :vm_ip_address,
    ip6: :vm_ip6_address,
  }
end
sanitize_interface(attributes, interface, context) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 126
def sanitize_interface(attributes, interface, context)
  sanitized = context.sanitize_attributes(attributes, available_attributes('nic'))
  sanitized.merge!(attributes.slice('network_id', 'security_group_id').compact_blank)
  sanitized.delete('network_id') if Foreman::Cast.to_bool(attributes['managed_network'])
  sanitized['identifier'] = interface['identifier'] if interface['identifier'].present?
  sanitized
end
select_nic_for_mac(nics, nic) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 38
def select_nic_for_mac(nics, nic)
  identifier = nic.identifier.to_s
  network_id = nic.compute_attributes.to_h.with_indifferent_access[:network_id]
  find_nic_by_identifier(nics, identifier) || find_nic_by_network(nics, network_id) || default_nic(nics, network_id)
end
server_update?(resource, change) click to toggle source
# File lib/foreman_opentofu/provider_types/stackit.rb, line 65
def server_update?(resource, change)
  resource['address'] == 'stackit_server.node1' && change['actions'] == ['update']
end
validate_provider_specific!(attrs, compute_resource) click to toggle source
# File lib/foreman_opentofu/provider_types/hetzner.rb, line 25
def validate_provider_specific!(attrs, compute_resource)
  disks = active_volumes(attrs, compute_resource)
  raise ArgumentError, _('Hetzner allows at most 16 volumes per server.') if disks.size > 16

  disks.each { |disk| validate_volume!(disk) }
end
validate_volume!(disk) click to toggle source
# File lib/foreman_opentofu/provider_types/hetzner.rb, line 32
def validate_volume!(disk)
  raise ArgumentError, _('Hetzner volume format is required when automount is enabled.') if Foreman::Cast.to_bool(disk[:automount]) && disk[:format].blank?
  raise ArgumentError, _('Hetzner volume format must be ext4 or xfs.') if disk[:format].present? && !%w[ext4 xfs].include?(disk[:format])
end
vm_ready(_vm) click to toggle source
# File lib/foreman_opentofu/provider_types/hetzner.rb, line 20
def vm_ready(_vm)
  # always ready ;-)
  true
end