Module: Kontena::Cli::Common

Extended by:
Forwardable
Included in:
Helper, Kontena::Cli::Certificate::AuthorizeCommand, Kontena::Cli::Certificate::DomainAuthorization::ListCommand, Kontena::Cli::Certificate::DomainAuthorization::RemoveAuthorizationCommand, Kontena::Cli::Certificate::ExportCommand, Kontena::Cli::Certificate::GetCommand, Kontena::Cli::Certificate::ImportCommand, Kontena::Cli::Certificate::ListCommand, Kontena::Cli::Certificate::RegisterCommand, Kontena::Cli::Certificate::RemoveCommand, Kontena::Cli::Certificate::RequestCommand, Kontena::Cli::Certificate::ShowCommand, Kontena::Cli::Cloud::LoginCommand, Kontena::Cli::Cloud::LogoutCommand, Kontena::Cli::Cloud::Master::AddCommand, Kontena::Cli::Cloud::Master::ListCommand, Kontena::Cli::Cloud::Master::RemoveCommand, Kontena::Cli::Cloud::Master::ShowCommand, Kontena::Cli::Cloud::Master::UpdateCommand, Kontena::Cli::Cloud::MasterCommand, CloudCommand, Kontena::Cli::Containers::ExecCommand, Kontena::Cli::Containers::InspectCommand, Kontena::Cli::Containers::ListCommand, Kontena::Cli::Containers::LogsCommand, Etcd::GetCommand, Etcd::HealthCommand, Etcd::ListCommand, Etcd::MkdirCommand, Etcd::RemoveCommand, Etcd::SetCommand, ExternalRegistries::AddCommand, ExternalRegistries::ListCommand, ExternalRegistries::RemoveCommand, Grids::AuditLogCommand, Grids::CloudConfigCommand, Grids::CreateCommand, Grids::CurrentCommand, Grids::EnvCommand, Grids::EventsCommand, Grids::HealthCommand, Grids::ListCommand, Grids::LogsCommand, Grids::RemoveCommand, Grids::ShowCommand, Grids::TrustedSubnets::AddCommand, Grids::TrustedSubnets::ListCommand, Grids::TrustedSubnets::RemoveCommand, Grids::UpdateCommand, Grids::UseCommand, Grids::Users::AddCommand, Grids::Users::ListCommand, Grids::Users::RemoveCommand, LogoutCommand, Master::AuditLogCommand, Master::Config::ExportCommand, Master::Config::GetCommand, Master::Config::ImportCommand, Master::Config::SetCommand, Master::Config::UnsetCommand, Master::CreateCommand, Master::CurrentCommand, Master::InitCloudCommand, Master::ListCommand, Master::LoginCommand, Master::LogoutCommand, Master::RemoveCommand, Master::SshCommand, Master::Token::CreateCommand, Master::Token::CurrentCommand, Master::Token::ListCommand, Master::Token::RemoveCommand, Master::Token::ShowCommand, Master::UseCommand, Master::User::InviteCommand, Master::User::ListCommand, Master::User::RemoveCommand, Master::User::Role::AddCommand, Master::User::Role::RemoveCommand, Nodes::CreateCommand, Nodes::EnvCommand, Nodes::HealthCommand, Nodes::Labels::AddCommand, Nodes::Labels::ListCommand, Nodes::Labels::RemoveCommand, Nodes::ListCommand, Nodes::RemoveCommand, Nodes::ResetTokenCommand, Nodes::ShowCommand, Nodes::SshCommand, Nodes::UpdateCommand, Plugins::InstallCommand, Plugins::ListCommand, Plugins::UninstallCommand, Plugins::UpgradeCommand, Registry::CreateCommand, Registry::RemoveCommand, Services::ContainersCommand, Services::CreateCommand, Services::DeployCommand, Services::Envs::AddCommand, Services::Envs::ListCommand, Services::Envs::RemoveCommand, Services::EventsCommand, Services::ExecCommand, Services::LinkCommand, Services::ListCommand, Services::LogsCommand, Services::MonitorCommand, Services::RemoveCommand, Services::RestartCommand, Services::ScaleCommand, Services::Secrets::LinkCommand, Services::Secrets::UnlinkCommand, Services::ServicesHelper, Services::ShowCommand, Services::StartCommand, Services::StatsCommand, Services::StopCommand, Services::UnlinkCommand, Services::UpdateCommand, Stacks::BuildCommand, Stacks::DeployCommand, Stacks::EventsCommand, Stacks::InspectCommand, Stacks::InstallCommand, Stacks::Labels::AddCommand, Stacks::Labels::ListCommand, Stacks::Labels::RemoveCommand, Stacks::ListCommand, Stacks::LogsCommand, Stacks::MonitorCommand, Stacks::Registry::CreateCommand, Stacks::Registry::MakePrivateCommand, Stacks::Registry::MakePublicCommand, Stacks::Registry::PullCommand, Stacks::Registry::PushCommand, Stacks::Registry::RemoveCommand, Stacks::Registry::SearchCommand, Stacks::Registry::ShowCommand, Stacks::RemoveCommand, Stacks::RestartCommand, Stacks::ShowCommand, Stacks::StopCommand, Stacks::UpgradeCommand, Stacks::ValidateCommand, Stacks::YAML::Opto::Resolvers::Certificates, Stacks::YAML::Opto::Resolvers::ServiceInstances, Stacks::YAML::Opto::Resolvers::ServiceLink, Stacks::YAML::Opto::Resolvers::Vault, Stacks::YAML::Opto::Resolvers::VaultCertPrompt, Stacks::YAML::Opto::Setters::Vault, Stacks::YAML::Prompt, Stacks::YAML::Reader, Vault::ExportCommand, Vault::ImportCommand, Vault::ListCommand, Vault::ReadCommand, Vault::RemoveCommand, Vault::UpdateCommand, Vault::WriteCommand, VersionCommand, Volumes::CreateCommand, Volumes::ListCommand, Volumes::RemoveCommand, Volumes::ShowCommand, Vpn::ConfigCommand, Vpn::CreateCommand, Vpn::RemoveCommand, WhoamiCommand, StacksCache::RegistryClientFactory
Defined in:
lib/kontena/cli/common.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.display_logoObject



