Class: Kontena::Cli::Config
- Inherits:
-
OpenStruct
- Object
- OpenStruct
- Kontena::Cli::Config
- Extended by:
- Forwardable
- Includes:
- Fields, 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, Fields, 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.
- #debug(&block) ⇒ Object
-
#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/.krates.json).
- #master_account_data ⇒ Object
-
#migrate_legacy_settings(settings) ⇒ Hash
Converts old style settings hash into modern one.
- #override_cloud_settings_from_env ⇒ Object
- #override_master_settings_from_env ⇒ Object
-
#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.
Methods included from Fields
Constructor Details
#initialize ⇒ Config
Returns a new instance of Config.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/kontena/cli/config.rb', line 40 def initialize super @logger = Kontena.logger load_settings_from_config_file override_master_settings_from_env override_cloud_settings_from_env debug { "Configuration loaded with #{servers.count} servers and #{accounts.count} accounts." } debug { "Current master: #{current_server || '(not selected)'}" } debug { "Current grid: #{current_grid || '(not selected)'}" } debug { "Current account: #{current_account.nil? ? '(not selected)' : current_account.name}" } end |
Instance Attribute Details
#current_account ⇒ Object
Returns the value of attribute current_account.
30 31 32 |
# File 'lib/kontena/cli/config.rb', line 30 def current_account @current_account end |
#current_server ⇒ Object
Returns the value of attribute current_server.
29 30 31 |
# File 'lib/kontena/cli/config.rb', line 29 def current_server @current_server end |
#logger ⇒ Object
Returns the value of attribute logger.
28 29 30 |
# File 'lib/kontena/cli/config.rb', line 28 def logger @logger end |
Class Method Details
.reset_instance ⇒ Object
33 34 35 36 |
# File 'lib/kontena/cli/config.rb', line 33 def self.reset_instance Singleton.send :__init__, self self end |
Instance Method Details
#accounts ⇒ Array
List of configured accounts
300 301 302 |
# File 'lib/kontena/cli/config.rb', line 300 def accounts @accounts ||= [] end |
#add_server(data) ⇒ Object
Add a new server to the configuration
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/kontena/cli/config.rb', line 307 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
225 226 227 |
# File 'lib/kontena/cli/config.rb', line 225 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.
275 276 277 278 279 280 281 282 283 |
# File 'lib/kontena/cli/config.rb', line 275 def config_filename return @config_filename if @config_filename if ENV['KONTENA_CONFIG'] debug { "Using #{ENV['KONTENA_CONFIG']} as config file set through env KONTENA_CONFIG"} @config_filename = ENV['KONTENA_CONFIG'] else @config_filename = default_config_filename end end |
#current_grid ⇒ String, NilClass
Name of the currently selected grid. Can override using KONTENA_GRID environment variable.
450 451 452 453 454 |
# File 'lib/kontena/cli/config.rb', line 450 def current_grid return ENV['KONTENA_GRID'] unless ENV['KONTENA_GRID'].to_s.empty? return nil unless current_master current_master.grid end |
#current_grid=(name) ⇒ Object
Set the current grid name.
460 461 462 463 464 465 466 |
# File 'lib/kontena/cli/config.rb', line 460 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
371 372 373 374 375 376 |
# File 'lib/kontena/cli/config.rb', line 371 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.
423 424 425 426 427 428 429 430 431 432 433 434 435 |
# File 'lib/kontena/cli/config.rb', line 423 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 |
#debug(&block) ⇒ Object
55 56 57 |
# File 'lib/kontena/cli/config.rb', line 55 def debug(&block) Kontena.logger.add(Logger::DEBUG, nil, 'CONFIG', &block) end |
#default_config_filename ⇒ Object
Generate the default configuration filename
286 287 288 |
# File 'lib/kontena/cli/config.rb', line 286 def default_config_filename File.join(Dir.home, '.krates.json') end |
#default_settings ⇒ Hash
Default settings hash, used when configuration file does not exist.
232 233 234 235 236 237 238 |
# File 'lib/kontena/cli/config.rb', line 232 def default_settings debug { 'Configuration file not found, using default settings.' } { 'current_server' => 'default', 'servers' => [] } end |
#extract_token!(hash = {}) ⇒ Object
133 134 135 136 137 138 139 |
# File 'lib/kontena/cli/config.rb', line 133 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
360 361 362 |
# File 'lib/kontena/cli/config.rb', line 360 def find_account(name) accounts.find{|a| a['name'] == name.to_s} end |
#find_account_index(name) ⇒ Object
364 365 366 |
# File 'lib/kontena/cli/config.rb', line 364 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)
348 349 350 |
# File 'lib/kontena/cli/config.rb', line 348 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).
329 330 331 |
# File 'lib/kontena/cli/config.rb', line 329 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)
356 357 358 |
# File 'lib/kontena/cli/config.rb', line 356 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.
340 341 342 |
# File 'lib/kontena/cli/config.rb', line 340 def find_server_index_by(criteria = {}) servers.find_index{|s| criteria.none? {|k,v| v != s[k]}} end |
#kontena_account_data ⇒ Object
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/kontena/cli/config.rb', line 193 def kontena_account_data { name: 'kontena', url: ENV['KONTENA_CLOUD_URL'] || 'https://cloud-api.kontena.io', stacks_url: ENV['KONTENA_STACK_REGISTRY_URL'] || 'https://stacks.kontena.io', token_endpoint: ENV['AUTH_TOKEN_ENDPOINT'] || 'https://cloud-api.kontena.io/oauth2/token', authorization_endpoint: ENV['AUTH_AUTHORIZE_ENDPOINT'] || 'https://cloud.kontena.io/login/oauth/authorize', userinfo_endpoint: ENV['AUTH_USERINFO_ENDPOINT'] || 'https://cloud-api.kontena.io/user', token_post_content_type: ENV['AUTH_TOKEN_POST_CONTENT_TYPE'] || 'application/x-www-form-urlencoded', code_requires_basic_auth: ENV['AUTH_CODE_REQUIRES_BASIC_AUTH'].to_s == true, token_method: ENV['AUTH_TOKEN_METHOD'] || 'post', scope: ENV['AUTH_USERINFO_SCOPE'] || 'user', client_id: nil, stacks_read_authentication: ENV['KONTENA_STACK_REGISTRY_READ_AUTHENTICATION'].to_s == 'true' } end |
#kontena_account_hash ⇒ Object
Returns a cleaned up version of the kontena account data with only the token and name.
484 485 486 487 488 489 490 491 492 |
# File 'lib/kontena/cli/config.rb', line 484 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/.krates.json)
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 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 183 184 185 186 187 188 189 190 191 |
# File 'lib/kontena/cli/config.rb', line 142 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? debug { "Renamed server to #{server.name} because a duplicate was found in config" } end servers << server end self.current_server = 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 |
#master_account_data ⇒ Object
210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/kontena/cli/config.rb', line 210 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
244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/kontena/cli/config.rb', line 244 def migrate_legacy_settings(settings) debug { "Migrating from legacy style configuration" } { 'current_server' => 'default', 'servers' => [ settings['server'].merge( 'name' => 'default', 'account' => 'kontena' ) ], 'accounts' => [ kontena_account_data ] } end |
#override_cloud_settings_from_env ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/kontena/cli/config.rb', line 103 def override_cloud_settings_from_env if ENV['KONTENA_CLOUD'] account = find_account(ENV['KONTENA_CLOUD']) if account debug { "Using cloud account #{ENV['KONTENA_CLOUD']} from config selected by env KONTENA_CLOUD" } self.current_account = account.name else debug { "Using new cloud account #{ENV['KONTENA_CLOUD']} from env" } account = Accout.new(kontena_account_data.merge(name: ENV['KONTENA_CLOUD'])) accounts << account end elsif current_account account = current_account end if account.nil? debug { 'No account data from config or env' } self.current_account = nil return end if ENV['KONTENA_CLOUD_TOKEN'] debug { 'Using cloud token from env KONTENA_CLOUD_TOKEN' } account.token ||= Token.new(parent_type: :account, parent_name: account.name) account.token.access_token = ENV['KONTENA_CLOUD_TOKEN'] account.token.refresh_token = nil account.token.expires_at = nil end end |
#override_master_settings_from_env ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 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 |
# File 'lib/kontena/cli/config.rb', line 59 def override_master_settings_from_env if ENV['KONTENA_URL'] server = find_server_by(url: ENV['KONTENA_URL']) if server.nil? debug { 'Using new master url from env KONTENA_URL' } server = Server.new( url: ENV['KONTENA_URL'], name: ENV['KONTENA_MASTER'] || 'default' ) servers << server else debug { "Using master #{server.name} in config found via url in env KONTENA_URL" } end elsif ENV['KONTENA_MASTER'] server = find_server_by(name: ENV['KONTENA_MASTER']) if server debug { "Using master #{ENV['KONTENA_MASTER']} set via env KONTENA_MASTER" } end elsif current_master server = current_master end if server.nil? debug { 'Could not determine a master through config or env' } self.current_master = nil return else self.current_master = server.name end if ENV['KONTENA_GRID'] debug { "Using grid #{ENV['KONTENA_GRID']} from env KONTENA_GRID" } server.grid = ENV['KONTENA_GRID'] end if ENV['KONTENA_TOKEN'] debug { 'Using master token from env KONTENA_TOKEN' } server.token ||= Token.new(parent_type: :master, parent_name: server.name) server.token.access_token = ENV['KONTENA_TOKEN'] server.token.refresh_token = nil server.token.expires_at = nil end end |
#parse_config_file ⇒ Hash
Read, parse and migrate the configuration file
261 262 263 264 265 266 267 268 269 |
# File 'lib/kontena/cli/config.rb', line 261 def parse_config_file 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.
405 406 407 408 |
# File 'lib/kontena/cli/config.rb', line 405 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
410 411 412 413 414 415 416 417 |
# File 'lib/kontena/cli/config.rb', line 410 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.
441 442 443 444 |
# File 'lib/kontena/cli/config.rb', line 441 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.
396 397 398 399 |
# File 'lib/kontena/cli/config.rb', line 396 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.
382 383 384 385 386 387 388 389 390 |
# File 'lib/kontena/cli/config.rb', line 382 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
293 294 295 |
# File 'lib/kontena/cli/config.rb', line 293 def servers @servers ||= [] end |
#to_hash ⇒ Hash
Generate a hash from the current configuration.
497 498 499 500 501 502 503 504 505 506 507 508 |
# File 'lib/kontena/cli/config.rb', line 497 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
513 514 515 |
# File 'lib/kontena/cli/config.rb', line 513 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.
519 520 521 522 523 |
# File 'lib/kontena/cli/config.rb', line 519 def write return nil if ENV['KONTENA_URL'] debug { "Writing configuration to #{config_filename}" } File.write(config_filename, to_json) end |