inspec-elasticsearch-resources 7.1.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 58760d82c2d98a35d500a16a7f9d2bcae471c9d2ec86d3bb14a6c8f7ad452bd3
4
+ data.tar.gz: fe15e5dc70c1d03b8b89d52d12f57e26dae997bd3b8963b0c87a31051de1eb17
5
+ SHA512:
6
+ metadata.gz: fa7b46e5fcb9c3686da96e9ed1a326146fbe4cf609da35e3f00c582a1d939acc122b4689454c68d3999a436015a65d8354dc65f121ece7de79755683a3a33d07
7
+ data.tar.gz: 233b5618829c579b8c5fcb0a8822b03fa84aecc07cddb3be9d8227ce73ca7deb9432b36459fe407f873e232a7049ab14a0dc905bc9e86ea845c1f4e4fdae9a76
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+ gem "inspec", git: "https://github.com/inspec/inspec", branch: "inspec-7"
5
+ gem "inspec-bin", git: "https://github.com/inspec/inspec", branch: "inspec-7"
6
+
7
+ gemspec
8
+
9
+ group :test do
10
+ gem "byebug"
11
+ gem "chefstyle"
12
+ gem "minitest"
13
+ gem "m"
14
+ gem "mocha"
15
+ gem "rake"
16
+ gem "simplecov"
17
+ gem "simplecov_json_formatter"
18
+ end
data/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # inspec-elasticsearch-resources
2
+ ElasticSearch InSpec Resources in a Gem
3
+
4
+ This repository contains the InSpec Elasticsearch resources, formerly contained in InSpec Core. In InSpec 7+, these resources are available in a gem, `inspec-elasticsearch-resources`.
5
+
6
+ ## Usage
7
+
8
+ To use this resource pack, add this dependency to your inspec.yml :
9
+
10
+ ```yaml
11
+ depends:
12
+ - name: inspec-elasticsearch-resources
13
+ gem: inspec-elasticsearch-resources
14
+ ```
15
+
@@ -0,0 +1,44 @@
1
+ # As plugins are usually packaged and distributed as a RubyGem,
2
+ # we have to provide a .gemspec file, which controls the gembuild
3
+ # and publish process. This is a fairly generic gemspec.
4
+
5
+ # It is traditional in a gemspec to dynamically load the current version
6
+ # from a file in the source tree. The next three lines make that happen.
7
+ lib = File.expand_path("lib", __dir__)
8
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
9
+ require "inspec-elasticsearch-resources/version"
10
+
11
+ Gem::Specification.new do |spec|
12
+ # Importantly, all InSpec plugins must be prefixed with `inspec-` (most
13
+ # plugins) or `train-` (plugins which add new connectivity features).
14
+ spec.name = "inspec-elasticsearch-resources"
15
+
16
+ # It is polite to namespace your plugin under InspecPlugins::YourPluginInCamelCase
17
+ spec.version = InspecPlugins::ElasticsearchResources::VERSION
18
+ spec.authors = ["InSpec Core Maintainers"]
19
+ spec.email = ["inspec@progress.com"]
20
+ spec.summary = "InSpec elasticsearch Resources in a Gem"
21
+ spec.description = "Contains InSpec 7.0+ resources fo interacting with Elasticsearch Resources."
22
+ spec.homepage = "https://github.com/inspec/inspec-elasticsearch-resources"
23
+ spec.license = "Apache-2.0"
24
+
25
+ # Though complicated-looking, this is pretty standard for a gemspec.
26
+ # It just filters what will actually be packaged in the gem (leaving
27
+ # out tests, etc)
28
+ spec.files = %w{
29
+ README.md inspec-elasticsearch-resources.gemspec Gemfile inspec.yml
30
+ } + Dir.glob(
31
+ "lib/**/*", File::FNM_DOTMATCH
32
+ ).reject { |f| File.directory?(f) }
33
+ spec.require_paths = ["lib"]
34
+
35
+ spec.required_ruby_version = ">= 3.1.0"
36
+
37
+ # If you rely on any other gems, list them here with any constraints.
38
+ # This is how `inspec plugin install` is able to manage your dependencies.
39
+ # For example, perhaps you are writing a thing that talks to AWS, and you
40
+ # want to ensure you have `aws-sdk` in a certain version.
41
+
42
+ # This plugin uses InSpec 7 Resource Pack Plugins
43
+ spec.add_dependency "inspec-core", ">= 7.0"
44
+ end
data/inspec.yml ADDED
@@ -0,0 +1,10 @@
1
+ name: inspec-elasticsearch-resources
2
+ title: Resource pack gem for ElasticsearchResources
3
+ maintainer: InSpec Core Maintainers
4
+ copyright: Progress Software Corporation
5
+ copyright_email: inspec@progress.com
6
+ license:
7
+ summary: elasticsearch InSpec Resources in a Gem
8
+ version: 7.1.2
9
+ supports:
10
+ platform: os
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+ # Plugin Definition file
3
+ # The purpose of this file is to declare to InSpec what plugin_types (capabilities)
4
+ # are included in this plugin, and provide activator that will load them as needed.
5
+
6
+ # It is important that this file load successfully and *quickly*.
7
+ # Your plugin's functionality may never be used on this InSpec run; so we keep things
8
+ # fast and light by only loading heavy things when they are needed.
9
+
10
+ # Presumably this is light
11
+ require "inspec-elasticsearch-resources/version"
12
+
13
+ # The InspecPlugins namespace is where all plugins should declare themselves.
14
+ # The "Inspec" capitalization is used throughout the InSpec source code; yes, it's
15
+ # strange.
16
+ module InspecPlugins
17
+ # Pick a reasonable namespace here for your plugin. A reasonable choice
18
+ # would be the CamelCase version of your plugin gem name.
19
+ # inspec-test-resources => TestResources
20
+ module ElasticsearchResources
21
+ # This simple class handles the plugin definition, so calling it simply Plugin is OK.
22
+ # Inspec.plugin returns various Classes, intended to be superclasses for various
23
+ # plugin components. Here, the one-arg form gives you the Plugin Definition superclass,
24
+ # which mainly gives you access to the activator / plugin_type DSL.
25
+ # The number '2' says you are asking for version 2 of the plugin API. If there are
26
+ # future versions, InSpec promises plugin API v2 will work for at least two more InSpec
27
+ # major versions.
28
+ class Plugin < ::Inspec.plugin(2)
29
+ # Internal machine name of the plugin. InSpec will use this in errors, etc.
30
+ plugin_name :"inspec-elasticsearch-resources"
31
+
32
+ # Define a new Resource Pack.
33
+ resource_pack :"inspec-elasticsearch-resources" do
34
+ # This file will load the resources implicitly via the superclass
35
+ require "inspec-elasticsearch-resources/resource_pack"
36
+
37
+ # Having loaded our functionality, return a class that represents the plugin.
38
+ # Reserved for future use.
39
+ InspecPlugins::ElasticsearchResources::ResourcePack
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ require "inspec/resource"
3
+
4
+ module InspecPlugins::ElasticsearchResources
5
+ # This class will provide the actual CLI implementation.
6
+ # Its superclass is provided by another call to Inspec.plugin,
7
+ # this time with two args. The first arg specifies we are requesting
8
+ # version 2 of the Plugins API. The second says we are making a Resource
9
+ # Pack plugin component, so please make available any DSL needed
10
+ # for that.
11
+ class ResourcePack < Inspec.plugin(2, :resource_pack)
12
+ # TBD
13
+ # load_timing :early <-- isn't that implicit in the rewuire statements
14
+ # train relationship declarations? <-- that should be in the gemspec
15
+ end
16
+ end
@@ -0,0 +1,168 @@
1
+ require "inspec/utils/filter"
2
+ require "hashie/mash"
3
+ require "inspec/resources/package"
4
+
5
+ class Elasticsearch < Inspec.resource(1)
6
+ name "elasticsearch"
7
+ supports platform: "unix"
8
+ desc "Use the Elasticsearch InSpec audit resource to test the status of nodes in
9
+ an Elasticsearch cluster."
10
+
11
+ example <<~EXAMPLE
12
+ describe elasticsearch('http://eshost.mycompany.biz:9200/', username: 'elastic', password: 'changeme', ssl_verify: false) do
13
+ its('node_count') { should >= 3 }
14
+ end
15
+
16
+ describe elasticsearch do
17
+ its('node_name') { should include 'node1' }
18
+ its('os') { should_not include 'MacOS' }
19
+ its('version') { should cmp > 1.2.0 }
20
+ end
21
+ EXAMPLE
22
+
23
+ filter = FilterTable.create
24
+ filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
25
+ filter.register_column(:cluster_name, field: "cluster_name")
26
+ .register_column(:node_name, field: "name")
27
+ .register_column(:transport_address, field: "transport_address")
28
+ .register_column(:host, field: "host")
29
+ .register_column(:ip, field: "ip")
30
+ .register_column(:version, field: "version")
31
+ .register_column(:build_hash, field: "build_hash")
32
+ .register_column(:total_indexing_buffer, field: "total_indexing_buffer")
33
+ .register_column(:roles, field: "roles")
34
+ .register_column(:settings, field: "settings")
35
+ .register_column(:os, field: "os")
36
+ .register_column(:process, field: "process")
37
+ .register_column(:jvm, field: "jvm")
38
+ .register_column(:transport, field: "transport")
39
+ .register_column(:http, field: "http")
40
+ .register_column(:plugins, field: "plugins")
41
+ .register_column(:plugin_list, field: "plugin_list")
42
+ .register_column(:modules, field: "modules")
43
+ .register_column(:module_list, field: "module_list")
44
+ .register_column(:node_id, field: "node_id")
45
+ .register_column(:ingest, field: "ingest")
46
+ .register_custom_property(:node_count) do |t, _|
47
+ t.entries.length
48
+ end
49
+
50
+ filter.install_filter_methods_on_resource(self, :nodes)
51
+
52
+ attr_reader :nodes, :url
53
+
54
+ def initialize(opts = {})
55
+ return skip_resource "Package `curl` not avaiable on the host" unless inspec.command("curl").exist?
56
+
57
+ @url = opts.fetch(:url, "http://localhost:9200")
58
+
59
+ username = opts.fetch(:username, nil)
60
+ password = opts.fetch(:password, nil)
61
+ ssl_verify = opts.fetch(:ssl_verify, true)
62
+
63
+ begin
64
+ cmd = inspec.command(curl_command_string(username, password, ssl_verify))
65
+ rescue => e
66
+ return skip_resource e.message
67
+ end
68
+
69
+ # after implementation of PR #2235, this begin..rescue won't be necessary.
70
+ # The checks in verify_curl_success! can raise their own skip message exception.
71
+ begin
72
+ verify_curl_success!(cmd)
73
+ rescue => e
74
+ return skip_resource e.message
75
+ end
76
+
77
+ begin
78
+ content = JSON.parse(cmd.stdout)
79
+ # after implementation of PR #2235, this can be broken out of the begin..rescue
80
+ # clause. The checks in verify_json_payload! can raise their own skip message exception.
81
+ verify_json_payload!(content)
82
+ rescue JSON::ParserError => e
83
+ return skip_resource "Couldn't parse the Elasticsearch response: #{e.message}"
84
+ rescue => e
85
+ return skip_resource e.message
86
+ end
87
+
88
+ @nodes = parse_cluster(content)
89
+ end
90
+
91
+ def to_s
92
+ "Elasticsearch Cluster #{url}"
93
+ end
94
+
95
+ private
96
+
97
+ def parse_cluster(content)
98
+ return [] unless content["nodes"]
99
+
100
+ nodes = []
101
+
102
+ content["nodes"].each do |node_id, node_data|
103
+ node_data = fix_mash_key_collision(node_data)
104
+
105
+ node = Hashie::Mash.new(node_data)
106
+ node.node_id = node_id
107
+ node.plugin_list = node.plugins.map(&:name)
108
+ node.module_list = node.modules.map(&:name)
109
+ node.cluster_name = node.settings.cluster.name
110
+ nodes << node
111
+ end
112
+
113
+ nodes
114
+ end
115
+
116
+ #
117
+ # Hashie::Mash will throw warnings if the Mash contains a key that is the same as a built-in
118
+ # method on a Hashie::Mash instance. This is a crude way of avoiding those warnings without
119
+ # hard-coding a bunch of key renames.
120
+ #
121
+ # Any key that is in conflict will be renamed "es_ORIGINALKEY"
122
+ #
123
+ def fix_mash_key_collision(data)
124
+ test_mash = Hashie::Mash.new
125
+
126
+ new_data = {}
127
+ data.each do |key, value|
128
+ new_key = test_mash.respond_to?(key.to_sym) ? "es_#{key}" : key
129
+ new_value = value.is_a?(Hash) ? fix_mash_key_collision(value) : value
130
+
131
+ new_data[new_key] = new_value
132
+ end
133
+
134
+ new_data
135
+ end
136
+
137
+ def curl_command_string(username, password, ssl_verify)
138
+ cmd_string = ["curl"]
139
+ cmd_string << "-k" unless ssl_verify
140
+ cmd_string << "-H 'Content-Type: application/json'"
141
+ cmd_string << " -u #{username}:#{password}" unless username.nil? || password.nil?
142
+ cmd_string << URI.join(url, "_nodes")
143
+
144
+ cmd_string.join(" ")
145
+ end
146
+
147
+ def verify_curl_success!(cmd)
148
+ # the following lines captures known possible curl command errors and provides compact skip resource messeges
149
+ if cmd.stderr =~ /Failed to connect/
150
+ raise "Connection refused - please check the URL #{url} for accuracy"
151
+ end
152
+
153
+ if cmd.stderr =~ /Peer's Certificate issuer is not recognized/
154
+ raise "Connection refused - peer certificate issuer is not recognized"
155
+ end
156
+
157
+ raise "Error fetching Elastcsearch data from curl #{url}: #{cmd.stderr}" unless cmd.exit_status == 0
158
+ end
159
+
160
+ def verify_json_payload!(content)
161
+ unless content["error"].nil?
162
+ raise "#{content["error"]["type"]}: #{content["error"]["reason"]}"
163
+ end
164
+
165
+ raise "No successful nodes available in cluster" if content["_nodes"]["successful"] == 0
166
+ end
167
+ end
168
+
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+ # This file simply makes it easier for CI engines to update
3
+ # the version stamp, and provide a clean way for the gemspec
4
+ # to learn the current version.
5
+ module InspecPlugins
6
+ module ElasticsearchResources
7
+ VERSION = "7.1.2"
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ # This file is known as the "entry point."
2
+ # This is the file InSpec will try to load if it
3
+ # thinks your plugin is installed.
4
+
5
+ # The *only* thing this file should do is setup the
6
+ # load path, then load the plugin definition file.
7
+
8
+ # Next two lines simply add the path of the gem to the load path.
9
+ # This is not needed when being loaded as a gem; but when doing
10
+ # plugin development, you may need it. Either way, it's harmless.
11
+
12
+ libdir = File.dirname(__FILE__)
13
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
14
+
15
+ require "inspec-elasticsearch-resources/plugin"
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inspec-elasticsearch-resources
3
+ version: !ruby/object:Gem::Version
4
+ version: 7.1.2
5
+ platform: ruby
6
+ authors:
7
+ - InSpec Core Maintainers
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2025-10-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: inspec-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '7.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '7.0'
27
+ description: Contains InSpec 7.0+ resources fo interacting with Elasticsearch Resources.
28
+ email:
29
+ - inspec@progress.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - Gemfile
35
+ - README.md
36
+ - inspec-elasticsearch-resources.gemspec
37
+ - inspec.yml
38
+ - lib/inspec-elasticsearch-resources.rb
39
+ - lib/inspec-elasticsearch-resources/plugin.rb
40
+ - lib/inspec-elasticsearch-resources/resource_pack.rb
41
+ - lib/inspec-elasticsearch-resources/resources/.gitkeep
42
+ - lib/inspec-elasticsearch-resources/resources/elasticsearch.rb
43
+ - lib/inspec-elasticsearch-resources/version.rb
44
+ homepage: https://github.com/inspec/inspec-elasticsearch-resources
45
+ licenses:
46
+ - Apache-2.0
47
+ metadata: {}
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 3.1.0
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubygems_version: 3.3.27
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: InSpec elasticsearch Resources in a Gem
67
+ test_files: []