354
355
356
# File 'lib/kontena/cli/common.rb', line 354

def 
  puts File.read(File.expand_path('../../../../LOGO', __FILE__))
end

.exit_with_error(msg, code = 1) ⇒ Object



165
166
167
168
169
# File 'lib/kontena/cli/common.rb', line 165

def exit_with_error(msg, code = 1)
  error = pastel.red('error')
  $stderr.puts " [#{error}] #{msg}"
  exit code
end

Instance Method Details

#access_token=(token) ⇒ Object



289
290
291
292
# File 'lib/kontena/cli/common.rb', line 289

def access_token=(token)
  require_current_master.token.access_token = token
  config.write
end

#add_master(server_name, master_info) ⇒ Object



294
295
296
# File 'lib/kontena/cli/common.rb', line 294

def add_master(server_name, master_info)
  config.add_server(master_info.merge('name' => server_name))
end

#any_key_to_continue(timeout = nil) ⇒ Object



304
305
306
307
308
309
# File 'lib/kontena/cli/common.rb', line 304

def any_key_to_continue(timeout = nil)
  return nil if running_silent?
  return nil unless $stdout.tty?
  return any_key_to_continue_with_timeout(timeout) if timeout
  prompt.keypress("Press any key to continue or ctrl-c to cancel.. ")
end

#any_key_to_continue_with_timeout(timeout = 9) ⇒ Object



298
299
300
301
302
# File 'lib/kontena/cli/common.rb', line 298

def any_key_to_continue_with_timeout(timeout=9)
  return nil if running_silent?
  return nil unless $stdout.tty?
  prompt.keypress("Press any key to continue or ctrl-c to cancel (Automatically continuing in :countdown seconds) ...", timeout: timeout)
end

#api_urlObject



