oxidized 0.30.1 → 0.31.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/.github/workflows/ruby.yml +2 -2
- data/.github/workflows/stale.yml +4 -2
- data/.rubocop.yml +18 -2
- data/.rubocop_todo.yml +5 -12
- data/CHANGELOG.md +61 -1
- data/CONTRIBUTING.md +5 -0
- data/Dockerfile +82 -21
- data/README.md +5 -21
- data/Rakefile +3 -2
- data/docs/Configuration.md +36 -12
- data/docs/Creating-Models.md +45 -4
- data/docs/Hooks.md +34 -0
- data/docs/Issues.md +91 -0
- data/docs/Model-Notes/Cumulus.md +5 -0
- data/docs/Model-Notes/FSOS.md +5 -0
- data/docs/Model-Notes/FortiOS.md +21 -5
- data/docs/Model-Notes/HPEAruba.md +31 -0
- data/docs/Model-Notes/OS6.md +10 -0
- data/docs/Model-Notes/RouterOS.md +15 -0
- data/docs/Model-Notes/SikluMHTG.md +7 -0
- data/docs/Outputs.md +2 -0
- data/docs/Release.md +18 -15
- data/docs/Sources.md +21 -0
- data/docs/Supported-OS-Types.md +11 -5
- data/docs/Troubleshooting.md +35 -0
- data/examples/device-simulation/README.md +173 -0
- data/examples/device-simulation/cmdsets/aoscx +9 -0
- data/examples/device-simulation/cmdsets/arubainstant +5 -0
- data/examples/device-simulation/cmdsets/asa +7 -0
- data/examples/device-simulation/cmdsets/ios +7 -0
- data/examples/device-simulation/cmdsets/nxos +5 -0
- data/examples/device-simulation/cmdsets/routeros +5 -0
- data/examples/device-simulation/cmdsets/srosmd +11 -0
- data/examples/device-simulation/device2yaml.rb +225 -0
- data/examples/device-simulation/yaml/aoscx_R0X25A-6410_FL.10.10.1100.yaml +2281 -0
- data/examples/device-simulation/yaml/aoscx_R8N85A-C6000-48G-CL4_PL.10.08.1010.yaml +451 -0
- data/examples/device-simulation/yaml/arubainstant_IAP515_8.10.0.6_VWLC.yaml +213 -0
- data/examples/device-simulation/yaml/asa_5512_9.12-4-67_single-context.yaml +531 -0
- data/examples/device-simulation/yaml/asr920_16.8.1b.yaml +1122 -0
- data/examples/device-simulation/yaml/garderos_R7709_003_006_068.yaml +101 -0
- data/examples/device-simulation/yaml/iosxe_C9200L-24P-4G_17.09.04a.yaml +514 -0
- data/examples/device-simulation/yaml/iosxe_C9800-L-F-K9_17.06.05.yaml +417 -0
- data/examples/device-simulation/yaml/riverbed_915.yaml +123 -0
- data/examples/device-simulation/yaml/routeros_CHR_7.10.1.yaml +145 -0
- data/examples/device-simulation/yaml/routeros_CHR_7.16.yaml +79 -0
- data/examples/device-simulation/yaml/routeros_L009UiGS_7.15.2.yaml +353 -0
- data/examples/podman-compose/Makefile +60 -17
- data/examples/podman-compose/README.md +63 -27
- data/examples/podman-compose/docker-compose.yml +11 -2
- data/examples/podman-compose/gitserver/.gitignore +1 -0
- data/examples/podman-compose/gitserver/Dockerfile +14 -0
- data/examples/podman-compose/model-simulation/Dockerfile-model +1 -1
- data/examples/podman-compose/model-simulation/asternos.sh +2 -0
- data/examples/podman-compose/oxidized-config/.gitignore +2 -0
- data/examples/podman-compose/oxidized-config/config +1 -1
- data/examples/podman-compose/oxidized-config/config_csv-file +46 -0
- data/examples/podman-compose/oxidized-config/config_csv-gitserver +56 -0
- data/examples/podman-compose/oxidized-ssh/.gitignore +1 -0
- data/lib/oxidized/config.rb +7 -1
- data/lib/oxidized/hook/githubrepo.rb +37 -7
- data/lib/oxidized/hook/slackdiff.rb +29 -7
- data/lib/oxidized/input/http.rb +1 -0
- data/lib/oxidized/input/telnet.rb +1 -1
- data/lib/oxidized/manager.rb +17 -16
- data/lib/oxidized/model/aoscx.rb +16 -2
- data/lib/oxidized/model/aosw.rb +7 -1
- data/lib/oxidized/model/arubainstant.rb +90 -0
- data/lib/oxidized/model/audiocodes.rb +2 -2
- data/lib/oxidized/model/cnos.rb +13 -10
- data/lib/oxidized/model/cumulus.rb +3 -0
- data/lib/oxidized/model/dlink.rb +1 -0
- data/lib/oxidized/model/dlinknextgen.rb +3 -0
- data/lib/oxidized/model/edgecos.rb +2 -1
- data/lib/oxidized/model/eos.rb +2 -0
- data/lib/oxidized/model/f5os.rb +17 -0
- data/lib/oxidized/model/firewareos.rb +10 -1
- data/lib/oxidized/model/fortios.rb +24 -1
- data/lib/oxidized/model/garderos.rb +43 -0
- data/lib/oxidized/model/h3c.rb +1 -1
- data/lib/oxidized/model/ibos.rb +1 -0
- data/lib/oxidized/model/ios.rb +20 -12
- data/lib/oxidized/model/iosxr.rb +1 -1
- data/lib/oxidized/model/lenovonos.rb +2 -0
- data/lib/oxidized/model/linuxgeneric.rb +1 -1
- data/lib/oxidized/model/netgear.rb +1 -1
- data/lib/oxidized/model/nodegrid.rb +1 -1
- data/lib/oxidized/model/nsxdfw.rb +30 -0
- data/lib/oxidized/model/nxos.rb +2 -1
- data/lib/oxidized/model/os6.rb +48 -0
- data/lib/oxidized/model/rgos.rb +1 -1
- data/lib/oxidized/model/riverbed.rb +104 -0
- data/lib/oxidized/model/routeros.rb +2 -2
- data/lib/oxidized/model/saos.rb +18 -1
- data/lib/oxidized/model/siklumhtg.rb +22 -0
- data/lib/oxidized/model/uplinkolt.rb +46 -0
- data/lib/oxidized/model/vyatta.rb +2 -2
- data/lib/oxidized/model/xos.rb +7 -0
- data/lib/oxidized/node.rb +30 -18
- data/lib/oxidized/nodes.rb +13 -5
- data/lib/oxidized/output/file.rb +45 -42
- data/lib/oxidized/output/git.rb +185 -160
- data/lib/oxidized/output/gitcrypt.rb +188 -186
- data/lib/oxidized/output/http.rb +53 -51
- data/lib/oxidized/output/output.rb +6 -4
- data/lib/oxidized/source/csv.rb +44 -49
- data/lib/oxidized/source/http.rb +63 -81
- data/lib/oxidized/source/jsonfile.rb +63 -0
- data/lib/oxidized/source/source.rb +43 -18
- data/lib/oxidized/source/sql.rb +66 -59
- data/lib/oxidized/version.rb +2 -2
- data/oxidized.gemspec +22 -16
- metadata +111 -15
data/lib/oxidized/source/http.rb
CHANGED
|
@@ -1,102 +1,84 @@
|
|
|
1
1
|
module Oxidized
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Oxidized.setup_logger
|
|
10
|
-
return unless @cfg.url.empty?
|
|
11
|
-
|
|
12
|
-
raise NoConfig, 'no source http url config, edit ~/.config/oxidized/config'
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
require "net/http"
|
|
16
|
-
require "net/https"
|
|
17
|
-
require "uri"
|
|
18
|
-
require "json"
|
|
19
|
-
|
|
20
|
-
def load(node_want = nil)
|
|
21
|
-
nodes = []
|
|
22
|
-
uri = URI.parse(@cfg.url)
|
|
23
|
-
data = JSON.parse(read_http(uri, node_want))
|
|
24
|
-
node_data = data
|
|
25
|
-
node_data = string_navigate(data, @cfg.hosts_location) if @cfg.hosts_location?
|
|
26
|
-
node_data = pagination(data, node_want) if @cfg.pagination?
|
|
2
|
+
module Source
|
|
3
|
+
require "oxidized/source/jsonfile"
|
|
4
|
+
class HTTP < JSONFile
|
|
5
|
+
def initialize
|
|
6
|
+
super
|
|
7
|
+
@cfg = Oxidized.config.source.http
|
|
8
|
+
end
|
|
27
9
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
10
|
+
def setup
|
|
11
|
+
Oxidized.setup_logger
|
|
12
|
+
if @cfg.empty?
|
|
13
|
+
Oxidized.asetus.user.source.http.url = 'https://url/api'
|
|
14
|
+
Oxidized.asetus.user.source.http.map.name = 'name'
|
|
15
|
+
Oxidized.asetus.user.source.http.map.model = 'model'
|
|
16
|
+
Oxidized.asetus.save :user
|
|
31
17
|
|
|
32
|
-
|
|
33
|
-
keys = {}
|
|
34
|
-
@cfg.map.each do |key, want_position|
|
|
35
|
-
keys[key.to_sym] = node_var_interpolate string_navigate(node, want_position)
|
|
18
|
+
raise NoConfig, "No source http config, edit #{Oxidized::Config.configfile}"
|
|
36
19
|
end
|
|
37
|
-
keys[:model] = map_model keys[:model] if keys.has_key? :model
|
|
38
|
-
keys[:group] = map_group keys[:group] if keys.has_key? :group
|
|
39
20
|
|
|
40
|
-
#
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
21
|
+
# check for mandatory attributes
|
|
22
|
+
if !@cfg.has_key?('url')
|
|
23
|
+
raise InvalidConfig, "url is a mandatory http source attribute, edit #{Oxidized::Config.configfile}"
|
|
24
|
+
elsif !@cfg.map.has_key?('name')
|
|
25
|
+
raise InvalidConfig, "map/name is a mandatory source attribute, edit #{Oxidized::Config.configfile}"
|
|
44
26
|
end
|
|
45
|
-
keys[:vars] = vars unless vars.empty?
|
|
46
|
-
|
|
47
|
-
nodes << keys
|
|
48
27
|
end
|
|
49
|
-
nodes
|
|
50
|
-
end
|
|
51
28
|
|
|
52
|
-
|
|
29
|
+
require "net/http"
|
|
30
|
+
require "net/https"
|
|
31
|
+
require "uri"
|
|
32
|
+
require "json"
|
|
53
33
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
34
|
+
def load(node_want = nil)
|
|
35
|
+
uri = URI.parse(@cfg.url)
|
|
36
|
+
data = JSON.parse(read_http(uri, node_want))
|
|
37
|
+
node_data = data
|
|
38
|
+
node_data = string_navigate_object(data, @cfg.hosts_location) if @cfg.hosts_location?
|
|
39
|
+
node_data = pagination(data, node_want) if @cfg.pagination?
|
|
40
|
+
|
|
41
|
+
transform_json(node_data)
|
|
61
42
|
end
|
|
62
|
-
object
|
|
63
|
-
end
|
|
64
43
|
|
|
65
|
-
|
|
66
|
-
node_data = []
|
|
67
|
-
raise Oxidized::OxidizedError, "if using pagination, 'pagination_key_name' setting must be set" unless @cfg.pagination_key_name?
|
|
44
|
+
private
|
|
68
45
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
break if data[next_key].nil?
|
|
46
|
+
def pagination(data, node_want)
|
|
47
|
+
node_data = []
|
|
48
|
+
raise Oxidized::OxidizedError, "if using pagination, 'pagination_key_name' setting must be set" unless @cfg.pagination_key_name?
|
|
73
49
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
50
|
+
next_key = @cfg.pagination_key_name
|
|
51
|
+
loop do
|
|
52
|
+
node_data += string_navigate_object(data, @cfg.hosts_location) if @cfg.hosts_location?
|
|
53
|
+
break if data[next_key].nil?
|
|
54
|
+
|
|
55
|
+
new_uri = URI.parse(data[next_key]) if data.has_key?(next_key)
|
|
56
|
+
data = JSON.parse(read_http(new_uri, node_want))
|
|
57
|
+
node_data += string_navigate_object(data, @cfg.hosts_location) if @cfg.hosts_location?
|
|
58
|
+
end
|
|
59
|
+
node_data
|
|
77
60
|
end
|
|
78
|
-
node_data
|
|
79
|
-
end
|
|
80
61
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
62
|
+
def read_http(uri, node_want)
|
|
63
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
64
|
+
http.use_ssl = true if uri.scheme == 'https'
|
|
65
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @cfg.secure
|
|
85
66
|
|
|
86
|
-
|
|
87
|
-
|
|
67
|
+
# Add read_timeout to handle case of big list of nodes (default value is 60 seconds)
|
|
68
|
+
http.read_timeout = Integer(@cfg.read_timeout) if @cfg.has_key? "read_timeout"
|
|
88
69
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
70
|
+
# map headers
|
|
71
|
+
headers = {}
|
|
72
|
+
@cfg.headers.each do |header, value|
|
|
73
|
+
headers[header] = value
|
|
74
|
+
end
|
|
94
75
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
76
|
+
req_uri = uri.request_uri
|
|
77
|
+
req_uri = "#{req_uri}/#{node_want}" if node_want
|
|
78
|
+
request = Net::HTTP::Get.new(req_uri, headers)
|
|
79
|
+
request.basic_auth(@cfg.user, @cfg.pass) if @cfg.user? && @cfg.pass?
|
|
80
|
+
http.request(request).body
|
|
81
|
+
end
|
|
100
82
|
end
|
|
101
83
|
end
|
|
102
84
|
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module Oxidized
|
|
2
|
+
module Source
|
|
3
|
+
class JSONFile < Source
|
|
4
|
+
require "json"
|
|
5
|
+
def initialize
|
|
6
|
+
@cfg = Oxidized.config.source.jsonfile
|
|
7
|
+
super
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def setup
|
|
11
|
+
if @cfg.empty?
|
|
12
|
+
Oxidized.asetus.user.source.jsonfile.file = File.join(Oxidized::Config::ROOT,
|
|
13
|
+
'router.json')
|
|
14
|
+
Oxidized.asetus.user.source.jsonfile.map.name = "name"
|
|
15
|
+
Oxidized.asetus.user.source.jsonfile.map.model = "model"
|
|
16
|
+
Oxidized.asetus.user.source.jsonfile.gpg = false
|
|
17
|
+
Oxidized.asetus.save :user
|
|
18
|
+
raise NoConfig, "No source json config, edit #{Oxidized::Config.configfile}"
|
|
19
|
+
end
|
|
20
|
+
require 'gpgme' if @cfg.gpg?
|
|
21
|
+
|
|
22
|
+
# map.name is mandatory
|
|
23
|
+
return if @cfg.map.has_key?('name')
|
|
24
|
+
|
|
25
|
+
raise InvalidConfig, "map/name is a mandatory source attribute, edit #{Oxidized::Config.configfile}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def load(*)
|
|
29
|
+
data = JSON.parse(open_file.read)
|
|
30
|
+
data = string_navigate_object(data, @cfg.hosts_location) if @cfg.hosts_location?
|
|
31
|
+
|
|
32
|
+
transform_json(data)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def transform_json(data)
|
|
38
|
+
nodes = []
|
|
39
|
+
data.each do |node|
|
|
40
|
+
next if node.empty?
|
|
41
|
+
|
|
42
|
+
# map node parameters
|
|
43
|
+
keys = {}
|
|
44
|
+
@cfg.map.each do |key, want_position|
|
|
45
|
+
keys[key.to_sym] = node_var_interpolate string_navigate_object(node, want_position)
|
|
46
|
+
end
|
|
47
|
+
keys[:model] = map_model keys[:model] if keys.has_key? :model
|
|
48
|
+
keys[:group] = map_group keys[:group] if keys.has_key? :group
|
|
49
|
+
|
|
50
|
+
# map node specific vars
|
|
51
|
+
vars = {}
|
|
52
|
+
@cfg.vars_map.each do |key, want_position|
|
|
53
|
+
vars[key.to_sym] = node_var_interpolate string_navigate_object(node, want_position)
|
|
54
|
+
end
|
|
55
|
+
keys[:vars] = vars unless vars.empty?
|
|
56
|
+
|
|
57
|
+
nodes << keys
|
|
58
|
+
end
|
|
59
|
+
nodes
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -1,26 +1,51 @@
|
|
|
1
1
|
module Oxidized
|
|
2
|
-
|
|
3
|
-
class
|
|
2
|
+
module Source
|
|
3
|
+
class Source
|
|
4
|
+
class NoConfig < OxidizedError; end
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
def initialize
|
|
7
|
+
@model_map = Oxidized.config.model_map || {}
|
|
8
|
+
@group_map = Oxidized.config.group_map || {}
|
|
9
|
+
end
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
def map_model(model)
|
|
12
|
+
@model_map.has_key?(model) ? @model_map[model] : model
|
|
13
|
+
end
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
def map_group(group)
|
|
16
|
+
@group_map.has_key?(group) ? @group_map[group] : group
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def node_var_interpolate(var)
|
|
20
|
+
case var
|
|
21
|
+
when "nil" then nil
|
|
22
|
+
when "false" then false
|
|
23
|
+
when "true" then true
|
|
24
|
+
else var
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def open_file
|
|
31
|
+
file = File.expand_path(@cfg.file)
|
|
32
|
+
if @cfg.gpg?
|
|
33
|
+
crypto = GPGME::Crypto.new password: @cfg.gpg_password
|
|
34
|
+
crypto.decrypt(File.open(file)).to_s
|
|
35
|
+
else
|
|
36
|
+
File.open(file)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
17
39
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
40
|
+
def string_navigate_object(object, wants)
|
|
41
|
+
wants = wants.split(".").map do |want|
|
|
42
|
+
head, match, _tail = want.partition(/\[\d+\]/)
|
|
43
|
+
match.empty? ? head : [head, match[1..-2].to_i]
|
|
44
|
+
end
|
|
45
|
+
wants.flatten.each do |want|
|
|
46
|
+
object = object[want] if object.respond_to? :each
|
|
47
|
+
end
|
|
48
|
+
object
|
|
24
49
|
end
|
|
25
50
|
end
|
|
26
51
|
end
|
data/lib/oxidized/source/sql.rb
CHANGED
|
@@ -1,75 +1,82 @@
|
|
|
1
1
|
module Oxidized
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
module Source
|
|
3
|
+
class SQL < Source
|
|
4
|
+
begin
|
|
5
|
+
require 'sequel'
|
|
6
|
+
rescue LoadError
|
|
7
|
+
raise OxidizedError, 'sequel not found: sudo gem install sequel'
|
|
8
|
+
end
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
def setup
|
|
11
|
+
if @cfg.empty?
|
|
12
|
+
Oxidized.asetus.user.source.sql.adapter = 'sqlite'
|
|
13
|
+
Oxidized.asetus.user.source.sql.database = File.join(Config::ROOT, 'sqlite.db')
|
|
14
|
+
Oxidized.asetus.user.source.sql.table = 'devices'
|
|
15
|
+
Oxidized.asetus.user.source.sql.map.name = 'name'
|
|
16
|
+
Oxidized.asetus.user.source.sql.map.model = 'rancid'
|
|
17
|
+
Oxidized.asetus.save :user
|
|
18
|
+
raise NoConfig, "No source sql config, edit #{Oxidized::Config.configfile}"
|
|
19
|
+
end
|
|
11
20
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Oxidized.asetus.user.source.sql.table = 'devices'
|
|
15
|
-
Oxidized.asetus.user.source.sql.map.name = 'name'
|
|
16
|
-
Oxidized.asetus.user.source.sql.map.model = 'rancid'
|
|
17
|
-
Oxidized.asetus.save :user
|
|
18
|
-
raise NoConfig, 'no source sql config, edit ~/.config/oxidized/config'
|
|
19
|
-
end
|
|
21
|
+
# map.name is mandatory
|
|
22
|
+
return if @cfg.map.has_key?('name')
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
db = connect
|
|
24
|
-
query = db[@cfg.table.to_sym]
|
|
25
|
-
query = query.with_sql(@cfg.query) if @cfg.query?
|
|
24
|
+
raise InvalidConfig, "map/name is a mandatory source attribute, edit #{Oxidized::Config.configfile}"
|
|
25
|
+
end
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
def load(node_want = nil)
|
|
28
|
+
nodes = []
|
|
29
|
+
db = connect
|
|
30
|
+
query = db[@cfg.table.to_sym]
|
|
31
|
+
query = query.with_sql(@cfg.query) if @cfg.query?
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
# map node parameters
|
|
31
|
-
keys = {}
|
|
32
|
-
@cfg.map.each { |key, sql_column| keys[key.to_sym] = node_var_interpolate node[sql_column.to_sym] }
|
|
33
|
-
keys[:model] = map_model keys[:model] if keys.has_key? :model
|
|
34
|
-
keys[:group] = map_group keys[:group] if keys.has_key? :group
|
|
33
|
+
query = query.where(@cfg.map.name.to_sym => node_want) if node_want
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
query.each do |node|
|
|
36
|
+
# map node parameters
|
|
37
|
+
keys = {}
|
|
38
|
+
@cfg.map.each { |key, sql_column| keys[key.to_sym] = node_var_interpolate node[sql_column.to_sym] }
|
|
39
|
+
keys[:model] = map_model keys[:model] if keys.has_key? :model
|
|
40
|
+
keys[:group] = map_group keys[:group] if keys.has_key? :group
|
|
42
41
|
|
|
43
|
-
|
|
42
|
+
# map node specific vars
|
|
43
|
+
vars = {}
|
|
44
|
+
@cfg.vars_map.each do |key, sql_column|
|
|
45
|
+
vars[key.to_sym] = node_var_interpolate node[sql_column.to_sym]
|
|
46
|
+
end
|
|
47
|
+
keys[:vars] = vars unless vars.empty?
|
|
48
|
+
|
|
49
|
+
nodes << keys
|
|
50
|
+
end
|
|
51
|
+
db.disconnect
|
|
52
|
+
nodes
|
|
44
53
|
end
|
|
45
|
-
db.disconnect
|
|
46
|
-
nodes
|
|
47
|
-
end
|
|
48
54
|
|
|
49
|
-
|
|
55
|
+
private
|
|
50
56
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
def initialize
|
|
58
|
+
super
|
|
59
|
+
@cfg = Oxidized.config.source.sql
|
|
60
|
+
end
|
|
55
61
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
def connect
|
|
63
|
+
options = {
|
|
64
|
+
adapter: @cfg.adapter,
|
|
65
|
+
host: @cfg.host?,
|
|
66
|
+
user: @cfg.user?,
|
|
67
|
+
password: @cfg.password?,
|
|
68
|
+
database: @cfg.database,
|
|
69
|
+
ssl_mode: @cfg.ssl_mode?
|
|
70
|
+
}
|
|
71
|
+
if @cfg.with_ssl?
|
|
72
|
+
options.merge!(sslca: @cfg.ssl_ca?,
|
|
73
|
+
sslcert: @cfg.ssl_cert?,
|
|
74
|
+
sslkey: @cfg.ssl_key?)
|
|
75
|
+
end
|
|
76
|
+
Sequel.connect(options)
|
|
77
|
+
rescue Sequel::AdapterNotFound => e
|
|
78
|
+
raise OxidizedError, "SQL adapter gem not installed: " + e.message
|
|
69
79
|
end
|
|
70
|
-
Sequel.connect(options)
|
|
71
|
-
rescue Sequel::AdapterNotFound => e
|
|
72
|
-
raise OxidizedError, "SQL adapter gem not installed: " + e.message
|
|
73
80
|
end
|
|
74
81
|
end
|
|
75
82
|
end
|
data/lib/oxidized/version.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module Oxidized
|
|
2
|
-
VERSION = '0.
|
|
3
|
-
VERSION_FULL = '0.
|
|
2
|
+
VERSION = '0.31.0'.freeze
|
|
3
|
+
VERSION_FULL = '0.31.0'.freeze
|
|
4
4
|
def self.version_set
|
|
5
5
|
version_full = %x(git describe --tags).chop rescue ""
|
|
6
6
|
version = %x(git describe --tags --abbrev=0).chop rescue ""
|
data/oxidized.gemspec
CHANGED
|
@@ -13,35 +13,41 @@ Gem::Specification.new do |s|
|
|
|
13
13
|
s.summary = 'feeble attempt at rancid'
|
|
14
14
|
s.description = 'software to fetch configuration from network devices and store them'
|
|
15
15
|
s.rubyforge_project = s.name
|
|
16
|
-
s.files = %x(git ls-files -z).split("\x0").reject { |f| f.match(
|
|
16
|
+
s.files = %x(git ls-files -z).split("\x0").reject { |f| f.match(/^(test|spec|features)\//) }
|
|
17
17
|
s.executables = %w[oxidized]
|
|
18
18
|
s.require_path = 'lib'
|
|
19
19
|
|
|
20
20
|
s.metadata['rubygems_mfa_required'] = 'true'
|
|
21
21
|
|
|
22
|
-
s.required_ruby_version = '>= 3.
|
|
22
|
+
s.required_ruby_version = '>= 3.1'
|
|
23
23
|
|
|
24
|
-
s.
|
|
25
|
-
s.
|
|
26
|
-
s.
|
|
27
|
-
s.
|
|
28
|
-
s.
|
|
29
|
-
s.
|
|
30
|
-
s.
|
|
31
|
-
s.
|
|
32
|
-
s.
|
|
33
|
-
s.
|
|
24
|
+
s.add_dependency 'asetus', '~> 0.1'
|
|
25
|
+
s.add_dependency 'bcrypt_pbkdf', '~> 1.0'
|
|
26
|
+
s.add_dependency 'ed25519', '~> 1.2'
|
|
27
|
+
s.add_dependency 'net-ftp', '~> 0.2'
|
|
28
|
+
s.add_dependency 'net-http-digest_auth', '~> 1.4'
|
|
29
|
+
s.add_dependency 'net-scp', '~> 4.0'
|
|
30
|
+
s.add_dependency 'net-ssh', '~> 7.3'
|
|
31
|
+
s.add_dependency 'net-telnet', '~> 0.2'
|
|
32
|
+
s.add_dependency 'psych', '~> 5.0'
|
|
33
|
+
s.add_dependency 'rugged', '~> 1.6'
|
|
34
|
+
s.add_dependency 'slop', '~> 4.6'
|
|
34
35
|
|
|
35
36
|
s.add_development_dependency 'bundler', '~> 2.2'
|
|
36
|
-
s.add_development_dependency 'git', '~>
|
|
37
|
+
s.add_development_dependency 'git', '~> 2'
|
|
37
38
|
s.add_development_dependency 'minitest', '~> 5.18'
|
|
38
39
|
s.add_development_dependency 'mocha', '~> 2.1'
|
|
39
40
|
s.add_development_dependency 'pry', '~> 0.14.2'
|
|
40
41
|
s.add_development_dependency 'rake', '~> 13.0'
|
|
41
|
-
s.add_development_dependency 'rubocop', '~> 1.
|
|
42
|
-
s.add_development_dependency 'rubocop-minitest', '~> 0.
|
|
42
|
+
s.add_development_dependency 'rubocop', '~> 1.68.0'
|
|
43
|
+
s.add_development_dependency 'rubocop-minitest', '~> 0.36.0'
|
|
43
44
|
s.add_development_dependency 'rubocop-rake', '~> 0.6.0'
|
|
45
|
+
s.add_development_dependency 'rubocop-sequel', '~> 0.3.3'
|
|
44
46
|
s.add_development_dependency 'simplecov', '~> 0.22.0'
|
|
45
47
|
s.add_development_dependency 'simplecov-cobertura', '~> 2.1.0'
|
|
46
|
-
s.add_development_dependency 'simplecov-html', '~> 0.
|
|
48
|
+
s.add_development_dependency 'simplecov-html', '~> 0.13.1'
|
|
49
|
+
|
|
50
|
+
# Dependencies on optional libraries, used for unit tests & development
|
|
51
|
+
s.add_development_dependency 'oxidized-web', '>= 0.14.0'
|
|
52
|
+
s.add_development_dependency 'sequel', '~> 5.63'
|
|
47
53
|
end
|