Class: Forward::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/forward/config.rb

Constant Summary collapse

CONFIG_FILE_VALUES =
[ :api_token ]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes = {}) ⇒ Config

Initializes a Config object with the given attributes.

attributes - A Hash of attributes

Returns the new Config object.



17
18
19
20
21
# File 'lib/forward/config.rb', line 17

def initialize(attributes = {})
  attributes.each do |key, value|
    self.send(:"#{key}=", value)
  end
end

Instance Attribute Details

#api_tokenObject

Returns the value of attribute api_token.



9
10
11
# File 'lib/forward/config.rb', line 9

def api_token
  @api_token
end

#idObject

Returns the value of attribute id.



8
9
10
# File 'lib/forward/config.rb', line 8

def id
  @id
end

#private_keyObject

Returns the value of attribute private_key.



10
11
12
# File 'lib/forward/config.rb', line 10

def private_key
  @private_key
end

Class Method Details

.config_pathObject

Returns the location of the forward config file based on the host os.

Returns the String path.



98
99
100
101
102
103
104
# File 'lib/forward/config.rb', line 98

def self.config_path
  if Forward.windows?
    File.join(ENV['HOME'], 'forward', 'config')
  else
    File.join(ENV['HOME'], '.forward')
  end
end

.createObject

Create a config by authenticating the user via the api, and saving the users api_token/id/private_key.

Returns the new Config object.



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/forward/config.rb', line 135

def self.create
  Forward.log.debug('Creating Config')
  if @updating_config || ask('Already have an account with Forward? ').chomp =~ /\Ay/i
    config             = Config.new
    email, password    = CLI.authenticate.values_at(:email, :password)
    config.update(Forward::Api::User.api_token(email, password))
    Forward::Api.token = config.api_token
    config.private_key = Forward::Api::TunnelKey.create

    config.write
  else
    message = "You'll need a Forward account first. You can create one at "
    message << HighLine.color('https://forwardhq.com', :underline)
    Client.cleanup_and_exit!(message)
  end
end

.create_or_loadObject

Create a config file if it doesn’t exist, load one if it does.

Returns the resulting Config object.



123
124
125
126
127
128
129
# File 'lib/forward/config.rb', line 123

def self.create_or_load
  if Config.present?
    Config.load
  else
    Config.create
  end
end

.key_file_present?Boolean

Checks to see if a ‘private_key’ exist.

Returns true or false based on the existence of the key file.

Returns:

  • (Boolean)


116
117
118
# File 'lib/forward/config.rb', line 116

def self.key_file_present?
  File.exist? key_path
end

.key_pathObject

Returns the location of the forward ssh private key based on the host os.

Returns the String path.



86
87
88
89
90
91
92
# File 'lib/forward/config.rb', line 86

def self.key_path
  if Forward.windows?
    File.join(ENV['HOME'], 'forward', 'key')
  else
    File.join(ENV['HOME'], '.ssh', 'forwardhq.com')
  end
end

.loadObject

It initializes a new Config instance, updates it with the config values from the config file, and raises an error if there’s not a config or if the config options aren’t valid.

Returns the Config object.

Raises:



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/forward/config.rb', line 157

def self.load
  Forward.log.debug('Loading Config')
  config = Config.new

  raise ConfigError, "Unable to find a forward config file at `#{config_path}'" unless Config.present?

  if File.read(config_path).include? '-----M-----'
    puts "Forward needs to update your config file, please re-authenticate"
    File.delete(config_path)
    @updating_config = true
    create_or_load
  end

  raise ConfigError, "Unable to find a forward key file at `#{key_path}'" unless Config.key_file_present?


  config.update(YAML.load_file(config_path).symbolize_keys)
  config.private_key = File.read(key_path)
  Forward::Api.token = config.api_token

  config.validate

  Forward.config = config

  config
end

.present?Boolean

Checks to see if a .forward config file exists.

Returns true or false based on the existence of the config file.

Returns:

  • (Boolean)


109
110
111
# File 'lib/forward/config.rb', line 109

def self.present?
  File.exist? config_path
end

Instance Method Details

#to_hashObject

Converts a Config object to a Hash.

Returns a Hash representation of the object



38
39
40
# File 'lib/forward/config.rb', line 38

def to_hash
  Hash[instance_variables.map { |var| [var[1..-1].to_sym, instance_variable_get(var)] }]
end

#update(attributes) ⇒ Object

Updates an existing Config object.

Returns the updated Config object.



26
27
28
29
30
31
32
33
# File 'lib/forward/config.rb', line 26

def update(attributes)
  Forward.log.debug('Updating Config')
  attributes.each do |key, value|
    self.send(:"#{key}=", value)
  end

  self
end

#validateObject

Validate that the required values are in the Config. Raises a config error if values are missing.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/forward/config.rb', line 44

def validate
  Forward.log.debug('Validating Config')
  attributes = [:api_token, :private_key]
  errors = []

  attributes.each do |attribute|
    value = instance_variable_get("@#{attribute}")

    errors << attribute if value.nil? || value.to_s.empty?
  end

  if errors.length == 1
    raise ConfigError, "#{errors.first} is a required field"
  elsif errors.length >= 2
    raise ConfigError, "#{errors.join(', ')} are required fields"
  end
end

#writeObject

Write the current config data to ‘config_path’, and the current private_key to ‘key_path’.

Returns the Config object.



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/forward/config.rb', line 66

def write
  Forward.log.debug('Writing Config')
  key_folder  = File.dirname(Config.key_path)
  config_data = to_hash.delete_if { |k,v| !CONFIG_FILE_VALUES.include?(k) }

  self.validate

  FileUtils.mkdir(key_folder) unless File.exist?(key_folder)
  File.open(Config.config_path, 'w') { |f| f.write(YAML.dump(config_data)) }
  File.open(Config.key_path, 'w') { |f| f.write(private_key) }

  self
rescue
  raise ConfigError, 'Unable to write config file'
end