Class: Kontena::Command

Inherits:
Clamp::Command
  • Object
show all
Defined in:
lib/kontena/command.rb

Direct Known Subclasses

Kontena::Cli::AppCommand, Kontena::Cli::Apps::BuildCommand, Kontena::Cli::Apps::ConfigCommand, Kontena::Cli::Apps::DeployCommand, Kontena::Cli::Apps::InitCommand, Kontena::Cli::Apps::ListCommand, Kontena::Cli::Apps::LogsCommand, Kontena::Cli::Apps::MonitorCommand, Kontena::Cli::Apps::RemoveCommand, Kontena::Cli::Apps::RestartCommand, Kontena::Cli::Apps::ScaleCommand, Kontena::Cli::Apps::ShowCommand, Kontena::Cli::Apps::StartCommand, Kontena::Cli::Apps::StopCommand, Kontena::Cli::Certificate::AuthorizeCommand, Kontena::Cli::Certificate::GetCommand, Kontena::Cli::Certificate::RegisterCommand, Kontena::Cli::CertificateCommand, 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, Kontena::Cli::CloudCommand, Kontena::Cli::ContainerCommand, Kontena::Cli::Containers::ExecCommand, Kontena::Cli::Containers::InspectCommand, Kontena::Cli::Containers::ListCommand, Kontena::Cli::Etcd::GetCommand, Kontena::Cli::Etcd::HealthCommand, Kontena::Cli::Etcd::ListCommand, Kontena::Cli::Etcd::MkdirCommand, Kontena::Cli::Etcd::RemoveCommand, Kontena::Cli::Etcd::SetCommand, Kontena::Cli::EtcdCommand, Kontena::Cli::ExternalRegistries::AddCommand, Kontena::Cli::ExternalRegistries::ListCommand, Kontena::Cli::ExternalRegistries::RemoveCommand, Kontena::Cli::ExternalRegistryCommand, Kontena::Cli::GridCommand, Kontena::Cli::Grids::AuditLogCommand, Kontena::Cli::Grids::CloudConfigCommand, Kontena::Cli::Grids::CreateCommand, Kontena::Cli::Grids::CurrentCommand, Kontena::Cli::Grids::EnvCommand, Kontena::Cli::Grids::EventsCommand, Kontena::Cli::Grids::HealthCommand, Kontena::Cli::Grids::ListCommand, Kontena::Cli::Grids::LogsCommand, Kontena::Cli::Grids::RemoveCommand, Kontena::Cli::Grids::ShowCommand, Kontena::Cli::Grids::TrustedSubnetCommand, Kontena::Cli::Grids::TrustedSubnets::AddCommand, Kontena::Cli::Grids::TrustedSubnets::ListCommand, Kontena::Cli::Grids::TrustedSubnets::RemoveCommand, Kontena::Cli::Grids::UpdateCommand, Kontena::Cli::Grids::UseCommand, Kontena::Cli::Grids::UserCommand, Kontena::Cli::Grids::Users::AddCommand, Kontena::Cli::Grids::Users::ListCommand, Kontena::Cli::Grids::Users::RemoveCommand, Kontena::Cli::LogoutCommand, Kontena::Cli::Master::AuditLogCommand, Kontena::Cli::Master::Config::ExportCommand, Kontena::Cli::Master::Config::GetCommand, Kontena::Cli::Master::Config::ImportCommand, Kontena::Cli::Master::Config::SetCommand, Kontena::Cli::Master::Config::UnsetCommand, Kontena::Cli::Master::ConfigCommand, Kontena::Cli::Master::CreateCommand, Kontena::Cli::Master::CurrentCommand, Kontena::Cli::Master::InitCloudCommand, Kontena::Cli::Master::JoinCommand, Kontena::Cli::Master::ListCommand, Kontena::Cli::Master::LoginCommand, Kontena::Cli::Master::LogoutCommand, Kontena::Cli::Master::RemoveCommand, Kontena::Cli::Master::SshCommand, Kontena::Cli::Master::Token::CreateCommand, Kontena::Cli::Master::Token::CurrentCommand, Kontena::Cli::Master::Token::ListCommand, Kontena::Cli::Master::Token::RemoveCommand, Kontena::Cli::Master::Token::ShowCommand, Kontena::Cli::Master::TokenCommand, Kontena::Cli::Master::UseCommand, Kontena::Cli::Master::User::InviteCommand, Kontena::Cli::Master::User::ListCommand, Kontena::Cli::Master::User::RemoveCommand, Kontena::Cli::Master::User::Role::AddCommand, Kontena::Cli::Master::User::Role::RemoveCommand, Kontena::Cli::Master::User::RoleCommand, Kontena::Cli::Master::UserCommand, Kontena::Cli::Master::UsersCommand, Kontena::Cli::MasterCommand, Kontena::Cli::NodeCommand, Kontena::Cli::Nodes::HealthCommand, Kontena::Cli::Nodes::LabelCommand, Kontena::Cli::Nodes::Labels::AddCommand, Kontena::Cli::Nodes::Labels::ListCommand, Kontena::Cli::Nodes::Labels::RemoveCommand, Kontena::Cli::Nodes::ListCommand, Kontena::Cli::Nodes::RemoveCommand, Kontena::Cli::Nodes::ShowCommand, Kontena::Cli::Nodes::SshCommand, Kontena::Cli::Nodes::UpdateCommand, Kontena::Cli::PluginCommand, Kontena::Cli::Plugins::InstallCommand, Kontena::Cli::Plugins::ListCommand, Kontena::Cli::Plugins::SearchCommand, Kontena::Cli::Plugins::UninstallCommand, Kontena::Cli::Registry::CreateCommand, Kontena::Cli::Registry::RemoveCommand, Kontena::Cli::RegistryCommand, Kontena::Cli::ServiceCommand, Kontena::Cli::Services::ContainersCommand, Kontena::Cli::Services::CreateCommand, Kontena::Cli::Services::DeployCommand, Kontena::Cli::Services::EnvCommand, Kontena::Cli::Services::Envs::AddCommand, Kontena::Cli::Services::Envs::ListCommand, Kontena::Cli::Services::Envs::RemoveCommand, Kontena::Cli::Services::EventsCommand, Kontena::Cli::Services::ExecCommand, Kontena::Cli::Services::LinkCommand, Kontena::Cli::Services::ListCommand, Kontena::Cli::Services::LogsCommand, Kontena::Cli::Services::MonitorCommand, Kontena::Cli::Services::RemoveCommand, Kontena::Cli::Services::RestartCommand, Kontena::Cli::Services::ScaleCommand, Kontena::Cli::Services::SecretCommand, Kontena::Cli::Services::Secrets::LinkCommand, Kontena::Cli::Services::Secrets::UnlinkCommand, Kontena::Cli::Services::ShowCommand, Kontena::Cli::Services::StartCommand, Kontena::Cli::Services::StatsCommand, Kontena::Cli::Services::StopCommand, Kontena::Cli::Services::UnlinkCommand, Kontena::Cli::Services::UpdateCommand, Kontena::Cli::StackCommand, Kontena::Cli::Stacks::BuildCommand, Kontena::Cli::Stacks::DeployCommand, Kontena::Cli::Stacks::EventsCommand, Kontena::Cli::Stacks::InstallCommand, Kontena::Cli::Stacks::ListCommand, Kontena::Cli::Stacks::LogsCommand, Kontena::Cli::Stacks::MonitorCommand, Kontena::Cli::Stacks::Registry::PullCommand, Kontena::Cli::Stacks::Registry::PushCommand, Kontena::Cli::Stacks::Registry::RemoveCommand, Kontena::Cli::Stacks::Registry::SearchCommand, Kontena::Cli::Stacks::Registry::ShowCommand, Kontena::Cli::Stacks::RegistryCommand, Kontena::Cli::Stacks::RemoveCommand, Kontena::Cli::Stacks::RestartCommand, Kontena::Cli::Stacks::ShowCommand, Kontena::Cli::Stacks::StopCommand, Kontena::Cli::Stacks::UpgradeCommand, Kontena::Cli::Stacks::ValidateCommand, Kontena::Cli::Vault::ExportCommand, Kontena::Cli::Vault::ImportCommand, Kontena::Cli::Vault::ListCommand, Kontena::Cli::Vault::ReadCommand, Kontena::Cli::Vault::RemoveCommand, Kontena::Cli::Vault::UpdateCommand, Kontena::Cli::Vault::WriteCommand, Kontena::Cli::VaultCommand, Kontena::Cli::VersionCommand, Kontena::Cli::VolumeCommand, Kontena::Cli::Volumes::CreateCommand, Kontena::Cli::Volumes::ListCommand, Kontena::Cli::Volumes::RemoveCommand, Kontena::Cli::Volumes::ShowCommand, Kontena::Cli::Vpn::ConfigCommand, Kontena::Cli::Vpn::CreateCommand, Kontena::Cli::Vpn::RemoveCommand, Kontena::Cli::VpnCommand, Kontena::Cli::WhoamiCommand, MainCommand

