octofacts-updater 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.
@@ -0,0 +1,36 @@
1
+ # This class reads a YAML file from the local file system so that it can be used as a source
2
+ # in octofacts-updater. This was originally intended for a quickstart tutorial, since it requires
3
+ # no real configuration. However it could also be used in production, if the user wants to create
4
+ # their own fact obtaining logic outside of octofacts-updater and simply feed in the results.
5
+
6
+ require_relative "base"
7
+
8
+ module OctofactsUpdater
9
+ module Service
10
+ class LocalFile < OctofactsUpdater::Service::Base
11
+ # Get the facts from a local file, without using PuppetDB, SSH, or any of the other automated methods.
12
+ #
13
+ # node - A String with the FQDN for which to retrieve facts
14
+ # config - A Hash with configuration settings
15
+ #
16
+ # Returns a Hash with the facts.
17
+ def self.facts(node, config = {})
18
+ unless config["localfile"].is_a?(Hash)
19
+ raise ArgumentError, "OctofactsUpdater::Service::LocalFile requires localfile section"
20
+ end
21
+ config_localfile = config["localfile"].dup
22
+
23
+ path_raw = config_localfile.delete("path")
24
+ unless path_raw
25
+ raise ArgumentError, "OctofactsUpdater::Service::LocalFile requires 'path' in the localfile section"
26
+ end
27
+ path = path_raw.gsub("%%NODE%%", node)
28
+ unless File.file?(path)
29
+ raise Errno::ENOENT, "OctofactsUpdater::Service::LocalFile cannot find a file at #{path.inspect}"
30
+ end
31
+
32
+ parse_yaml(File.read(path))
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,42 @@
1
+ # This class interacts with puppetdb to pull the facts from the recent
2
+ # run of Puppet on a given node. This uses octocatalog-diff on the back end to
3
+ # pull the facts from puppetdb.
4
+
5
+ require "octocatalog-diff"
6
+
7
+ module OctofactsUpdater
8
+ module Service
9
+ class PuppetDB
10
+ # Get the facts for a specific node.
11
+ #
12
+ # node - A String with the FQDN for which to retrieve facts
13
+ # config - An optional Hash with configuration settings
14
+ #
15
+ # Returns a Hash with the facts (via octocatalog-diff)
16
+ def self.facts(node, config = {})
17
+ fact_obj = OctocatalogDiff::Facts.new(
18
+ node: node.strip,
19
+ backend: :puppetdb,
20
+ puppetdb_url: puppetdb_url(config)
21
+ )
22
+ facts = fact_obj.facts(node)
23
+ return facts unless facts.nil?
24
+ raise OctocatalogDiff::Errors::FactSourceError, "Fact retrieval failed for #{node}"
25
+ end
26
+
27
+ # Get the puppetdb URL from the configuration or environment.
28
+ #
29
+ # config - An optional Hash with configuration settings
30
+ #
31
+ # Returns a String with the PuppetDB URL
32
+ def self.puppetdb_url(config = {})
33
+ answer = [
34
+ config.fetch("puppetdb", {}).fetch("url", nil),
35
+ ENV["PUPPETDB_URL"]
36
+ ].compact
37
+ raise "PuppetDB URL not configured or set in environment" unless answer.any?
38
+ answer.first
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,58 @@
1
+ # This class interacts with a puppetserver to obtain facts from that server's YAML cache.
2
+ # This is achieved by SSH-ing to the server and obtaining the fact file directly from the
3
+ # puppetserver's cache. This can also be used to SSH to an actual node and run a command,
4
+ # e.g. `facter -p --yaml` to grab actual facts from a running production node.
5
+
6
+ require "net/ssh"
7
+ require "shellwords"
8
+
9
+ require_relative "base"
10
+
11
+ module OctofactsUpdater
12
+ module Service
13
+ class SSH < OctofactsUpdater::Service::Base
14
+ CACHE_DIR = "/opt/puppetlabs/server/data/puppetserver/yaml/facts"
15
+ COMMAND = "cat %%NODE%%.yaml"
16
+
17
+ # Get the facts for a specific node.
18
+ #
19
+ # node - A String with the FQDN for which to retrieve facts
20
+ # config - A Hash with configuration settings
21
+ #
22
+ # Returns a Hash with the facts.
23
+ def self.facts(node, config = {})
24
+ unless config["ssh"].is_a?(Hash)
25
+ raise ArgumentError, "OctofactsUpdater::Service::SSH requires ssh section"
26
+ end
27
+ config_ssh = config["ssh"].dup
28
+
29
+ server_raw = config_ssh.delete("server")
30
+ unless server_raw
31
+ raise ArgumentError, "OctofactsUpdater::Service::SSH requires 'server' in the ssh section"
32
+ end
33
+ server = server_raw.gsub("%%NODE%%", node)
34
+
35
+ user = config_ssh.delete("user") || ENV["USER"]
36
+ unless user
37
+ raise ArgumentError, "OctofactsUpdater::Service::SSH requires 'user' in the ssh section"
38
+ end
39
+
40
+ # Default is to 'cd (puppetserver cache dir) && cat (node).yaml' but this can
41
+ # be overridden by specifying a command in the SSH options. "%%NODE%%" will always
42
+ # be replaced by the FQDN of the node in the overall result.
43
+ cache_dir = config_ssh.delete("cache_dir") || CACHE_DIR
44
+ command_raw = config_ssh.delete("command") || "cd #{Shellwords.escape(cache_dir)} && #{COMMAND}"
45
+ command = command_raw.gsub("%%NODE%%", node)
46
+
47
+ # Everything left over in config["ssh"] (once server, user, command, and cache_dir are removed) is
48
+ # symbolized and passed directory to Net::SSH.
49
+ net_ssh_opts = config_ssh.map { |k, v| [k.to_sym, v] }.to_h || {}
50
+ ret = Net::SSH.start(server, user, net_ssh_opts) do |ssh|
51
+ ssh.exec! command
52
+ end
53
+ return { "name" => node, "values" => parse_yaml(ret.to_s.strip) } if ret.exitstatus == 0
54
+ raise "ssh failed with exitcode=#{ret.exitstatus}: #{ret.to_s.strip}"
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,3 @@
1
+ module OctofactsUpdater
2
+ VERSION = File.read(File.expand_path("../../.version", File.dirname(__FILE__))).strip
3
+ end
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: octofacts-updater
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - GitHub, Inc.
8
+ - Kevin Paulisse
9
+ - Antonio Santos
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2017-10-06 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: diffy
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: 3.1.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: 3.1.0
29
+ - !ruby/object:Gem::Dependency
30
+ name: octocatalog-diff
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: 1.4.1
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 1.4.1
43
+ - !ruby/object:Gem::Dependency
44
+ name: octokit
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 4.2.0
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 4.2.0
57
+ - !ruby/object:Gem::Dependency
58
+ name: net-ssh
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '2.9'
64
+ type: :runtime
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '2.9'
71
+ description: |
72
+ Octofacts-updater is a series of scripts to construct the fact fixture files and index files consumed by octofacts.
73
+ email: opensource+octofacts@github.com
74
+ executables:
75
+ - octofacts-updater
76
+ extensions: []
77
+ extra_rdoc_files: []
78
+ files:
79
+ - ".version"
80
+ - bin/octofacts-updater
81
+ - lib/octofacts_updater.rb
82
+ - lib/octofacts_updater/cli.rb
83
+ - lib/octofacts_updater/fact.rb
84
+ - lib/octofacts_updater/fact_index.rb
85
+ - lib/octofacts_updater/fixture.rb
86
+ - lib/octofacts_updater/plugin.rb
87
+ - lib/octofacts_updater/plugins/ip.rb
88
+ - lib/octofacts_updater/plugins/ssh.rb
89
+ - lib/octofacts_updater/plugins/static.rb
90
+ - lib/octofacts_updater/service/base.rb
91
+ - lib/octofacts_updater/service/enc.rb
92
+ - lib/octofacts_updater/service/github.rb
93
+ - lib/octofacts_updater/service/local_file.rb
94
+ - lib/octofacts_updater/service/puppetdb.rb
95
+ - lib/octofacts_updater/service/ssh.rb
96
+ - lib/octofacts_updater/version.rb
97
+ homepage: https://github.com/github/octofacts
98
+ licenses:
99
+ - MIT
100
+ metadata: {}
101
+ post_install_message:
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: 2.1.0
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubyforge_project:
117
+ rubygems_version: 2.2.5
118
+ signing_key:
119
+ specification_version: 4
120
+ summary: Scripts to update octofacts fixtures from recent Puppet runs
121
+ test_files: []