inspec-cloudformation 0.0.1

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: 0bac1eaa6b1118ac6bb8066a77210d81199502aa46c8c6d0a66280f098fd0fca
4
+ data.tar.gz: 93fb485ae89f6c423a3dc815b1acd5a892e8d9849487d5ba562526b0b421cad9
5
+ SHA512:
6
+ metadata.gz: af62285f8c803d4e32303a271469412ecd78f28d6534a1e198d721ab264bf13b8da5130755dd14e54440b9e47bbcc25211e9796930e2a120ddd568d00dc882c0
7
+ data.tar.gz: 2b3692f7fbd654e8de573e58a8708dbbaade5e43658aefad4aeea1bcb0bb5bbab30e6673e0f16c7c53f11e65c519cea3edebbb775a68ef86c764460ff712939b
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ # gem "inspec-bin"
6
+ gem 'rake-release'
7
+
8
+
9
+
10
+ group :development do
11
+ gem "chefstyle", "2.2.0"
12
+ gem "m"
13
+ gem "bundler"
14
+ gem "byebug"
15
+ gem "minitest"
16
+ gem "rake"
17
+ gem "rubocop"
18
+ end
data/README.md ADDED
@@ -0,0 +1 @@
1
+ # inspec-cloudformation
@@ -0,0 +1,38 @@
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-cloudformation/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-cloudformation"
15
+
16
+ # It is polite to namespace your plugin under InspecPlugins::YourPluginInCamelCase
17
+ spec.version = InspecPlugins::Vault::VERSION
18
+ spec.authors = ["Andy Boutte"]
19
+ spec.email = ["andyboutte@gmail.com"]
20
+ spec.summary = "Use CloudFormation Outputs in your InSpec profiles"
21
+ spec.description = "This plugin allows InSpec 'inputs' to be provided by CloudFormation Outputs."
22
+ spec.homepage = "https://github.com/aboutte/inspec-cloudformation"
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-cloudformation.gemspec Gemfile
30
+ } + Dir.glob(
31
+ "lib/**/*", File::FNM_DOTMATCH
32
+ ).reject { |f| File.directory?(f) }
33
+ spec.require_paths = ["lib"]
34
+
35
+ # If you rely on any other gems, list them here with any constraints.
36
+ # This is how `inspec plugin install` is able to manage your dependencies.
37
+
38
+ end
@@ -0,0 +1,156 @@
1
+ require 'aws-sdk-cloudformation'
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+ # See https://github.com/inspec/inspec/blob/master/docs/dev/plugins.md#implementing-input-plugins
13
+
14
+ module InspecPlugins::Vault
15
+ class Input < Inspec.plugin(2, :input)
16
+
17
+ VALID_PATTERNS = [
18
+ Regexp.new("^databag://[^/]+/[^/]+/.+$"),
19
+ Regexp.new("^node://[^/]*/attributes/.+$"),
20
+ ].freeze
21
+
22
+ attr_reader :plugin_conf
23
+ # attr_reader :mount_point
24
+ # attr_reader :path_prefix
25
+ # attr_reader :vault
26
+ attr_reader :priority
27
+ attr_reader :input_name
28
+ attr_reader :logger
29
+
30
+ def initialize
31
+ @plugin_conf = Inspec::Config.cached.fetch_plugin_config("inspec-cloudformation")
32
+
33
+ @logger = Inspec::Log
34
+ logger.debug format("inspec-cloudformation plugin version %s", VERSION)
35
+
36
+ # @mount_point = fetch_plugin_setting("mount_point", "secret")
37
+ # @path_prefix = fetch_plugin_setting("path_prefix", "inspec")
38
+
39
+ # We need priority to be numeric; even though env vars or JSON may present it as string - hence the to_i
40
+ @priority = fetch_plugin_setting("priority", 60).to_i
41
+
42
+ # @vault = Vault::Client.new(
43
+ # address: fetch_vault_setting("vault_addr"),
44
+ # token: fetch_vault_setting("vault_token")
45
+ # )
46
+ end
47
+
48
+ # What priority should an input value recieve from us?
49
+ # This plgin does not currently allow setting this on a per-input basis,
50
+ # so they all recieve the same "default" value.
51
+ # Implements https://github.com/inspec/inspec/blob/master/dev-docs/plugins.md#default_priority
52
+ def default_priority
53
+ priority
54
+ end
55
+
56
+ # returns Array of input names as strings
57
+ # def list_inputs(profile_name)
58
+ # vault.with_retries(Vault::HTTPConnectionError) do
59
+ # path = logical_path_for_profile(profile_name)
60
+ # doc = vault.logical.read(path)
61
+ # return [] unless doc
62
+
63
+ # return doc.data[:data].keys.map(&:to_s)
64
+ # end
65
+ # end
66
+
67
+ # Fetch a value of a single input from Vault
68
+
69
+ def fetch(profile_name, input_name)
70
+ return nil if input_name.include?('_')
71
+
72
+
73
+ cf = Aws::CloudFormation::Client.new
74
+
75
+ # input format will be "cloudformation stack name / output name"
76
+
77
+ stack_name = input_name.split('/').first
78
+ output_name = input_name.split('/').last
79
+
80
+ logger.info format("The stack name is %s", stack_name)
81
+ logger.info format("The output name is %s", output_name)
82
+
83
+ name = { stack_name: stack_name }
84
+ resp = cf.describe_stacks(name)
85
+ return nil if resp.stacks.nil? || resp.stacks.empty?
86
+ stack = resp.stacks.first
87
+ stack.outputs.each do |output|
88
+ next unless output['output_key'] == output_name
89
+ return output['output_value']
90
+ end
91
+
92
+ # stacks.each do |stack|
93
+ # next if input(stack).nil? # If HRA addon was skipped we expect the input to be skipped also
94
+
95
+ # end
96
+
97
+
98
+
99
+ # @input_name = input_name
100
+
101
+ # path = logical_path_for_profile(profile_name)
102
+ # item = input_name
103
+
104
+ # if absolute_path?
105
+ # _empty, *path, item = input_name.split("/")
106
+ # path = logical_path path.join("/")
107
+ # end
108
+
109
+ # logger.info format("Reading Vault secret from %s", path)
110
+ # vault.with_retries(Vault::HTTPConnectionError) do
111
+ # doc = vault.logical.read(path)
112
+ # # Keys from vault are always symbolized
113
+ # return doc.data[:data][item.to_sym] if doc
114
+ # end
115
+ end
116
+
117
+ private
118
+
119
+ # # Assumption for profile based lookups: inputs have been stored on documents named
120
+ # # for their profiles, and each input has a key-value pair in the document.
121
+ # def logical_path_for_profile(profile_name)
122
+ # logical_path(profile_name)
123
+ # end
124
+
125
+ # def logical_path(relative_path)
126
+ # # When you actually read a value, on the KV2 backend you must
127
+ # # read secret/data/path, not secret/path (as on the CLI)
128
+ # # https://www.vaultproject.io/api/secret/kv/kv-v2.html#read-secret-version
129
+ # # Is this true for all backends?
130
+ # "#{mount_point}/data/#{prefix}#{relative_path}"
131
+ # end
132
+
133
+ # def prefix
134
+ # return "#{path_prefix}/" unless absolute_path?
135
+
136
+ # ""
137
+ # end
138
+
139
+ # def absolute_path?
140
+ # input_name.start_with?("/")
141
+ # end
142
+
143
+ def valid_plugin_input?(input)
144
+ VALID_PATTERNS.any? { |regex| regex.match? input }
145
+ end
146
+
147
+ def fetch_plugin_setting(setting_name, default = nil)
148
+ env_var_name = "INSPEC_CLOUDFORMATION_#{setting_name.upcase}"
149
+ ENV[env_var_name] || plugin_conf[setting_name] || default
150
+ end
151
+
152
+ # def fetch_vault_setting(setting_name)
153
+ # ENV[setting_name.upcase] || plugin_conf[setting_name]
154
+ # end
155
+ end
156
+ end
@@ -0,0 +1,25 @@
1
+ # Plugin Definition file
2
+ # The purpose of this file is to declare to InSpec what plugin_types (capabilities)
3
+ # are included in this plugin, and provide hooks that will load them as needed.
4
+
5
+ # It is important that this file load successfully and *quickly*.
6
+ # Your plugin's functionality may never be used on this InSpec run; so we keep things
7
+ # fast and light by only loading heavy things when they are needed.
8
+
9
+ # Presumably this is light
10
+ require "inspec-cloudformation/version"
11
+ module InspecPlugins
12
+ module Vault
13
+ class Plugin < ::Inspec.plugin(2)
14
+ # Internal machine name of the plugin. InSpec will use this in errors, etc.
15
+ plugin_name :'inspec-cloudformation'
16
+
17
+ # Define an Input plugin type.
18
+ input :vault do
19
+ require_relative "input"
20
+ InspecPlugins::Vault::Input
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,8 @@
1
+ # This file simply makes it easier for CI engines to update
2
+ # the version stamp, and provide a clean way for the gemspec
3
+ # to learn the current version.
4
+ module InspecPlugins
5
+ module Vault
6
+ VERSION = "0.0.1".freeze
7
+ end
8
+ end
@@ -0,0 +1,14 @@
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
+ libdir = File.dirname(__FILE__)
12
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
13
+
14
+ require "inspec-cloudformation/plugin"
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inspec-cloudformation
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andy Boutte
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-07-01 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: This plugin allows InSpec 'inputs' to be provided by CloudFormation Outputs.
14
+ email:
15
+ - andyboutte@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - Gemfile
21
+ - README.md
22
+ - inspec-cloudformation.gemspec
23
+ - lib/inspec-cloudformation.rb
24
+ - lib/inspec-cloudformation/input.rb
25
+ - lib/inspec-cloudformation/plugin.rb
26
+ - lib/inspec-cloudformation/version.rb
27
+ homepage: https://github.com/aboutte/inspec-cloudformation
28
+ licenses:
29
+ - Apache-2.0
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubygems_version: 3.1.6
47
+ signing_key:
48
+ specification_version: 4
49
+ summary: Use CloudFormation Outputs in your InSpec profiles
50
+ test_files: []