vagrant-docker-certificates-manager 0.2.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 +7 -0
- data/CHANGELOG.md +8 -0
- data/LICENSE.md +22 -0
- data/README.md +197 -0
- data/lib/vagrant-docker-certificates-manager/VERSION +1 -0
- data/lib/vagrant-docker-certificates-manager/actions/install.rb +60 -0
- data/lib/vagrant-docker-certificates-manager/actions/uninstall.rb +47 -0
- data/lib/vagrant-docker-certificates-manager/command.rb +190 -0
- data/lib/vagrant-docker-certificates-manager/config.rb +38 -0
- data/lib/vagrant-docker-certificates-manager/helpers.rb +179 -0
- data/lib/vagrant-docker-certificates-manager/plugin.rb +32 -0
- data/lib/vagrant-docker-certificates-manager/util/cert.rb +35 -0
- data/lib/vagrant-docker-certificates-manager/util/os.rb +132 -0
- data/lib/vagrant-docker-certificates-manager/util/registry.rb +53 -0
- data/lib/vagrant-docker-certificates-manager/util/ui.rb +31 -0
- data/lib/vagrant-docker-certificates-manager/version.rb +10 -0
- data/lib/vagrant-docker-certificates-manager.rb +3 -0
- data/locales/en.yml +93 -0
- data/locales/fr.yml +93 -0
- metadata +110 -0
@@ -0,0 +1,179 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "i18n"
|
4
|
+
require "yaml"
|
5
|
+
|
6
|
+
module VagrantDockerCertificatesManager
|
7
|
+
module UiHelpers
|
8
|
+
class MissingTranslationError < StandardError; end
|
9
|
+
class UnsupportedLocaleError < StandardError; end
|
10
|
+
|
11
|
+
SUPPORTED = [:en, :fr].freeze
|
12
|
+
NAMESPACE = "vdcm".freeze
|
13
|
+
OUR_SPACES = %w[messages. errors. usage. help. prompts. log. emoji. cli. add. remove. list. install.
|
14
|
+
uninstall.].freeze
|
15
|
+
|
16
|
+
EMOJI = {
|
17
|
+
success: "✅",
|
18
|
+
info: "🔍",
|
19
|
+
ongoing: "🔁",
|
20
|
+
warning: "⚠️",
|
21
|
+
error: "❌",
|
22
|
+
version: "💾",
|
23
|
+
broom: "🧹",
|
24
|
+
question: "❓"
|
25
|
+
}.freeze
|
26
|
+
|
27
|
+
module_function
|
28
|
+
|
29
|
+
def setup_i18n!
|
30
|
+
return if defined?(@i18n_setup) && @i18n_setup
|
31
|
+
::I18n.enforce_available_locales = false
|
32
|
+
base = File.expand_path("../../locales", __dir__)
|
33
|
+
::I18n.load_path |= Dir[File.join(base, "*.yml")]
|
34
|
+
::I18n.available_locales = SUPPORTED
|
35
|
+
default = ((ENV["VDCM_LANG"] || ENV["LANG"] || "en")[0,2] rescue "en").to_sym
|
36
|
+
::I18n.default_locale = SUPPORTED.include?(default) ? default : :en
|
37
|
+
::I18n.backend.load_translations
|
38
|
+
@i18n_setup = true
|
39
|
+
end
|
40
|
+
|
41
|
+
def set_locale!(lang, strict: false)
|
42
|
+
setup_i18n!
|
43
|
+
|
44
|
+
raw = (lang || ENV["VDCM_LANG"] || ENV["LANG"] || "en").to_s
|
45
|
+
sym = raw[0, 2].to_s.downcase.to_sym
|
46
|
+
sym = :en if sym.nil? || sym == :""
|
47
|
+
|
48
|
+
unless SUPPORTED.include?(sym)
|
49
|
+
if strict
|
50
|
+
raise UnsupportedLocaleError,
|
51
|
+
"#{e(:error)} Unsupported language: #{sym}. Available: #{SUPPORTED.join(', ')}"
|
52
|
+
else
|
53
|
+
sym = :en
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
::I18n.locale = sym
|
58
|
+
::I18n.backend.load_translations
|
59
|
+
sym
|
60
|
+
end
|
61
|
+
|
62
|
+
def e(key, no_emoji: false)
|
63
|
+
return "" if no_emoji || ENV["VDCM_NO_EMOJI"] == "1"
|
64
|
+
EMOJI[key] || ""
|
65
|
+
end
|
66
|
+
|
67
|
+
def ns_key(key)
|
68
|
+
k = key.to_s
|
69
|
+
k.start_with?("#{NAMESPACE}.") ? k : "#{NAMESPACE}.#{k}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def t(key, **opts)
|
73
|
+
setup_i18n!
|
74
|
+
::I18n.t(ns_key(key), **opts)
|
75
|
+
end
|
76
|
+
|
77
|
+
def t!(key, **opts)
|
78
|
+
setup_i18n!
|
79
|
+
k = ns_key(key)
|
80
|
+
if our_key?(k) && !::I18n.exists?(k, ::I18n.locale)
|
81
|
+
raise MissingTranslationError, "#{e(:error)} [#{::I18n.locale}] Missing translation for key: #{k}"
|
82
|
+
end
|
83
|
+
::I18n.t(k, **opts)
|
84
|
+
end
|
85
|
+
|
86
|
+
def t_hash(key)
|
87
|
+
v = t(key, default: {})
|
88
|
+
v.is_a?(Hash) ? v : {}
|
89
|
+
end
|
90
|
+
|
91
|
+
def level_to_emoji(level)
|
92
|
+
case level
|
93
|
+
when :success then :success
|
94
|
+
when :warn then :warning
|
95
|
+
when :error then :error
|
96
|
+
else :info
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def say(env_or_ui, level, key = nil, raw: nil, no_emoji: false, **kv)
|
101
|
+
setup_i18n!
|
102
|
+
ui = (env_or_ui.respond_to?(:[]) ? (env_or_ui[:ui] || env_or_ui[:machine]&.ui) : env_or_ui)
|
103
|
+
msg = raw || (key ? t(key, **kv) : nil)
|
104
|
+
return if ui.nil? || msg.nil?
|
105
|
+
|
106
|
+
prefix = e(level_to_emoji(level), no_emoji: no_emoji)
|
107
|
+
line = prefix.empty? ? msg : "#{prefix} #{msg}"
|
108
|
+
|
109
|
+
case level
|
110
|
+
when :warn then ui.warn(line)
|
111
|
+
when :error then ui.error(line)
|
112
|
+
else ui.info(line)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def debug(env_or_ui, msg)
|
117
|
+
return unless ENV["VDCM_DEBUG"].to_s == "1"
|
118
|
+
say(env_or_ui, :info, nil, raw: "#{e(:question)} #{msg}")
|
119
|
+
end
|
120
|
+
|
121
|
+
def print_general_help(no_emoji: false, ui: nil)
|
122
|
+
setup_i18n!
|
123
|
+
lines = []
|
124
|
+
lines << "#{e(:info, no_emoji: no_emoji)} #{t('help.general_title')}"
|
125
|
+
lines << " #{t('cli.usage')}"
|
126
|
+
t_hash("help.commands").each_value { |line| lines << " #{line}" }
|
127
|
+
|
128
|
+
if ui
|
129
|
+
lines.each { |ln| ui.info(ln) }
|
130
|
+
else
|
131
|
+
lines.each { |ln| puts ln }
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def print_topic_help(topic, no_emoji: false, ui: nil)
|
136
|
+
setup_i18n!
|
137
|
+
topic = (topic || "").to_s.strip.downcase
|
138
|
+
return print_general_help(no_emoji: no_emoji, ui: ui) if topic.empty?
|
139
|
+
|
140
|
+
base = "help.topic.#{topic}"
|
141
|
+
title = t("#{base}.title", default: nil)
|
142
|
+
usage = t("#{base}.usage", default: nil)
|
143
|
+
desc = t("#{base}.description", default: nil)
|
144
|
+
opts = t_hash("#{base}.options")
|
145
|
+
exs = ::I18n.t("#{base}.examples", default: [])
|
146
|
+
|
147
|
+
if title.nil? && usage.nil? && desc.nil? && opts.empty? && exs.empty?
|
148
|
+
return print_general_help(no_emoji: no_emoji, ui: ui)
|
149
|
+
end
|
150
|
+
|
151
|
+
lines = []
|
152
|
+
lines << "#{e(:info, no_emoji: no_emoji)} #{title || t('help.topic_fallback_title', topic: topic)}"
|
153
|
+
lines << " #{t('help.usage_label')}"
|
154
|
+
lines << " #{usage || 'vagrant certs help'}"
|
155
|
+
if desc && !desc.strip.empty?
|
156
|
+
lines << " #{t('help.description_label')}"
|
157
|
+
lines << " #{desc}"
|
158
|
+
end
|
159
|
+
unless opts.empty?
|
160
|
+
lines << " #{t('help.options_label')}"
|
161
|
+
opts.each_value { |line| lines << " #{line}" }
|
162
|
+
end
|
163
|
+
if exs.is_a?(Array) && !exs.empty?
|
164
|
+
lines << " #{t('help.examples_label')}"
|
165
|
+
exs.each { |ex| lines << " #{ex}" }
|
166
|
+
end
|
167
|
+
|
168
|
+
if ui
|
169
|
+
lines.each { |ln| ui.info(ln) }
|
170
|
+
else
|
171
|
+
lines.each { |ln| puts ln }
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def our_key?(k)
|
176
|
+
OUR_SPACES.any? { |ns| k.start_with?("#{NAMESPACE}.#{ns}") || k.start_with?(ns) }
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "vagrant"
|
4
|
+
require_relative "version"
|
5
|
+
require_relative "config"
|
6
|
+
require_relative "command"
|
7
|
+
require_relative "helpers"
|
8
|
+
|
9
|
+
module VagrantDockerCertificatesManager
|
10
|
+
class Plugin < Vagrant.plugin("2")
|
11
|
+
name "docker_certificates"
|
12
|
+
|
13
|
+
UiHelpers.setup_i18n!
|
14
|
+
|
15
|
+
config(:docker_certificates) do
|
16
|
+
require_relative "config"
|
17
|
+
VagrantDockerCertificatesManager::Config
|
18
|
+
end
|
19
|
+
|
20
|
+
command("certs") { Command }
|
21
|
+
|
22
|
+
action_hook(:install_cert_on_up, :machine_action_up) do |hook|
|
23
|
+
require_relative "actions/install"
|
24
|
+
hook.after Vagrant::Action::Builtin::Provision, Actions::Install
|
25
|
+
end
|
26
|
+
|
27
|
+
action_hook(:uninstall_cert_on_destroy, :machine_action_destroy) do |hook|
|
28
|
+
require_relative "actions/uninstall"
|
29
|
+
hook.before Vagrant::Action::Builtin::GracefulHalt, Actions::Uninstall
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "openssl"
|
4
|
+
|
5
|
+
module VagrantDockerCertificatesManager
|
6
|
+
module Cert
|
7
|
+
MARKER = "VDCM"
|
8
|
+
|
9
|
+
module_function
|
10
|
+
|
11
|
+
def read_cert(path)
|
12
|
+
OpenSSL::X509::Certificate.new(File.read(path))
|
13
|
+
end
|
14
|
+
|
15
|
+
def sha1(path)
|
16
|
+
cert = read_cert(path)
|
17
|
+
OpenSSL::Digest::SHA1.hexdigest(cert.to_der).upcase
|
18
|
+
end
|
19
|
+
|
20
|
+
def subject_cn(path)
|
21
|
+
cert = read_cert(path)
|
22
|
+
pair = cert.subject.to_a.find { |(k, _v, _t)| k == "CN" }
|
23
|
+
pair ? pair[1].to_s : nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def default_name_from(path)
|
27
|
+
base = File.basename(path).sub(/\.(pem|crt|cer)$/i, "")
|
28
|
+
base.empty? ? "local.dev" : base
|
29
|
+
end
|
30
|
+
|
31
|
+
def nickname_for(name)
|
32
|
+
"#{MARKER}:#{name}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "open3"
|
4
|
+
require_relative "cert"
|
5
|
+
|
6
|
+
module VagrantDockerCertificatesManager
|
7
|
+
module OS
|
8
|
+
module_function
|
9
|
+
|
10
|
+
def detect
|
11
|
+
if defined?(Vagrant) && Vagrant.const_defined?(:Util) && Vagrant::Util.const_defined?(:Platform)
|
12
|
+
return :mac if Vagrant::Util::Platform.darwin?
|
13
|
+
return :windows if Vagrant::Util::Platform.windows?
|
14
|
+
return :linux if Vagrant::Util::Platform.linux?
|
15
|
+
else
|
16
|
+
plat = RbConfig::CONFIG["host_os"].downcase
|
17
|
+
return :mac if plat.include?("darwin")
|
18
|
+
return :windows if plat =~ /mswin|mingw|windows/
|
19
|
+
return :linux if plat.include?("linux")
|
20
|
+
end
|
21
|
+
:unknown
|
22
|
+
end
|
23
|
+
|
24
|
+
def run(cmd)
|
25
|
+
out, err, st = Open3.capture3(cmd)
|
26
|
+
[st.success?, out, err]
|
27
|
+
end
|
28
|
+
|
29
|
+
def mac_add_trusted_cert(path, name)
|
30
|
+
ok, *_ = run(%(sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "#{path}"))
|
31
|
+
ok
|
32
|
+
end
|
33
|
+
|
34
|
+
def mac_has_cert_fingerprint?(fp)
|
35
|
+
ok, out, _ = run(%(security find-certificate -a -Z /Library/Keychains/System.keychain 2>/dev/null))
|
36
|
+
return false unless ok
|
37
|
+
out.include?(fp)
|
38
|
+
end
|
39
|
+
|
40
|
+
def mac_remove_by_fp(fp)
|
41
|
+
ok, out, _ = run(%(security find-certificate -a -Z /Library/Keychains/System.keychain 2>/dev/null))
|
42
|
+
return true unless ok
|
43
|
+
hash = out.lines.find { |l| l =~ /SHA-1 hash:\s*#{fp}/i } ? fp : nil
|
44
|
+
return true unless hash
|
45
|
+
run(%(sudo security delete-certificate -Z #{hash} /Library/Keychains/System.keychain)).first
|
46
|
+
end
|
47
|
+
|
48
|
+
def linux_install_cert(path, name, nss: true, firefox: false)
|
49
|
+
dest = "/usr/local/share/ca-certificates/#{Cert::MARKER.downcase}-#{name}.crt"
|
50
|
+
ok1, = run(%(sudo cp "#{path}" "#{dest}"))
|
51
|
+
ok2, = run("sudo update-ca-certificates")
|
52
|
+
okn = true
|
53
|
+
okn &&= linux_nss_install(path, name) if nss
|
54
|
+
okf = true
|
55
|
+
okf &&= linux_firefox_install(path, name) if firefox
|
56
|
+
ok1 && ok2 && okn && okf
|
57
|
+
end
|
58
|
+
|
59
|
+
def linux_has_cert_file?(name)
|
60
|
+
File.exist?("/usr/local/share/ca-certificates/#{Cert::MARKER.downcase}-#{name}.crt")
|
61
|
+
end
|
62
|
+
|
63
|
+
def linux_uninstall_cert(name, nss: true, firefox: false)
|
64
|
+
dest = "/usr/local/share/ca-certificates/#{Cert::MARKER.downcase}-#{name}.crt"
|
65
|
+
run(%(sudo rm -f "#{dest}"))
|
66
|
+
run("sudo update-ca-certificates")
|
67
|
+
linux_nss_uninstall(name) if nss
|
68
|
+
linux_firefox_uninstall(name) if firefox
|
69
|
+
true
|
70
|
+
end
|
71
|
+
|
72
|
+
def linux_nss_install(path, name)
|
73
|
+
db = %(sql:"$HOME/.pki/nssdb")
|
74
|
+
run(%(certutil -d #{db} -A -t "C,," -n "#{Cert.nickname_for(name)}" -i "#{path}")).first
|
75
|
+
end
|
76
|
+
|
77
|
+
def linux_nss_uninstall(name)
|
78
|
+
db = %(sql:"$HOME/.pki/nssdb")
|
79
|
+
run(%(certutil -d #{db} -D -n "#{Cert.nickname_for(name)}"))
|
80
|
+
true
|
81
|
+
end
|
82
|
+
|
83
|
+
def linux_firefox_profiles
|
84
|
+
home = ENV["HOME"]
|
85
|
+
[
|
86
|
+
"#{home}/.mozilla/firefox",
|
87
|
+
"#{home}/.var/app/org.mozilla.firefox/.mozilla/firefox",
|
88
|
+
"#{home}/snap/firefox/common/.mozilla/firefox"
|
89
|
+
].select { |d| File.directory?(d) }.flat_map { |base| Dir.glob(File.join(base, "*.default*")) }
|
90
|
+
end
|
91
|
+
|
92
|
+
def linux_firefox_install(path, name)
|
93
|
+
profiles = linux_firefox_profiles
|
94
|
+
profiles.all? do |profile|
|
95
|
+
run(%(certutil -A -n "#{Cert.nickname_for(name)}" -t "C,," -i "#{path}" -d "sql:#{profile}")).first
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def linux_firefox_uninstall(name)
|
100
|
+
linux_firefox_profiles.each do |profile|
|
101
|
+
run(%(certutil -D -n "#{Cert.nickname_for(name)}" -d "sql:#{profile}"))
|
102
|
+
end
|
103
|
+
true
|
104
|
+
end
|
105
|
+
|
106
|
+
def win_install_cert(path, name)
|
107
|
+
ok, out, err = run(%(certutil -addstore -f "ROOT" "#{path}"))
|
108
|
+
return false unless ok
|
109
|
+
fp = Cert.sha1(path)
|
110
|
+
ps = %(
|
111
|
+
$cert = Get-ChildItem Cert:\\LocalMachine\\Root | Where-Object { $_.Thumbprint -eq "#{fp}" };
|
112
|
+
if ($cert) { $cert.FriendlyName = "#{Cert.nickname_for(name)}"; }
|
113
|
+
).strip
|
114
|
+
run(%(powershell -NoProfile -NonInteractive -Command "#{ps}"))
|
115
|
+
true
|
116
|
+
end
|
117
|
+
|
118
|
+
def win_has_cert_fingerprint?(fp)
|
119
|
+
ps = %q{
|
120
|
+
$c = Get-ChildItem Cert:\LocalMachine\Root | Where-Object { $_.Thumbprint -eq "__FP__" };
|
121
|
+
if ($c) { "YES" } else { "NO" }
|
122
|
+
}.strip.gsub("__FP__", fp.to_s)
|
123
|
+
|
124
|
+
ok, out, _ = run(%(powershell -NoProfile -NonInteractive -Command "#{ps}"))
|
125
|
+
ok && out.to_s.strip == "YES"
|
126
|
+
end
|
127
|
+
|
128
|
+
def win_remove_by_fp(fp)
|
129
|
+
run(%(certutil -delstore "ROOT" #{fp})).first
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
require "fileutils"
|
5
|
+
|
6
|
+
module VagrantDockerCertificatesManager
|
7
|
+
module Registry
|
8
|
+
module_function
|
9
|
+
|
10
|
+
def db_path
|
11
|
+
File.join(Dir.home, ".vagrant.d", "vdcm", "certs.json")
|
12
|
+
end
|
13
|
+
|
14
|
+
def ensure_dir!
|
15
|
+
FileUtils.mkdir_p(File.dirname(db_path))
|
16
|
+
end
|
17
|
+
|
18
|
+
def load
|
19
|
+
ensure_dir!
|
20
|
+
return {} unless File.exist?(db_path)
|
21
|
+
JSON.parse(File.read(db_path))
|
22
|
+
rescue
|
23
|
+
{}
|
24
|
+
end
|
25
|
+
|
26
|
+
def save(data)
|
27
|
+
ensure_dir!
|
28
|
+
File.write(db_path, JSON.pretty_generate(data))
|
29
|
+
end
|
30
|
+
|
31
|
+
def track(fp, attrs)
|
32
|
+
data = load
|
33
|
+
data[fp] = attrs
|
34
|
+
save(data)
|
35
|
+
end
|
36
|
+
|
37
|
+
def untrack(fp)
|
38
|
+
data = load
|
39
|
+
removed = !data.delete(fp).nil?
|
40
|
+
save(data)
|
41
|
+
removed
|
42
|
+
end
|
43
|
+
|
44
|
+
def find_by_path(path)
|
45
|
+
data = load
|
46
|
+
data.find { |_fp, v| File.expand_path(v["path"]) == File.expand_path(path) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def all
|
50
|
+
load
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
require_relative "../helpers"
|
5
|
+
|
6
|
+
module VagrantDockerCertificatesManager
|
7
|
+
module Ui
|
8
|
+
module_function
|
9
|
+
|
10
|
+
def say(env, level, key = nil, raw: nil, **kv)
|
11
|
+
UiHelpers.say(env, level, key, raw: raw, **kv)
|
12
|
+
end
|
13
|
+
|
14
|
+
def emit(json, action, result)
|
15
|
+
if json
|
16
|
+
puts JSON.dump(result.merge(action: action))
|
17
|
+
return
|
18
|
+
end
|
19
|
+
no_emoji = ENV["VDCM_NO_EMOJI"].to_s == "1"
|
20
|
+
ok_mark = no_emoji ? "[OK]" : UiHelpers.e(:success)
|
21
|
+
ko_mark = no_emoji ? "[ERR]" : UiHelpers.e(:error)
|
22
|
+
|
23
|
+
status = result[:status] || result[:state]
|
24
|
+
if status == "success" || status == "ok"
|
25
|
+
puts "#{ok_mark} #{action}"
|
26
|
+
else
|
27
|
+
puts "#{ko_mark} #{action}: #{result[:error] || 'error'}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/locales/en.yml
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
en:
|
2
|
+
vdcm:
|
3
|
+
cli:
|
4
|
+
title: "Vagrant Docker Certificates Manager"
|
5
|
+
usage: "Usage: vagrant certs <add|remove|list|version|help> [options]"
|
6
|
+
opt_lang: "Force language (en|fr)"
|
7
|
+
opt_no_emoji: "Disable emoji in CLI output"
|
8
|
+
opt_help: "Show help and exit"
|
9
|
+
|
10
|
+
help:
|
11
|
+
general_title: "Vagrant Docker Certificates Manager — Commands:"
|
12
|
+
topic_header: "Help: vagrant certs %{topic}"
|
13
|
+
usage_label: "Usage:"
|
14
|
+
description_label: "Description:"
|
15
|
+
options_label: "Options:"
|
16
|
+
examples_label: "Examples:"
|
17
|
+
commands:
|
18
|
+
add: "vagrant certs add [PATH] # Install the certificate"
|
19
|
+
remove: "vagrant certs remove [PATH] # Uninstall the certificate"
|
20
|
+
list: "vagrant certs list # Show tracked certificates"
|
21
|
+
version: "vagrant certs version # Print plugin version"
|
22
|
+
help: "vagrant certs help [TOPIC] # This help"
|
23
|
+
topic:
|
24
|
+
add:
|
25
|
+
usage: "vagrant certs add <PATH_CERT_FILE> [--lang en|fr] [--no-emoji]"
|
26
|
+
description: "Install the given Root CA into the system trust store. Fails if already present."
|
27
|
+
options:
|
28
|
+
lang: "--lang <en|fr> Force language"
|
29
|
+
noemoji: "--no-emoji Disable emoji in output"
|
30
|
+
examples:
|
31
|
+
- "vagrant certs add ./certs/rootca.pem"
|
32
|
+
remove:
|
33
|
+
usage: "vagrant certs remove <PATH_CERT_FILE> [--lang en|fr] [--no-emoji]"
|
34
|
+
description: "Remove a certificate previously installed by this plugin using its path (or tracked entry)."
|
35
|
+
options:
|
36
|
+
lang: "--lang <en|fr> Force language"
|
37
|
+
noemoji: "--no-emoji Disable emoji in output"
|
38
|
+
examples:
|
39
|
+
- "vagrant certs remove ./certs/rootca.pem"
|
40
|
+
list:
|
41
|
+
usage: "vagrant certs list [--lang en|fr] [--no-emoji]"
|
42
|
+
description: "Show certificates tracked by this plugin."
|
43
|
+
options:
|
44
|
+
lang: "--lang <en|fr> Force language"
|
45
|
+
noemoji: "--no-emoji Disable emoji in output"
|
46
|
+
|
47
|
+
messages:
|
48
|
+
version_line: "v%{v}."
|
49
|
+
|
50
|
+
errors:
|
51
|
+
invalid_path: "Invalid certificate path: %{path}"
|
52
|
+
missing_path_remove: "You must provide a path for removal."
|
53
|
+
not_found_for_remove: "No tracked certificate found for path: %{path}"
|
54
|
+
already_present: "The certificate %{name} already exists."
|
55
|
+
install_failed: "Certificate installation failed."
|
56
|
+
uninstall_failed: "Certificate removal failed."
|
57
|
+
remove_failed: "Remove failed."
|
58
|
+
cert_not_found: "Certificate file not found: %{path}"
|
59
|
+
os_unsupported: "Unsupported OS for this action."
|
60
|
+
unknown_command: "Unknown command: %{cmd}"
|
61
|
+
|
62
|
+
add:
|
63
|
+
success: "Certificate %{name} installed."
|
64
|
+
|
65
|
+
remove:
|
66
|
+
success: "Certificate removed."
|
67
|
+
|
68
|
+
list:
|
69
|
+
header: "Certificates installed by this plugin:"
|
70
|
+
empty: "No certificate tracked by this plugin."
|
71
|
+
|
72
|
+
install:
|
73
|
+
start: "Installing certificate %{name} from %{path}..."
|
74
|
+
success: "Certificate %{name} installed."
|
75
|
+
fail: "Failed to install certificate %{name}."
|
76
|
+
skip: "Install on up disabled; skipping."
|
77
|
+
|
78
|
+
uninstall:
|
79
|
+
start: "Uninstalling certificate %{name}..."
|
80
|
+
success: "Certificate %{name} removed."
|
81
|
+
fail: "Failed to remove certificate %{name}."
|
82
|
+
skip: "Remove on destroy disabled; skipping."
|
83
|
+
|
84
|
+
errors:
|
85
|
+
invalid_path: "Invalid certificate path: %{path}"
|
86
|
+
missing_path_remove: "You must provide a path for removal."
|
87
|
+
not_found_for_remove: "No tracked certificate found for path: %{path}"
|
88
|
+
already_present: "The certificate %{name} already exists."
|
89
|
+
install_failed: "Certificate installation failed."
|
90
|
+
uninstall_failed: "Certificate removal failed."
|
91
|
+
remove_failed: "Remove failed."
|
92
|
+
os_unsupported: "Unsupported OS for this action."
|
93
|
+
unknown_command: "Unknown command: %{cmd}"
|
data/locales/fr.yml
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
fr:
|
2
|
+
vdcm:
|
3
|
+
cli:
|
4
|
+
title: "Gestionnaire de certificats Docker pour Vagrant"
|
5
|
+
usage: "Utilisation : vagrant certs <add|remove|list|version|help> [options]"
|
6
|
+
opt_lang: "Forcer la langue (en|fr)"
|
7
|
+
opt_no_emoji: "Désactiver les émojis dans la sortie"
|
8
|
+
opt_help: "Afficher l'aide et quitter"
|
9
|
+
|
10
|
+
help:
|
11
|
+
general_title: "Gestionnaire de certificats — Commandes :"
|
12
|
+
topic_header: "Aide : vagrant certs %{topic}"
|
13
|
+
usage_label: "Utilisation :"
|
14
|
+
description_label: "Description :"
|
15
|
+
options_label: "Options :"
|
16
|
+
examples_label: "Exemples :"
|
17
|
+
commands:
|
18
|
+
add: "vagrant certs add [CHEMIN] # Installer le certificat"
|
19
|
+
remove: "vagrant certs remove [CHEMIN] # Désinstaller le certificat"
|
20
|
+
list: "vagrant certs list # Afficher les certificats suivis"
|
21
|
+
version: "vagrant certs version # Afficher la version du plugin"
|
22
|
+
help: "vagrant certs help [SUJET] # Cette aide"
|
23
|
+
topic:
|
24
|
+
add:
|
25
|
+
usage: "vagrant certs add <CHEMIN_CERT> [--lang en|fr] [--no-emoji]"
|
26
|
+
description: "Installe la CA fournie dans le trousseau système. Échoue si elle existe déjà."
|
27
|
+
options:
|
28
|
+
lang: "--lang <en|fr> Forcer la langue"
|
29
|
+
noemoji: "--no-emoji Désactiver les émojis"
|
30
|
+
examples:
|
31
|
+
- "vagrant certs add ./certs/rootca.pem"
|
32
|
+
remove:
|
33
|
+
usage: "vagrant certs remove <CHEMIN_CERT> [--lang en|fr] [--no-emoji]"
|
34
|
+
description: "Supprime un certificat installé par ce plugin à partir de son chemin (ou de l'entrée suivie)."
|
35
|
+
options:
|
36
|
+
lang: "--lang <en|fr> Forcer la langue"
|
37
|
+
noemoji: "--no-emoji Désactiver les émojis"
|
38
|
+
examples:
|
39
|
+
- "vagrant certs remove ./certs/rootca.pem"
|
40
|
+
list:
|
41
|
+
usage: "vagrant certs list [--lang en|fr] [--no-emoji]"
|
42
|
+
description: "Affiche les certificats suivis par ce plugin."
|
43
|
+
options:
|
44
|
+
lang: "--lang <en|fr> Forcer la langue"
|
45
|
+
noemoji: "--no-emoji Désactiver les émojis"
|
46
|
+
|
47
|
+
messages:
|
48
|
+
version_line: "v%{v}."
|
49
|
+
|
50
|
+
errors:
|
51
|
+
invalid_path: "Chemin de certificat invalide : %{path}"
|
52
|
+
missing_path_remove: "Vous devez fournir un chemin pour la suppression."
|
53
|
+
not_found_for_remove: "Aucun certificat suivi pour le chemin : %{path}"
|
54
|
+
already_present: "Le certificat %{name} existe déjà."
|
55
|
+
install_failed: "Échec de l'installation du certificat."
|
56
|
+
uninstall_failed: "Échec de la suppression du certificat."
|
57
|
+
remove_failed: "Échec de la suppression."
|
58
|
+
cert_not_found: "Fichier certificat introuvable : %{path}"
|
59
|
+
os_unsupported: "Système non pris en charge pour cette action."
|
60
|
+
unknown_command: "Commande inconnue : %{cmd}"
|
61
|
+
|
62
|
+
add:
|
63
|
+
success: "Certificat %{name} installé."
|
64
|
+
|
65
|
+
remove:
|
66
|
+
success: "Certificat supprimé."
|
67
|
+
|
68
|
+
list:
|
69
|
+
header: "Certificats installés par ce plugin :"
|
70
|
+
empty: "Aucun certificat suivi par ce plugin."
|
71
|
+
|
72
|
+
install:
|
73
|
+
start: "Installation du certificat %{name} depuis %{path}…"
|
74
|
+
success: "Certificat %{name} installé."
|
75
|
+
fail: "Échec de l'installation du certificat %{name}."
|
76
|
+
skip: "Installation à l'up désactivée ; on ignore."
|
77
|
+
|
78
|
+
uninstall:
|
79
|
+
start: "Désinstallation du certificat %{name}…"
|
80
|
+
success: "Certificat %{name} supprimé."
|
81
|
+
fail: "Échec de la suppression du certificat %{name}."
|
82
|
+
skip: "Suppression à la destruction désactivée ; on ignore."
|
83
|
+
|
84
|
+
errors:
|
85
|
+
invalid_path: "Chemin de certificat invalide : %{path}"
|
86
|
+
missing_path_remove: "Vous devez fournir un chemin à supprimer."
|
87
|
+
not_found_for_remove: "Aucun certificat suivi pour le chemin : %{path}"
|
88
|
+
already_present: "Le certificat %{name} existe déjà."
|
89
|
+
install_failed: "Échec de l'installation du certificat."
|
90
|
+
uninstall_failed: "Échec de la suppression du certificat."
|
91
|
+
remove_failed: "Échec de la suppression."
|
92
|
+
os_unsupported: "Système non pris en charge pour cette action."
|
93
|
+
unknown_command: "Commande inconnue : %{cmd}"
|