From da00e359aa14ac956d990d47989f61a312b0367c Mon Sep 17 00:00:00 2001 From: Vasu1105 Date: Mon, 14 Jun 2021 18:17:05 +0530 Subject: [PATCH 1/3] Add mongodb_conf resource to InSpec Signed-off-by: Vasu1105 --- .../content/inspec/resources/mongodb_conf.md | 69 +++++++++++++++++++ lib/inspec/resources.rb | 2 + lib/inspec/resources/mongodb.rb | 66 ++++++++++++++++++ lib/inspec/resources/mongodb_conf.rb | 43 ++++++++++++ test/fixtures/cmd/mongodb-version | 1 + test/fixtures/files/mongod.conf | 24 +++++++ test/fixtures/files/mongodb-version | 1 + test/helpers/mock_loader.rb | 2 + test/unit/resources/mongodb_conf_test.rb | 19 +++++ test/unit/resources/mongodb_test.rb | 16 +++++ 10 files changed, 243 insertions(+) create mode 100644 docs-chef-io/content/inspec/resources/mongodb_conf.md create mode 100644 lib/inspec/resources/mongodb.rb create mode 100644 lib/inspec/resources/mongodb_conf.rb create mode 100644 test/fixtures/cmd/mongodb-version create mode 100644 test/fixtures/files/mongod.conf create mode 100644 test/fixtures/files/mongodb-version create mode 100644 test/unit/resources/mongodb_conf_test.rb create mode 100644 test/unit/resources/mongodb_test.rb diff --git a/docs-chef-io/content/inspec/resources/mongodb_conf.md b/docs-chef-io/content/inspec/resources/mongodb_conf.md new file mode 100644 index 000000000..333e78073 --- /dev/null +++ b/docs-chef-io/content/inspec/resources/mongodb_conf.md @@ -0,0 +1,69 @@ ++++ +title = "mongodb_conf resource" +draft = false +gh_repo = "inspec" +platform = "os" + +[menu] + [menu.inspec] + title = "mongodb_conf" + identifier = "inspec/resources/os/mongodb_conf.md mongodb_conf resource" + parent = "inspec/resources/os" ++++ + +Use the `mongodb_conf` Chef InSpec audit resource to test the contents of the configuration file for MongoDB, typically located at `/etc/mongod.conf` or `C:\Program Files\MongoDB\Server\\bin\mongod.cfg`, depending on the platform. + +## Availability + +### Installation + +This resource is distributed along with Chef InSpec itself. You can use it automatically. + +## Syntax + +A `mongodb_conf` resource block declares one (or more) settings in the `mongodb.conf` file, and then compares the setting in the configuration file to the value stated in the test: + + describe mongodb_conf('path') do + its('setting') { should eq 'value' } + end + +where + +- `'setting'` specifies a setting in the `mongodb.conf` file +- `('path')` is the non-default path to the `mongodb.conf` file (optional) +- `should eq 'value'` is the value that is expected + +## Examples + +The following examples show how to use this Chef InSpec audit resource. + +### Test the key management configuration options + + describe mongodb_conf do + its(['security', 'enableEncryption']) { should eq true } + end + +### Test the port on which MongoDB listens + + describe mongodb_conf do + its('port') { should eq 27017 } + end + +### Test the security configuration options + + describe mongodb_conf do + its(['security', 'authorization']) { should eq 'enabled' } + end + + +## Matchers + +For a full list of available matchers, please visit our [matchers page](/inspec/matchers/). + +### setting + +The `setting` matcher tests specific, named settings in the `mongod.conf` file: + + its(['setting') { should eq 'value' } + +Use a `setting` matcher for each setting to be tested. diff --git a/lib/inspec/resources.rb b/lib/inspec/resources.rb index 6f153e94d..1bdf0021d 100644 --- a/lib/inspec/resources.rb +++ b/lib/inspec/resources.rb @@ -71,6 +71,8 @@ require "inspec/resources/key_rsa" require "inspec/resources/ksh" require "inspec/resources/limits_conf" require "inspec/resources/login_defs" +require "inspec/resources/mongodb" +require "inspec/resources/mongodb_conf" require "inspec/resources/mount" require "inspec/resources/mssql_session" require "inspec/resources/mysql" diff --git a/lib/inspec/resources/mongodb.rb b/lib/inspec/resources/mongodb.rb new file mode 100644 index 000000000..66600b587 --- /dev/null +++ b/lib/inspec/resources/mongodb.rb @@ -0,0 +1,66 @@ +module Inspec::Resources + class Mongodb < Inspec.resource(1) + name "mongodb" + supports platform: "unix" + supports platform: "windows" + + desc "The 'mongodb' resource is a helper for the 'mongodb_conf' & 'mongodb_session' resources. Please use those instead." + + attr_reader :conf_path + + def initialize + case inspec.os[:family] + when "debian", "fedora", "redhat", "linux", "suse" + init_linux + when "darwin" + init_macos + when "windows" + init_windows + end + end + + def to_s + "MongoDB" + end + + private + + def init_linux + @conf_path = "/etc/mongod.conf" + end + + def init_macos + @conf_path = "/usr/local/etc/mongod.conf" + end + + def init_windows + dir = "C:\\Program Files\\MongoDB\\Server" + @version = version_from_dir(dir) + unless @version.to_s.empty? + @conf_path = "#{dir}\\#{@version}\\bin\\mongod.cfg" + end + end + + def version_from_dir(dir) + dirs = inspec.command("Get-ChildItem -Path \"#{dir}\" -Name").stdout + entries = dirs.lines.count + case entries + when 0 + warn "Could not determine version of installed MongoDB by inspecting #{dir}" + nil + when 1 + warn "Using #{dirs}: #{dir_to_version(dirs)}" + dir_to_version(dirs) + else + warn "Multiple versions of MongoDB installed or incorrect base dir #{dir}" + first = dir_to_version(dirs.lines.first) + warn "Using the first version found: #{first}" + first + end + end + + def dir_to_version(dir) + dir.chomp.split("/").last + end + end +end diff --git a/lib/inspec/resources/mongodb_conf.rb b/lib/inspec/resources/mongodb_conf.rb new file mode 100644 index 000000000..ec1dd986f --- /dev/null +++ b/lib/inspec/resources/mongodb_conf.rb @@ -0,0 +1,43 @@ +require "inspec/resources/json" +require "inspec/resources/mongodb" + +module Inspec::Resources + class MongodbConf < JsonConfig + name "mongodb_conf" + supports platform: "unix" + supports platform: "windows" + desc "Use the mongodb_conf InSpec audit resource to test the contents of the configuration file for MongoDB, typically located at `/etc/mongod.conf` or `C:\\Program Files\\MongoDB\\Server\\\\bin\\mongod.cfg`, depending on the platform." + example <<~EXAMPLE + describe mongodb_conf do + its(["storage", "dbPath"]) { should eq "/var/lib/mongodb" } + its("port") { should eq 27017 } + end + EXAMPLE + + def initialize(conf_path = nil) + @conf_path = conf_path || inspec.mongodb.conf_path + + if @conf_path.nil? + return skip_resource "MongoDB conf path is not set." + end + + super(@conf_path) + end + + def port + params["net"]["port"] + end + + private + + def parse(content) + YAML.load(content) + rescue => e + raise Inspec::Exceptions::ResourceFailed, "Unable to parse `mongod.conf` or `mongod.cfg` file: #{e.message}" + end + + def resource_base_name + "MongoDB Configuration" + end + end +end diff --git a/test/fixtures/cmd/mongodb-version b/test/fixtures/cmd/mongodb-version new file mode 100644 index 000000000..515be8f91 --- /dev/null +++ b/test/fixtures/cmd/mongodb-version @@ -0,0 +1 @@ +4.4 diff --git a/test/fixtures/files/mongod.conf b/test/fixtures/files/mongod.conf new file mode 100644 index 000000000..a19226ed5 --- /dev/null +++ b/test/fixtures/files/mongod.conf @@ -0,0 +1,24 @@ +# mongod.conf + +# for documentation of all options, see: +# http://docs.mongodb.org/manual/reference/configuration-options/ + +# Where and how to store data. +storage: + dbPath: /var/lib/mongodb + journal: + enabled: true +# engine: +# mmapv1: +# wiredTiger: + +# where to write logging data. +systemLog: + destination: file + logAppend: true + path: /var/log/mongodb/mongod.log + +# network interfaces +net: + port: 27017 + bindIp: 127.0.0.1 diff --git a/test/fixtures/files/mongodb-version b/test/fixtures/files/mongodb-version new file mode 100644 index 000000000..515be8f91 --- /dev/null +++ b/test/fixtures/files/mongodb-version @@ -0,0 +1 @@ +4.4 diff --git a/test/helpers/mock_loader.rb b/test/helpers/mock_loader.rb index 7652abd40..300540fa4 100644 --- a/test/helpers/mock_loader.rb +++ b/test/helpers/mock_loader.rb @@ -110,6 +110,7 @@ class MockLoader "/etc/audit/auditd.conf" => mockfile.call("auditd.conf"), "/etc/mysql/my.cnf" => mockfile.call("mysql.conf"), "/etc/mysql/mysql2.conf" => mockfile.call("mysql2.conf"), + "/etc/mongod.conf" => mockfile.call("mongod.conf"), "/etc/rabbitmq/rabbitmq.config" => mockfile.call("rabbitmq.config"), "kitchen.yml" => mockfile.call("kitchen.yml"), "example.csv" => mockfile.call("example.csv"), @@ -564,6 +565,7 @@ class MockLoader "sestatus" => cmd.call("sestatus"), "semodule -lfull" => cmd.call("semodule-lfull"), "semanage boolean -l -n" => cmd.call("semanage-boolean"), + "Get-ChildItem -Path \"C:\\Program Files\\MongoDB\\Server\" -Name" => cmd.call("mongodb-version"), } if @platform && (@platform[:name] == "windows" || @platform[:name] == "freebsd") diff --git a/test/unit/resources/mongodb_conf_test.rb b/test/unit/resources/mongodb_conf_test.rb new file mode 100644 index 000000000..8b071f977 --- /dev/null +++ b/test/unit/resources/mongodb_conf_test.rb @@ -0,0 +1,19 @@ +require "helper" +require "inspec/resource" +require "inspec/resources/mongodb_conf" + +describe "Inspec::Resources::MongodbConf" do + it "verify mongd.conf config parsing" do + resource = load_resource("mongodb_conf", "/etc/mongod.conf") + _(resource.params["storage"]["dbPath"]).must_equal "/var/lib/mongodb" + _(resource.params["systemLog"]["path"]).must_equal "/var/log/mongodb/mongod.log" + _(resource.port).must_equal 27017 + end + + it "verify mongd.conf config parsing use default configuration file location." do + resource = load_resource("mongodb_conf") + _(resource.params["storage"]["dbPath"]).must_equal "/var/lib/mongodb" + _(resource.params["systemLog"]["path"]).must_equal "/var/log/mongodb/mongod.log" + _(resource.port).must_equal 27017 + end +end diff --git a/test/unit/resources/mongodb_test.rb b/test/unit/resources/mongodb_test.rb new file mode 100644 index 000000000..4ac119eae --- /dev/null +++ b/test/unit/resources/mongodb_test.rb @@ -0,0 +1,16 @@ +require "helper" +require "inspec/resource" +require "inspec/resources/mongodb" + +describe "Inspec::Resources::Mongodb" do + it "sets default configuration path" do + resource = MockLoader.new(:windows).load_resource("mongodb") + _(resource.conf_path).must_equal "C:\\Program Files\\MongoDB\\Server\\4.4\\bin\\mongod.cfg" + end + + it "sets default configuration path" do + resource = MockLoader.new(:centos7).load_resource("mongodb") + _(resource.conf_path).must_equal "/etc/mongod.conf" + end +end + From 5f85e177455cd80857710db2049cdd43e66c3db9 Mon Sep 17 00:00:00 2001 From: Vasu1105 Date: Mon, 14 Jun 2021 19:41:56 +0530 Subject: [PATCH 2/3] Removed warning as per review comments Signed-off-by: Vasu1105 --- lib/inspec/resources/mongodb.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/inspec/resources/mongodb.rb b/lib/inspec/resources/mongodb.rb index 66600b587..a7099539f 100644 --- a/lib/inspec/resources/mongodb.rb +++ b/lib/inspec/resources/mongodb.rb @@ -49,7 +49,6 @@ module Inspec::Resources warn "Could not determine version of installed MongoDB by inspecting #{dir}" nil when 1 - warn "Using #{dirs}: #{dir_to_version(dirs)}" dir_to_version(dirs) else warn "Multiple versions of MongoDB installed or incorrect base dir #{dir}" From 607d9a1ebc02db9c9c3155b0b6bdc3bffcae4f3c Mon Sep 17 00:00:00 2001 From: Vasu1105 Date: Tue, 15 Jun 2021 20:04:00 +0530 Subject: [PATCH 3/3] Removed port property Signed-off-by: Vasu1105 --- docs-chef-io/content/inspec/resources/mongodb_conf.md | 6 +++--- lib/inspec/resources/mongodb_conf.rb | 6 +----- test/unit/resources/mongodb_conf_test.rb | 3 +-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/docs-chef-io/content/inspec/resources/mongodb_conf.md b/docs-chef-io/content/inspec/resources/mongodb_conf.md index 333e78073..31004df84 100644 --- a/docs-chef-io/content/inspec/resources/mongodb_conf.md +++ b/docs-chef-io/content/inspec/resources/mongodb_conf.md @@ -40,19 +40,19 @@ The following examples show how to use this Chef InSpec audit resource. ### Test the key management configuration options describe mongodb_conf do - its(['security', 'enableEncryption']) { should eq true } + its(["security", "enableEncryption"]) { should eq true } end ### Test the port on which MongoDB listens describe mongodb_conf do - its('port') { should eq 27017 } + its(["net", "port"]) { should eq 27017 } end ### Test the security configuration options describe mongodb_conf do - its(['security', 'authorization']) { should eq 'enabled' } + its(["security", "authorization"]) { should eq "enabled" } end diff --git a/lib/inspec/resources/mongodb_conf.rb b/lib/inspec/resources/mongodb_conf.rb index ec1dd986f..6f1370f66 100644 --- a/lib/inspec/resources/mongodb_conf.rb +++ b/lib/inspec/resources/mongodb_conf.rb @@ -10,7 +10,7 @@ module Inspec::Resources example <<~EXAMPLE describe mongodb_conf do its(["storage", "dbPath"]) { should eq "/var/lib/mongodb" } - its("port") { should eq 27017 } + its(["net", "port"]) { should eq 27017 } end EXAMPLE @@ -24,10 +24,6 @@ module Inspec::Resources super(@conf_path) end - def port - params["net"]["port"] - end - private def parse(content) diff --git a/test/unit/resources/mongodb_conf_test.rb b/test/unit/resources/mongodb_conf_test.rb index 8b071f977..6b0c86d1c 100644 --- a/test/unit/resources/mongodb_conf_test.rb +++ b/test/unit/resources/mongodb_conf_test.rb @@ -7,13 +7,12 @@ describe "Inspec::Resources::MongodbConf" do resource = load_resource("mongodb_conf", "/etc/mongod.conf") _(resource.params["storage"]["dbPath"]).must_equal "/var/lib/mongodb" _(resource.params["systemLog"]["path"]).must_equal "/var/log/mongodb/mongod.log" - _(resource.port).must_equal 27017 + _(resource.params["net"]["port"]).must_equal 27017 end it "verify mongd.conf config parsing use default configuration file location." do resource = load_resource("mongodb_conf") _(resource.params["storage"]["dbPath"]).must_equal "/var/lib/mongodb" _(resource.params["systemLog"]["path"]).must_equal "/var/log/mongodb/mongod.log" - _(resource.port).must_equal 27017 end end