Defined Under Namespace

Modules: Finalizer

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#arguments ⇒ Object

Returns the value of attribute arguments.



15
16
17
# File 'lib/kontena/command.rb', line 15

def arguments
  @arguments
end

#exit_code ⇒ Object (readonly)

Returns the value of attribute exit_code.



17
18
19
# File 'lib/kontena/command.rb', line 17

def exit_code
  @exit_code
end

#result ⇒ Object (readonly)

Returns the value of attribute result.



16
17
18
# File 'lib/kontena/command.rb', line 16

def result
  @result
end

Class Method Details

Overwrite Clamp's banner command. Calling banner multiple times will now add lines to the banner message instead of overwriting the whole message. This is useful if callbacks add banner messages.

Parameters:



103
104
105
# File 'lib/kontena/command.rb', line 103

def self.banner(msg, extra_feed = true)
  self.description = [self.description, extra_feed ? "\n#{msg}" : msg].compact.join("\n")
end

.callback_matcher(cmd_class = nil, cmd_type = nil) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/kontena/command.rb', line 79

def self.callback_matcher(cmd_class = nil, cmd_type = nil)
  unless cmd_class
    if @command_class.nil?
      return nil
    else
      return [@command_class, @command_type]
    end
  end
  @command_class = cmd_class.to_sym
  @command_type = cmd_type.to_sym
  [@command_class, @command_type]
