kitsune-kit 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +117 -2
- data/CONTRIBUTING.md +83 -0
- data/README.md +108 -136
- data/SECURITY.md +25 -0
- data/bin/kit +4 -1
- data/docs/architecture/decisions/0001-product-boundary.md +23 -0
- data/docs/architecture/decisions/0002-core-and-interfaces.md +23 -0
- data/docs/architecture/decisions/0003-configuration-state-and-secrets.md +23 -0
- data/docs/architecture/decisions/0004-supported-platforms.md +19 -0
- data/docs/architecture/decisions/0005-operation-semantics.md +19 -0
- data/docs/architecture/decisions/0006-tui-backend.md +21 -0
- data/docs/architecture/provider-adapters.md +49 -0
- data/docs/architecture.md +89 -0
- data/docs/commands.md +210 -0
- data/docs/configuration.md +210 -0
- data/docs/getting-started.md +133 -0
- data/docs/providers/digitalocean.md +52 -0
- data/docs/releasing.md +43 -0
- data/docs/roadmap.md +46 -0
- data/docs/security-audit.md +130 -0
- data/docs/security.md +116 -0
- data/docs/services/postgres.md +78 -0
- data/docs/services/redis.md +53 -0
- data/docs/testing.md +200 -0
- data/docs/troubleshooting.md +123 -0
- data/docs/tui.md +57 -0
- data/lib/kitsune/kit/adapters/confirming_host_key_verifier.rb +42 -0
- data/lib/kitsune/kit/adapters/digitalocean_provider.rb +217 -0
- data/lib/kitsune/kit/adapters/fake_clock.rb +34 -0
- data/lib/kitsune/kit/adapters/fake_provider.rb +107 -0
- data/lib/kitsune/kit/adapters/fake_reporter.rb +34 -0
- data/lib/kitsune/kit/adapters/fake_secret_store.rb +35 -0
- data/lib/kitsune/kit/adapters/fake_state_store.rb +91 -0
- data/lib/kitsune/kit/adapters/fake_transport.rb +56 -0
- data/lib/kitsune/kit/adapters/net_ssh_transport.rb +155 -0
- data/lib/kitsune/kit/adapters/provider.rb +34 -0
- data/lib/kitsune/kit/adapters/transport.rb +22 -0
- data/lib/kitsune/kit/adapters/transport_factory.rb +116 -0
- data/lib/kitsune/kit/application.rb +170 -0
- data/lib/kitsune/kit/cancellation.rb +21 -0
- data/lib/kitsune/kit/cli.rb +802 -64
- data/lib/kitsune/kit/clock.rb +11 -0
- data/lib/kitsune/kit/configuration.rb +493 -0
- data/lib/kitsune/kit/errors.rb +98 -0
- data/lib/kitsune/kit/events.rb +55 -0
- data/lib/kitsune/kit/operations/ensure_dns_records.rb +165 -0
- data/lib/kitsune/kit/operations/ensure_server.rb +135 -0
- data/lib/kitsune/kit/operations/ensure_service.rb +285 -0
- data/lib/kitsune/kit/operations/remote_script.rb +214 -0
- data/lib/kitsune/kit/operations/service_backup.rb +71 -0
- data/lib/kitsune/kit/operations/service_files.rb +127 -0
- data/lib/kitsune/kit/operations/service_firewall.rb +190 -0
- data/lib/kitsune/kit/operations/service_state.rb +59 -0
- data/lib/kitsune/kit/plan.rb +72 -0
- data/lib/kitsune/kit/reporters/human.rb +89 -0
- data/lib/kitsune/kit/reporters/json.rb +65 -0
- data/lib/kitsune/kit/reporters/reporter.rb +11 -0
- data/lib/kitsune/kit/result.rb +28 -0
- data/lib/kitsune/kit/run_journal.rb +102 -0
- data/lib/kitsune/kit/run_logger.rb +37 -0
- data/lib/kitsune/kit/scripts/docker.sh +137 -0
- data/lib/kitsune/kit/scripts/firewall.sh +205 -0
- data/lib/kitsune/kit/scripts/metrics.sh +54 -0
- data/lib/kitsune/kit/scripts/ssh.sh +95 -0
- data/lib/kitsune/kit/scripts/swap.sh +86 -0
- data/lib/kitsune/kit/scripts/unattended.sh +81 -0
- data/lib/kitsune/kit/scripts/user.sh +114 -0
- data/lib/kitsune/kit/secret_filter.rb +54 -0
- data/lib/kitsune/kit/secret_store.rb +32 -0
- data/lib/kitsune/kit/secret_stores/store.rb +12 -0
- data/lib/kitsune/kit/service_compose.rb +72 -0
- data/lib/kitsune/kit/state_store.rb +158 -0
- data/lib/kitsune/kit/state_stores/store.rb +15 -0
- data/lib/kitsune/kit/tui/actions.rb +72 -0
- data/lib/kitsune/kit/tui/application.rb +35 -0
- data/lib/kitsune/kit/tui/controller.rb +162 -0
- data/lib/kitsune/kit/tui/renderer.rb +134 -0
- data/lib/kitsune/kit/tui/state.rb +18 -0
- data/lib/kitsune/kit/tui/store.rb +88 -0
- data/lib/kitsune/kit/tui/terminal.rb +95 -0
- data/lib/kitsune/kit/version.rb +1 -1
- data/lib/kitsune/kit/workflows/apply_plan.rb +145 -0
- data/lib/kitsune/kit/workflows/base.rb +31 -0
- data/lib/kitsune/kit/workflows/build_plan.rb +33 -0
- data/lib/kitsune/kit/workflows/destroy_server.rb +84 -0
- data/lib/kitsune/kit/workflows/doctor.rb +225 -0
- data/lib/kitsune/kit/workflows/environment_selection.rb +70 -0
- data/lib/kitsune/kit/workflows/import_server.rb +100 -0
- data/lib/kitsune/kit/workflows/initialize_project.rb +121 -0
- data/lib/kitsune/kit/workflows/inspect_environment.rb +44 -0
- data/lib/kitsune/kit/workflows/rollback.rb +54 -0
- data/lib/kitsune/kit/workflows/support_bundle.rb +82 -0
- data/lib/kitsune/kit.rb +41 -2
- metadata +122 -79
- data/.rspec +0 -3
- data/Rakefile +0 -8
- data/kitsune-kit-logo.jpg +0 -0
- data/lib/kitsune/blueprints/.env.template +0 -31
- data/lib/kitsune/blueprints/docker/postgres.yml +0 -27
- data/lib/kitsune/blueprints/docker/redis.yml +0 -23
- data/lib/kitsune/blueprints/kit.env.template +0 -1
- data/lib/kitsune/kit/ansi_color.rb +0 -78
- data/lib/kitsune/kit/commands/bootstrap.rb +0 -134
- data/lib/kitsune/kit/commands/bootstrap_docker.rb +0 -66
- data/lib/kitsune/kit/commands/dns.rb +0 -112
- data/lib/kitsune/kit/commands/init.rb +0 -148
- data/lib/kitsune/kit/commands/install_docker_engine.rb +0 -146
- data/lib/kitsune/kit/commands/postinstall_docker.rb +0 -142
- data/lib/kitsune/kit/commands/provision.rb +0 -43
- data/lib/kitsune/kit/commands/setup_do_metrics.rb +0 -123
- data/lib/kitsune/kit/commands/setup_docker_prereqs.rb +0 -151
- data/lib/kitsune/kit/commands/setup_firewall.rb +0 -132
- data/lib/kitsune/kit/commands/setup_postgres_docker.rb +0 -246
- data/lib/kitsune/kit/commands/setup_redis_docker.rb +0 -241
- data/lib/kitsune/kit/commands/setup_swap.rb +0 -151
- data/lib/kitsune/kit/commands/setup_unattended.rb +0 -132
- data/lib/kitsune/kit/commands/setup_user.rb +0 -189
- data/lib/kitsune/kit/commands/ssh.rb +0 -46
- data/lib/kitsune/kit/commands/switch_env.rb +0 -42
- data/lib/kitsune/kit/defaults.rb +0 -91
- data/lib/kitsune/kit/env_loader.rb +0 -41
- data/lib/kitsune/kit/options_builder.rb +0 -26
- data/lib/kitsune/kit/provisioner.rb +0 -107
- data/sig/kitsune/kit.rbs +0 -6
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
require "thor"
|
|
2
|
-
require "net/ssh"
|
|
3
|
-
require_relative "../defaults"
|
|
4
|
-
require_relative "../options_builder"
|
|
5
|
-
|
|
6
|
-
module Kitsune
|
|
7
|
-
module Kit
|
|
8
|
-
module Commands
|
|
9
|
-
class PostinstallDocker < Thor
|
|
10
|
-
namespace "postinstall_docker"
|
|
11
|
-
|
|
12
|
-
class_option :server_ip, aliases: "-s", required: true, desc: "Server IP address or hostname"
|
|
13
|
-
class_option :ssh_port, aliases: "-p", desc: "SSH port"
|
|
14
|
-
class_option :ssh_key_path, aliases: "-k", desc: "Path to your private SSH key"
|
|
15
|
-
|
|
16
|
-
desc "create", "Apply Docker post-install configuration (start service, add groups, create network)"
|
|
17
|
-
def create
|
|
18
|
-
filled_options = Kitsune::Kit::OptionsBuilder.build(
|
|
19
|
-
options,
|
|
20
|
-
required: [:server_ip],
|
|
21
|
-
defaults: Kitsune::Kit::Defaults.ssh
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
with_ssh_connection(filled_options) do |ssh|
|
|
25
|
-
perform_setup(ssh)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
desc "rollback", "Undo Docker post-install configuration"
|
|
30
|
-
def rollback
|
|
31
|
-
filled_options = Kitsune::Kit::OptionsBuilder.build(
|
|
32
|
-
options,
|
|
33
|
-
required: [:server_ip],
|
|
34
|
-
defaults: Kitsune::Kit::Defaults.ssh
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
with_ssh_connection(filled_options) do |ssh|
|
|
38
|
-
perform_rollback(ssh)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
no_commands do
|
|
43
|
-
def with_ssh_connection(filled_options)
|
|
44
|
-
server = filled_options[:server_ip]
|
|
45
|
-
port = filled_options[:ssh_port]
|
|
46
|
-
key = File.expand_path(filled_options[:ssh_key_path])
|
|
47
|
-
|
|
48
|
-
say "🔑 Connecting as deploy@#{server}:#{port}", :green
|
|
49
|
-
Net::SSH.start(server, "deploy", port: port, keys: [key], non_interactive: true, timeout: 5) do |ssh|
|
|
50
|
-
yield ssh
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def perform_setup(ssh)
|
|
55
|
-
output = ssh.exec! <<~EOH
|
|
56
|
-
set -e
|
|
57
|
-
|
|
58
|
-
sudo mkdir -p /usr/local/backups
|
|
59
|
-
sudo chown deploy:deploy /usr/local/backups
|
|
60
|
-
|
|
61
|
-
BACKUP_DIR="/usr/local/backups"
|
|
62
|
-
SCRIPT_ID="postinstall_docker"
|
|
63
|
-
BEFORE_FILE="${BACKUP_DIR}/${SCRIPT_ID}.before"
|
|
64
|
-
AFTER_FILE="${BACKUP_DIR}/${SCRIPT_ID}.after"
|
|
65
|
-
|
|
66
|
-
echo "✍🏻 Performing post-install Docker tasks"
|
|
67
|
-
|
|
68
|
-
if [ ! -f "$AFTER_FILE" ]; then
|
|
69
|
-
# Record state
|
|
70
|
-
systemctl is-enabled docker &>/dev/null && echo "docker.service enabled" >> "$BEFORE_FILE" || echo "docker.service disabled" >> "$BEFORE_FILE"
|
|
71
|
-
groups deploy | grep -q docker && echo "deploy in docker group" >> "$BEFORE_FILE" || echo "deploy not in docker group" >> "$BEFORE_FILE"
|
|
72
|
-
sudo docker network inspect private &>/dev/null && echo "network private exists" >> "$BEFORE_FILE" || echo "network private absent" >> "$BEFORE_FILE"
|
|
73
|
-
|
|
74
|
-
# Start and enable Docker
|
|
75
|
-
sudo systemctl start docker
|
|
76
|
-
sudo systemctl enable docker
|
|
77
|
-
echo "🚀 Docker service started and enabled"
|
|
78
|
-
echo "docker.service enabled" >> "$AFTER_FILE"
|
|
79
|
-
|
|
80
|
-
# Add deploy to docker group
|
|
81
|
-
sudo usermod -aG docker deploy
|
|
82
|
-
echo "👥 Added 'deploy' to docker group"
|
|
83
|
-
echo "added docker group" >> "$AFTER_FILE"
|
|
84
|
-
|
|
85
|
-
# Create private network if missing
|
|
86
|
-
if ! sudo docker network inspect private &>/dev/null; then
|
|
87
|
-
sudo docker network create -d bridge private
|
|
88
|
-
echo "🌐 Created Docker network 'private'"
|
|
89
|
-
echo "created network private" >> "$AFTER_FILE"
|
|
90
|
-
fi
|
|
91
|
-
|
|
92
|
-
echo "✅ Post-install Docker tasks complete"
|
|
93
|
-
else
|
|
94
|
-
echo "🔄 Post-install tasks already applied, skipping setup"
|
|
95
|
-
fi
|
|
96
|
-
EOH
|
|
97
|
-
say output
|
|
98
|
-
say "✅ Post-install Docker setup completed", :green
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def perform_rollback(ssh)
|
|
102
|
-
output = ssh.exec! <<~EOH
|
|
103
|
-
set -e
|
|
104
|
-
|
|
105
|
-
sudo mkdir -p /usr/local/backups
|
|
106
|
-
sudo chown deploy:deploy /usr/local/backups
|
|
107
|
-
|
|
108
|
-
BACKUP_DIR="/usr/local/backups"
|
|
109
|
-
SCRIPT_ID="postinstall_docker"
|
|
110
|
-
BEFORE_FILE="${BACKUP_DIR}/${SCRIPT_ID}.before"
|
|
111
|
-
AFTER_FILE="${BACKUP_DIR}/${SCRIPT_ID}.after"
|
|
112
|
-
|
|
113
|
-
echo "🔄 Rolling back post-install Docker tasks..."
|
|
114
|
-
|
|
115
|
-
if [ -f "$AFTER_FILE" ]; then
|
|
116
|
-
if grep -Fxq "docker.service enabled" "$AFTER_FILE"; then
|
|
117
|
-
sudo systemctl disable docker
|
|
118
|
-
echo " - Docker service disabled"
|
|
119
|
-
fi
|
|
120
|
-
if grep -Fxq "added docker group" "$AFTER_FILE"; then
|
|
121
|
-
sudo gpasswd -d deploy docker || true
|
|
122
|
-
echo " - Removed 'deploy' from docker group"
|
|
123
|
-
fi
|
|
124
|
-
if grep -Fxq "created network private" "$AFTER_FILE"; then
|
|
125
|
-
sudo docker network rm private || true
|
|
126
|
-
echo " - Removed Docker network 'private'"
|
|
127
|
-
fi
|
|
128
|
-
sudo rm -f "$BEFORE_FILE" "$AFTER_FILE"
|
|
129
|
-
else
|
|
130
|
-
echo " - no marker for $SCRIPT_ID, skipping rollback"
|
|
131
|
-
fi
|
|
132
|
-
|
|
133
|
-
echo "✅ Rollback complete"
|
|
134
|
-
EOH
|
|
135
|
-
say output
|
|
136
|
-
say "✅ Post-install Docker rollback completed", :green
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
end
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
require "thor"
|
|
2
|
-
require_relative "../defaults"
|
|
3
|
-
require_relative "../provisioner"
|
|
4
|
-
require_relative "../options_builder"
|
|
5
|
-
|
|
6
|
-
module Kitsune
|
|
7
|
-
module Kit
|
|
8
|
-
module Commands
|
|
9
|
-
class Provision < Thor
|
|
10
|
-
namespace "provision"
|
|
11
|
-
|
|
12
|
-
class_option :droplet_name, type: :string, aliases: "-n", desc: "Droplet name"
|
|
13
|
-
class_option :region, type: :string, aliases: "-r", desc: "Region"
|
|
14
|
-
class_option :size, type: :string, aliases: "-s", desc: "Size"
|
|
15
|
-
class_option :image, type: :string, aliases: "-i", desc: "Image"
|
|
16
|
-
class_option :tag, type: :string, aliases: "-t", desc: "Tag to filter/create"
|
|
17
|
-
class_option :ssh_key_id, type: :string, aliases: "-k", desc: "SSH key ID"
|
|
18
|
-
|
|
19
|
-
desc "create", "Create the Droplet if it doesn't exist"
|
|
20
|
-
def create
|
|
21
|
-
filled_options = Kitsune::Kit::OptionsBuilder.build(
|
|
22
|
-
options,
|
|
23
|
-
required: [:ssh_key_id],
|
|
24
|
-
defaults: Kitsune::Kit::Defaults.infra
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
Provisioner.new(filled_options).create_or_show
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
desc "rollback", "Remove the Droplet if it exists"
|
|
31
|
-
def rollback
|
|
32
|
-
filled_options = Kitsune::Kit::OptionsBuilder.build(
|
|
33
|
-
options,
|
|
34
|
-
required: [:ssh_key_id],
|
|
35
|
-
defaults: Kitsune::Kit::Defaults.infra
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
Provisioner.new(filled_options).rollback
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
require "thor"
|
|
2
|
-
require "net/ssh"
|
|
3
|
-
require_relative "../defaults"
|
|
4
|
-
require_relative "../options_builder"
|
|
5
|
-
|
|
6
|
-
module Kitsune
|
|
7
|
-
module Kit
|
|
8
|
-
module Commands
|
|
9
|
-
class SetupDoMetrics < Thor
|
|
10
|
-
namespace "setup_do_metrics"
|
|
11
|
-
|
|
12
|
-
class_option :server_ip, aliases: "-s", required: true, desc: "Server IP address"
|
|
13
|
-
class_option :ssh_port, aliases: "-p", desc: "SSH port"
|
|
14
|
-
class_option :ssh_key_path, aliases: "-k", desc: "SSH private key path"
|
|
15
|
-
|
|
16
|
-
desc "create", "Install and enable the DigitalOcean Metrics Agent"
|
|
17
|
-
def create
|
|
18
|
-
unless Kitsune::Kit::Defaults.metrics[:enable_do_metrics]
|
|
19
|
-
say "⚠️ DigitalOcean Metrics Agent setup is disabled via ENABLE_DO_METRICS=false", :yellow
|
|
20
|
-
return
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
filled_options = Kitsune::Kit::OptionsBuilder.build(
|
|
24
|
-
options,
|
|
25
|
-
required: [:server_ip],
|
|
26
|
-
defaults: Kitsune::Kit::Defaults.ssh
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
with_ssh_connection(filled_options) do |ssh|
|
|
30
|
-
install_agent(ssh)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
desc "rollback", "Uninstall the DigitalOcean Metrics Agent"
|
|
35
|
-
def rollback
|
|
36
|
-
filled_options = Kitsune::Kit::OptionsBuilder.build(
|
|
37
|
-
options,
|
|
38
|
-
required: [:server_ip],
|
|
39
|
-
defaults: Kitsune::Kit::Defaults.ssh
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
with_ssh_connection(filled_options) do |ssh|
|
|
43
|
-
uninstall_agent(ssh)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
no_commands do
|
|
48
|
-
def with_ssh_connection(filled_options)
|
|
49
|
-
Net::SSH.start(
|
|
50
|
-
filled_options[:server_ip],
|
|
51
|
-
"deploy",
|
|
52
|
-
port: filled_options[:ssh_port],
|
|
53
|
-
keys: [File.expand_path(filled_options[:ssh_key_path])],
|
|
54
|
-
non_interactive: true,
|
|
55
|
-
timeout: 5
|
|
56
|
-
) do |ssh|
|
|
57
|
-
yield ssh
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def install_agent(ssh)
|
|
62
|
-
marker = "/usr/local/backups/setup_do_metrics.after"
|
|
63
|
-
|
|
64
|
-
script = <<~BASH
|
|
65
|
-
set -e
|
|
66
|
-
sudo mkdir -p /usr/local/backups
|
|
67
|
-
|
|
68
|
-
if [ -f "#{marker}" ]; then
|
|
69
|
-
echo "🔁 Metrics Agent already installed, skipping."
|
|
70
|
-
exit 0
|
|
71
|
-
fi
|
|
72
|
-
|
|
73
|
-
echo "✍🏻 Installing DigitalOcean Metrics Agent..."
|
|
74
|
-
curl -sSL https://repos.insights.digitalocean.com/install.sh | sudo bash
|
|
75
|
-
|
|
76
|
-
sudo touch "#{marker}"
|
|
77
|
-
echo "✅ Metrics Agent installed"
|
|
78
|
-
|
|
79
|
-
ps aux | grep do-agent | grep -v grep || echo "⚠️ do-agent process not found"
|
|
80
|
-
BASH
|
|
81
|
-
|
|
82
|
-
say ssh.exec!(script)
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def uninstall_agent(ssh)
|
|
86
|
-
marker = "/usr/local/backups/setup_do_metrics.after"
|
|
87
|
-
|
|
88
|
-
script = <<~BASH
|
|
89
|
-
set -e
|
|
90
|
-
|
|
91
|
-
if [ ! -f "#{marker}" ]; then
|
|
92
|
-
echo "💡 No marker for metrics agent found. Skipping rollback."
|
|
93
|
-
exit 0
|
|
94
|
-
fi
|
|
95
|
-
|
|
96
|
-
echo "🧹 Uninstalling DigitalOcean Metrics Agent..."
|
|
97
|
-
|
|
98
|
-
if dpkg -l | grep -q do-agent; then
|
|
99
|
-
echo "📦 Removing do-agent package..."
|
|
100
|
-
sudo apt-get remove --purge -y do-agent
|
|
101
|
-
else
|
|
102
|
-
echo "💡 do-agent is not installed, skipping package removal."
|
|
103
|
-
fi
|
|
104
|
-
|
|
105
|
-
if systemctl list-unit-files | grep -q do-agent.service; then
|
|
106
|
-
echo "✍🏻 Stopping do-agent service..."
|
|
107
|
-
sudo systemctl stop do-agent || true
|
|
108
|
-
sudo systemctl disable do-agent || true
|
|
109
|
-
else
|
|
110
|
-
echo "💡 do-agent.service not found in systemd, skipping stop/disable"
|
|
111
|
-
fi
|
|
112
|
-
|
|
113
|
-
sudo rm -f "#{marker}"
|
|
114
|
-
echo "✅ Metrics Agent removed"
|
|
115
|
-
BASH
|
|
116
|
-
|
|
117
|
-
say ssh.exec!(script)
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
end
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
require "thor"
|
|
2
|
-
require "net/ssh"
|
|
3
|
-
require_relative "../options_builder"
|
|
4
|
-
require_relative "../defaults"
|
|
5
|
-
|
|
6
|
-
module Kitsune
|
|
7
|
-
module Kit
|
|
8
|
-
module Commands
|
|
9
|
-
class SetupDockerPrereqs < Thor
|
|
10
|
-
namespace "setup_docker_prereqs"
|
|
11
|
-
|
|
12
|
-
class_option :server_ip, aliases: "-s", required: true, desc: "Server IP address or hostname"
|
|
13
|
-
class_option :ssh_port, aliases: "-p", desc: "SSH port"
|
|
14
|
-
class_option :ssh_key_path, aliases: "-k", desc: "Path to your private SSH key"
|
|
15
|
-
|
|
16
|
-
desc "create", "Install Docker prerequisites on the remote server"
|
|
17
|
-
def create
|
|
18
|
-
filled_options = Kitsune::Kit::OptionsBuilder.build(
|
|
19
|
-
options,
|
|
20
|
-
required: [:server_ip],
|
|
21
|
-
defaults: Kitsune::Kit::Defaults.ssh
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
with_ssh_connection(filled_options) do |ssh|
|
|
25
|
-
perform_setup(ssh)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
desc "rollback", "Remove installed Docker prerequisites from the remote server"
|
|
30
|
-
def rollback
|
|
31
|
-
filled_options = Kitsune::Kit::OptionsBuilder.build(
|
|
32
|
-
options,
|
|
33
|
-
required: [:server_ip],
|
|
34
|
-
defaults: Kitsune::Kit::Defaults.ssh
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
with_ssh_connection(filled_options) do |ssh|
|
|
38
|
-
perform_rollback(ssh)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
no_commands do
|
|
43
|
-
def with_ssh_connection(filled_options)
|
|
44
|
-
server = filled_options[:server_ip]
|
|
45
|
-
port = filled_options[:ssh_port]
|
|
46
|
-
key = File.expand_path(filled_options[:ssh_key_path])
|
|
47
|
-
|
|
48
|
-
say "🔑 Connecting as deploy@#{server}:#{port}", :green
|
|
49
|
-
Net::SSH.start(server, "deploy", port: port, keys: [key], non_interactive: true, timeout: 5) do |ssh|
|
|
50
|
-
yield ssh
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def perform_setup(ssh)
|
|
55
|
-
output = ssh.exec! <<~EOH
|
|
56
|
-
set -e
|
|
57
|
-
|
|
58
|
-
sudo mkdir -p /usr/local/backups
|
|
59
|
-
sudo chown deploy:deploy /usr/local/backups
|
|
60
|
-
|
|
61
|
-
BACKUP_DIR="/usr/local/backups"
|
|
62
|
-
SCRIPT_ID="setup_docker_prereqs"
|
|
63
|
-
BEFORE_FILE="${BACKUP_DIR}/${SCRIPT_ID}.before"
|
|
64
|
-
AFTER_FILE="${BACKUP_DIR}/${SCRIPT_ID}.after"
|
|
65
|
-
|
|
66
|
-
TARGET_PKGS=(
|
|
67
|
-
apt-transport-https
|
|
68
|
-
ca-certificates
|
|
69
|
-
curl
|
|
70
|
-
gnupg
|
|
71
|
-
lsb-release
|
|
72
|
-
software-properties-common
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
echo "✍🏻 TARGET_PKGS=(\${TARGET_PKGS[*]})"
|
|
76
|
-
|
|
77
|
-
if [ ! -f "$AFTER_FILE" ]; then
|
|
78
|
-
for pkg in "\${TARGET_PKGS[@]}"; do
|
|
79
|
-
if dpkg -l "\$pkg" &>/dev/null; then
|
|
80
|
-
echo "\$pkg" >> "$BEFORE_FILE"
|
|
81
|
-
fi
|
|
82
|
-
done
|
|
83
|
-
|
|
84
|
-
echo "✍🏻 Installing prerequisites..."
|
|
85
|
-
sudo apt-get update -y
|
|
86
|
-
sudo apt-get install -y "\${TARGET_PKGS[@]}"
|
|
87
|
-
sudo touch "$AFTER_FILE" && echo " - marker created at $AFTER_FILE"
|
|
88
|
-
else
|
|
89
|
-
echo "🔁 Already set up, ensuring latest"
|
|
90
|
-
sudo apt-get update -y
|
|
91
|
-
sudo apt-get install -y "\${TARGET_PKGS[@]}"
|
|
92
|
-
echo "✅ Prerequisites are current"
|
|
93
|
-
fi
|
|
94
|
-
EOH
|
|
95
|
-
say output
|
|
96
|
-
say "✅ Docker prerequisites setup completed", :green
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def perform_rollback(ssh)
|
|
100
|
-
output = ssh.exec! <<~EOH
|
|
101
|
-
set -e
|
|
102
|
-
|
|
103
|
-
sudo mkdir -p /usr/local/backups
|
|
104
|
-
sudo chown deploy:deploy /usr/local/backups
|
|
105
|
-
|
|
106
|
-
BACKUP_DIR="/usr/local/backups"
|
|
107
|
-
SCRIPT_ID="setup_docker_prereqs"
|
|
108
|
-
BEFORE_FILE="${BACKUP_DIR}/${SCRIPT_ID}.before"
|
|
109
|
-
AFTER_FILE="${BACKUP_DIR}/${SCRIPT_ID}.after"
|
|
110
|
-
|
|
111
|
-
TARGET_PKGS=(
|
|
112
|
-
apt-transport-https
|
|
113
|
-
ca-certificates
|
|
114
|
-
curl
|
|
115
|
-
gnupg
|
|
116
|
-
lsb-release
|
|
117
|
-
software-properties-common
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
echo "✍🏻 TARGET_PKGS=(\${TARGET_PKGS[*]})"
|
|
121
|
-
|
|
122
|
-
if [ -f "$AFTER_FILE" ]; then
|
|
123
|
-
to_remove=()
|
|
124
|
-
for pkg in "\${TARGET_PKGS[@]}"; do
|
|
125
|
-
if dpkg -l "\$pkg" &>/dev/null; then
|
|
126
|
-
if ! grep -Fxq "\$pkg" "$BEFORE_FILE"; then
|
|
127
|
-
to_remove+=("\$pkg")
|
|
128
|
-
fi
|
|
129
|
-
fi
|
|
130
|
-
done
|
|
131
|
-
|
|
132
|
-
if [ \${#to_remove[@]} -gt 0 ]; then
|
|
133
|
-
echo "🔁 Removing packages..."
|
|
134
|
-
sudo apt-get remove -y "\${to_remove[@]}" && echo " - removed: \${to_remove[*]}"
|
|
135
|
-
else
|
|
136
|
-
echo " - no new packages to remove"
|
|
137
|
-
fi
|
|
138
|
-
|
|
139
|
-
sudo rm -f "$BEFORE_FILE" "$AFTER_FILE" && echo " - backups removed"
|
|
140
|
-
else
|
|
141
|
-
echo " - no marker for $SCRIPT_ID, skipping removal"
|
|
142
|
-
fi
|
|
143
|
-
EOH
|
|
144
|
-
say output
|
|
145
|
-
say "✅ Docker prerequisites rollback completed", :green
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
end
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
require "thor"
|
|
2
|
-
require "net/ssh"
|
|
3
|
-
require_relative "../defaults"
|
|
4
|
-
require_relative "../options_builder"
|
|
5
|
-
|
|
6
|
-
module Kitsune
|
|
7
|
-
module Kit
|
|
8
|
-
module Commands
|
|
9
|
-
class SetupFirewall < Thor
|
|
10
|
-
namespace "setup_firewall"
|
|
11
|
-
|
|
12
|
-
class_option :server_ip, aliases: "-s", required: true, desc: "Server IP address or hostname"
|
|
13
|
-
class_option :ssh_port, aliases: "-p", desc: "SSH port"
|
|
14
|
-
class_option :ssh_key_path, aliases: "-k", desc: "Path to your private SSH key"
|
|
15
|
-
|
|
16
|
-
desc "create", "Setup UFW firewall rules on the remote server"
|
|
17
|
-
def create
|
|
18
|
-
filled_options = Kitsune::Kit::OptionsBuilder.build(
|
|
19
|
-
options,
|
|
20
|
-
required: [:server_ip],
|
|
21
|
-
defaults: Kitsune::Kit::Defaults.ssh
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
with_ssh_connection(filled_options) do |ssh|
|
|
25
|
-
perform_setup(ssh, filled_options)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
desc "rollback", "Remove UFW firewall rules and disable UFW on the remote server"
|
|
30
|
-
def rollback
|
|
31
|
-
filled_options = Kitsune::Kit::OptionsBuilder.build(
|
|
32
|
-
options,
|
|
33
|
-
required: [:server_ip],
|
|
34
|
-
defaults: Kitsune::Kit::Defaults.ssh
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
with_ssh_connection(filled_options) do |ssh|
|
|
38
|
-
perform_rollback(ssh, filled_options)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
no_commands do
|
|
43
|
-
def with_ssh_connection(filled_options)
|
|
44
|
-
server = filled_options[:server_ip]
|
|
45
|
-
port = filled_options[:ssh_port]
|
|
46
|
-
key = File.expand_path(filled_options[:ssh_key_path])
|
|
47
|
-
|
|
48
|
-
say "🔑 Connecting as deploy@#{server}:#{port}", :green
|
|
49
|
-
Net::SSH.start(server, "deploy", port: port, keys: [key], non_interactive: true, timeout: 5) do |ssh|
|
|
50
|
-
yield ssh
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def perform_setup(ssh, filled_options)
|
|
55
|
-
ssh_port = filled_options[:ssh_port]
|
|
56
|
-
|
|
57
|
-
output = ssh.exec! <<~EOH
|
|
58
|
-
set -e
|
|
59
|
-
|
|
60
|
-
echo "✍🏻 Updating repositories and ensuring UFW is installed…"
|
|
61
|
-
if ! dpkg -l | grep -q ufw; then
|
|
62
|
-
sudo apt-get update -y
|
|
63
|
-
sudo apt-get install -y ufw && echo " - ufw installed"
|
|
64
|
-
else
|
|
65
|
-
echo " - ufw is already installed"
|
|
66
|
-
fi
|
|
67
|
-
|
|
68
|
-
echo "✍🏻 Configuring UFW rules…"
|
|
69
|
-
add_rule() {
|
|
70
|
-
local rule="$1"
|
|
71
|
-
if ! sudo ufw status | grep -q "$rule"; then
|
|
72
|
-
sudo ufw allow "$rule" >/dev/null 2>&1 && echo " - rule '$rule' added"
|
|
73
|
-
else
|
|
74
|
-
echo " - rule '$rule' already exists"
|
|
75
|
-
fi
|
|
76
|
-
}
|
|
77
|
-
add_rule "#{ssh_port}/tcp"
|
|
78
|
-
add_rule "80/tcp"
|
|
79
|
-
add_rule "443/tcp"
|
|
80
|
-
|
|
81
|
-
echo "✍🏻 Enabling UFW logging…"
|
|
82
|
-
if ! sudo ufw status verbose | grep -q "Logging: on"; then
|
|
83
|
-
sudo ufw logging on >/dev/null 2>&1 && echo " - logging enabled"
|
|
84
|
-
else
|
|
85
|
-
echo " - logging was already enabled"
|
|
86
|
-
fi
|
|
87
|
-
|
|
88
|
-
echo "✍🏻 Enabling UFW…"
|
|
89
|
-
if sudo ufw status | grep -q "Status: inactive"; then
|
|
90
|
-
sudo ufw --force enable >/dev/null 2>&1 && echo " - UFW enabled"
|
|
91
|
-
else
|
|
92
|
-
echo " - UFW is already enabled"
|
|
93
|
-
fi
|
|
94
|
-
EOH
|
|
95
|
-
say output
|
|
96
|
-
say "✅ Firewall setup completed", :green
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def perform_rollback(ssh, filled_options)
|
|
100
|
-
ssh_port = filled_options[:ssh_port]
|
|
101
|
-
|
|
102
|
-
output = ssh.exec! <<~EOH
|
|
103
|
-
set -e
|
|
104
|
-
|
|
105
|
-
echo "🔁 Removing UFW rules…"
|
|
106
|
-
delete_rule() {
|
|
107
|
-
local rule="$1"
|
|
108
|
-
if sudo ufw status | grep -q "$rule"; then
|
|
109
|
-
sudo ufw delete allow "$rule" >/dev/null 2>&1 && echo " - rule '$rule' removed"
|
|
110
|
-
else
|
|
111
|
-
echo " - rule '$rule' does not exist"
|
|
112
|
-
fi
|
|
113
|
-
}
|
|
114
|
-
delete_rule "#{ssh_port}/tcp"
|
|
115
|
-
delete_rule "80/tcp"
|
|
116
|
-
delete_rule "443/tcp"
|
|
117
|
-
|
|
118
|
-
echo "✍🏻 Disabling UFW if active…"
|
|
119
|
-
if sudo ufw status | grep -q "Status: inactive"; then
|
|
120
|
-
echo " - UFW is already inactive"
|
|
121
|
-
else
|
|
122
|
-
sudo ufw --force disable >/dev/null 2>&1 && echo " - UFW disabled"
|
|
123
|
-
fi
|
|
124
|
-
EOH
|
|
125
|
-
say output
|
|
126
|
-
say "✅ Firewall rollback completed", :green
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
end
|