243
244
245
# File 'lib/kontena/cli/common.rb', line 243

def api_url
  config.require_current_master.url
end

#api_url=(api_url) ⇒ Object



284
285
286
287
# File 'lib/kontena/cli/common.rb', line 284

def api_url=(api_url)
  config.current_master.url = api_url
  config.write
end

#caret(msg, dots: true) ⇒ Object

Output a message like: “> Reading foofoo ..”

Parameters:

  • message (String)

    the message to display

  • dots (TrueClass, FalseClass) (defaults to: true)

    set to false if you don’t want to add “..” after the message



127
128
129
# File 'lib/kontena/cli/common.rb', line 127

def caret(msg, dots: true)
  puts "#{pastel.green('>')} #{msg}#{" #{pastel.green('..')}" if dots}"
end

#clear_current_gridObject



247
248
249
250
# File 'lib/kontena/cli/common.rb', line 247

def clear_current_grid
  current_master.delete_field(:grid) if require_current_master.respond_to?(:grid)
  config.write
end

#client(token = nil, api_url = nil) ⇒ Object



224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/kontena/cli/common.rb', line 224

def client(token = nil, api_url = nil)
  return @client if @client

  if token.kind_of?(String)
    token = Kontena::Cli::Config::Token.new(access_token: token)
  end

  @client = Kontena::Client.new(
    api_url || require_current_master.url,
    token || require_current_master.token,
    ssl_cert_path: require_current_master.ssl_cert_path,
    ssl_subject_cn: require_current_master.ssl_subject_cn,
  )
end

#cloud_auth?Boolean

Returns:

  • (Boolean)


209
210
211
212
213
214
# File 'lib/kontena/cli/common.rb', line 209

def cloud_auth?
  return false unless 
  return false unless .token
  return false unless .token.access_token
  true
end

#cloud_clientObject



216
217
218
# File 'lib/kontena/cli/common.rb', line 216

def cloud_client
  @cloud_client ||= Kontena::Client.new(.url, .token, prefix: '/')
end

#configObject



39
40
41
# File 'lib/kontena/cli/common.rb', line 39

def config
  Kontena::Cli::Config.instance
end

#confirm(message = 'Destructive command. You can skip this prompt by running this command with --force option. Are you sure?') ⇒ Object



276
277
278
279
280
281
282
# File 'lib/kontena/cli/common.rb', line 276

def confirm(message = 'Destructive command. You can skip this prompt by running this command with --force option. Are you sure?')
  if self.respond_to?(:force?) && self.force?
    return
  end
  exit_with_error 'Command requires --force' unless $stdout.tty? && $stdin.tty?
  prompt.yes?(message) || error('Aborted command.')
end

#confirm_command(name, message = nil) ⇒ Object



265
266
267
268
269
270
271
272
273
274
# File 'lib/kontena/cli/common.rb', line 265

def confirm_command(name, message = nil)
  if self.respond_to?(:force?) && self.force?
    return
  end
  puts message if message
  exit_with_error 'Command requires --force' unless $stdout.tty? && $stdin.tty?
  puts "Destructive command. To proceed, type \"#{name}\" or re-run this command with --force option."

  ask("Enter '#{name}' to confirm: ") == name.to_s || error("Confirmation did not match #{name}. Aborted command.")
end

#current_gridObject



252
253
254
# File 'lib/kontena/cli/common.rb', line 252

def current_grid
  (self.respond_to?(:grid) ? self.grid : nil) || config.current_grid
end

#current_master_indexObject



256
257
258
# File 'lib/kontena/cli/common.rb', line 256

def current_master_index
  config.find_server_index(require_current_master.name)
end

#debug?Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/kontena/cli/common.rb', line 43

def debug?
  Kontena.debug?
end

#display_account_login_infoObject



311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/kontena/cli/common.rb', line 311

def 
  if 
    if .token && .token.access_token
      begin
        puts [
          pastel.green("Authenticated to Kontena Cloud at"),
          pastel.yellow(.url),
          pastel.green("as"),
          pastel.yellow(.username)
        ].join(' ')
      rescue
      end
    else
      puts pastel.cyan("Not authenticated to Kontena Cloud")
    end
  end