end

.inherited(where) ⇒ Object



75
76
77
# File 'lib/kontena/command.rb', line 75

def self.inherited(where)
  where.extend Finalizer
end

.load_subcommand(path) ⇒ Object



71
72
73
# File 'lib/kontena/command.rb', line 71

def self.load_subcommand(path)
  Kontena::Cli::SubcommandLoader.new(path)
end

.requires_current_account_token ⇒ Object



121
122
123
124
125
126
# File 'lib/kontena/command.rb', line 121

def self.
  unless Kontena::Cli::Config. && Kontena::Cli::Config..token && Kontena::Cli::Config..token.access_token
    banner "#{Kontena.pastel.green("Requires account authentication")}: This command requires that you have authenticated to Kontena Cloud using 'kontena cloud auth'"
  end
   = true
end

.requires_current_account_token? ⇒ Boolean

Returns:

  • (Boolean)


145
146
147
# File 'lib/kontena/command.rb', line 145

def self.
   ||= false
end

.requires_current_grid ⇒ Object



114
115
116
117
118
119
# File 'lib/kontena/command.rb', line 114

def self.requires_current_grid
  unless Kontena::Cli::Config.current_grid
    banner "#{Kontena.pastel.green("Requires current grid")}: This command requires that you have selected a grid as the current grid using 'kontena grid use' or by setting KONTENA_GRID environment variable."
  end
  @requires_current_grid = true
end

.requires_current_grid? ⇒ Boolean

Returns:

  • (Boolean)


137
138
139
# File 'lib/kontena/command.rb', line 137

def self.requires_current_grid?
  @requires_current_grid ||= false
end

.requires_current_master ⇒ Object



107
108
109
110
111
112
# File 'lib/kontena/command.rb', line 107

def self.requires_current_master
  unless Kontena::Cli::Config.current_master
    banner "#{Kontena.pastel.green("Requires current master")}: This command requires that you have selected a current master using 'kontena master login' or 'kontena master use'. You can also use the environment variable KONTENA_URL to specify the master address or KONTENA_MASTER=master_name to override the current_master setting."
  end
  @requires_current_master = true
end

.requires_current_master? ⇒ Boolean

Returns:

  • (Boolean)


129
130
131
# File 'lib/kontena/command.rb', line 129

def self.requires_current_master?
  @requires_current_master ||= false
end

.requires_current_master_token ⇒ Object



154
155
156
# File 'lib/kontena/command.rb', line 154

def self.requires_current_master_token
  @requires_current_master_token = true
end

.requires_current_master_token? ⇒ Boolean

Returns:

  • (Boolean)


158
159
160
# File 'lib/kontena/command.rb', line 158

def self.requires_current_master_token?
  @requires_current_master_token ||= false
