class Bcome::Orchestration::InteractiveTerraform

Constants

COMMAND_PROMPT
QUIT
  • Provides access to the metadata framework, so that data may be shared between Orchestrative processes and Terraform

  • Transparent authorization, by passing in cloud authorisation details from the bcome session

  • Passes in SSH credentials directly, which can be used to bootstrap machines.

Public Class Methods

new(*params) click to toggle source
Calls superclass method Bcome::Orchestration::Base::new
# File lib/objects/orchestration/interactive_terraform.rb, line 14
def initialize(*params)
  super
  raise ::Bcome::Exception::Generic, "Missing terraform configuration directory #{path_to_env_config}" unless File.exist?(path_to_env_config)
end

Public Instance Methods

backend_config_parameter_string() click to toggle source
# File lib/objects/orchestration/interactive_terraform.rb, line 86
def backend_config_parameter_string
  ## Backend configs are loaded before Terraform Core which means that we cannot use variables directly in our backend config.
  ## This is a pain as we'll have authorised with GCP via the console, and so all sesssion have an access token readily available.
  ## This patch passes the access token directly to terraform as a parameter.

  ## GCP only for now. Support for AWS may come later as needed/requested.
  return '' unless @node.network_driver.is_a?(::Bcome::Driver::Gcp)

  "\s-backend-config \"access_token=#{@node.network_driver.network_credentials[:access_token]}\"\s"
end
command(raw_command) click to toggle source

Formulate a terraform command

# File lib/objects/orchestration/interactive_terraform.rb, line 103
def command(raw_command)
  cmd = "cd #{path_to_env_config} ; terraform #{raw_command}"
  cmd = "#{cmd} #{var_string}" if raw_command =~ Regexp.new(/^apply$|plan|destroy|refresh/)
  cmd
end
execute() click to toggle source
# File lib/objects/orchestration/interactive_terraform.rb, line 19
def execute
  show_intro_text
  wait_for_command_input
end
form_var_string() click to toggle source

Get the terraform variables for this stack, and merge in with our networking & ssh credentials

# File lib/objects/orchestration/interactive_terraform.rb, line 59
def form_var_string
  terraform_vars = terraform_metadata

  terraform_vars.each do |key, value|
    # Join arrays into a string (note we cannot handle nested arrays yet)
    terraform_vars[key] = value.join(',') if value.is_a?(Array)
  end

  cleaned_data = terraform_vars.reject do |_k, v|
    v.is_a?(Hash)
  end # we can't yet handle nested terraform metadata on the command line so no hashes

  all_vars = cleaned_data

  if @node.network_driver.has_network_credentials?
    network_credentials = @node.network_driver.network_credentials
    all_vars = cleaned_data.merge(network_credentials)
  end

  all_vars[:ssh_user] = @node.ssh_driver.user
  all_vars.collect { |key, value| "-var #{key}=\"#{value}\"" }.join("\s")
end
path_to_env_config() click to toggle source

Retrieve the path to the terraform configurations for this stack

# File lib/objects/orchestration/interactive_terraform.rb, line 98
def path_to_env_config
  @path_to_env_config ||= "terraform/environments/#{@node.namespace.gsub(':', '_')}"
end
process_command(raw_command) click to toggle source

PROCESSING INTERACTIVE COMMANDS

# File lib/objects/orchestration/interactive_terraform.rb, line 36
def process_command(raw_command)
  full_command = command(raw_command)
  @node.execute_local(full_command)
  wait_for_command_input
end
show_intro_text() click to toggle source
# File lib/objects/orchestration/interactive_terraform.rb, line 24
def show_intro_text
  puts "\n\n"
  puts "Interactive Terraform\n".underline
  puts "Namespace:\s" + @node.namespace.to_s.informational
  puts "Configuration Path:\s" + "#{path_to_env_config}/*".informational
  puts "\nConfigured metadata:\s" + terraform_metadata.inspect.informational

  puts "\nAny commands you enter here will be passed directly to Terraform in your configuration path scope."
end
terraform_metadata() click to toggle source

COMMAND PROCESSING

# File lib/objects/orchestration/interactive_terraform.rb, line 54
def terraform_metadata
  @terraform_metadata ||= @node.metadata.fetch('terraform', @node.metadata.fetch(:terraform, {}))
end
var_string() click to toggle source
# File lib/objects/orchestration/interactive_terraform.rb, line 82
def var_string
  @var_string ||= form_var_string
end
wait_for_command_input() click to toggle source

HANDLING USER INPUT

# File lib/objects/orchestration/interactive_terraform.rb, line 44
def wait_for_command_input
  raw_command = wait_for_input
  process_command(raw_command) unless raw_command == QUIT
end
wait_for_input(message = COMMAND_PROMPT) click to toggle source
# File lib/objects/orchestration/interactive_terraform.rb, line 49
def wait_for_input(message = COMMAND_PROMPT)
  ::Readline.readline("\n#{message}", true).squeeze('').to_s
end