end

#display_login_info(only: nil) ⇒ Object



349
350
351
352
# File 'lib/kontena/cli/common.rb', line 349

def (only: nil)
    unless only == :account
   unless only == :master
end

#display_master_login_infoObject



329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
# File 'lib/kontena/cli/common.rb', line 329

def 
  server = config.current_master
  if server
    if server.token && server.token.access_token
      puts [
        pastel.green('Authenticated to Kontena Master'),
        pastel.yellow(server.name),
        pastel.green('at'),
        pastel.yellow(server.url),
        pastel.green('as'),
        pastel.yellow(server.token.username || server.username)
      ].join(' ')
    else
      puts pastel.cyan("Not authenticated to current master #{server.name}")
    end
  else
    puts pastel.cyan("Current master not selected")
  end
end

#error(message = "Error") ⇒ Object



260
261
262
263
# File 'lib/kontena/cli/common.rb', line 260

def error(message = "Error")
  prompt.error(message)
  exit(1)
end

#kontena_accountObject



205
206
207
# File 'lib/kontena/cli/common.rb', line 205

def 
  @kontena_account ||= config.
end

#loggerObject



23
24
25
# File 'lib/kontena/cli/common.rb', line 23

def logger
  Kontena.logger
end

#pastelObject



31
32
33
# File 'lib/kontena/cli/common.rb', line 31

def pastel
  Kontena.pastel
end

Print that doesn’t print if self.silent?



83
84
85
86
87
88
89
# File 'lib/kontena/cli/common.rb', line 83

def print(*msgs)
  if running_silent?
    logger.debug(msgs.join)
  else
    super(*msgs)
  end
end

#promptObject



27
28
29
# File 'lib/kontena/cli/common.rb', line 27

def prompt
  Kontena.prompt
end

#puts(*msgs) ⇒ Object

Puts that doesn’t puts if self.silent?



92
93
94
95
96
97
98
99
100
101
# File 'lib/kontena/cli/common.rb', line 92

def puts(*msgs)
  if running_silent?
    msgs.compact.each { |msg| logger.debug(msg) }
  elsif Thread.main['spinners'] && !Thread.main['spinners'].empty?
    Thread.main['spinner_msgs'] ||= []
    msgs.each { |msg| Thread.main['spinner_msgs'] << msg }
  else
    super(*msgs)
  end
end

#require_api_urlObject



172
173
174
# File 'lib/kontena/cli/common.rb', line 172

def require_api_url
  config.require_current_master.url
end

#require_tokenObject



176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/kontena/cli/common.rb', line 176

def require_token
  retried ||= false
  config.require_current_master_token
rescue Kontena::Cli::Config::TokenExpiredError
  if retried
    raise ArgumentError, "Current master access token has expired and refresh failed."
  else
    logger.debug "Access token expired, trying to refresh"
    retried = true
    client.refresh_token && retry
  end
end

#reset_clientObject



239
240
241
# File 'lib/kontena/cli/common.rb', line 239

def reset_client
  @client = nil
end

#reset_cloud_clientObject



220
221
222
# File 'lib/kontena/cli/common.rb', line 220

def reset_cloud_client
  @cloud_client = nil
end

#running_quiet?Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/kontena/cli/common.rb', line 68

def running_quiet?
  self.respond_to?(:quiet?) && self.quiet?
end

#running_silent?Boolean

Returns:

  • (Boolean)


60
61
62
# File 'lib/kontena/cli/common.rb', line 60

def running_silent?
  self.respond_to?(:silent?) && self.silent?
end

#running_verbose?Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/kontena/cli/common.rb', line 64

def running_verbose?
  self.respond_to?(:verbose?) && self.verbose?
end

#spin_if(obj_or_proc, message, &block) ⇒ Object

Run a spinner with a message for the block if a truthy value or a proc returns true.

Examples:

