swarm_cluster_cli_ope 0.5.2 → 0.6
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 +16 -0
- data/Gemfile.lock +13 -14
- data/README.md +17 -3
- data/lib/swarm_cluster_cli_ope/base_configuration.rb +2 -0
- data/lib/swarm_cluster_cli_ope/kubernetes/configuration.rb +1 -1
- data/lib/swarm_cluster_cli_ope/kubernetes/pod.rb +1 -0
- data/lib/swarm_cluster_cli_ope/kubernetes/sync_configs/rsync.rb +36 -10
- data/lib/swarm_cluster_cli_ope/sync_configs/env_configs.rb +29 -9
- data/lib/swarm_cluster_cli_ope/sync_configs/mongo_db.rb +94 -0
- data/lib/swarm_cluster_cli_ope/sync_configs/post_gres.rb +8 -5
- data/lib/swarm_cluster_cli_ope/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 956724efc48101ced01f9b90733cb45f4e7278a7e8da2d54edf7e85a1b103cab
|
4
|
+
data.tar.gz: e3d20867dcd4bc2cafa42b9997bfdbbf4cfeea4cbeb50881bdbebf615320056a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 898033f68020b639df391e38728e8ac63fc284b29dbb7ead531578f10fc11aaa102d2109ebe4d43db9254a1ca2df63149ff8d50341bf7bf509a2d1e0dea5f611
|
7
|
+
data.tar.gz: 85f316b0cef0d08ce7f768d7d35a67b023b728a86315433cb4bcaaf45fdaf1c71e46d609f7255a593a2aea61860d037f84bf259a5e39d417f8b64a9850c610b0
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
## Changelog
|
2
2
|
|
3
|
+
# 0.6
|
4
|
+
- sync con MongoDB
|
5
|
+
|
6
|
+
# 0.5.6
|
7
|
+
- correzione parsing variabili ambiente con '=='
|
8
|
+
|
9
|
+
# 0.5.5
|
10
|
+
- correzione utilizzo e configurazione variabili ambiente nelle configurazioni.
|
11
|
+
- controllo di non installare rsync e killall nel caso siano già presenti.
|
12
|
+
|
13
|
+
# 0.5.4
|
14
|
+
- bug permessi sul file password dell'rsync
|
15
|
+
|
16
|
+
# 0.5.3
|
17
|
+
- bug selezione pod, ora filtra solamente per i containers che sono attivi
|
18
|
+
|
3
19
|
# 0.4
|
4
20
|
- implementazione push pull con il comando **stacksync** di pg
|
5
21
|
- controllo di versione sul file caricato rispeto a gemma, con conseguente warning
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
swarm_cluster_cli_ope (0.
|
4
|
+
swarm_cluster_cli_ope (0.6)
|
5
5
|
activesupport
|
6
6
|
open4
|
7
7
|
thor (~> 1.0)
|
@@ -10,23 +10,22 @@ PATH
|
|
10
10
|
GEM
|
11
11
|
remote: https://rubygems.org/
|
12
12
|
specs:
|
13
|
-
activesupport (6.
|
13
|
+
activesupport (6.1.3)
|
14
14
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
15
|
-
i18n (>=
|
16
|
-
minitest (
|
17
|
-
tzinfo (~>
|
18
|
-
zeitwerk (~> 2.
|
19
|
-
concurrent-ruby (1.1.
|
20
|
-
i18n (1.8.
|
15
|
+
i18n (>= 1.6, < 2)
|
16
|
+
minitest (>= 5.1)
|
17
|
+
tzinfo (~> 2.0)
|
18
|
+
zeitwerk (~> 2.3)
|
19
|
+
concurrent-ruby (1.1.8)
|
20
|
+
i18n (1.8.9)
|
21
21
|
concurrent-ruby (~> 1.0)
|
22
|
-
minitest (5.14.
|
22
|
+
minitest (5.14.4)
|
23
23
|
open4 (1.3.4)
|
24
24
|
rake (12.3.3)
|
25
|
-
thor (1.0
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
zeitwerk (2.4.1)
|
25
|
+
thor (1.1.0)
|
26
|
+
tzinfo (2.0.4)
|
27
|
+
concurrent-ruby (~> 1.0)
|
28
|
+
zeitwerk (2.4.2)
|
30
29
|
|
31
30
|
PLATFORMS
|
32
31
|
ruby
|
data/README.md
CHANGED
@@ -112,10 +112,11 @@ ogni configurazione è composta da:
|
|
112
112
|
|
113
113
|
- service è il nome del servizio (o nel caso di k8s una stringa da utilizzare come selettore labels)
|
114
114
|
- how è il come sincronizzare, definendo la tipologia:
|
115
|
-
- pg -> DB
|
115
|
+
- pg -> DB: dump del DB con pgdump
|
116
116
|
- mysql -> DB: dump del db con mysqldump
|
117
117
|
- sqlite3 -> DB: viene eseguita una copia del file
|
118
118
|
- rsync -> RSYNC
|
119
|
+
- mongodb -> mongodump e mongorestore
|
119
120
|
- configs: è un hash con le configurazioni per ogni tipo di sincronizzazione
|
120
121
|
|
121
122
|
Possibili CFGS per tipologia:
|
@@ -159,8 +160,21 @@ Possibili CFGS per tipologia:
|
|
159
160
|
- pg_user_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: POSTGRES_USER
|
160
161
|
- pg_user: "postgres" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: postgres
|
161
162
|
- database_name_env: "POSTGRES_DB" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: POSTGRES_DB
|
162
|
-
- database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
|
163
|
-
|
163
|
+
- database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
|
164
|
+
- mongo:
|
165
|
+
- local: -> hash di configurazioni per il DB locale
|
166
|
+
- service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
|
167
|
+
- password: "" -> password per DB
|
168
|
+
- username: "" -> username per DB
|
169
|
+
- database_name: "nome_db" -> nome del DB
|
170
|
+
- exclude_from_sync: "coll1,coll2" -> elenco di collections di cui non eseguire il dump quando facciamo PUSH, DEFAULT: ''
|
171
|
+
- remote: -> hash di configurazioni per il DB remoto
|
172
|
+
- service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
|
173
|
+
- password: "" -> password per DB
|
174
|
+
- username: "" -> username per DB
|
175
|
+
- database_name: "nome_db" -> nome del DB
|
176
|
+
- exclude_from_sync: "coll1,coll2" -> elenco di collections di cui non eseguire il dump quando facciamo PULL, DEFAULT: ''
|
177
|
+
|
164
178
|
#### EXAMPLE:
|
165
179
|
Esempio di sincronizzazione di un file sqlite3 e una cartella
|
166
180
|
|
@@ -90,6 +90,7 @@ module SwarmClusterCliOpe
|
|
90
90
|
base_cmd << "--context=#{context}" unless context.blank?
|
91
91
|
base_cmd << "get pod"
|
92
92
|
base_cmd << "--selector=#{selector}"
|
93
|
+
base_cmd << "--field-selector=status.phase=Running" #solo pod che stanno girando teniamo sotto controllo
|
93
94
|
base_cmd << "--output=json"
|
94
95
|
|
95
96
|
cmd = ShellCommandExecution.new(base_cmd)
|
@@ -15,7 +15,6 @@ module SwarmClusterCliOpe
|
|
15
15
|
@configs[:configs][:remote]
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
18
|
# @return [SwarmClusterCliOpe::ShellCommandResponse]
|
20
19
|
def push
|
21
20
|
execute(direction: :up)
|
@@ -26,7 +25,6 @@ module SwarmClusterCliOpe
|
|
26
25
|
execute(direction: :down)
|
27
26
|
end
|
28
27
|
|
29
|
-
|
30
28
|
private
|
31
29
|
|
32
30
|
def execute(direction: :down)
|
@@ -36,7 +34,6 @@ module SwarmClusterCliOpe
|
|
36
34
|
exit
|
37
35
|
end
|
38
36
|
|
39
|
-
|
40
37
|
if yes? "Attenzione, i dati locali o remoti verranno sovrascritti/cancellati?[y,yes]"
|
41
38
|
|
42
39
|
podname = container.name
|
@@ -46,13 +43,30 @@ module SwarmClusterCliOpe
|
|
46
43
|
exit
|
47
44
|
end
|
48
45
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
46
|
+
# controllo presenza comandi necessari
|
47
|
+
command_installed = false
|
48
|
+
cmd_ricerca = container.exec(['bash -c "command -v rsync && command -v killall"'])
|
49
|
+
unless cmd_ricerca.failed?
|
50
|
+
num_commands = cmd_ricerca.raw_result[:stdout].split("\n").count rescue 0
|
51
|
+
if num_commands == 2
|
52
|
+
command_installed = true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
unless command_installed
|
57
|
+
# tentiamo di installarlo
|
58
|
+
cmd = container.exec(['bash -c "apt update && apt install -yq rsync psmisc"'])
|
59
|
+
if cmd.failed?
|
60
|
+
puts "Problemi nell'installazione di rsync nel pod"
|
61
|
+
else
|
62
|
+
command_installed = true
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
if command_installed
|
67
|
+
cmd = container.cp_in(configs_path("rsyncd.conf"), "/tmp/.")
|
54
68
|
copy_1 = cmd.execute.failed?
|
55
|
-
cmd = container.cp_in(
|
69
|
+
cmd = container.cp_in(configs_path("rsyncd.secrets"), "/tmp/.")
|
56
70
|
copy_2 = cmd.execute.failed?
|
57
71
|
cmd = container.exec(['bash -c "chmod 600 /tmp/rsyncd.secrets && chown root /tmp/*"'])
|
58
72
|
chmod = cmd.failed?
|
@@ -76,11 +90,15 @@ module SwarmClusterCliOpe
|
|
76
90
|
|
77
91
|
sleep 1
|
78
92
|
|
93
|
+
# forzo i permessi sul file della password
|
94
|
+
cmd = ShellCommandExecution.new(["chmod 600 #{ configs_path("password")}"])
|
95
|
+
cmd.execute
|
96
|
+
|
79
97
|
# lanciamo il comando quindi per far rsync
|
80
98
|
rsync_command = [
|
81
99
|
"rsync -az --no-o --no-g",
|
82
100
|
"--delete",
|
83
|
-
"--password-file=#{
|
101
|
+
"--password-file=#{ configs_path("password")}"
|
84
102
|
]
|
85
103
|
|
86
104
|
if direction == :up
|
@@ -119,6 +137,14 @@ module SwarmClusterCliOpe
|
|
119
137
|
|
120
138
|
end
|
121
139
|
|
140
|
+
##
|
141
|
+
# Estrapola la path al file di configurazione
|
142
|
+
# @param [String] file
|
143
|
+
# @return [String]
|
144
|
+
def configs_path(file)
|
145
|
+
File.expand_path("../../rsync_cfgs/#{file}", __FILE__)
|
146
|
+
end
|
147
|
+
|
122
148
|
end
|
123
149
|
end
|
124
150
|
end
|
@@ -17,6 +17,7 @@ module SwarmClusterCliOpe
|
|
17
17
|
##
|
18
18
|
# Metodo che richiama la lambda della generazione del container al momento che ne
|
19
19
|
# è proprio necessario
|
20
|
+
# @return [SwarmClusterCliOpe::Commands::Container,SwarmClusterCliOpe::Kubernetes::Pod]
|
20
21
|
def container
|
21
22
|
@container ||= @lambda_container.call
|
22
23
|
end
|
@@ -26,17 +27,17 @@ module SwarmClusterCliOpe
|
|
26
27
|
@configs[:service] || @sync_configs.service
|
27
28
|
end
|
28
29
|
|
29
|
-
|
30
30
|
##
|
31
31
|
# Costruisce i metodi che restituiscono i valori delle configurazioni
|
32
32
|
#
|
33
33
|
# @param [String,Symbol] name -> nome della stringa con cui viene generato il metodo
|
34
|
-
# @param [String,Symbol] default_env -> nome env default nel caso non sia passato
|
34
|
+
# @param [String,Symbol,Array<String,Symbol>] default_env -> nome env default nel caso non sia passato
|
35
35
|
# @param [String,Symbol] configuration_name -> nome della configurazione da utilizzare per estrapolare la configurazione
|
36
36
|
# in automatico viene tenuto conto se cercare per la versione
|
37
37
|
# con _env o senza....precedenza SENZA
|
38
|
+
# @param [Block] from_proc -> proc da utilizzare per ricavare il valore
|
38
39
|
# @param [nil,String] default_value se non è estrapolato nessun valore, viene utilizzato il valore di default
|
39
|
-
def self.define_cfgs(name, default_env
|
40
|
+
def self.define_cfgs(name, default_env: nil, configuration_name:, default_value: nil, from_proc: nil)
|
40
41
|
configuration_name ||= name
|
41
42
|
|
42
43
|
define_method(name) do
|
@@ -44,23 +45,42 @@ module SwarmClusterCliOpe
|
|
44
45
|
|
45
46
|
#valore restituito direttamente dalla configurazione
|
46
47
|
if @configs.key?(configuration_name)
|
47
|
-
value = @configs["#{configuration_name}".to_sym]
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
value = @configs["#{configuration_name}".to_sym]
|
49
|
+
end
|
50
|
+
# se non abbiamo nulla dalle configurazioni utilizziamo le variabili d'ambiente
|
51
|
+
if value.nil? and default_env
|
52
|
+
|
53
|
+
#cerchiamo nella lista delle variabili ambiente possibili, la prima che ha un valore la tengo per buona
|
54
|
+
env_vars = []
|
55
|
+
env_vars << @configs["#{configuration_name}_env".to_sym]
|
56
|
+
env_vars << default_env
|
57
|
+
env_vars.flatten!
|
58
|
+
env_vars.compact!
|
59
|
+
|
60
|
+
env_vars.each do |env_var|
|
61
|
+
value = find_env_file_variable(env_var)
|
62
|
+
break unless value.nil?
|
63
|
+
end
|
64
|
+
|
51
65
|
end
|
66
|
+
# se non abbiamo ancora nulla e abbiamo una proc proseguiamo
|
67
|
+
if value.nil? and from_proc
|
68
|
+
value = from_proc.call(container)
|
69
|
+
end
|
70
|
+
|
71
|
+
value = value || default_value
|
72
|
+
|
52
73
|
self.instance_variable_set("@#{name}", value)
|
53
74
|
end
|
54
75
|
|
55
76
|
end
|
56
77
|
|
57
|
-
|
58
78
|
private
|
59
79
|
|
60
80
|
##
|
61
81
|
# Estrae l'env dal container e ne tiene in memoria una copia, in modo da non fare multiple chiamate
|
62
82
|
def env
|
63
|
-
@env ||= container.exec("env").raw_result[:stdout].
|
83
|
+
@env ||= Hash[ container.exec("env").raw_result[:stdout].scan(/-{0,2}([^=\s]+)(?:[=\s](\S+))?/) ]
|
64
84
|
end
|
65
85
|
|
66
86
|
def find_env_file_variable(env_var)
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module SwarmClusterCliOpe
|
2
|
+
module SyncConfigs
|
3
|
+
class MongoDb < BaseDatabase
|
4
|
+
|
5
|
+
# @return [TrueClass, FalseClass]
|
6
|
+
def pull
|
7
|
+
resume('pull')
|
8
|
+
if yes?("Confermare il comando?[y,yes]")
|
9
|
+
|
10
|
+
tmp_file = make_dump(remote, container)
|
11
|
+
|
12
|
+
local_container.copy_in(tmp_file, tmp_file)
|
13
|
+
|
14
|
+
restore(tmp_file, remote, local, local_container)
|
15
|
+
end
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [TrueClass, FalseClass]
|
20
|
+
def push
|
21
|
+
resume('PUSH')
|
22
|
+
if yes?("ATTENZIONE !!!!!!PUSH!!!!! - Confermare il comando?[y,yes]")
|
23
|
+
tmp_file = make_dump(local, local_container)
|
24
|
+
container.copy_in(tmp_file, tmp_file)
|
25
|
+
restore(tmp_file, local, remote, container)
|
26
|
+
end
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Classe interna che rappresenta le configurazioni del DB
|
32
|
+
class EnvConfigs < BaseDatabase::EnvConfigs
|
33
|
+
|
34
|
+
define_cfgs :database_name, configuration_name: :database_name
|
35
|
+
define_cfgs :username, configuration_name: :username
|
36
|
+
define_cfgs :password, configuration_name: :password
|
37
|
+
|
38
|
+
define_cfgs :database_version, default_env: "MONGO_VERSION", configuration_name: :version
|
39
|
+
|
40
|
+
##
|
41
|
+
# Possiamo definire una lista, comma-separated, per limitare le collections da non importare
|
42
|
+
define_cfgs :exclude_from_sync, default_env: "EXCLUDE_FROM_SYNC", configuration_name: :exclude_from_sync, default_value: ""
|
43
|
+
|
44
|
+
##
|
45
|
+
# Helper per avere un array di collections da non sincronizzare, specifico per mongodb
|
46
|
+
# @return [Array<String>]
|
47
|
+
def excluded_collections
|
48
|
+
return [] if exclude_from_sync.nil?
|
49
|
+
exclude_from_sync.split(",").compact
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# @param [String] tmp_file
|
57
|
+
# @param [EnvConfigs] from_env environment sorgente (per rinominare anche il nome del DB)
|
58
|
+
# @param [EnvConfigs] to_env environment di arrivo (per rinominare anche il nome del DB)
|
59
|
+
# @param [SwarmClusterCliOpe::Models::Container] cnt in cui eseguire l'import
|
60
|
+
def restore(tmp_file, from_env, to_env, cnt)
|
61
|
+
command = []
|
62
|
+
command << "bash -c '"
|
63
|
+
command << "mongorestore"
|
64
|
+
command << "--nsFrom '#{from_env.database_name}.*'"
|
65
|
+
command << "--nsTo '#{to_env.database_name}.*'"
|
66
|
+
command << "--drop --archive=#{tmp_file} --gzip"
|
67
|
+
command << "'"
|
68
|
+
|
69
|
+
cnt.exec(command.join " ")
|
70
|
+
end
|
71
|
+
|
72
|
+
# @param [EnvConfigs] environment
|
73
|
+
# @param [SwarmClusterCliOpe::Models::Container] cnt
|
74
|
+
def make_dump(environment, cnt)
|
75
|
+
tmp_file = "/tmp/dump.#{Time.now.to_i}.archive"
|
76
|
+
command = []
|
77
|
+
command << "bash -c '"
|
78
|
+
|
79
|
+
command << "mongodump --db #{environment.database_name} "
|
80
|
+
environment.excluded_collections.each do |collection|
|
81
|
+
command << " --excludeCollection \"#{collection}\" "
|
82
|
+
end
|
83
|
+
command << "--username \"#{environment.username}\" " if environment.username
|
84
|
+
command << "--password \"#{environment.password}\" " if environment.password
|
85
|
+
command << "--archive --gzip"
|
86
|
+
|
87
|
+
command << "' > #{tmp_file}"
|
88
|
+
cnt.exec(command.join " ")
|
89
|
+
tmp_file
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -50,11 +50,14 @@ module SwarmClusterCliOpe
|
|
50
50
|
# Classe interna che rappresenta le configurazioni del DB
|
51
51
|
class EnvConfigs < BaseDatabase::EnvConfigs
|
52
52
|
|
53
|
-
define_cfgs :database_name, default_env: "POSTGRES_DB", configuration_name: :database_name
|
54
|
-
define_cfgs :username, default_env: "POSTGRES_USER", configuration_name: :pg_user, default_value: 'postgres'
|
55
|
-
define_cfgs :password, default_env: "POSTGRES_PASSWORD", configuration_name: :pg_password
|
56
|
-
|
57
|
-
define_cfgs :database_version, default_env: "PG_MAJOR", configuration_name: :pg_version
|
53
|
+
define_cfgs :database_name, default_env: ["POSTGRES_DB", "POSTGRESQL_DATABASE"], configuration_name: :database_name
|
54
|
+
define_cfgs :username, default_env: ["POSTGRES_USER", "POSTGRESQL_USERNAME"], configuration_name: :pg_user, default_value: 'postgres'
|
55
|
+
define_cfgs :password, default_env: ["POSTGRES_PASSWORD", "POSTGRESQL_PASSWORD"], configuration_name: :pg_password
|
56
|
+
|
57
|
+
define_cfgs :database_version, default_env: "PG_MAJOR", configuration_name: :pg_version,
|
58
|
+
from_proc: ->(container) {
|
59
|
+
container.exec("postgres -V").raw_result[:stdout].strip.match(/((\d+\.)?(\d+\.)?(\*|\d+))$/)[1] rescue nil
|
60
|
+
}
|
58
61
|
|
59
62
|
end
|
60
63
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: swarm_cluster_cli_ope
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.6'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marino Bonetti
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -126,6 +126,7 @@ files:
|
|
126
126
|
- lib/swarm_cluster_cli_ope/sync_configs/base_database.rb
|
127
127
|
- lib/swarm_cluster_cli_ope/sync_configs/copy.rb
|
128
128
|
- lib/swarm_cluster_cli_ope/sync_configs/env_configs.rb
|
129
|
+
- lib/swarm_cluster_cli_ope/sync_configs/mongo_db.rb
|
129
130
|
- lib/swarm_cluster_cli_ope/sync_configs/mysql.rb
|
130
131
|
- lib/swarm_cluster_cli_ope/sync_configs/post_gres.rb
|
131
132
|
- lib/swarm_cluster_cli_ope/sync_configs/rsync.rb
|