end

Instance Method Details

#help_requested? ⇒ Boolean

Returns:

  • (Boolean)


179
180
181
182
183
# File 'lib/kontena/command.rb', line 179

def help_requested?
  return true if @arguments.include?('--help')
  return true if @arguments.include?('-h')
  false
end

#run(arguments) ⇒ Object



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/kontena/command.rb', line 185

def run(arguments)
  Kontena.logger.debug { "Running #{self.class.name} with #{arguments.inspect} -- callback matcher = '#{self.class.callback_matcher.nil? ? "nil" : self.class.callback_matcher.map(&:to_s).join(' ')}'" }
  @arguments = arguments

  run_callbacks :before_parse unless help_requested?

  parse @arguments

  unless help_requested?
    verify_current_master
    verify_current_master_token
    verify_current_grid
    run_callbacks :before
  end

  begin
    @result = execute
    @exit_code = @result.kind_of?(FalseClass) ? 1 : 0
  rescue SystemExit => exc
    @result = exc.status == 0
    @exit_code = exc.status
  end
  run_callbacks :after unless help_requested?
  exit(@exit_code) if @exit_code.to_i > 0
  @result
rescue Excon::Errors::SocketError => ex
  if ex.message.include?('Unable to verify certificate')
    $stderr.puts " [#{Kontena.pastel.red('error')}] The server uses a certificate signed by an unknown authority."
    $stderr.puts "         You can trust this server by copying server CA pem file to: #{Kontena.pastel.yellow("~/.kontena/certs/<hostname>.pem")}"
    $stderr.puts "         If kontena cannot find your system ca bundle, you can set #{Kontena.pastel.yellow('SSL_CERT_DIR=/etc/ssl/certs')} env variable to load them from another location."
    $stderr.puts "         Protip: you can bypass the certificate check by setting #{Kontena.pastel.yellow('SSL_IGNORE_ERRORS=true')} env variable, but any data you send to the server could be intercepted by others."
    abort
  else
    abort(ex.message)
  end
rescue Kontena::Errors::StandardError => ex
  raise ex if ENV['DEBUG']
  Kontena.logger.error(ex)
  abort(" [#{Kontena.pastel.red('error')}] #{ex.status} : #{ex.message}")
rescue Errno::EPIPE
  # If user is piping the command outputs to some other command that might exit before CLI has outputted everything
  abort
rescue Clamp::HelpWanted, Clamp::UsageError
  raise
rescue => ex
  raise ex if ENV['DEBUG']
  Kontena.logger.error(ex)
  abort(" [#{Kontena.pastel.red('error')}] #{ex.class.name} : #{ex.message}\n         See #{Kontena.log_target} or run the command again with environment DEBUG=true set to see the full exception")
end

#run_callbacks(state) ⇒ Object



92
93
94
95
96
# File 'lib/kontena/command.rb', line 92

def run_callbacks(state)
  if self.class.respond_to?(:callback_matcher) && !self.class.callback_matcher.nil? && !self.class.callback_matcher.compact.empty?
    Kontena::Callback.run_callbacks(self.class.callback_matcher, state, self)
  end
end

#verify_current_account_token ⇒ Object



149
150
151
152
# File 'lib/kontena/command.rb', line 149

def 
  retried ||= false
  Kontena::Cli::Config.instance. if self.class.
end

#verify_current_grid ⇒ Object



141
142
143
# File 'lib/kontena/command.rb', line 141

def verify_current_grid
  Kontena::Cli::Config.instance.require_current_grid if self.class.requires_current_grid?
end

#verify_current_master ⇒ Object



133
134
135
# File 'lib/kontena/command.rb', line 133

def verify_current_master
  Kontena::Cli::Config.instance.require_current_master if self.class.requires_current_master?
end

#verify_current_master_token ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/kontena/command.rb', line 162

def verify_current_master_token
  return nil unless self.class.requires_current_master_token?
  retried ||= false
  Kontena::Cli::Config.instance.require_current_master_token
rescue Kontena::Cli::Config::TokenExpiredError
  success = Kontena::Client.new(
    Kontena::Cli::Config.instance.current_master.url,
    Kontena::Cli::Config.instance.current_master.token
  ).refresh_token
  if success && !retried
    retried = true
    retry
  else
    raise Kontena::Cli::Config::TokenExpiredError, "The access token has expired and refresh failed. Try authenticating again, use: kontena master login"
  end
end