Class: Kontena::Cli::Config
- Inherits:
-
OpenStruct
- Object
- OpenStruct
- Kontena::Cli::Config
- Extended by:
- Forwardable
- Includes:
- Singleton
- Defined in:
- lib/kontena/cli/config.rb
Overview
Helper to access and update the CLI configuration file.
Also provides a "fake" config hash that behaves just like the file based config when ENV-variables are used instead of config file.
Defined Under Namespace
Modules: ConfigurationInstance, TokenSerializer Classes: Account, Server, Token
Constant Summary collapse
- TokenExpiredError =
Class.new(StandardError)
Instance Attribute Summary collapse
-
#current_account ⇒ Object
Returns the value of attribute current_account.
-
#current_server ⇒ Object
Returns the value of attribute current_server.
-
#logger ⇒ Object
Returns the value of attribute logger.
Class Method Summary collapse
Instance Method Summary collapse
-
#accounts ⇒ Array
List of configured accounts.
-
#add_server(data) ⇒ Object
Add a new server to the configuration.
-
#config_file_available? ⇒ Boolean
Verifies access to existing configuration file.
-
#config_filename ⇒ String
Return the configuration file path.
-
#current_grid ⇒ String, NilClass
Name of the currently selected grid.
-
#current_grid=(name) ⇒ Object
Set the current grid name.
-
#current_master ⇒ Server
Currently selected master's configuration data.
-
#current_master=(name) ⇒ Object
Set the current master.
-
#default_config_filename ⇒ Object
Generate the default configuration filename.
-
#default_settings ⇒ Hash
Default settings hash, used when configuration file does not exist.
- #extract_token!(hash = {}) ⇒ Object
- #find_account(name) ⇒ Object
- #find_account_index(name) ⇒ Object
-
#find_server(name) ⇒ Server, NilClass
Shortcut to find_server_by(name: name).
-
#find_server_by(criteria = {}) ⇒ Server, NilClass
Search the server list for a server by field(s) and value(s).
-
#find_server_index(name) ⇒ Fixnum, NilClass
Shortcut to find_server_index_by(name: name).
-
#find_server_index_by(criteria = {}) ⇒ Fixnum, NilClass
Search the server list for a server by field(s) and value(s) and return its index.
-
#initialize ⇒ Config
constructor
A new instance of Config.
- #kontena_account_data ⇒ Object
-
#kontena_account_hash ⇒ Object
Returns a cleaned up version of the kontena account data with only the token and name.
-
#load_settings_from_config_file ⇒ Object
Load configuration from default location ($HOME/.kontena_client.json).
-
#load_settings_from_env ⇒ Object
Craft a regular looking configuration based on ENV variables.
- #master_account_data ⇒ Object
-
#migrate_legacy_settings(settings) ⇒ Hash
Converts old style settings hash into modern one.
-
#parse_config_file ⇒ Hash
Read, parse and migrate the configuration file.
-
#require_current_account ⇒ Account
Raises unless current account is selected.
- #require_current_account_token ⇒ Object
-
#require_current_grid ⇒ String
Raises unless current grid is selected.
-
#require_current_master ⇒ Server
Raises unless current master is selected.
-
#require_current_master_token ⇒ Token
Raises unless current master has token.
-
#servers ⇒ Array
List of configured servers.
-
#to_hash ⇒ Hash
Generate a hash from the current configuration.
-
#to_json ⇒ String
Generate a JSON string from the current configuration.
-
#write ⇒ Object
Write the current configuration to config file.
Constructor Details
#initialize ⇒ Config
Returns a new instance of Config.
27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/kontena/cli/config.rb', line 27 def initialize super @logger = Logger.new(ENV["DEBUG"] ? $stderr : $stdout) @logger.level = ENV["DEBUG"].nil? ? Logger::INFO : Logger::DEBUG @logger.progname = 'CONFIG' load_settings_from_env || load_settings_from_config_file logger.debug "Configuration loaded with #{servers.count} servers." logger.debug "Current master: #{current_server || '(not selected)'}" logger.debug "Current grid: #{current_grid || '(not selected)'}" end |
Instance Attribute Details
#current_account ⇒ Object
Returns the value of attribute current_account.
18 19 20 |
# File 'lib/kontena/cli/config.rb', line 18 def current_account @current_account end |
#current_server ⇒ Object
Returns the value of attribute current_server.
17 18 19 |
# File 'lib/kontena/cli/config.rb', line 17 def current_server @current_server end |
#logger ⇒ Object
Returns the value of attribute logger.
16 17 18 |
# File 'lib/kontena/cli/config.rb', line 16 def logger @logger end |
Class Method Details
.reset_instance ⇒ Object
20 21 22 23 |
# File 'lib/kontena/cli/config.rb', line 20 def self.reset_instance Singleton.send :__init__, self self end |
Instance Method Details
#accounts ⇒ Array
List of configured accounts
221 222 223 |
# File 'lib/kontena/cli/config.rb', line 221 def accounts @accounts ||= [] end |
#add_server(data) ⇒ Object
Add a new server to the configuration
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'lib/kontena/cli/config.rb', line 228 def add_server(data) token = Token.new( access_token: data.delete('token'), refresh_token: data.delete('refresh_token'), expires_at: data.delete('token_expires_at'), parent_type: :master, parent_name: data['name'] || data[:name] ) server = Server.new(data.merge(token: token)) if (existing_index = find_server_index(server.name)) servers[existing_index] = server else servers << server end write end |
#config_file_available? ⇒ Boolean
Verifies access to existing configuration file
152 153 154 |
# File 'lib/kontena/cli/config.rb', line 152 def config_file_available? File.exist?(config_filename) && File.readable?(config_filename) end |
#config_filename ⇒ String
Return the configuration file path. You can override the default by using KONTENA_CONFIG environment variable.
202 203 204 |
# File 'lib/kontena/cli/config.rb', line 202 def config_filename @config_filename ||= ENV['KONTENA_CONFIG'] || default_config_filename end |
#current_grid ⇒ String, NilClass
Name of the currently selected grid. Can override using KONTENA_GRID environment variable.
371 372 373 |
# File 'lib/kontena/cli/config.rb', line 371 def current_grid ENV['KONTENA_GRID'] || (current_master && current_master.grid) end |
#current_grid=(name) ⇒ Object
Set the current grid name.
379 380 381 382 383 384 385 |
# File 'lib/kontena/cli/config.rb', line 379 def current_grid=(name) if current_master current_master.grid = name else raise ArgumentError, "Current master not selected, can't set grid." end end |
#current_master ⇒ Server
Currently selected master's configuration data
292 293 294 295 296 297 |
# File 'lib/kontena/cli/config.rb', line 292 def current_master return servers[@current_master_index] if @current_master_index return nil unless current_server @current_master_index = find_server_index(current_server) servers[@current_master_index] if @current_master_index end |
#current_master=(name) ⇒ Object
Set the current master.
344 345 346 347 348 349 350 351 352 353 354 355 356 |
# File 'lib/kontena/cli/config.rb', line 344 def current_master=(name) @current_master_index = nil if name.nil? self.current_server = nil else index = find_server_index(name.respond_to?(:name) ? name.name : name) if index self.current_server = servers[index].name else raise ArgumentError, "Server '#{name}' does not exist, can't add as current master." end end end |
#default_config_filename ⇒ Object
Generate the default configuration filename
207 208 209 |
# File 'lib/kontena/cli/config.rb', line 207 def default_config_filename File.join(Dir.home, '.kontena_client.json') end |
#default_settings ⇒ Hash
Default settings hash, used when configuration file does not exist.
159 160 161 162 163 164 165 |
# File 'lib/kontena/cli/config.rb', line 159 def default_settings logger.debug 'Configuration file not found, using default settings.' { 'current_server' => 'default', 'servers' => [] } end |
#extract_token!(hash = {}) ⇒ Object
61 62 63 64 65 66 67 |
# File 'lib/kontena/cli/config.rb', line 61 def extract_token!(hash={}) Token.new( access_token: hash.delete('token'), refresh_token: hash.delete('refresh_token'), expires_at: hash.delete('token_expires_at').to_i ) end |
#find_account(name) ⇒ Object
281 282 283 |
# File 'lib/kontena/cli/config.rb', line 281 def find_account(name) accounts.find{|a| a['name'] == name.to_s} end |
#find_account_index(name) ⇒ Object
285 286 287 |
# File 'lib/kontena/cli/config.rb', line 285 def find_account_index(name) accounts.find_index{|a| a['name'] == name.to_s} end |
#find_server(name) ⇒ Server, NilClass
Shortcut to find_server_by(name: name)
269 270 271 |
# File 'lib/kontena/cli/config.rb', line 269 def find_server(name) find_server_by(name: name) end |
#find_server_by(criteria = {}) ⇒ Server, NilClass
Search the server list for a server by field(s) and value(s).
250 251 252 |
# File 'lib/kontena/cli/config.rb', line 250 def find_server_by(criteria = {}) servers.find{|s| criteria.none? {|k,v| v != s[k]}} end |
#find_server_index(name) ⇒ Fixnum, NilClass
Shortcut to find_server_index_by(name: name)
277 278 279 |
# File 'lib/kontena/cli/config.rb', line 277 def find_server_index(name) find_server_index_by(name: name) end |
#find_server_index_by(criteria = {}) ⇒ Fixnum, NilClass
Search the server list for a server by field(s) and value(s) and return its index.
261 262 263 |
# File 'lib/kontena/cli/config.rb', line 261 def find_server_index_by(criteria = {}) servers.find_index{|s| criteria.none? {|k,v| v != s[k]}} end |
#kontena_account_data ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/kontena/cli/config.rb', line 121 def kontena_account_data { name: 'kontena', url: 'https://cloud-api.kontena.io', stacks_url: 'https://stacks.kontena.io', token_endpoint: 'https://cloud-api.kontena.io/oauth2/token', authorization_endpoint: 'https://cloud.kontena.io/login/oauth/authorize', userinfo_endpoint: 'https://cloud-api.kontena.io/user', token_post_content_type: 'application/x-www-form-urlencoded', code_requires_basic_auth: false, token_method: 'post', scope: 'user', client_id: nil } end |
#kontena_account_hash ⇒ Object
Returns a cleaned up version of the kontena account data with only the token and name.
403 404 405 406 407 408 409 410 411 |
# File 'lib/kontena/cli/config.rb', line 403 def kontena_account_hash hash = { name: 'kontena' } acc = find_account('kontena') if acc && acc.token hash[:username] = acc.username if acc.username hash.merge!(acc.token.to_h) end hash end |
#load_settings_from_config_file ⇒ Object
Load configuration from default location ($HOME/.kontena_client.json)
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/kontena/cli/config.rb', line 70 def load_settings_from_config_file settings = config_file_available? ? parse_config_file : default_settings Array(settings['servers']).each do |server_data| if server_data['token'] token = extract_token!(server_data) token.parent_type = :master token.parent_name = server_data['name'] server = Server.new(server_data) server.token = token else server = Server.new(server_data) end server.account ||= 'master' if servers.find { |s| s['name'] == server.name} server.name = "#{server.name}-2" server.name.succ! until servers.find { |s| s['name'] == server.name }.nil? logger.debug "Renamed server to #{server.name} because a duplicate was found in config" end servers << server end self.current_server = ENV['KONTENA_MASTER'] || settings['current_server'] Array(settings['accounts']).each do |account_data| if account_data['token'] token = extract_token!(account_data) token.parent_type = :account token.parent_name = account_data['name'] account = Account.new(account_data) account.token = token else account = Account.new(account_data) end accounts << account end ka = find_account('kontena') if ka kontena_account_data.each {|k,v| ka[k] = v} else accounts << Account.new(kontena_account_data) end master_index = find_account_index('master') accounts.delete_at(master_index) if master_index accounts << Account.new(master_account_data) self.current_account = settings['current_account'] || 'kontena' end |
#load_settings_from_env ⇒ Object
Craft a regular looking configuration based on ENV variables
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/kontena/cli/config.rb', line 40 def load_settings_from_env return nil unless ENV['KONTENA_URL'] logger.debug 'Loading configuration from ENV' servers << Server.new( url: ENV['KONTENA_URL'], name: 'default', token: Token.new(access_token: ENV['KONTENA_TOKEN'], parent_type: :master, parent_name: 'default'), grid: ENV['KONTENA_GRID'], parent_type: :master, parent_name: 'default' ) accounts << Account.new( url: ENV['AUTH_API_URL'] || 'https://auth.kontena.io', name: 'kontena', token: Token.new(access_token: ENV['KONTENA_ACCOUNT_TOKEN'], parent_type: :account, parent_name: 'default') ) self.current_master = 'default' self.current_account = 'kontena' end |
#master_account_data ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/kontena/cli/config.rb', line 137 def master_account_data { name: 'master', token_endpoint: '/oauth2/token', authorization_endpoint: '/oauth2/authorize', userinfo_endpoint: '/v1/user', token_post_content_type: 'application/json', token_method: 'post', code_requires_basic_auth: false } end |
#migrate_legacy_settings(settings) ⇒ Hash
Converts old style settings hash into modern one
171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/kontena/cli/config.rb', line 171 def migrate_legacy_settings(settings) logger.debug "Migrating from legacy style configuration" { 'current_server' => 'default', 'servers' => [ settings['server'].merge( 'name' => 'default', 'account' => 'kontena' ) ], 'accounts' => [ kontena_account_data ] } end |
#parse_config_file ⇒ Hash
Read, parse and migrate the configuration file
188 189 190 191 192 193 194 195 196 |
# File 'lib/kontena/cli/config.rb', line 188 def parse_config_file logger.debug "Loading configuration from #{config_filename}" settings = JSON.load(File.read(config_filename)) if settings.has_key?('server') settings = migrate_legacy_settings(settings) else settings end end |
#require_current_account ⇒ Account
Raises unless current account is selected.
326 327 328 329 |
# File 'lib/kontena/cli/config.rb', line 326 def require_current_account return @current_account if @current_account raise ArgumentError, "You are not logged into an authorization provider. Use: kontena cloud login" end |
#require_current_account_token ⇒ Object
331 332 333 334 335 336 337 338 |
# File 'lib/kontena/cli/config.rb', line 331 def require_current_account_token account = require_current_account if !account || account.token.nil? || account.token.access_token.nil? raise ArgumentError, "You are not logged in to Kontena Cloud. Use: kontena cloud login" elsif account.token.expired? raise TokenExpiredError, "The cloud access token has expired and needs to be refreshed." unless cloud_client.refresh_token end end |
#require_current_grid ⇒ String
Raises unless current grid is selected.
362 363 364 365 |
# File 'lib/kontena/cli/config.rb', line 362 def require_current_grid return current_grid if current_grid raise ArgumentError, "You have not selected a grid. Use: kontena grid" end |
#require_current_master ⇒ Server
Raises unless current master is selected.
317 318 319 320 |
# File 'lib/kontena/cli/config.rb', line 317 def require_current_master return current_master if current_master raise ArgumentError, "You are not logged into a Kontena Master. Use: kontena master login" end |
#require_current_master_token ⇒ Token
Raises unless current master has token.
303 304 305 306 307 308 309 310 311 |
# File 'lib/kontena/cli/config.rb', line 303 def require_current_master_token require_current_master token = current_master.token if token && token.access_token return token unless token.expired? raise TokenExpiredError, "The access token has expired and needs to be refreshed." end raise ArgumentError, "You are not logged into a Kontena Master. Use: kontena master login" end |
#servers ⇒ Array
List of configured servers
214 215 216 |
# File 'lib/kontena/cli/config.rb', line 214 def servers @servers ||= [] end |
#to_hash ⇒ Hash
Generate a hash from the current configuration.
416 417 418 419 420 421 422 423 424 425 426 427 |
# File 'lib/kontena/cli/config.rb', line 416 def to_hash hash = { current_server: (self.current_server && find_server(self.current_server)) ? self.current_server : nil, current_account: self.current_account ? self.current_account.name : nil, servers: servers.map(&:to_h), accounts: accounts.reject{|a| a.name == 'master' || a.name == 'kontena'}.map(&:to_h) + [kontena_account_hash] } hash[:servers].each do |server| server.delete(:account) if server[:account] == 'master' end hash end |
#to_json ⇒ String
Generate a JSON string from the current configuration
432 433 434 |
# File 'lib/kontena/cli/config.rb', line 432 def to_json JSON.pretty_generate(to_hash) end |
#write ⇒ Object
Write the current configuration to config file. Does nothing if using settings from environment variables.
438 439 440 441 442 |
# File 'lib/kontena/cli/config.rb', line 438 def write return nil if ENV['KONTENA_URL'] logger.debug "Writing configuration to #{config_filename}" File.write(config_filename, to_json) end |