smart_proxy_ansible 3.2.1 → 3.3.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/lib/smart_proxy_ansible/api.rb +11 -3
- data/lib/smart_proxy_ansible/configuration_loader.rb +20 -0
- data/lib/smart_proxy_ansible/exception.rb +3 -0
- data/lib/smart_proxy_ansible/playbooks_reader.rb +37 -0
- data/lib/smart_proxy_ansible/plugin.rb +3 -16
- data/lib/smart_proxy_ansible/reader_helper.rb +44 -0
- data/lib/smart_proxy_ansible/roles_reader.rb +3 -36
- data/lib/smart_proxy_ansible/runner/ansible_runner.rb +47 -4
- data/lib/smart_proxy_ansible/task_launcher/ansible_runner.rb +1 -1
- data/lib/smart_proxy_ansible/validate_settings.rb +7 -0
- data/lib/smart_proxy_ansible/version.rb +1 -1
- data/lib/smart_proxy_ansible.rb +4 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a1934350dedb103c779cdf61196cff80a43751d260fd5f550d26289dc63f388
|
4
|
+
data.tar.gz: cee72032c8d95fde92021ef8c312e9c4f0408b9ac1d88b5a0ebf9cdd97bc906c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a473838108c4b9cbcef9da311410a2fda5bc39047a2cd4c623533ef718918583de1c830105b92a52303bfc41e1eeb933f1d4a898380a0cf9b01c32d7fb07cb76
|
7
|
+
data.tar.gz: cf1aa8ca722850fd39d312cefcbf178e193fcf391ca8058638dd26db01c288f7350ea6c80e5fb004e87cdda664f5200f24b83b61a2dc3226d88006d0efff7cb3
|
@@ -28,15 +28,23 @@ module Proxy
|
|
28
28
|
{}.to_json
|
29
29
|
end
|
30
30
|
|
31
|
+
get '/playbooks_names' do
|
32
|
+
PlaybooksReader.playbooks_names.to_json
|
33
|
+
end
|
34
|
+
|
35
|
+
get '/playbooks/:playbooks_names?' do
|
36
|
+
PlaybooksReader.playbooks(params[:playbooks_names]).to_json
|
37
|
+
end
|
38
|
+
|
31
39
|
private
|
32
40
|
|
33
41
|
def extract_variables(role_name)
|
34
42
|
variables = {}
|
35
43
|
role_name_parts = role_name.split('.')
|
36
44
|
if role_name_parts.count == 3
|
37
|
-
|
38
|
-
variables[role_name]
|
39
|
-
.extract_variables("#{path}/ansible_collections/#{role_name_parts[0]}/#{role_name_parts[1]}/roles/#{role_name_parts[2]}")
|
45
|
+
ReaderHelper.collections_paths.split(':').each do |path|
|
46
|
+
variables[role_name] = VariablesExtractor
|
47
|
+
.extract_variables("#{path}/ansible_collections/#{role_name_parts[0]}/#{role_name_parts[1]}/roles/#{role_name_parts[2]}") if variables[role_name].nil? || variables[role_name].empty?
|
40
48
|
end
|
41
49
|
else
|
42
50
|
RolesReader.roles_path.split(':').each do |path|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Proxy::Ansible
|
2
|
+
class ConfigurationLoader
|
3
|
+
def load_classes
|
4
|
+
require 'smart_proxy_dynflow'
|
5
|
+
require 'smart_proxy_dynflow/continuous_output'
|
6
|
+
require 'smart_proxy_ansible/task_launcher/ansible_runner'
|
7
|
+
require 'smart_proxy_ansible/task_launcher/playbook'
|
8
|
+
require 'smart_proxy_ansible/actions'
|
9
|
+
require 'smart_proxy_ansible/remote_execution_core/ansible_runner'
|
10
|
+
require 'smart_proxy_ansible/runner/ansible_runner'
|
11
|
+
require 'smart_proxy_ansible/runner/command_creator'
|
12
|
+
require 'smart_proxy_ansible/runner/playbook'
|
13
|
+
|
14
|
+
Proxy::Dynflow::TaskLauncherRegistry.register('ansible-runner',
|
15
|
+
TaskLauncher::AnsibleRunner)
|
16
|
+
Proxy::Dynflow::TaskLauncherRegistry.register('ansible-playbook',
|
17
|
+
TaskLauncher::Playbook)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -37,5 +37,8 @@ module Proxy
|
|
37
37
|
class ReadConfigFileException < Proxy::Ansible::Exception; end
|
38
38
|
class ReadRolesException < Proxy::Ansible::Exception; end
|
39
39
|
class ReadVariablesException < Proxy::Ansible::Exception; end
|
40
|
+
class NotExistingWorkingDirException < Proxy::Ansible::Exception; end
|
41
|
+
class ReadPlaybooksNamesException < Proxy::Ansible::Exception; end
|
42
|
+
class ReadPlaybooksException < Proxy::Ansible::Exception; end
|
40
43
|
end
|
41
44
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Proxy
|
2
|
+
module Ansible
|
3
|
+
# Implements the logic needed to read the playbooks and associated information
|
4
|
+
class PlaybooksReader
|
5
|
+
class << self
|
6
|
+
def playbooks_names
|
7
|
+
ReaderHelper.collections_paths.split(':').flat_map { |path| get_playbooks_names(path) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def playbooks(playbooks_to_import)
|
11
|
+
ReaderHelper.collections_paths.split(':').reduce([]) do |playbooks, path|
|
12
|
+
playbooks.concat(read_collection_playbooks(path, playbooks_to_import))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_playbooks_names(collections_path)
|
17
|
+
Dir.glob("#{collections_path}/ansible_collections/*/*/playbooks/*").map do |path|
|
18
|
+
ReaderHelper.playbook_or_role_full_name(path)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def read_collection_playbooks(collections_path, playbooks_to_import = nil)
|
23
|
+
Dir.glob("#{collections_path}/ansible_collections/*/*/playbooks/*").map do |path|
|
24
|
+
name = ReaderHelper.playbook_or_role_full_name(path)
|
25
|
+
{
|
26
|
+
name: name,
|
27
|
+
playbooks_content: File.readlines(path)
|
28
|
+
} if playbooks_to_import.nil? || playbooks_to_import.include?(name)
|
29
|
+
end.compact
|
30
|
+
rescue Errno::ENOENT, Errno::EACCES => e
|
31
|
+
message = "Could not read Ansible playbooks #{collections_path} - #{e.message}"
|
32
|
+
raise ReadPlaybooksException, message
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -8,22 +8,9 @@ module Proxy
|
|
8
8
|
default_settings :ansible_dir => Dir.home
|
9
9
|
# :working_dir => nil
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
require 'smart_proxy_ansible/task_launcher/ansible_runner'
|
15
|
-
require 'smart_proxy_ansible/task_launcher/playbook'
|
16
|
-
require 'smart_proxy_ansible/actions'
|
17
|
-
require 'smart_proxy_ansible/remote_execution_core/ansible_runner'
|
18
|
-
require 'smart_proxy_ansible/runner/ansible_runner'
|
19
|
-
require 'smart_proxy_ansible/runner/command_creator'
|
20
|
-
require 'smart_proxy_ansible/runner/playbook'
|
21
|
-
|
22
|
-
Proxy::Dynflow::TaskLauncherRegistry.register('ansible-runner',
|
23
|
-
TaskLauncher::AnsibleRunner)
|
24
|
-
Proxy::Dynflow::TaskLauncherRegistry.register('ansible-playbook',
|
25
|
-
TaskLauncher::Playbook)
|
26
|
-
end
|
11
|
+
load_classes ::Proxy::Ansible::ConfigurationLoader
|
12
|
+
load_validators :validate_settings => ::Proxy::Ansible::ValidateSettings
|
13
|
+
validate :validate!, :validate_settings => nil
|
27
14
|
end
|
28
15
|
end
|
29
16
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Proxy
|
2
|
+
module Ansible
|
3
|
+
# Helper for Playbooks Reader
|
4
|
+
class ReaderHelper
|
5
|
+
class << self
|
6
|
+
DEFAULT_COLLECTIONS_PATHS = '/etc/ansible/collections:/usr/share/ansible/collections'.freeze
|
7
|
+
DEFAULT_CONFIG_FILE = '/etc/ansible/ansible.cfg'.freeze
|
8
|
+
|
9
|
+
def collections_paths
|
10
|
+
config_path(path_from_config('collections_paths'), DEFAULT_COLLECTIONS_PATHS)
|
11
|
+
end
|
12
|
+
|
13
|
+
def config_path(config_line, default)
|
14
|
+
return default if config_line.empty?
|
15
|
+
|
16
|
+
config_line_key = config_line.first.split('=').first.strip
|
17
|
+
# In case of commented roles_path key "#roles_path" or #collections_paths, return default
|
18
|
+
return default if ['#roles_path', '#collections_paths'].include?(config_line_key)
|
19
|
+
|
20
|
+
config_line.first.split('=').last.strip
|
21
|
+
end
|
22
|
+
|
23
|
+
def path_from_config(config_key)
|
24
|
+
File.readlines(DEFAULT_CONFIG_FILE).select do |line|
|
25
|
+
line =~ /^\s*#{config_key}/
|
26
|
+
end
|
27
|
+
rescue Errno::ENOENT, Errno::EACCES => e
|
28
|
+
RolesReader.logger.debug(e.backtrace)
|
29
|
+
message = "Could not read Ansible config file #{DEFAULT_CONFIG_FILE} - #{e.message}"
|
30
|
+
raise ReadConfigFileException.new(message), message
|
31
|
+
end
|
32
|
+
|
33
|
+
def playbook_or_role_full_name(path)
|
34
|
+
parts = path.split('/')
|
35
|
+
playbook = parts.pop
|
36
|
+
parts.pop
|
37
|
+
collection = parts.pop
|
38
|
+
author = parts.pop
|
39
|
+
"#{author}.#{collection}.#{playbook}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -5,33 +5,16 @@ module Proxy
|
|
5
5
|
# Implements the logic needed to read the roles and associated information
|
6
6
|
class RolesReader
|
7
7
|
class << self
|
8
|
-
DEFAULT_CONFIG_FILE = '/etc/ansible/ansible.cfg'.freeze
|
9
8
|
DEFAULT_ROLES_PATH = '/etc/ansible/roles:/usr/share/ansible/roles'.freeze
|
10
|
-
DEFAULT_COLLECTIONS_PATHS = '/etc/ansible/collections:/usr/share/ansible/collections'.freeze
|
11
9
|
|
12
10
|
def list_roles
|
13
11
|
roles = roles_path.split(':').map { |path| read_roles(path) }.flatten
|
14
|
-
collection_roles = collections_paths.split(':').map { |path| read_collection_roles(path) }.flatten
|
12
|
+
collection_roles = ReaderHelper.collections_paths.split(':').map { |path| read_collection_roles(path) }.flatten
|
15
13
|
roles + collection_roles
|
16
14
|
end
|
17
15
|
|
18
16
|
def roles_path
|
19
|
-
config_path(path_from_config('roles_path'), DEFAULT_ROLES_PATH)
|
20
|
-
end
|
21
|
-
|
22
|
-
def collections_paths
|
23
|
-
config_path(path_from_config('collections_paths'), DEFAULT_COLLECTIONS_PATHS)
|
24
|
-
end
|
25
|
-
|
26
|
-
def config_path(config_line, default)
|
27
|
-
# Default to /etc/ansible/roles if config_line is empty
|
28
|
-
return default if config_line.empty?
|
29
|
-
|
30
|
-
config_line_key = config_line.first.split('=').first.strip
|
31
|
-
# In case of commented roles_path key "#roles_path" or #collections_paths, return default
|
32
|
-
return default if ['#roles_path', '#collections_paths'].include?(config_line_key)
|
33
|
-
|
34
|
-
config_line.first.split('=').last.strip
|
17
|
+
ReaderHelper.config_path(ReaderHelper.path_from_config('roles_path'), DEFAULT_ROLES_PATH)
|
35
18
|
end
|
36
19
|
|
37
20
|
def logger
|
@@ -58,33 +41,17 @@ module Proxy
|
|
58
41
|
|
59
42
|
def glob_path(path)
|
60
43
|
Dir.glob path
|
61
|
-
|
62
44
|
end
|
63
45
|
|
64
46
|
def read_collection_roles(collections_path)
|
65
47
|
Dir.glob("#{collections_path}/ansible_collections/*/*/roles/*").map do |path|
|
66
|
-
|
67
|
-
role = parts.pop
|
68
|
-
parts.pop
|
69
|
-
collection = parts.pop
|
70
|
-
author = parts.pop
|
71
|
-
"#{author}.#{collection}.#{role}"
|
48
|
+
ReaderHelper.playbook_or_role_full_name(path)
|
72
49
|
end
|
73
50
|
rescue Errno::ENOENT, Errno::EACCES => e
|
74
51
|
logger.debug(e.backtrace)
|
75
52
|
message = "Could not read Ansible roles #{collections_path} - #{e.message}"
|
76
53
|
raise ReadRolesException.new(message), message
|
77
54
|
end
|
78
|
-
|
79
|
-
def path_from_config(config_key)
|
80
|
-
File.readlines(DEFAULT_CONFIG_FILE).select do |line|
|
81
|
-
line =~ /^\s*#{config_key}/
|
82
|
-
end
|
83
|
-
rescue Errno::ENOENT, Errno::EACCES => e
|
84
|
-
logger.debug(e.backtrace)
|
85
|
-
message = "Could not read Ansible config file #{DEFAULT_CONFIG_FILE} - #{e.message}"
|
86
|
-
raise ReadConfigFileException.new(message), message
|
87
|
-
end
|
88
55
|
end
|
89
56
|
end
|
90
57
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'shellwords'
|
2
|
+
require 'yaml'
|
2
3
|
|
3
4
|
require 'smart_proxy_dynflow/runner/command'
|
4
5
|
require 'smart_proxy_dynflow/runner/base'
|
@@ -7,6 +8,7 @@ module Proxy::Ansible
|
|
7
8
|
module Runner
|
8
9
|
class AnsibleRunner < ::Proxy::Dynflow::Runner::Parent
|
9
10
|
include ::Proxy::Dynflow::Runner::Command
|
11
|
+
attr_reader :execution_timeout_interval, :command_pid
|
10
12
|
|
11
13
|
def initialize(input, suspended_action:)
|
12
14
|
super input, :suspended_action => suspended_action
|
@@ -19,12 +21,16 @@ module Proxy::Ansible
|
|
19
21
|
@check_mode = action_input[:check_mode]
|
20
22
|
@tags = action_input[:tags]
|
21
23
|
@tags_flag = action_input[:tags_flag]
|
24
|
+
@passphrase = action_input['secrets']['key_passphrase']
|
25
|
+
@execution_timeout_interval = action_input[:execution_timeout_interval]
|
26
|
+
@cleanup_working_dirs = action_input.fetch(:cleanup_working_dirs, true)
|
22
27
|
end
|
23
28
|
|
24
29
|
def start
|
25
30
|
prepare_directory_structure
|
26
31
|
write_inventory
|
27
32
|
write_playbook
|
33
|
+
write_ssh_key if !@passphrase.nil? && !@passphrase.empty?
|
28
34
|
start_ansible_runner
|
29
35
|
end
|
30
36
|
|
@@ -46,9 +52,26 @@ module Proxy::Ansible
|
|
46
52
|
end
|
47
53
|
end
|
48
54
|
|
55
|
+
def timeout
|
56
|
+
logger.debug('job timed out')
|
57
|
+
super
|
58
|
+
end
|
59
|
+
|
60
|
+
def timeout_interval
|
61
|
+
execution_timeout_interval
|
62
|
+
end
|
63
|
+
|
64
|
+
def kill
|
65
|
+
::Process.kill('SIGTERM', @command_pid)
|
66
|
+
publish_exit_status(2)
|
67
|
+
@inventory['all']['hosts'].each { |hostname| @exit_statuses[hostname] = 2 }
|
68
|
+
broadcast_data('Timeout for execution passed, stopping the job', 'stderr')
|
69
|
+
close
|
70
|
+
end
|
71
|
+
|
49
72
|
def close
|
50
73
|
super
|
51
|
-
FileUtils.remove_entry(@root) if @tmp_working_dir
|
74
|
+
FileUtils.remove_entry(@root) if @tmp_working_dir && Dir.exist?(@root) && @cleanup_working_dirs
|
52
75
|
end
|
53
76
|
|
54
77
|
private
|
@@ -85,10 +108,17 @@ module Proxy::Ansible
|
|
85
108
|
def handle_broadcast_data(event)
|
86
109
|
log_event("broadcast", event)
|
87
110
|
if event['event'] == 'playbook_on_stats'
|
111
|
+
failures = event.dig('event_data', 'failures') || {}
|
112
|
+
unreachable = event.dig('event_data', 'dark') || {}
|
88
113
|
header, *rows = event['stdout'].strip.lines.map(&:chomp)
|
89
114
|
@outputs.keys.select { |key| key.is_a? String }.each do |host|
|
90
115
|
line = rows.find { |row| row =~ /#{host}/ }
|
91
116
|
publish_data_for(host, [header, line].join("\n"), 'stdout')
|
117
|
+
|
118
|
+
# If the task has been rescued, it won't consider a failure
|
119
|
+
if @exit_statuses[host].to_i != 0 && failures[host].to_i <= 0 && unreachable[host].to_i <= 0
|
120
|
+
publish_exit_status_for(host, 0)
|
121
|
+
end
|
92
122
|
end
|
93
123
|
else
|
94
124
|
broadcast_data(event['stdout'] + "\n", 'stdout')
|
@@ -111,6 +141,19 @@ module Proxy::Ansible
|
|
111
141
|
File.write(File.join(@root, 'project', 'playbook.yml'), @playbook)
|
112
142
|
end
|
113
143
|
|
144
|
+
def write_ssh_key
|
145
|
+
key_path = File.join(@root, 'env', 'ssh_key')
|
146
|
+
File.symlink(File.expand_path(Proxy::RemoteExecution::Ssh::Plugin.settings[:ssh_identity_key_file]), key_path)
|
147
|
+
|
148
|
+
passwords_path = File.join(@root, 'env', 'passwords')
|
149
|
+
# here we create a secrets file for ansible-runner, which uses the key as regexp
|
150
|
+
# to match line asking for password, given the limitation to match only first 100 chars
|
151
|
+
# and the fact the line contains dynamically created temp directory, the regexp
|
152
|
+
# mentions only things that are always there, such as artifacts directory and the key name
|
153
|
+
secrets = YAML.dump({ "for.*/artifacts/.*/ssh_key_data:" => @passphrase })
|
154
|
+
File.write(passwords_path, secrets, perm: 0o600)
|
155
|
+
end
|
156
|
+
|
114
157
|
def start_ansible_runner
|
115
158
|
env = {}
|
116
159
|
env['FOREMAN_CALLBACK_DISABLE'] = '1' if @rex_command
|
@@ -133,7 +176,7 @@ module Proxy::Ansible
|
|
133
176
|
end
|
134
177
|
|
135
178
|
def check_cmd
|
136
|
-
check_mode? ? '--check' : ''
|
179
|
+
check_mode? ? '"--check"' : ''
|
137
180
|
end
|
138
181
|
|
139
182
|
def verbosity
|
@@ -145,11 +188,11 @@ module Proxy::Ansible
|
|
145
188
|
end
|
146
189
|
|
147
190
|
def check_mode?
|
148
|
-
@check_mode == true
|
191
|
+
@check_mode == true && @rex_command == false
|
149
192
|
end
|
150
193
|
|
151
194
|
def prepare_directory_structure
|
152
|
-
inner = %w[inventory project].map { |part| File.join(@root, part) }
|
195
|
+
inner = %w[inventory project env].map { |part| File.join(@root, part) }
|
153
196
|
([@root] + inner).each do |path|
|
154
197
|
FileUtils.mkdir_p path
|
155
198
|
end
|
@@ -24,7 +24,7 @@ module Proxy::Ansible
|
|
24
24
|
# Discard everything apart from hostname to be able to tell the actions
|
25
25
|
# apart when debugging
|
26
26
|
def transform_input(input)
|
27
|
-
{ 'action_input' =>
|
27
|
+
{ 'action_input' => super['action_input'].slice('name', :task_id) }
|
28
28
|
end
|
29
29
|
|
30
30
|
# def self.input_format
|
@@ -0,0 +1,7 @@
|
|
1
|
+
module Proxy::Ansible
|
2
|
+
class ValidateSettings < ::Proxy::PluginValidators::Base
|
3
|
+
def validate!(settings)
|
4
|
+
raise NotExistingWorkingDirException.new("Working directory does not exist") unless settings[:working_dir].nil? || File.directory?(File.expand_path(settings[:working_dir]))
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
data/lib/smart_proxy_ansible.rb
CHANGED
@@ -4,8 +4,12 @@ module Proxy
|
|
4
4
|
# Basic requires for this plugin
|
5
5
|
module Ansible
|
6
6
|
require 'smart_proxy_ansible/version'
|
7
|
+
require 'smart_proxy_ansible/configuration_loader'
|
8
|
+
require 'smart_proxy_ansible/validate_settings'
|
7
9
|
require 'smart_proxy_ansible/plugin'
|
8
10
|
require 'smart_proxy_ansible/roles_reader'
|
11
|
+
require 'smart_proxy_ansible/playbooks_reader'
|
12
|
+
require 'smart_proxy_ansible/reader_helper'
|
9
13
|
require 'smart_proxy_ansible/variables_extractor'
|
10
14
|
end
|
11
15
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_proxy_ansible
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Nečas
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-01-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -154,9 +154,12 @@ files:
|
|
154
154
|
- lib/smart_proxy_ansible.rb
|
155
155
|
- lib/smart_proxy_ansible/actions.rb
|
156
156
|
- lib/smart_proxy_ansible/api.rb
|
157
|
+
- lib/smart_proxy_ansible/configuration_loader.rb
|
157
158
|
- lib/smart_proxy_ansible/exception.rb
|
158
159
|
- lib/smart_proxy_ansible/http_config.ru
|
160
|
+
- lib/smart_proxy_ansible/playbooks_reader.rb
|
159
161
|
- lib/smart_proxy_ansible/plugin.rb
|
162
|
+
- lib/smart_proxy_ansible/reader_helper.rb
|
160
163
|
- lib/smart_proxy_ansible/remote_execution_core/ansible_runner.rb
|
161
164
|
- lib/smart_proxy_ansible/roles_reader.rb
|
162
165
|
- lib/smart_proxy_ansible/runner/ansible_runner.rb
|
@@ -164,6 +167,7 @@ files:
|
|
164
167
|
- lib/smart_proxy_ansible/runner/playbook.rb
|
165
168
|
- lib/smart_proxy_ansible/task_launcher/ansible_runner.rb
|
166
169
|
- lib/smart_proxy_ansible/task_launcher/playbook.rb
|
170
|
+
- lib/smart_proxy_ansible/validate_settings.rb
|
167
171
|
- lib/smart_proxy_ansible/variables_extractor.rb
|
168
172
|
- lib/smart_proxy_ansible/version.rb
|
169
173
|
- settings.d/ansible.yml.example
|
@@ -186,7 +190,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
186
190
|
- !ruby/object:Gem::Version
|
187
191
|
version: '0'
|
188
192
|
requirements: []
|
189
|
-
rubygems_version: 3.
|
193
|
+
rubygems_version: 3.3.4
|
190
194
|
signing_key:
|
191
195
|
specification_version: 4
|
192
196
|
summary: Smart-Proxy Ansible plugin
|