spin_if(proc { prompt.yes?("for real?") }, "Doing as requested") do
  # doing stuff
end
spin_if(a == 1, "Value of 'a' is 1, so let's do this") do
  # doing stuff
end

Parameters:

  • obj_or_proc (Object, Proc)

    something that responds to .call or is truthy/falsey

  • message (String)

    the message to display

Returns:

  • anything the block returns



142
143
144
145
146
147
148
149
# File 'lib/kontena/cli/common.rb', line 142

def spin_if(obj_or_proc, message, &block)
  if (obj_or_proc.respond_to?(:call) && obj_or_proc.call) || obj_or_proc
    spinner(message, &block)
  else
    logger.debug { message }
    yield
  end
end

#spinner(msg, &block) ⇒ Object



35
36
37
# File 'lib/kontena/cli/common.rb', line 35

def spinner(msg, &block)
   Kontena::Cli::Spinner.spin(msg, &block)
end

#sprint(*msgs) ⇒ Object

Print that prints even when self.silent?



78
79
80
# File 'lib/kontena/cli/common.rb', line 78

def sprint(*msgs)
  ::Kernel.print(*msgs)
end

#sputs(*msgs) ⇒ Object

Puts that puts even when self.silent?



73
74
75
# File 'lib/kontena/cli/common.rb', line 73

def sputs(*msgs)
  ::Kernel.puts(*msgs)
end

#stdin_input(message = nil, mode = :ask) ⇒ Object

Read from STDIN. If stdin is a console, use prompt to ask.

Parameters:

  • message (String) (defaults to: nil)
  • mode (Symbol) (defaults to: :ask)

    (prompt method: :ask, :multiline, etc)



50
51
52
53
54
55
56
57
58
# File 'lib/kontena/cli/common.rb', line 50

def stdin_input(message = nil, mode = :ask)
  if $stdin.tty?
    Array(prompt.send(mode, message)).join.chomp
  elsif !$stdin.eof?
    $stdin.read.chomp
  else
    exit_with_error 'Missing input'
  end
end

#use_refresh_token(server) ⇒ Object

Invalidate refresh_token

Parameters:



191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/kontena/cli/common.rb', line 191

def use_refresh_token(server)
  return unless server.token
  return unless server.token.refresh_token
  return if server.token.expired?
  client = Kontena::Client.new(server.url, server.token,
    ssl_cert_path: server.ssl_cert_path,
    ssl_subject_cn: server.ssl_subject_cn,
  )
  logger.debug "Trying to invalidate refresh token on #{server.name}"
  client.refresh_token
rescue => ex
  logger.debug "Refreshing failed: #{ex.class.name} : #{ex.message}"
end

#vfakespinner(msg, success: true) ⇒ Object

Like vspinner but without actually running any block



152
153
154
155
156
157
158
# File 'lib/kontena/cli/common.rb', line 152

def vfakespinner(msg, success: true)
  if !running_verbose?
    logger.debug { msg }
    return
  end
  puts " [#{ success ? pastel.green('done') : pastel.red('fail')}] #{msg}"
end

#vputs(msg = nil) ⇒ Object

Only output message if in verbose mode



104
105
106
107
108
109
110
# File 'lib/kontena/cli/common.rb', line 104

def vputs(msg = nil)
  if running_verbose?
    puts msg
  elsif debug? && msg
    logger.debug msg
  end
end

#vspinner(msg, &block) ⇒ Object

Only show spinner when in verbose mode



113
114
115
116
117
118
119
120
121
122
# File 'lib/kontena/cli/common.rb', line 113

def vspinner(msg, &block)
  return vfakespinner(msg) unless block_given?

  if running_verbose? && $stdout.tty?
    spinner(msg, &block)
  else
    logger.debug { msg }
    yield
  end
end

#warning(msg) ⇒ Object



160
161
162
163
# File 'lib/kontena/cli/common.rb', line 160

def warning(msg)
  warning = pastel.yellow('warn')
  $stderr.puts " [#{warning}] #{msg}"
end