central-cli 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.dockerignore +3 -0
- data/.gitignore +15 -0
- data/.rspec +6 -0
- data/.rubocop.yml +5 -0
- data/Dockerfile +15 -0
- data/Gemfile +10 -0
- data/LICENSE +191 -0
- data/README.md +39 -0
- data/Rakefile +9 -0
- data/VERSION +1 -0
- data/bin/cm +85 -0
- data/central-cli.gemspec +35 -0
- data/central-docker.sh +6 -0
- data/lib/central/cli/app_command.rb +29 -0
- data/lib/central/cli/apps/build_command.rb +24 -0
- data/lib/central/cli/apps/central_yml_generator.rb +88 -0
- data/lib/central/cli/apps/common.rb +166 -0
- data/lib/central/cli/apps/deploy_command.rb +191 -0
- data/lib/central/cli/apps/docker_compose_generator.rb +48 -0
- data/lib/central/cli/apps/docker_helper.rb +85 -0
- data/lib/central/cli/apps/dockerfile_generator.rb +15 -0
- data/lib/central/cli/apps/init_command.rb +91 -0
- data/lib/central/cli/apps/list_command.rb +68 -0
- data/lib/central/cli/apps/logs_command.rb +76 -0
- data/lib/central/cli/apps/monitor_command.rb +93 -0
- data/lib/central/cli/apps/remove_command.rb +80 -0
- data/lib/central/cli/apps/restart_command.rb +38 -0
- data/lib/central/cli/apps/scale_command.rb +31 -0
- data/lib/central/cli/apps/show_command.rb +23 -0
- data/lib/central/cli/apps/start_command.rb +39 -0
- data/lib/central/cli/apps/stop_command.rb +39 -0
- data/lib/central/cli/auth/aws/create_command.rb +34 -0
- data/lib/central/cli/auth/aws_command.rb +7 -0
- data/lib/central/cli/auth/list_command.rb +28 -0
- data/lib/central/cli/auth_command.rb +9 -0
- data/lib/central/cli/bytes_helper.rb +38 -0
- data/lib/central/cli/common.rb +148 -0
- data/lib/central/cli/container_command.rb +10 -0
- data/lib/central/cli/containers/exec_command.rb +21 -0
- data/lib/central/cli/containers/inspect_command.rb +22 -0
- data/lib/central/cli/etcd/common.rb +7 -0
- data/lib/central/cli/etcd/get_command.rb +26 -0
- data/lib/central/cli/etcd/list_command.rb +31 -0
- data/lib/central/cli/etcd/mkdir_command.rb +21 -0
- data/lib/central/cli/etcd/remove_command.rb +25 -0
- data/lib/central/cli/etcd/set_command.rb +22 -0
- data/lib/central/cli/etcd_command.rb +16 -0
- data/lib/central/cli/external_registries/add_command.rb +21 -0
- data/lib/central/cli/external_registries/delete_command.rb +15 -0
- data/lib/central/cli/external_registries/list_command.rb +27 -0
- data/lib/central/cli/external_registries/remove_command.rb +13 -0
- data/lib/central/cli/external_registry_command.rb +14 -0
- data/lib/central/cli/login_command.rb +121 -0
- data/lib/central/cli/logout_command.rb +7 -0
- data/lib/central/cli/master/aws/create_command.rb +41 -0
- data/lib/central/cli/master/aws_command.rb +7 -0
- data/lib/central/cli/master/azure/create_command.rb +39 -0
- data/lib/central/cli/master/azure_command.rb +11 -0
- data/lib/central/cli/master/digital_ocean/create_command.rb +35 -0
- data/lib/central/cli/master/digital_ocean_command.rb +11 -0
- data/lib/central/cli/master/list_command.rb +28 -0
- data/lib/central/cli/master/use_command.rb +34 -0
- data/lib/central/cli/master/users/add_role_command.rb +26 -0
- data/lib/central/cli/master/users/invite_command.rb +24 -0
- data/lib/central/cli/master/users/list_command.rb +18 -0
- data/lib/central/cli/master/users/remove_command.rb +22 -0
- data/lib/central/cli/master/users/remove_role_command.rb +25 -0
- data/lib/central/cli/master/users_command.rb +15 -0
- data/lib/central/cli/master/vagrant/create_command.rb +25 -0
- data/lib/central/cli/master/vagrant/restart_command.rb +20 -0
- data/lib/central/cli/master/vagrant/ssh_command.rb +15 -0
- data/lib/central/cli/master/vagrant/start_command.rb +20 -0
- data/lib/central/cli/master/vagrant/stop_command.rb +20 -0
- data/lib/central/cli/master/vagrant/terminate_command.rb +13 -0
- data/lib/central/cli/master/vagrant_command.rb +21 -0
- data/lib/central/cli/master_command.rb +19 -0
- data/lib/central/cli/node_command.rb +30 -0
- data/lib/central/cli/nodes/add_label_command.rb +19 -0
- data/lib/central/cli/nodes/aws/create_command.rb +40 -0
- data/lib/central/cli/nodes/aws/restart_command.rb +29 -0
- data/lib/central/cli/nodes/aws/terminate_command.rb +21 -0
- data/lib/central/cli/nodes/aws_command.rb +14 -0
- data/lib/central/cli/nodes/azure/create_command.rb +40 -0
- data/lib/central/cli/nodes/azure/restart_command.rb +31 -0
- data/lib/central/cli/nodes/azure/terminate_command.rb +21 -0
- data/lib/central/cli/nodes/azure_command.rb +14 -0
- data/lib/central/cli/nodes/digital_ocean/create_command.rb +32 -0
- data/lib/central/cli/nodes/digital_ocean/restart_command.rb +27 -0
- data/lib/central/cli/nodes/digital_ocean/terminate_command.rb +19 -0
- data/lib/central/cli/nodes/digital_ocean_command.rb +14 -0
- data/lib/central/cli/nodes/label_command.rb +12 -0
- data/lib/central/cli/nodes/labels/add_command.rb +19 -0
- data/lib/central/cli/nodes/labels/remove_command.rb +23 -0
- data/lib/central/cli/nodes/list_command.rb +62 -0
- data/lib/central/cli/nodes/remove_command.rb +16 -0
- data/lib/central/cli/nodes/remove_label_command.rb +23 -0
- data/lib/central/cli/nodes/show_command.rb +49 -0
- data/lib/central/cli/nodes/ssh_command.rb +31 -0
- data/lib/central/cli/nodes/update_command.rb +20 -0
- data/lib/central/cli/nodes/vagrant/create_command.rb +27 -0
- data/lib/central/cli/nodes/vagrant/restart_command.rb +26 -0
- data/lib/central/cli/nodes/vagrant/ssh_command.rb +21 -0
- data/lib/central/cli/nodes/vagrant/start_command.rb +26 -0
- data/lib/central/cli/nodes/vagrant/stop_command.rb +26 -0
- data/lib/central/cli/nodes/vagrant/terminate_command.rb +17 -0
- data/lib/central/cli/nodes/vagrant_command.rb +20 -0
- data/lib/central/cli/register_command.rb +21 -0
- data/lib/central/cli/registry/create_command.rb +144 -0
- data/lib/central/cli/registry/delete_command.rb +22 -0
- data/lib/central/cli/registry/remove_command.rb +19 -0
- data/lib/central/cli/registry_command.rb +11 -0
- data/lib/central/cli/service_command.rb +49 -0
- data/lib/central/cli/services/add_env_command.rb +19 -0
- data/lib/central/cli/services/add_secret_command.rb +24 -0
- data/lib/central/cli/services/container_command.rb +8 -0
- data/lib/central/cli/services/containers_command.rb +32 -0
- data/lib/central/cli/services/create_command.rb +90 -0
- data/lib/central/cli/services/delete_command.rb +19 -0
- data/lib/central/cli/services/deploy_command.rb +21 -0
- data/lib/central/cli/services/env_command.rb +11 -0
- data/lib/central/cli/services/envs/add_command.rb +19 -0
- data/lib/central/cli/services/envs/list_command.rb +20 -0
- data/lib/central/cli/services/envs/remove_command.rb +18 -0
- data/lib/central/cli/services/envs_command.rb +20 -0
- data/lib/central/cli/services/link_command.rb +26 -0
- data/lib/central/cli/services/list_command.rb +42 -0
- data/lib/central/cli/services/logs_command.rb +57 -0
- data/lib/central/cli/services/monitor_command.rb +58 -0
- data/lib/central/cli/services/remove_command.rb +17 -0
- data/lib/central/cli/services/remove_env_command.rb +18 -0
- data/lib/central/cli/services/remove_secret_command.rb +28 -0
- data/lib/central/cli/services/restart_command.rb +17 -0
- data/lib/central/cli/services/scale_command.rb +17 -0
- data/lib/central/cli/services/secret_command.rb +9 -0
- data/lib/central/cli/services/secrets/link_command.rb +24 -0
- data/lib/central/cli/services/secrets/unlink_command.rb +28 -0
- data/lib/central/cli/services/services_helper.rb +360 -0
- data/lib/central/cli/services/show_command.rb +18 -0
- data/lib/central/cli/services/start_command.rb +17 -0
- data/lib/central/cli/services/stats_command.rb +74 -0
- data/lib/central/cli/services/stop_command.rb +17 -0
- data/lib/central/cli/services/unlink_command.rb +25 -0
- data/lib/central/cli/services/update_command.rb +78 -0
- data/lib/central/cli/stack_command.rb +32 -0
- data/lib/central/cli/stack_options.rb +11 -0
- data/lib/central/cli/stacks/add_user_command.rb +18 -0
- data/lib/central/cli/stacks/audit_log_command.rb +21 -0
- data/lib/central/cli/stacks/cloud_config_command.rb +41 -0
- data/lib/central/cli/stacks/common.rb +95 -0
- data/lib/central/cli/stacks/create_command.rb +26 -0
- data/lib/central/cli/stacks/current_command.rb +25 -0
- data/lib/central/cli/stacks/env_command.rb +32 -0
- data/lib/central/cli/stacks/list_command.rb +35 -0
- data/lib/central/cli/stacks/list_users_command.rb +26 -0
- data/lib/central/cli/stacks/logs_command.rb +81 -0
- data/lib/central/cli/stacks/remove_command.rb +26 -0
- data/lib/central/cli/stacks/remove_user_command.rb +17 -0
- data/lib/central/cli/stacks/show_command.rb +19 -0
- data/lib/central/cli/stacks/trusted_subnets/add_command.rb +16 -0
- data/lib/central/cli/stacks/trusted_subnets/list_command.rb +17 -0
- data/lib/central/cli/stacks/trusted_subnets/remove_command.rb +20 -0
- data/lib/central/cli/stacks/update_command.rb +27 -0
- data/lib/central/cli/stacks/use_command.rb +21 -0
- data/lib/central/cli/stacks/user_command.rb +11 -0
- data/lib/central/cli/stacks/users/add_command.rb +18 -0
- data/lib/central/cli/stacks/users/list_command.rb +18 -0
- data/lib/central/cli/stacks/users/remove_command.rb +17 -0
- data/lib/central/cli/user/forgot_password_command.rb +16 -0
- data/lib/central/cli/user/reset_password_command.rb +21 -0
- data/lib/central/cli/user/verify_command.rb +22 -0
- data/lib/central/cli/user_command.rb +12 -0
- data/lib/central/cli/vault/list_command.rb +25 -0
- data/lib/central/cli/vault/read_command.rb +17 -0
- data/lib/central/cli/vault/remove_command.rb +14 -0
- data/lib/central/cli/vault/update_command.rb +18 -0
- data/lib/central/cli/vault/write_command.rb +22 -0
- data/lib/central/cli/vault_command.rb +16 -0
- data/lib/central/cli/version.rb +5 -0
- data/lib/central/cli/version_command.rb +22 -0
- data/lib/central/cli/vpn/config_command.rb +25 -0
- data/lib/central/cli/vpn/create_command.rb +71 -0
- data/lib/central/cli/vpn/delete_command.rb +21 -0
- data/lib/central/cli/vpn/remove_command.rb +19 -0
- data/lib/central/cli/vpn_command.rb +13 -0
- data/lib/central/cli/whoami_command.rb +20 -0
- data/lib/central/client.rb +208 -0
- data/lib/central/errors.rb +10 -0
- data/lib/central/machine/aws.rb +14 -0
- data/lib/central/machine/aws/auth_provisioner.rb +161 -0
- data/lib/central/machine/aws/cloudinit.yml +71 -0
- data/lib/central/machine/aws/cloudinit_master.yml +118 -0
- data/lib/central/machine/aws/cloudinit_oauth.yml +76 -0
- data/lib/central/machine/aws/common.rb +31 -0
- data/lib/central/machine/aws/master_provisioner.rb +171 -0
- data/lib/central/machine/aws/node_destroyer.rb +46 -0
- data/lib/central/machine/aws/node_provisioner.rb +214 -0
- data/lib/central/machine/azure.rb +13 -0
- data/lib/central/machine/azure/cloudinit.yml +64 -0
- data/lib/central/machine/azure/cloudinit_master.yml +106 -0
- data/lib/central/machine/azure/logger.rb +26 -0
- data/lib/central/machine/azure/master_provisioner.rb +125 -0
- data/lib/central/machine/azure/node_destroyer.rb +52 -0
- data/lib/central/machine/azure/node_provisioner.rb +126 -0
- data/lib/central/machine/cert_helper.rb +39 -0
- data/lib/central/machine/cloud_config/cloudinit.yml +70 -0
- data/lib/central/machine/cloud_config/node_generator.rb +27 -0
- data/lib/central/machine/common.rb +16 -0
- data/lib/central/machine/digital_ocean.rb +13 -0
- data/lib/central/machine/digital_ocean/cloudinit.yml +64 -0
- data/lib/central/machine/digital_ocean/cloudinit_master.yml +118 -0
- data/lib/central/machine/digital_ocean/master_provisioner.rb +99 -0
- data/lib/central/machine/digital_ocean/node_destroyer.rb +40 -0
- data/lib/central/machine/digital_ocean/node_provisioner.rb +81 -0
- data/lib/central/machine/random_name.rb +39 -0
- data/lib/central/machine/vagrant.rb +12 -0
- data/lib/central/machine/vagrant/Vagrantfile.master.rb.erb +116 -0
- data/lib/central/machine/vagrant/Vagrantfile.node.rb.erb +32 -0
- data/lib/central/machine/vagrant/cloudinit.yml +73 -0
- data/lib/central/machine/vagrant/master_destroyer.rb +34 -0
- data/lib/central/machine/vagrant/master_provisioner.rb +79 -0
- data/lib/central/machine/vagrant/node_destroyer.rb +38 -0
- data/lib/central/machine/vagrant/node_provisioner.rb +68 -0
- data/lib/central/scripts/completer +157 -0
- data/lib/central/scripts/init +11 -0
- data/spec/central/cli/app/common_spec.rb +150 -0
- data/spec/central/cli/app/deploy_command_spec.rb +598 -0
- data/spec/central/cli/app/docker_helper_spec.rb +102 -0
- data/spec/central/cli/app/scale_spec.rb +49 -0
- data/spec/central/cli/common_spec.rb +117 -0
- data/spec/central/cli/login_command_spec.rb +31 -0
- data/spec/central/cli/master/current_command_spec.rb +55 -0
- data/spec/central/cli/master/use_command_spec.rb +37 -0
- data/spec/central/cli/master/users/invite_command_spec.rb +34 -0
- data/spec/central/cli/master/users/remove_command_spec.rb +26 -0
- data/spec/central/cli/master/users/roles/add_command_spec.rb +34 -0
- data/spec/central/cli/master/users/roles/remove_command_spec.rb +34 -0
- data/spec/central/cli/register_command_spec.rb +56 -0
- data/spec/central/cli/services/containers_command_spec.rb +40 -0
- data/spec/central/cli/services/link_command_spec.rb +38 -0
- data/spec/central/cli/services/restart_command_spec.rb +27 -0
- data/spec/central/cli/services/secrets/link_command_spec.rb +59 -0
- data/spec/central/cli/services/secrets/unlink_command_spec.rb +48 -0
- data/spec/central/cli/services/services_helper_spec.rb +170 -0
- data/spec/central/cli/services/unlink_command_spec.rb +38 -0
- data/spec/central/cli/stacks/trusted_subnets/add_command_spec.rb +37 -0
- data/spec/central/cli/stacks/trusted_subnets/list_command_spec.rb +30 -0
- data/spec/central/cli/stacks/trusted_subnets/remove_command_spec.rb +37 -0
- data/spec/central/cli/version_command_spec.rb +16 -0
- data/spec/fixtures/central.yml +17 -0
- data/spec/fixtures/docker-compose.yml +8 -0
- data/spec/fixtures/mysql.yml +3 -0
- data/spec/fixtures/wordpress-scaled.yml +3 -0
- data/spec/fixtures/wordpress.yml +2 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/support/client_helpers.rb +30 -0
- data/spec/support/fixtures_helpers.rb +7 -0
- data/tasks/rspec.rake +5 -0
- metadata +463 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative '../common'
|
2
|
+
|
3
|
+
module Central::Cli::Stacks::Users
|
4
|
+
class RemoveCommand < Clamp::Command
|
5
|
+
include Central::Cli::Common
|
6
|
+
include Central::Cli::StackOptions
|
7
|
+
include Central::Cli::Stacks::Common
|
8
|
+
|
9
|
+
parameter 'EMAIL', 'Email address'
|
10
|
+
|
11
|
+
def execute
|
12
|
+
require_api_url
|
13
|
+
token = require_token
|
14
|
+
result = client(token).delete("stacks/#{current_stack}/users/#{email}")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Central::Cli::User
|
2
|
+
class ForgotPasswordCommand < Clamp::Command
|
3
|
+
include Central::Cli::Common
|
4
|
+
|
5
|
+
parameter 'EMAIL', 'Email address'
|
6
|
+
|
7
|
+
option '--auth-provider-url', 'URL', 'Auth provider URL', default: 'https://auth.bluebeluga.io/'
|
8
|
+
|
9
|
+
def execute
|
10
|
+
params = { email: email }
|
11
|
+
auth_client = Central::Client.new(auth_provider_url)
|
12
|
+
auth_client.post('user/password_reset', params)
|
13
|
+
puts 'Email with password reset instructions is sent to your email address. Please follow the instructions to change your password.'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Central::Cli::User
|
2
|
+
class ResetPasswordCommand < Clamp::Command
|
3
|
+
include Central::Cli::Common
|
4
|
+
|
5
|
+
parameter 'TOKEN', 'Password reset token'
|
6
|
+
|
7
|
+
option '--auth-provider-url', 'URL', 'Auth provider URL', default: 'https://auth.bluebeluga.io/'
|
8
|
+
|
9
|
+
def execute
|
10
|
+
require 'highline/import'
|
11
|
+
|
12
|
+
password = ask('Password: ') { |q| q.echo = '*' }
|
13
|
+
password2 = ask('Password again: ') { |q| q.echo = '*' }
|
14
|
+
abort("Passwords don't match") if password != password2
|
15
|
+
params = { token: token, password: password }
|
16
|
+
auth_client = Central::Client.new(auth_provider_url)
|
17
|
+
auth_client.put('user/password_reset', params)
|
18
|
+
puts 'Password is now changed. To login with the new password, please run: cm login'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Central::Cli::User
|
2
|
+
class VerifyCommand < Clamp::Command
|
3
|
+
include Central::Cli::Common
|
4
|
+
|
5
|
+
parameter 'TOKEN', 'Central verify token'
|
6
|
+
|
7
|
+
option '--auth-provider-url', 'URL', 'Auth provider URL', default: 'https://auth.bluebeluga.io/'
|
8
|
+
|
9
|
+
def execute
|
10
|
+
require_api_url
|
11
|
+
|
12
|
+
params = { token: token }
|
13
|
+
begin
|
14
|
+
auth_client = Central::Client.new(auth_provider_url)
|
15
|
+
auth_client.post('user/email_confirm', params)
|
16
|
+
puts 'Account verified'.colorize(:green)
|
17
|
+
rescue Central::Errors::StandardError
|
18
|
+
abort 'Invalid verify token'.colorize(:red)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require_relative 'user/verify_command'
|
2
|
+
require_relative 'user/forgot_password_command'
|
3
|
+
require_relative 'user/reset_password_command'
|
4
|
+
|
5
|
+
class Central::Cli::UserCommand < Clamp::Command
|
6
|
+
subcommand 'verify', 'Verify user account', Central::Cli::User::VerifyCommand
|
7
|
+
subcommand 'forgot-password', 'Request password reset for Central account', Central::Cli::User::ForgotPasswordCommand
|
8
|
+
subcommand 'reset-password', 'Reset Central account password', Central::Cli::User::ResetPasswordCommand
|
9
|
+
|
10
|
+
def execute
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'tty'
|
2
|
+
|
3
|
+
module Central::Cli::Vault
|
4
|
+
class ListCommand < Clamp::Command
|
5
|
+
include Central::Cli::Common
|
6
|
+
include Central::Cli::StackOptions
|
7
|
+
|
8
|
+
def execute
|
9
|
+
require_api_url
|
10
|
+
token = require_token
|
11
|
+
result = client(token).get("stacks/#{current_stack}/secrets")
|
12
|
+
header = ['Name', 'Created at']
|
13
|
+
rows = []
|
14
|
+
result['secrets'].sort_by { |s| s['name'] }.each do |secret|
|
15
|
+
rows << [secret['name'], secret['created_at']]
|
16
|
+
end
|
17
|
+
|
18
|
+
ttable = TTY::Table.new header: header, rows: Array.new(rows)
|
19
|
+
renderer = TTY::Table::Renderer::Unicode.new(ttable)
|
20
|
+
renderer.border.style = :cyan
|
21
|
+
renderer.padding = [0, 1, 0, 1]
|
22
|
+
puts renderer.render
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Central::Cli::Vault
|
2
|
+
class ReadCommand < Clamp::Command
|
3
|
+
include Central::Cli::Common
|
4
|
+
include Central::Cli::StackOptions
|
5
|
+
|
6
|
+
parameter 'NAME', 'Secret name'
|
7
|
+
|
8
|
+
def execute
|
9
|
+
require_api_url
|
10
|
+
token = require_token
|
11
|
+
result = client(token).get("secrets/#{current_stack}/#{name}")
|
12
|
+
puts "#{result['name']}:"
|
13
|
+
puts " created_at: #{result['created_at']}"
|
14
|
+
puts " value: #{result['value']}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Central::Cli::Vault
|
2
|
+
class RemoveCommand < Clamp::Command
|
3
|
+
include Central::Cli::Common
|
4
|
+
include Central::Cli::StackOptions
|
5
|
+
|
6
|
+
parameter 'NAME', 'Secret name'
|
7
|
+
|
8
|
+
def execute
|
9
|
+
require_api_url
|
10
|
+
token = require_token
|
11
|
+
client(token).delete("secrets/#{current_stack}/#{name}")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Central::Cli::Vault
|
2
|
+
class UpdateCommand < Clamp::Command
|
3
|
+
include Central::Cli::Common
|
4
|
+
|
5
|
+
parameter 'NAME', 'Secret name'
|
6
|
+
parameter '[VALUE]', 'Secret value'
|
7
|
+
|
8
|
+
def execute
|
9
|
+
require_api_url
|
10
|
+
token = require_token
|
11
|
+
secret = value
|
12
|
+
secret = STDIN.read if secret.to_s == ''
|
13
|
+
abort('No value provided') if secret.to_s == ''
|
14
|
+
data = { value: secret }
|
15
|
+
client(token).put("stacks/#{current_stack}/secrets/#{name}", data)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Central::Cli::Vault
|
2
|
+
class WriteCommand < Clamp::Command
|
3
|
+
include Central::Cli::Common
|
4
|
+
include Central::Cli::StackOptions
|
5
|
+
|
6
|
+
parameter 'NAME', 'Secret name'
|
7
|
+
parameter '[VALUE]', 'Secret value'
|
8
|
+
|
9
|
+
def execute
|
10
|
+
require_api_url
|
11
|
+
token = require_token
|
12
|
+
secret = value
|
13
|
+
secret = STDIN.read if secret.to_s == ''
|
14
|
+
abort('No value provided') if secret.to_s == ''
|
15
|
+
data = {
|
16
|
+
name: name,
|
17
|
+
value: secret
|
18
|
+
}
|
19
|
+
client(token).post("stacks/#{current_stack}/secrets", data)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative 'vault/write_command'
|
2
|
+
require_relative 'vault/list_command'
|
3
|
+
require_relative 'vault/read_command'
|
4
|
+
require_relative 'vault/remove_command'
|
5
|
+
require_relative 'vault/update_command'
|
6
|
+
|
7
|
+
class Central::Cli::VaultCommand < Clamp::Command
|
8
|
+
subcommand %w(list ls), 'List secrets', Central::Cli::Vault::ListCommand
|
9
|
+
subcommand 'write', 'Write a secret', Central::Cli::Vault::WriteCommand
|
10
|
+
subcommand 'read', 'Read secret', Central::Cli::Vault::ReadCommand
|
11
|
+
subcommand 'update', 'Update secret', Central::Cli::Vault::UpdateCommand
|
12
|
+
subcommand %w(remove rm), 'Remove secret', Central::Cli::Vault::RemoveCommand
|
13
|
+
|
14
|
+
def execute
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative 'version'
|
2
|
+
|
3
|
+
class Central::Cli::VersionCommand < Clamp::Command
|
4
|
+
include Central::Cli::Common
|
5
|
+
|
6
|
+
def execute
|
7
|
+
url = begin
|
8
|
+
api_url
|
9
|
+
rescue
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
puts "cli: #{Central::Cli::VERSION}"
|
13
|
+
if url
|
14
|
+
resp = begin
|
15
|
+
JSON.parse(client.http_client.get(path: '/').body)
|
16
|
+
rescue
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
puts "master: #{resp['version']} (#{url})" if resp
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Central::Cli::Vpn
|
2
|
+
class ConfigCommand < Clamp::Command
|
3
|
+
include Central::Cli::Common
|
4
|
+
include Central::Cli::StackOptions
|
5
|
+
|
6
|
+
def execute
|
7
|
+
require 'rbconfig'
|
8
|
+
require_api_url
|
9
|
+
payload = { cmd: ['/usr/local/bin/ovpn_getclient', 'CENTRAL_VPN_CLIENT'] }
|
10
|
+
stdout, stderr = client(require_token).post("containers/#{current_stack}/vpn/vpn-1/exec", payload)
|
11
|
+
if linux?
|
12
|
+
stdout << "\n"
|
13
|
+
stdout << "up /etc/openvpn/update-resolv-conf\n"
|
14
|
+
stdout << "down /etc/openvpn/update-resolv-conf\n"
|
15
|
+
end
|
16
|
+
puts stdout
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [Boolean]
|
20
|
+
def linux?
|
21
|
+
host_os = RbConfig::CONFIG['host_os']
|
22
|
+
host_os.include?('linux')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'shell-spinner'
|
2
|
+
|
3
|
+
module Central::Cli::Vpn
|
4
|
+
class CreateCommand < Clamp::Command
|
5
|
+
include Central::Cli::Common
|
6
|
+
include Central::Cli::StackOptions
|
7
|
+
|
8
|
+
option '--node', 'NODE', 'Node name where VPN is deployed'
|
9
|
+
option '--ip', 'IP', 'Node ip-address'
|
10
|
+
|
11
|
+
def execute
|
12
|
+
require_api_url
|
13
|
+
token = require_token
|
14
|
+
preferred_node = node
|
15
|
+
|
16
|
+
vpn = begin
|
17
|
+
client(token).get("services/#{current_stack}/vpn")
|
18
|
+
rescue
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
abort('VPN already exists') if vpn
|
22
|
+
|
23
|
+
nodes = client(token).get("stacks/#{current_stack}/nodes")
|
24
|
+
if preferred_node.nil?
|
25
|
+
node = nodes['nodes'].find { |n| n['connected'] }
|
26
|
+
abort('Cannot find any online nodes') if node.nil?
|
27
|
+
else
|
28
|
+
node = nodes['nodes'].find { |n| n['connected'] && n['name'] == preferred_node }
|
29
|
+
abort('Node not found') if node.nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
vpn_ip = node_vpn_ip(node)
|
33
|
+
data = {
|
34
|
+
name: 'vpn',
|
35
|
+
stateful: true,
|
36
|
+
image: 'fishyard/openvpn:ethwe',
|
37
|
+
ports: [
|
38
|
+
{
|
39
|
+
container_port: '1194',
|
40
|
+
node_port: '1194',
|
41
|
+
protocol: 'udp'
|
42
|
+
}
|
43
|
+
],
|
44
|
+
cap_add: ['NET_ADMIN'],
|
45
|
+
env: ["OVPN_SERVER_URL=udp://#{vpn_ip}:1194"],
|
46
|
+
affinity: ["node==#{node['name']}"]
|
47
|
+
}
|
48
|
+
client(token).post("stacks/#{current_stack}/services", data)
|
49
|
+
client(token).post("services/#{current_stack}/vpn/deploy", {})
|
50
|
+
ShellSpinner 'Deploying vpn service ' do
|
51
|
+
sleep 1 until client(token).get("services/#{current_stack}/vpn")['state'] != 'deploying'
|
52
|
+
end
|
53
|
+
puts "OpenVPN service is now started (udp://#{vpn_ip}:1194)."
|
54
|
+
puts "Use 'cm vpn config' to fetch OpenVPN client config to your machine "\
|
55
|
+
'(it takes a while until config is ready).'
|
56
|
+
end
|
57
|
+
|
58
|
+
# @param [Hash] node
|
59
|
+
# @return [String]
|
60
|
+
def node_vpn_ip(node)
|
61
|
+
return ip unless ip.nil?
|
62
|
+
|
63
|
+
# vagrant
|
64
|
+
if api_url == 'http://192.168.66.100:8080'
|
65
|
+
node['private_ip']
|
66
|
+
else
|
67
|
+
node['public_ip']
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Central::Cli::Vpn
|
2
|
+
class DeleteCommand < Clamp::Command
|
3
|
+
include Central::Cli::Common
|
4
|
+
include Central::Cli::StackOptions
|
5
|
+
|
6
|
+
def execute
|
7
|
+
puts "DEPRECATION WARNING: Support for 'cm vpn delete' will be dropped. Use 'cm vpn remove' instead.".colorize(:red)
|
8
|
+
require_api_url
|
9
|
+
token = require_token
|
10
|
+
|
11
|
+
vpn = begin
|
12
|
+
client(token).get("services/#{current_stack}/vpn")
|
13
|
+
rescue
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
abort('VPN service does not exist') if vpn.nil?
|
17
|
+
|
18
|
+
client(token).delete("services/#{current_stack}/vpn")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Central::Cli::Vpn
|
2
|
+
class RemoveCommand < Clamp::Command
|
3
|
+
include Central::Cli::Common
|
4
|
+
|
5
|
+
def execute
|
6
|
+
require_api_url
|
7
|
+
token = require_token
|
8
|
+
|
9
|
+
vpn = begin
|
10
|
+
client(token).get("services/#{current_stack}/vpn")
|
11
|
+
rescue
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
abort('VPN service does not exist') if vpn.nil?
|
15
|
+
|
16
|
+
client(token).delete("services/#{current_stack}/vpn")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative 'vpn/create_command'
|
2
|
+
require_relative 'vpn/config_command'
|
3
|
+
require_relative 'vpn/remove_command'
|
4
|
+
require_relative 'vpn/delete_command'
|
5
|
+
|
6
|
+
class Central::Cli::VpnCommand < Clamp::Command
|
7
|
+
subcommand 'create', 'Create VPN service', Central::Cli::Vpn::CreateCommand
|
8
|
+
subcommand 'config', 'Show/Export VPN config', Central::Cli::Vpn::ConfigCommand
|
9
|
+
subcommand %w(remove rm), 'Remove VPN service', Central::Cli::Vpn::RemoveCommand
|
10
|
+
|
11
|
+
def execute
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Central::Cli::WhoamiCommand < Clamp::Command
|
2
|
+
include Central::Cli::Common
|
3
|
+
|
4
|
+
option '--bash-completion-path', :flag, 'Show bash completion path', hidden: true
|
5
|
+
|
6
|
+
def execute
|
7
|
+
if bash_completion_path?
|
8
|
+
puts File.realpath(File.join(__dir__, '../scripts/init'))
|
9
|
+
exit 0
|
10
|
+
end
|
11
|
+
|
12
|
+
require_api_url
|
13
|
+
puts "Master: #{current_master['name']}"
|
14
|
+
puts "URL: #{api_url}"
|
15
|
+
puts "Stack: #{current_stack}"
|
16
|
+
token = require_token
|
17
|
+
user = client(token).get('user')
|
18
|
+
puts "User: #{user['email']}"
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'excon'
|
3
|
+
require_relative 'errors'
|
4
|
+
require 'central/cli/version'
|
5
|
+
|
6
|
+
module Central
|
7
|
+
class Client
|
8
|
+
attr_accessor :default_headers
|
9
|
+
attr_reader :http_client
|
10
|
+
|
11
|
+
# Initialize api client
|
12
|
+
#
|
13
|
+
# @param [String] api_url
|
14
|
+
# @param [Hash] default_headers
|
15
|
+
def initialize(api_url, default_headers = {})
|
16
|
+
Excon.defaults[:ssl_verify_peer] = false if ignore_ssl_errors?
|
17
|
+
@http_client = Excon.new(api_url)
|
18
|
+
@default_headers = {
|
19
|
+
'Accept' => 'application/json',
|
20
|
+
'Content-Type' => 'application/json',
|
21
|
+
'User-Agent' => "central-cli/#{Central::Cli::VERSION}"
|
22
|
+
}.merge(default_headers)
|
23
|
+
@api_url = api_url
|
24
|
+
end
|
25
|
+
|
26
|
+
# Get request
|
27
|
+
#
|
28
|
+
# @param [String] path
|
29
|
+
# @param [Hash,NilClass] params
|
30
|
+
# @param [Hash] headers
|
31
|
+
# @return [Hash]
|
32
|
+
def get(path, params = nil, headers = {})
|
33
|
+
response = http_client.get(
|
34
|
+
path: request_uri(path),
|
35
|
+
query: params,
|
36
|
+
headers: request_headers(headers)
|
37
|
+
)
|
38
|
+
if response.status == 200
|
39
|
+
parse_response(response)
|
40
|
+
else
|
41
|
+
handle_error_response(response)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Get request
|
46
|
+
#
|
47
|
+
# @param [String] path
|
48
|
+
# @param [Lambda] response_block
|
49
|
+
# @param [Hash,NilClass] params
|
50
|
+
# @param [Hash] headers
|
51
|
+
def get_stream(path, response_block, params = nil, headers = {})
|
52
|
+
http_client.get(
|
53
|
+
read_timeout: 360,
|
54
|
+
path: request_uri(path),
|
55
|
+
query: params,
|
56
|
+
headers: request_headers(headers),
|
57
|
+
response_block: response_block
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Post request
|
62
|
+
#
|
63
|
+
# @param [String] path
|
64
|
+
# @param [Object] obj
|
65
|
+
# @param [Hash] params
|
66
|
+
# @param [Hash] headers
|
67
|
+
# @return [Hash]
|
68
|
+
def post(path, obj, params = {}, headers = {})
|
69
|
+
request_headers = request_headers(headers)
|
70
|
+
request_options = {
|
71
|
+
path: request_uri(path),
|
72
|
+
headers: request_headers,
|
73
|
+
body: encode_body(obj, request_headers['Content-Type']),
|
74
|
+
query: params
|
75
|
+
}
|
76
|
+
|
77
|
+
response = http_client.post(request_options)
|
78
|
+
if [200, 201].include?(response.status)
|
79
|
+
parse_response(response)
|
80
|
+
else
|
81
|
+
handle_error_response(response)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Put request
|
86
|
+
#
|
87
|
+
# @param [String] path
|
88
|
+
# @param [Object] obj
|
89
|
+
# @param [Hash] params
|
90
|
+
# @param [Hash] headers
|
91
|
+
# @return [Hash]
|
92
|
+
def put(path, obj, params = {}, headers = {})
|
93
|
+
request_headers = request_headers(headers)
|
94
|
+
request_options = {
|
95
|
+
path: request_uri(path),
|
96
|
+
headers: request_headers,
|
97
|
+
body: encode_body(obj, request_headers['Content-Type']),
|
98
|
+
query: params
|
99
|
+
}
|
100
|
+
|
101
|
+
response = http_client.put(request_options)
|
102
|
+
if [200, 201].include?(response.status)
|
103
|
+
parse_response(response)
|
104
|
+
else
|
105
|
+
handle_error_response(response)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Delete request
|
110
|
+
#
|
111
|
+
# @param [String] path
|
112
|
+
# @param [Hash,String] body
|
113
|
+
# @param [Hash] params
|
114
|
+
# @param [Hash] headers
|
115
|
+
# @return [Hash]
|
116
|
+
def delete(path, body = nil, params = {}, headers = {})
|
117
|
+
request_headers = request_headers(headers)
|
118
|
+
request_options = {
|
119
|
+
path: request_uri(path),
|
120
|
+
headers: request_headers,
|
121
|
+
body: encode_body(body, request_headers['Content-Type']),
|
122
|
+
query: params
|
123
|
+
}
|
124
|
+
response = http_client.delete(request_options)
|
125
|
+
if response.status == 200
|
126
|
+
parse_response(response)
|
127
|
+
else
|
128
|
+
handle_error_response(response)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
##
|
135
|
+
# Get full request uri
|
136
|
+
#
|
137
|
+
# @param [String] path
|
138
|
+
# @return [String]
|
139
|
+
def request_uri(path)
|
140
|
+
"/v1/#{path}"
|
141
|
+
end
|
142
|
+
|
143
|
+
##
|
144
|
+
# Get request headers
|
145
|
+
#
|
146
|
+
# @param [Hash] headers
|
147
|
+
# @return [Hash]
|
148
|
+
def request_headers(headers = {})
|
149
|
+
@default_headers.merge(headers)
|
150
|
+
end
|
151
|
+
|
152
|
+
##
|
153
|
+
# Encode body based on content type
|
154
|
+
#
|
155
|
+
# @param [Object] body
|
156
|
+
# @param [String] content_type
|
157
|
+
def encode_body(body, content_type)
|
158
|
+
if content_type == 'application/json'
|
159
|
+
dump_json(body)
|
160
|
+
else
|
161
|
+
body
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
##
|
166
|
+
# Parse response
|
167
|
+
#
|
168
|
+
# @param [HTTP::Message]
|
169
|
+
# @return [Object]
|
170
|
+
def parse_response(response)
|
171
|
+
if response.headers['Content-Type'].include?('application/json')
|
172
|
+
parse_json(response.body)
|
173
|
+
else
|
174
|
+
response.body
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
##
|
179
|
+
# Parse json
|
180
|
+
#
|
181
|
+
# @param [String] json
|
182
|
+
# @return [Hash,Object,NilClass]
|
183
|
+
def parse_json(json)
|
184
|
+
JSON.parse(json)
|
185
|
+
rescue
|
186
|
+
nil
|
187
|
+
end
|
188
|
+
|
189
|
+
##
|
190
|
+
# Dump json
|
191
|
+
#
|
192
|
+
# @param [Object] obj
|
193
|
+
# @return [String]
|
194
|
+
def dump_json(obj)
|
195
|
+
JSON.dump(obj)
|
196
|
+
end
|
197
|
+
|
198
|
+
def ignore_ssl_errors?
|
199
|
+
ENV['SSL_IGNORE_ERRORS'] == 'true'
|
200
|
+
end
|
201
|
+
|
202
|
+
def handle_error_response(response)
|
203
|
+
message = response.body
|
204
|
+
message = 'Not found' if response.status == 404 && message == ''
|
205
|
+
fail Central::Errors::StandardError.new(response.status, message)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|